Support Forums
[Tutorial/Explaination] Secure your application better when using GUIDTech/HWID - Printable Version

+- Support Forums (https://www.supportforums.net)
+-- Forum: Categories (https://www.supportforums.net/forumdisplay.php?fid=87)
+--- Forum: Coding Support Forums (https://www.supportforums.net/forumdisplay.php?fid=18)
+---- Forum: Visual Basic and the .NET Framework (https://www.supportforums.net/forumdisplay.php?fid=19)
+---- Thread: [Tutorial/Explaination] Secure your application better when using GUIDTech/HWID (/showthread.php?tid=19262)



[Tutorial/Explaination] Secure your application better when using GUIDTech/HWID - The-One - 06-03-2011

Hello,

This is probably one of the last tutorials I write(School, Socials, etc.) I've been working on this allot.

Now, on the last one, I've been thinking, it could be easy to crack. (I tried it). First a note, all those crack me's here doesn't make any sense, like anyone will let a customer select a set of check boxes to continue? So, you could do a few things, the CRC like I did. Tried it, could make some people sweat, but if you read a few things about Assembly you can easy crack it. (Deobfuscating makes it harder of course, but sill all those 'l33t hax0r t00ls' will help you deobfuscating it).

Now, the protection, you should be doing a few checks, simple, but it won't make your application uncrackable.

Lets start, this is my code to check if the user is a legit user:

Code:
Private Function RunCheck(ByVal GUID As String) As String
  Dim http As HttpWebRequest = HttpWebRequest.Create(Site & "?serial=" & GUID) 'The site it connects to.
  Dim res As HttpWebResponse = http.GetResponse()
  Dim res_output As New StreamReader(res.GetResponseStream)

  While res_output.EndOfStream = False
    Dim l As String = res_output.ReadLine
    If l.Contains(MD5(GUID)) Then
    Return y
    INT(1) = 1 'This comes later...
    Exit Function
    Else
    If l.Contains(MD5(MD5(GUID))) Then
    INT(1) = 1 'This comes later..
    GUIDSAVE = GUID
    Return x
    Exit Function
    End If
    End If
  End While
  http = Nothing
  res.Close()
  res_output.Close()
  Return y
    End Function

Now, x and y are the value's the script uses to let the 'Start' code know whether is passed the check or not.

As you see, my GUIDsystem/HWIDsystem will return a double hashed GUID if valid, else it just hashes it once.

Normally the check-table will be like this:


This is how I would let mine look like:


Okay, first of all those f*cking messagebox'es REMOVE THEM its so freaking easy to find those in a debugger. Then just changing ONE value and its patched.

This is my start code:

Code:
Public Sub Start(ByVal GUID As String, ByVal link As String)
  Dim res As String = RunCheck(GUID).ToString
  If res = x Then
    guidx = GUID 'I set the guid here, for later use.
    HardToDestroy(0)
    Exit Sub
  ElseIf res = y Then
    HardToDestroy(1)
    Exit Sub
  End If
    End Sub

Okay, now in Assembly something like that will be:

Code:
call 001    'RunCheck
mov B00, eax    'Set's res (String)
cmp B00, B001  'Is it X?
jz 002    'YES!  
mov B002, B003  'Set guidx
mov ebx, 0     '0 (Hard to destroy)
call 003     'Calls Hardtodestroy
jnz 003     'It didn't pass
mov ebx, 1    '1 (Hard to destroys)
call 003    'Calls hardtodestroy)

Okay, some beginner is Assembly will not see whether he has to patch jz or jnz. (Both Jumps to another code). Someone who's been using Assembly for a while might recognize it. And someone who knows Assembly will crack it.

It doesn't matter if you didn't understand the last code, but I added it for the people who wants to know it.

Oh, HardToDestroy is just a sub who kill's the process, and if it fails it just uses Me.Close. But, if the parameter is 0 it won't do a thing. And if its 1 or bigger, it will close the program.

Now, how can we protect it, so that if someone cracks/patches it, they are unable to use the program?

Simply by using threads:

Code:
Private thr As New Thread(AddressOf MainCheck)

    Private INT As Integer() = {0, 0}


Now, under your Hwid/Guid check code, add INT(0) = 1. (See my code above).

Next, in your Sub Check1() (Make it if you haven't done it) add a code which checks whether is it set or not. Make sure it starts checking at INT(1) since we use INT(0) for a different check.

Okay! You probably found out you have to use a For-Each. Now into the Check1 set INT(0) = 1.

Check this with Check2, but in check2 also check if INT(1) is set.


As you see, I added another INT(2) to check whether is passed the HardToDestroy or not.

Now, we are going to make our main-thread.
And this is how I made my MainCheck:

Code:
Private Sub MainCheck()
r:
  Array.Clear(INT, INT.GetLowerBound(0), INT.Length) 'Clear the array
  Thread.Sleep(10)
  LiveCheck()
  Thread.Sleep(1000)
  Check1()
  Thread.Sleep(100)
  Check2()
  Thread.Sleep(5000)
  GoTo r
    End Sub

YOU MUST MAKE YOUR OWN LIVECHECK - ITS JUST SOME SORT OF CHECK AS RUNCHECK

ALSO DON'T FORGET TO START MAINCHECK'S THREAD!


Now it Check's every 5 seconds weather the user is valid or not.
The only thing this does is it makes your application a little bit harder to crack.

I didn't really wanted this to be difficult but just for people who are starting protecting there programs.

Thanks for reading,

The-One