Sometimes we have sensitive code that we want to protect - perhaps its related to reading a serial/keyfile, that kind of thing. People often use executable packers to not only compress their exes to make them smaller but also to hide their code from direct disassembly. Crackers then have to 'unpack' the exe, which often simply involves running it and dumping the process module from memory.

Here is a simple macro you can use at the end of any sub or function (or even anywhere in the middle if you like), and it will 'trash' (overwrite with nullchars) all the code from the very start of the sub/func up to the point where the macro is used. Any code after the macro call is preserved.

And it goes without saying that you would only use this on subs/functions that are only called ONCE ...

Code:
#COMPILE EXE
#INCLUDE "win32api.inc"
 
MACRO TrashFunction
 MACROTEMP dwCodeStart, dwCodeLen, oldProt, EndOfProc
 LOCAL dwCodeStart AS DWORD, dwCodeLen AS DWORD, oldProt AS DWORD
 dwCodeStart = CODEPTR(Example): dwCodeLen = CODEPTR(EndOfProc) - dwCodeStart
 IF VirtualProtect(BYVAL dwCodeStart, BYVAL dwCodeLen, BYVAL %PAGE_EXECUTE_READWRITE, oldProt) THEN
    EndOfProc:
    POKE$ dwCodeStart, STRING$(dwCodeLen, 0)   '// Use 0 for nullchars, &h90 for NOPs, &hCC for Int3 breakpoints
 END IF
END MACRO
 
SUB Example
 STDOUT "This code WILL be trashed as it is before TrashFunction"
 TrashFunction   '// Trash all code in this function up to this point
 STDOUT "This code WONT be trashed as it is after TrashFunction
END SUB
 
FUNCTION PBMAIN() AS LONG
CALL Example
STDOUT "Press a key to continue ...";: WAITKEY$
END FUNCTION
Here is the Example sub from above seen in memory with a debugger - the highlighted code is the inline TrashFunction macro:


Here is the same code after using TrashFunction. As you can see the entire start of the function has been overwritten, and even most of the inline TrashFunction has also been overwritten:
Attached Files