From what I read, doing a checksum of code (combined with guard pages) is a good place to start to detect it. I've read quite a few references, papers, articles, etc but barely any actually list the code I'd be after. I had a quick go at doing it myself (Just to get something working) and so far I got:
- Code: Select all
HINSTANCE hInstance = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hInstance;
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD)hInstance + dosHeader->e_lfanew);
PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION (ntHeaders), codeSection = NULL;
for (int section = 0; section < ntHeaders->FileHeader.NumberOfSections; ++section)
if( sectionHeader[section].VirtualAddress <= ntHeaders->OptionalHeader.AddressOfEntryPoint //Entry point is within section (i.e. Code segment)
&& ntHeaders->OptionalHeader.AddressOfEntryPoint < sectionHeader[section].VirtualAddress + sectionHeader[section].Misc.VirtualSize )
codeSection = sectionHeader;
if(!codeSection) return 0;
//uses common crc32 implimentation
return crc32buf((char*)((DWORD)hInstance + codeSection->VirtualAddress), codeSection->Misc.VirtualSize);
I've tested it in various stages of the game and it seems to be consistent, but when compiled with /DYNAMICBASE (MSVC extention for Address Space Layout Randomization) it differs. I'm not entirely sure if that actually randomizes elements of the code segment or splits it up, or something else, but detailed documentation of implementation on windows isn't easy to come by (There's several papers about defeating it, might be able to infer it from them). Obviously it's an advantage to have it enabled for security.
Although maybe I've done it wrong, maybe I'm going about it the wrong way, I'm not sure since I've only read theory on it and only small bits of code. We already use a executable packer at the moment.
I'm wondering if anyone has already done something similar or has a better idea of what I should be looking at?