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.
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
Comment