Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Protect code from mods, bpx's etc by checksum

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PBWin/PBCC Protect code from mods, bpx's etc by checksum

    Simple example of how to use a checksum to protect a range of code (entire functions even) from any changes, such as code modifications or Int3 software breakpoints (0xCC byte).

    In this example I protect an entire function (SUB Protected()), although you can essentially use it on any code ranges - CODEPTR() and Label:'s our are friends here. You can use any checksum algorithm you like, I've simply used FNV32 here as its small and simple.

    Code:
    #COMPILE EXE
    
    FUNCTION FNV32(BYVAL dwOffset AS DWORD, BYVAL dwLen AS DWORD, BYVAL offset_basis AS DWORD) AS DWORD
    #REGISTER NONE
    ! mov esi, dwOffset      ;esi = ptr to buffer
    ! mov ecx, dwLen         ;ecx = length of buffer (counter)
    ! mov eax, offset_basis  ;set to 0 for FNV-0, or 2166136261 for FNV-1
    ! mov edi, &h01000193    ;FNV_32_PRIME = 16777619
    ! xor ebx, ebx           ;ebx = 0
    nextbyte:
    ! mul edi                ;eax = eax * FNV_32_PRIME
    ! mov bl, [esi]          ;bl = byte from esi
    ! xor eax, ebx           ;al = al xor bl
    ! inc esi                ;esi = esi + 1 (buffer pos)
    ! dec ecx                ;ecx = ecx - 1 (counter)
    ! jnz nextbyte           ;if ecx is 0, jmp to NextByte
    ! mov FUNCTION, eax      ;else, function = eax
    END FUNCTION
    
    SUB Protected()
     '// All code in this sub is protected.
     '// Any changes to the code will require regenerating the checksum.
     MSGBOX "Protected routine"
    END SUB
    
    FUNCTION PBMAIN() AS LONG
        #REGISTER NONE
        DIM dwSize AS DWORD, dwHash AS DWORD, addr1 AS DWORD, addr2 AS DWORD
        addr1 = CODEPTR(Protected)  'Addr of sub/func to protect
        addr2 = CODEPTR(PBMAIN)     'Addr of sub/func immediately under the protected one
        dwSize = addr2 - addr1 - 9  'Calculate size of code, less 9 bytes which aren't in the routine
        dwHash = FNV32(BYVAL addr1, BYVAL dwSize, BYVAL 2166136261)  'Calculate hash
        MSGBOX "Calculated hash: 0x" & HEX$(dwHash,8)
        ! mov eax, dwHash           ;eax = hash
        ! cmp eax, &hE80ED8B1       ;Compare calculated hash with known (pre-calculated) hash
        ! jne Modified              ;If theyre different, jump to Modified
        CALL Protected              'otherwise, call our protected routine as we know it's ok
        EXIT FUNCTION
        Modified:
        MSGBOX "SUB Protected() has been modified!" & $CRLF & "New hash = " & HEX$(dwHash,8)
    END FUNCTION
    -

  • #2
    The sub Protected() is never called using Windows 7, 32-bit whether recompiled or if program is called using a shortcut.
    What needs to be changed in the demo so the protected routine is called?
    This is always displayed: MSGBOX "SUB Protected() has been modified!" & $CRLF & "New hash = " & HEX$(dwHash,8)
    The world is full of apathy, but who cares?

    Comment


    • #3
      Note that the 1st time you run the program the hash will possibly be incorrect (eg. I compiled with a different version of PB than Mike Doty, so the resulting binary is slightly different), in which case you'll get the "Sub has been modified!" msgbox.

      So, simply adjust this line:
      ! cmp eax, &hE80ED8B1
      Replace &hE80ED8B1 with the hash you are shown in the msgbox.
      -

      Comment


      • #4
        Code:
        Thank you, Wayne!
        Used the returned value below and all is well!
        
        Not sure where the -9 bytes which aren't in the routine?
        Not sure how to protect the whole program?
        
        ! cmp eax, &h3BA8C29F ;Compare calculated hash with known (pre-calculated) hash
        The world is full of apathy, but who cares?

        Comment


        • #5
          To protect a local range of code instead of a sub/function (just address locations shown here) ...
          Code:
          Msgbox "Im unprotected code"
          [COLOR="DarkGreen"]ProtectStart:
           Msgbox "Im protected (you cannot modify my code or set a software breakpoint on me)"
          ProtectEnd:
          [/COLOR] 
          LOCAL lStart AS LONG, lEnd AS LONG, lLen AS LONG
          lStart = CODEPTR(ProtectStart)
          lEnd = CODEPTR(ProtectEnd)
          lLen = lEnd - lStart
          -

          Comment

          Working...
          X