Writing a Trampoline Function

2020-03-24 06:56发布

问题:

I have managed to overwrite the first few bytes of a function in memory and detour it to my own function. I'm now having problems creating a trampoline function to bounce control back over to the real function.

This is a second part to my question here.

BYTE *buf = (BYTE*)VirtualAlloc(buf, 12, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
void (*ptr)(void) = (void (*)(void))buf;

vm_t* VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *), vmInterpret_t interpret )
{
    MessageBox(NULL, L"Oh Snap! VM_Create Hooked!", L"Success!", MB_OK);

    ptr();

    return NULL;//control should never get this far
}

void Hook_VM_Create(void)
{
    DWORD dwBackup;
    VirtualProtect((void*)0x00477C3E, 7, PAGE_EXECUTE_READWRITE, &dwBackup);

    //save the original bytes
    memset(buf, 0x90, sizeof(buf));
    memcpy(buf, (void*)0x00477C3E, 7);

    //finish populating the buffer with the jump instructions to the original functions
    BYTE *jmp2 = (BYTE*)malloc(5);
    int32_t offset2 = ((int32_t)0x00477C3E+7) - ((int32_t)&buf+12);
    memset((void*)jmp2, 0xE9, 1);
    memcpy((void*)(jmp2+1), &offset2, sizeof(offset2));
    memcpy((void*)(buf+7), jmp2, 5);

    VirtualProtect((void*)0x00477C3E, 7, PAGE_EXECUTE_READ, &dwBackup);
}

0x00477C3E is the address of the function that has been overwritten. The asm for the original function are saved to buf before i over write them. Then my 5 byte jmp instruction is added to buf to return to the rest of the original function.

The problem arises when ptr() is called, the program crashes. When debugging the site it crashes at does not look like my ptr() function, however double checking my offset calculation looks correct.

NOTE: superfluous code is omitted to make reading through everything easier

EDIT: This is what the ptr() function looks like in ollydbg

0FFB0000   55               PUSH EBP
0FFB0001   57               PUSH EDI
0FFB0002   56               PUSH ESI
0FFB0003   53               PUSH EBX
0FFB0004   83EC 0C          SUB ESP,0C
0FFB0007  -E9 F1484EFD      JMP 0D4948FD

So it would appear as though my offset calculation is wrong.

回答1:

So your buf[] ends up containing 2 things:

  • 7 first bytes of the original instruction
  • jmp

Then you transfer control to buf. Is it guaranteed that the first 7 bytes contain only whole instructions? If not, you can crash while or after executing the last, incomplete instruction beginning in those 7 bytes.

Is it guaranteed that the instructions in those 7 bytes do not do any EIP-relative calculations (this includes instructions with EIP-relative addressing such as jumps and calls primarily)? If not, continuation in the original function won't work properly and probably will end up crashing the program.

Does the original function take any parameters? If it does, simply doing ptr(); will make that original code work with garbage taken from the registers and/or stack (depends on the calling convention) and can crash.

EDIT: One more thing. Use buf+12 instead of &buf+12. In your code buf is a pointer, not array.