#define UNLOCKED 0x0 #define LOCKED 0xffffffff __declspec(naked) void HookFunction() { __asm { pushf //4 bytes pusha //8 * 4 bytes = 32 bytes //Inlined TlsGetValue: mov ebx, fs:0x18 //Get linear address of ThreadInformationBlock (file:///N:/reference.html#ThreadInformationBlock) mov ecx, [tlsIndex] mov eax, [ebx + ecx*4 + 0xe10] checkSemaphore: cmp eax, LOCKED jz execute //set the semaphore: mov eax, LOCKED mov [ebx + ecx*4 + 0xe10], eax log: //Do actual logging via lookup table //Don't forget to retrieve 'stack-size' of hooked function for use in stack-shift. shiftstack: add esp, 0x4 //add some more space for a copy of return address of the target. mov ecx, 0xa //flags + registers + the a return address TODO: Add number of args. mov edi, esp sub edi, 0x2c mov esi, edi mov eax, esi //Keep a copy of the original esp in eax. sub esi, 0x4 rep movs edi, esi //We've now shifted the entire 'state block' down on the stack, creating a void. /* In addition, in this instance, the data we want in the 'void' * (our target's return address) * is already there ;) */ //now overwrite the return address to come back to returnHandler so we can unlock the hook. mov [eax], returnHandler execute: //restore state: popa popf //Execute the overwritten prolog: push ebp mov ebp, esp //return to the function: ret returnHandler: pushf pusha //Inlined TlsGetValue: mov ebx, fs:0x18 //Get linear address of ThreadInformationBlock (file:///N:/reference.html#ThreadInformationBlock) mov ecx, [tlsIndex] //set the semaphore: mov eax, UNLOCKED mov [ebx + ecx*4 + 0xe10], eax popf popa ret //to the original caller! } }