Valhalla Legends Forums Archive | Visual Basic Programming | Re: Visual Basic Program Protection

AuthorMessageTime
MysT_DooM
ok so i made a little prog that asks for the user to enter a password to use the program. it was very effective for people with no cracking knowledge.

But some people were able to hex the program and figure out the password....
any1 have any ideas how to protect from these types of things or if you can point me in the right direction.
January 5, 2006, 9:15 PM
LoRd
[quote]any1 have any ideas how to protect from these types of things [/quote]

Don't use password-based authentication.
January 5, 2006, 9:16 PM
inner.
Did you put the password just in a string and that's it?
January 5, 2006, 9:20 PM
Myndfyr
[quote author=inner. link=topic=13801.msg140663#msg140663 date=1136496047]
Did you put the password just in a string and that's it?
[/quote]

Even that wouldn't be effective (hashing the password, or some other encryption method).  At the end of the day, he's going to need multiple layers of protection to be effective, including possibly runtime code modification, encryption, and code verification.
January 5, 2006, 9:35 PM
inner.
I didn't mean it to be effective, I was going to say to him if he was doing that then that would be a very inefficent/bad way of doing a Authentication Protection for a program.
January 5, 2006, 9:37 PM
MysT_DooM
Private Sub Command1_Click()
If Text1.text = "ΨΫαͮds" Then
MsgBox "Key Machine Access Granted"
Form1.Show

Else
MsgBox "Key Machine Access Denied"
Text1.text = ""
End If
Unload Me
End Sub

:(

Edit: what i was thinking was if there could be a way when the user types in the password and hits the command button, it will verify the password with a text file online at some site with the latest password. 
January 5, 2006, 10:27 PM
LoRd
[quote author=MysT_DooM link=topic=13801.msg140680#msg140680 date=1136500065]
Private Sub Command1_Click()
If Text1.text = "ΨΫαͮds" Then
MsgBox "Key Machine Access Granted"
Form1.Show

Else
MsgBox "Key Machine Access Denied"
Text1.text = ""
End If
Unload Me
End Sub

:(

Edit: what i was thinking was if there could be a way when the user types in the password and hits the command button, it will verify the password with a text file online at some site with the latest password. 
[/quote]

That would be just as easy to bypass, if not easier.
January 5, 2006, 10:47 PM
Myndfyr
[quote author=Lord[nK] link=topic=13801.msg140683#msg140683 date=1136501267]
That would be just as easy to bypass, if not easier.
[/quote]
One byte in a hex editor.
January 5, 2006, 11:07 PM
Networks
[quote author=Lord[nK] link=topic=13801.msg140683#msg140683 date=1136501267]
[quote author=MysT_DooM link=topic=13801.msg140680#msg140680 date=1136500065]
Private Sub Command1_Click()
If Text1.text = "ΨΫαͮds" Then
MsgBox "Key Machine Access Granted"
Form1.Show

Else
MsgBox "Key Machine Access Denied"
Text1.text = ""
End If
Unload Me
End Sub

:(

Edit: what i was thinking was if there could be a way when the user types in the password and hits the command button, it will verify the password with a text file online at some site with the latest password. 
[/quote]

That would be just as easy to bypass, if not easier.
[/quote]

Give the guy some slack, I highly doubt any leet crackers are THAT interested in his application.

You can do that, use MSINET control or the Winsock control. However lord is correct it's easy to just jump your entire authentication completely, I recently cracked a program like that.

I would think about who ever you're giving this application out to, if they are knowledge people they WILL crack it however if they aren't I wouldn't worry to much then. IT really depends.

Edit:
I wouldn't recommend the online thing since they could hex-edit the URL and direct to their own computer locally and use any password they choose. Try to create an algorithm of some sort similar to serials. Seems harder to crack and can be unique to each user.
January 5, 2006, 11:13 PM
LoRd
[quote author=MyndFyre link=topic=13801.msg140688#msg140688 date=1136502420]
[quote author=Lord[nK] link=topic=13801.msg140683#msg140683 date=1136501267]
That would be just as easy to bypass, if not easier.
[/quote]
One byte in a hex editor.
[/quote]

Or a single viewing of a webpage. ;p
January 5, 2006, 11:13 PM
LoRd
[quote author=Networks link=topic=13801.msg140690#msg140690 date=1136502801]
[quote author=Lord[nK] link=topic=13801.msg140683#msg140683 date=1136501267]
[quote author=MysT_DooM link=topic=13801.msg140680#msg140680 date=1136500065]
Private Sub Command1_Click()
If Text1.text = "ΨΫαͮds" Then
MsgBox "Key Machine Access Granted"
Form1.Show

Else
MsgBox "Key Machine Access Denied"
Text1.text = ""
End If
Unload Me
End Sub

:(

Edit: what i was thinking was if there could be a way when the user types in the password and hits the command button, it will verify the password with a text file online at some site with the latest password. 
[/quote]

That would be just as easy to bypass, if not easier.
[/quote]

Give the guy some slack, I highly doubt any leet crackers are THAT interested in his application.[/quote]

They were interested enough to "crack" it in the first place.

We're simply trying to make a point: It's difficult to secure an application from even the most novice "crackers".  There was an enitre thread concerning this exact topic made just a few months ago.  I'd recommend looking it over.
January 5, 2006, 11:14 PM
Forged
This is still easy to crack, just by nopping the entire check, but it might keep out some of the hex kids.
[code]
Public Function Hash(ByVal Val$)
On Error Resume Next
Dim Q$

If Len(Val) <> 12 Then
    MsgBox "Invalid Password, Try Again", vbExclamation, "Wrong"
    Form1.txtPass = ""
Else
    Q = Val * 12
    'Form1.txtPass = Q
    ' 1 0 5 1 6 2 5 1 5 8 5 0 2 4
    ' L    L E    L          O
    Q = Replace(Q, "0", "")
    Q = Replace(Q, "1", "L")
    Q = Replace(Q, "2", "")
    Q = Replace(Q, "3", "")
    Q = Replace(Q, "4", "O")
    Q = Replace(Q, "5", "")
    Q = Replace(Q, "6", "E")
    Q = Replace(Q, "7", "")
    Q = Replace(Q, "8", "")
    'Form1.txtPass = Q
        If Len(Q) <> 5 Then
            MsgBox "Invalid Password, Try Again", vbExclamation, "Wrong"
            Form1.txtPass = ""
        Else
            Q = Replace(Q, "L", 7)
            Q = Replace(Q, "O", 3)
            Q = Replace(Q, "E", 5)
            Q = Q * 3
            'Form1.txtPass = Q
            '2 3 2 7 1 9
            '  K  I L L
           
                If Len(Q) = 6 Then
                    Q = Replace(Q, "2", "")
                    Q = Replace(Q, "3", "k")
                    Q = Replace(Q, "7", "i")
                    Q = Replace(Q, "1", "l")
                    Q = Replace(Q, "9", "L")
                        If Q = "kilL" Then
                            Form2.Show
                        Else
                            MsgBox "Invalid Password, Try Again", vbExclamation, "Wrong"
                            Form1.txtPass = ""
                        End If
                Else
                    MsgBox "Invalid Password, Try Again", vbExclamation, "Wrong"
                    Form1.txtPass = ""
                End If
        End If
           
           
End If

End Function
[/code]
January 5, 2006, 11:23 PM
JoeTheOdd
May want to post what hashes to kilL.
January 6, 2006, 12:16 AM
Forged
or just look at the source code, doesn't take a rocket scientist. 
January 6, 2006, 1:53 AM
laurion
Use hardware based authorization [Grab info about their system, make it a hex string, check a website for the string].
January 6, 2006, 3:27 AM
rabbit
The user can alter hosts to point to their own auth page, so online checking isn't the most effective method ever.
January 6, 2006, 4:05 AM
laurion
use  the hardware method, check it a different way-perhaps code in all the valid serials into the prog?
January 6, 2006, 4:13 AM
KkBlazekK
Okay, reverse engineer it and make a program that generates the code for your hardware.
January 6, 2006, 10:37 AM
laurion
Now come on, how many people are really going to know how to do that, or yet, do it effectively?  :-\ Thats an effective auth method and has worked for me so far.  ;D If I can find the code (reformat) I will help you out..
January 6, 2006, 3:43 PM
MysT_DooM
thx , ill research more into some of ur guys ideas and implement them.

and networks "Give the guy some slack, I highly doubt any leet crackers are THAT interested in his application."

ouch thas low :( 
well maybe some of u know maybe not but i am making a very unique Key Generator...the general decription is on www.BnetWarfare.cjb.net
On the site the current ver is 1.0 but its up to 1.3 now and i added the decode and encode options to it plus User Specified Generating so u can generate as many keys as u like.  I didnt implement any of the algo or similarties into the generating yet, but if u guys want to take a look at the prog so far, pm me.
January 6, 2006, 4:20 PM
Networks
[quote author=MysT_DooM link=topic=13801.msg140816#msg140816 date=1136564418]
thx , ill research more into some of ur guys ideas and implement them.

and networks "Give the guy some slack, I highly doubt any leet crackers are THAT interested in his application."

ouch thas low :( 
well maybe some of u know maybe not but i am making a very unique Key Generator...the general decription is on www.BnetWarfare.cjb.net
On the site the current ver is 1.0 but its up to 1.3 now and i added the decode and encode options to it plus User Specified Generating so u can generate as many keys as u like.  I didnt implement any of the algo or similarties into the generating yet, but if u guys want to take a look at the prog so far, pm me.
[/quote]

Yeah....well...wasn't REALLY meant like that but you can tell that if you don't know how to create a better auth protection then a plain text password to your program chances are that your program probably isn't that great as well.

It's probably better to suit your auth protection needs based on your users, that way you don't go through to much trouble for something possibly frivolous. No offense. :D
January 6, 2006, 4:40 PM
rabbit
off-topic: Not only is that website horrible, it's flying text shit is annoying as hell.

on-topic: No matter how strong your protection is, all that is required to override it is to change 1 instruction if all you do is an "if(legitimateProgram() == true)" sort of thing.
January 7, 2006, 3:52 AM
MysT_DooM
Rabbit, if you read the second pop up it tells you site was never ment to be fancy or nice looking.....
January 7, 2006, 4:15 AM
laurion
not sure how efficient this is, you dont need all the API of course
the registry code is not mine, got it off pscode  :P



[code]
Option Explicit

'----[ API's ]----'
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long
Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, lpcbName As Long, ByVal lpReserved As Long, ByVal lpClass As String, lpcbClass As Long, lpftLastWriteTime As Any) As Long
Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, ByVal lpData As String, lpcbData As Long) As Long
Private Declare Function RegQueryValueExA Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, ByRef lpData As Long, lpcbData As Long) As Long
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long
Private Declare Function RegSetValueExA Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Long, ByVal cbData As Long) As Long
Private Declare Function RegSetValueExB Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Byte, ByVal cbData As Long) As Long
Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long

'----[ Constants ]----'
Private Const ERROR_SUCCESS = 0&
Private Const ERROR_BADDB = 1009&
Private Const ERROR_BADKEY = 1010&
Private Const ERROR_CANTOPEN = 1011&
Private Const ERROR_CANTREAD = 1012&
Private Const ERROR_CANTWRITE = 1013&
Private Const ERROR_OUTOFMEMORY = 14&
Private Const ERROR_INVALID_PARAMETER = 87&
Private Const ERROR_ACCESS_DENIED = 5&
Private Const ERROR_NO_MORE_ITEMS = 259&
Private Const ERROR_MORE_DATA = 234&
Private Const KEY_QUERY_VALUE = &H1&
Private Const KEY_SET_VALUE = &H2&
Private Const KEY_CREATE_SUB_KEY = &H4&
Private Const KEY_ENUMERATE_SUB_KEYS = &H8&
Private Const KEY_NOTIFY = &H10&
Private Const KEY_CREATE_LINK = &H20&
Private Const READ_CONTROL = &H20000
Private Const WRITE_DAC = &H40000
Private Const WRITE_OWNER = &H80000
Private Const SYNCHRONIZE = &H100000
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const STANDARD_RIGHTS_READ = READ_CONTROL
Private Const STANDARD_RIGHTS_WRITE = READ_CONTROL
Private Const STANDARD_RIGHTS_EXECUTE = READ_CONTROL
Private Const STANDARD_RIGHTS_ALL = &H1F0000
Private Const KEY_READ = STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY
Private Const KEY_WRITE = STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY
Private Const KEY_EXECUTE = KEY_READ
Private Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))

'----[ Enums ]----'
Public Enum rcMainKey      'root keys constants
    HKEY_CLASSES_ROOT = &H80000000
    HKEY_CURRENT_USER = &H80000001
    HKEY_LOCAL_MACHINE = &H80000002
    HKEY_USERS = &H80000003
    HKEY_PERFORMANCE_DATA = &H80000004
    HKEY_CURRENT_CONFIG = &H80000005
    HKEY_DYN_DATA = &H80000006
End Enum

Public Enum rcRegType      'data types constants
    REG_NONE = 0
    REG_SZ = 1
    REG_EXPAND_SZ = 2
    REG_BINARY = 3
    REG_DWORD = 4
    REG_DWORD_LITTLE_ENDIAN = 4
    REG_DWORD_BIG_ENDIAN = 5
    REG_LINK = 6
    REG_MULTI_SZ = 7
    REG_RESOURCE_LIST = 8
    REG_FULL_RESOURCE_DESCRIPTOR = 9
    REG_RESOURCE_REQUIREMENTS_LIST = 10
End Enum

'----[ Dim's ]----'
Private hKey            As Long
Private mainKey          As Long
Private sKey            As String
Private lBufferSize      As Long
Private lDataSize        As Long
Private ByteArray()      As Byte
Private createNoExists  As Boolean
Dim blnTime As Boolean

'---------------------'

Public Function ReadString(ByVal sPath As String, ByVal sName As String, _
                          Optional sDefault As String = vbNullChar) As String
   
    Dim sdata As String, lDuz As Long
   
    hKey = GetKeys(sPath, sKey)
   
    'try to open key
    If (RegOpenKeyEx(hKey, sKey, 0, KEY_READ, mainKey) = ERROR_SUCCESS) Then
        sdata = Space(255)    'make buffer
        lDuz = Len(sdata)      'get buffer size (255)
        'try to query data
        If (RegQueryValueEx(mainKey, sName, 0, REG_SZ, sdata, lDuz) = ERROR_SUCCESS) Then
            RegCloseKey mainKey 'close key
            sdata = Trim$(sdata) 'trims string
            ReadString = Left$(sdata, Len(sdata) - 1) 'returning readed value
        Else
            ReadString = sDefault 'return default value (error)
        End If
    Else
        ReadString = sDefault 'return default value (error)
    End If

End Function
Private Function GetKeys(sPath As String, sKey As String) As rcMainKey
Dim pos As Long, mk As String
   
    'replace long with short root constants
    sPath = Replace$(sPath, "HKEY_CURRENT_USER", "HKCU", , , 1)
    sPath = Replace$(sPath, "HKEY_LOCAL_MACHINE", "HKLM", , , 1)
    sPath = Replace$(sPath, "HKEY_CLASSES_ROOT", "HKCR", , , 1)
    sPath = Replace$(sPath, "HKEY_USERS", "HKUS", , , 1)
    sPath = Replace$(sPath, "HKEY_PERFORMANCE_DATA", "HKPD", , , 1)
    sPath = Replace$(sPath, "HKEY_DYN_DATA", "HKDD", , , 1)
    sPath = Replace$(sPath, "HKEY_CURRENT_CONFIG", "HKCC", , , 1)
   
    pos = InStr(1, sPath, "\") 'get pos of first slash

    If (pos = 0) Then 'writting to root
        mk = UCase$(sPath)
        sKey = ""
    Else
        mk = UCase$(Left$(sPath, 4)) 'get hkey
        sKey = Right$(sPath, Len(sPath) - pos) 'get path
    End If
   
    Select Case mk 'return main key handle
        Case "HKCU": GetKeys = HKEY_CURRENT_USER
        Case "HKLM": GetKeys = HKEY_LOCAL_MACHINE
        Case "HKCR": GetKeys = HKEY_CLASSES_ROOT
        Case "HKUS": GetKeys = HKEY_USERS
        Case "HKPD": GetKeys = HKEY_PERFORMANCE_DATA
        Case "HKDD": GetKeys = HKEY_DYN_DATA
        Case "HKCC": GetKeys = HKEY_CURRENT_CONFIG
    End Select
   
End Function

Private Sub cmdCheck_Click()
txtKey.Text = StrToHex(ReadString("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\SYSTEM", "SystemBiosVersion"))
txtKey.Text = txtKey.Text & StrToHex(ReadString("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0", "Identifier"))
txtKey.Text = txtKey.Text & StrToHex(ReadString("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0", "ProcessorNameString"))
lblCount.Caption = "Length of String: " & Len(txtKey.Text)
End Sub

Public Function StrToHex(ByVal String1 As String) As String
Dim strTemp As String, strReturn As String, i As Long
For i = 1 To Len(String1)
strTemp = Hex(Asc(Mid(String1, i, 1)))
If Len(strTemp) = 1 Then strTemp = "0" & strTemp
strReturn = strReturn & strTemp
Next i
StrToHex = strReturn
End Function[/code]
You could either store all the valid key strings in a string array, or use inet to check them on a website, or use winsock to check on a website [by connecting to the server via port 80, sending a GET request, easier than using inet because tis 1 less file your user might not have].
January 7, 2006, 8:04 PM
Newby
If you used a hash-based authentication (translate the password into a hash and compare it with the hash so all they see is the hash value when they disassemble it) I bet they'll give up.
January 7, 2006, 8:42 PM
Yegg
[quote author=MysT_DooM link=topic=13801.msg140900#msg140900 date=1136607353]
Rabbit, if you read the second pop up it tells you site was never ment to be fancy or nice looking.....
[/quote]

What he was getting at is that it causes an annoyance.
January 8, 2006, 6:59 PM
KkBlazekK
[quote author=Newby link=topic=13801.msg140973#msg140973 date=1136666550]
If you used a hash-based authentication (translate the password into a hash and compare it with the hash so all they see is the hash value when they disassemble it) I bet they'll give up.
[/quote]
[quote author=MyndFyre link=topic=13801.msg140688#msg140688 date=1136502420]
One byte in a hex editor.
[/quote]
January 13, 2006, 12:35 AM
Quarantine
Here's a totally new and radical idea: Pack your code.
January 13, 2006, 12:59 AM
rabbit
I used to do that, but Newby kept screaming at me like "I'LL JUST UNPACK IT!!"  That combined with me not caring that much, I stopped packing.  It was just an extra step in my release process.  Although, for some of my larger programs (the beastly 2meg FoFoBot), doing a upx brought that down to a nice 800kb.
January 13, 2006, 3:55 AM
Quarantine
Don't use UPX when one parameter can depack it :p
January 13, 2006, 10:45 AM
rabbit
That's what I meant.
January 13, 2006, 5:41 PM
Networks
[quote author=rabbit link=topic=13801.msg141606#msg141606 date=1137124517]
I used to do that, but Newby kept screaming at me like "I'LL JUST UNPACK IT!!"  That combined with me not caring that much, I stopped packing.  It was just an extra step in my release process.  Although, for some of my larger programs (the beastly 2meg FoFoBot), doing a upx brought that down to a nice 800kb.
[/quote]

Or use a commercial packer that isn't as popular? Find a packer that doesn't also have an immediate unpacker. In other words do some research on your packer at least. There are numerous code obfuscation techniques that you can use beside a packer though.
January 13, 2006, 10:41 PM
rabbit
Another solution is to just go open source :)
January 13, 2006, 10:59 PM
TheMinistered
Or... you could... go out on a wiiiide branch... and write your own packer? ;p like omg! why didn't I think of that?  That way... they need knowledge of asm and how packers work...
January 18, 2006, 6:35 AM
Newby
[quote author=Blaze link=topic=13801.msg141590#msg141590 date=1137112547]
[quote author=Newby link=topic=13801.msg140973#msg140973 date=1136666550]
If you used a hash-based authentication (translate the password into a hash and compare it with the hash so all they see is the hash value when they disassemble it) I bet they'll give up.
[/quote]
[quote author=MyndFyre link=topic=13801.msg140688#msg140688 date=1136502420]
One byte in a hex editor.
[/quote]
[/quote]

Eww, I forgot about that. Wow. :O
January 21, 2006, 2:58 AM
MysT_DooM
I've decided to implement the hardware based auth, seems like the best one.
January 22, 2006, 2:39 AM
rabbit
[quote author=MyndFyre link=topic=13801.msg140688#msg140688 date=1136502420]
One byte in a hex editor.
[/quote]
January 22, 2006, 2:26 PM
laurion
[quote author=rabbit link=topic=13801.msg142753#msg142753 date=1137940008]
[quote author=MyndFyre link=topic=13801.msg140688#msg140688 date=1136502420]
One byte in a hex editor.
[/quote]
[/quote]
Then why don't you tell him how to do it instead of making useless posts like that? You obviously know, tell.
January 22, 2006, 2:28 PM
Networks
God just use that auth and find some commercial packer like SoftComp and I am sure you'll be fine.
January 22, 2006, 3:52 PM
rabbit
[quote author=Tazo link=topic=13801.msg142754#msg142754 date=1137940121]
[quote author=rabbit link=topic=13801.msg142753#msg142753 date=1137940008]
[quote author=MyndFyre link=topic=13801.msg140688#msg140688 date=1136502420]
One byte in a hex editor.
[/quote]
[/quote]
Then why don't you tell him how to do it instead of making useless posts like that? You obviously know, tell.
[/quote]It's been said before: pack it.  Just about every check that can be done from VB is pretty much "IF x Then Y", where all you have to do is change je to jne.  It's pretty blatant if you've read the entire thread.
January 22, 2006, 11:20 PM
JoeTheOdd
How not to protect your program.
January 23, 2006, 3:16 AM
rabbit
Joe, that wasn't protected at all.
January 23, 2006, 11:30 PM

Search