Can I make my VB exe detect tampering with its own code?

Is it possible to make my .exe know if it has been altered, like a CRC or something?
rbendAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mark2150Commented:
Yeah, but it generally isn't worth the effort as there is very little hacking of the .EXE files going on.

One easy way to make a hidden copyright that is essentially tamper proof is to make a little .BMP that has your copyright notice on it. Load this into a PictureBox at design time. This will be compiled into your program as the .Picture property of some invisible control and the text of the .BMP is a pattern of *dots* and not ASCII so ASCII scanners won't see it. You set the .Visible property TRUE when some oddball combination is true (Alt/Shift/Double Right Click on the background of the form, etc) and *bang* you can prove it's *YOUR* code and there is essentially no way anyone is going to stumble across it or be able to alter it once the program is compiled.

M
0
KDivadCommented:
How about this? It ain't pretty, but it might work.

To check the file:
1. When app starts (before it is visible), shell a "checker" app and end the main one. If the "checker" app is unavailable, end the main one.
2. The checker app should now begin to try to open the main one as a file.
3. Read the file in about 1000 byte chunks.
4. Figure some way to verify a total for these bytes. Might I suggest adding the ANSI codes?
5a. If all the totals for each chunk are correct, you can probably assume that the app hasn't been modified and can relaunch it.
5b. If a total is incorrect, then the main app is either corrupt or has been modified. Either way, it shouldn't be run.

Main app:

Sub Form_Load

    If Left$(Command$, 4) <> "Good" Then
        x = Shell("Checker.app " & Command$)
        End
    End If
    Params = Right$(Command$, Len(Command$) - 5)

End Sub

Checker app:

Sub Verify()

    Dim FT As String
    Open Main.app For Binary As 1
    For I = 1 To Whatever
        Get #1, , FT
        ChunkTotal = 0
        For J = 1 To Len(FT)
            ChunkTotal = ChunkTotal + Asc(Mid$(FT, I, 1)
        Next
        If Not VerifyTotal(I, CheckTotal) Then
            'File is not the same as original
            End
        End If
    Next
    'If it gets this far, the file is the same as original
    Shell("Main.app Good " & Command$)

End Sub

Function VerifyTotal(ByVal Chunk As Long, ByVal Total As Long) As Boolean

    Select Case Chunk
    Case 1
        If Not Total = Whatever Then VerifyTotal = False
    Case ...
    ...
    End Select

End Function


This would (assuming it's coded properly) require that both apps be modified in order for a modified copy of the original to pass the test. Combined with Mark's suggestion, this could make a strong defense against a lot of foul play.

Later,
0
KDivadCommented:
If done right, you could also make it look like a single app instead of the bouncing back and forth.
0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

cvidlerCommented:
I've been working on something that will suit you perfectly.

When you've finished compiling your program, run a branding program on the finished executable, this will calculate a CRC32 of the whole file and store the CRC32 in the executable file in such a way that the calculated CRC does not alter the CRC of the file (that's the bit I haven't perfected yet)

And when your program runs it will check itself against the stored CRC.

Now as mentioned I have not finished it yet, but when I do I'll post a message on EE and other sites to tell everyone...
0
mark2150Commented:
The trick is to exclude the CRC's location from the computation of the CRC! Been there - done that!

This is not a major item to defeat. Have broken a couple of CRC based locks in my time. It ain't that hard to do.

M
0
cvidlerCommented:
You misunderstand,

I'm working on a way (it can be done) to include teh CRC with the file data in teh crc calculation, this involves complex (matrix math) algorithms (but only in the CRC creator) to do - It is not perfect yet, works sometimes other not.

eg.

The actual CRC becomes part of the file data (of which all gets calculated) thus making it a whole lot harder to crack.
0
rbendAuthor Commented:
To Mark2150: Thank you for your response but I believe (after visiting many crack NG's, that hacking of .exe's is done all the time. That's my concern. I have a good program and I want to try to keep it worth something for as long as I can.
To CVIDLER: You seem to be on the track of what I need, but of course I can't award the points if the answer isn't available. PLEASE e-mail me with your solution when its ready. (soon I hope)
rbender@rosina.com
To KDIVAD: You have an interesting suggestion. I will try to implement it and see if it suites the application. I may ask you for clarification
0
mark2150Commented:
Don't overvalue your program. The marketplace has pretty well decided that copy protection is not worth the effort. Programs need to have the programmer spend time making the app better, not coding copy protection.

Put a hidden copyright in your app so you can *PROVE* that it's your property and let 'em steal. Sue the pants off anyone you catch.

Business users will tend to *BUY* copies of software even if they got a hacked version *first*. This is because they are stationary targets and can't base their business on some hacked app. Lots of home users run illegal copies of software but this tends to build the "buzz" about the apps and *generate* sales. A lot of hackers "crack" a program just to see what it takes, play with it for a little while and then move on to the next one. They're not *using* your app even though they have a cracked copy of it so you're not loosing sales.

With connection to the internet becomming almost universal, why not have your app sense if it's on the net and if so, have it send a quickie little message to you with the machine ID, IP address, etc.? At least this way you'ld know who to look at for theft?

M
0
KDivadCommented:
rbend, I will be waiting to see if you need help.
0
rbendAuthor Commented:
KDavid:
I guess I do. I tried your "checker" app Idea but just couldn't make it work.
Maybe you could write it up using real stuff like Notepad or something??
0
KDivadCommented:
Give me just a few moments...
0
KDivadCommented:
Alright, this is what I have. I used it on notepad and it works fine.

I wrote this first function to make life a little easier for you (and me). It opens the app(or any file) that you are going to want to check and generates the Verifier function. You pass three params to it. The first param is the app you wish to check. The second is the output file to print the function into. The third is the size of each section to check. (Notepad is 53,248 bytes long. A section size of 1000 bytes will make the verifier function have 54 cases in the select case. Smaller sections are probably more accurate while larger sections are slightly faster and make a smaller function. Defaults to 10000 bytes.) Returns false if it failed for some reason, true if it succeeded.

Public Function CreateVerifierRoutine(ByVal VerifyApp As String, ByVal OutPutFile As String, Optional ByVal ChunkSize As Long = 10000) As Boolean

    Dim FFile As Long
    Dim Chunk As String
    Dim Extra As String
    Dim NumChunks As Long
    Dim Total As Long
    Dim I As Long
    Dim Final As String
On Error GoTo hError
    FFile = FreeFile
    Chunk = String(ChunkSize, 0)
    Open VerifyApp For Binary As FFile
    NumChunks = LOF(1) \ ChunkSize
    If NumChunks * ChunkSize < LOF(1) Then Extra = String(LOF(1) - NumChunks * ChunkSize, 0)
    Final = "Public Function Verifier(ByVal ChunkNumber As Long, ByVal ChunkTotal As Long) As Boolean" & vbNewLine & vbNewLine & "    Select Case ChunkNumber" & vbNewLine
    For I = 1 To NumChunks
        Get #1, , Chunk
        Total = 0
        For J = 1 To ChunkSize
            Total = Total + Asc(Mid$(Chunk, J, 1))
        Next
        Final = Final & "    Case " & CStr(I) & vbNewLine & "        Verifier = IIF(ChunkTotal = " & CStr(Total) & ", True, False)" & vbNewLine
        DoEvents
    Next
    If Not Extra = "" Then
        Get #1, , Extra
        Total = 0
        For J = 1 To Len(Extra)
            Total = Total + Asc(Mid$(Extra, J, 1))
        Next
        Final = Final & "    Case " & CStr(I) & vbNewLine & "        Verifier = IIF(ChunkTotal = " & CStr(Total) & ", True, False)" & vbNewLine
    End If
    Close
    Final = Final & "    End Select" & vbNewLine & vbNewLine & "End Function"
    Open OutPutFile For Binary As FFile
    Put #1, , Final
    Close
    CreateVerifierRoutine = True
    Exit Function

hError:
    CreateVerifierRoutine = False

End Function

This second function is the one in your final app. Pass two parameters. The first is the app(or file) to check and the second is the section size from earlier. (You may notice that it's almost identical to the previous function.) This is the one you would call from your "checker" app.

Public Function VerifierRoutine(ByVal VerifyApp As String, ByVal ChunkSize As Long) As Boolean

    Dim FFile As Long
    Dim Chunk As String
    Dim Extra As String
    Dim NumChunks As Long
    Dim Total As Long
    Dim I As Long
On Error GoTo hError
    FFile = FreeFile
    Chunk = String(ChunkSize, 0)
    Open VerifyApp For Binary As FFile
    NumChunks = LOF(1) \ ChunkSize
    If NumChunks * ChunkSize < LOF(1) Then Extra = String(LOF(1) - NumChunks * ChunkSize, 0)
    For I = 1 To NumChunks
        Get #1, , Chunk
        Total = 0
        For J = 1 To ChunkSize
            Total = Total + Asc(Mid$(Chunk, J, 1))
        Next
        If Not Verifier(I, Total) Then
            VerifierRoutine = False
            Exit Function
        End If
        DoEvents
    Next
    If Not Extra = "" Then
        Get #1, , Extra
        Total = 0
        For J = 1 To Len(Extra)
            Total = Total + Asc(Mid$(Extra, J, 1))
        Next
        If Not Verifier(I, Total) Then
            VerifierRoutine = False
            Exit Function
        End If
    End If
    Close
    VerifierRoutine = True
    Exit Function

hError:
    VerifierRoutine = False

End Function

This third function is an excerpt from the Verifier function generated when I tested it on Notepad.

Public Function Verifier(ByVal ChunkNumber As Long, ByVal ChunkTotal As Long) As Boolean

    Select Case ChunkNumber
    Case 1
        Verifier = IIf(ChunkTotal = 14698, True, False)
    Case 2
        Verifier = IIf(ChunkTotal = 0, True, False)
    ...
    ...
    ...
    Case 53
        Verifier = IIf(ChunkTotal = 0, True, False)
    Case 54
        Verifier = IIf(ChunkTotal = 0, True, False)
    End Select

End Function

Hope this helps!
Let me know if you need more help.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rbendAuthor Commented:
thanks for your extra effort. I don't have it working totally yet but I have enough to know this is what I want.
0
KDivadCommented:
Glad I could help!
Are you having any specific problems?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.