// how can I execute a jmp instruction when I need to? 1. Organize a buffer for the JMP executing
enum {
#ifndef _WIN64
jmpAddrIdx = 2, // Index of the Address in Jump-Buffer
jmpLen = 10, // Length of the Jump-Buffer
#else
jmpAddrIdx = 3, // Index of the Address in Jump-Buffer
jmpLen = 16, // Length of the Jump-Buffer
#endif
};
static BYTE jmp[jmpLen] = {
#ifdef _WIN64
0x50, // push rax (len:01)
0x48, 0xb8, // mov rax, DWORD_PTR (len:10)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x87, 0x04, 0x24, // xchg rax, [rsp] (len:04)
0xc3 // ret (len:01)
#else
0x50, // push eax (len:01)
0xb8, // mov eax, DWORD_PTR (len:05)
0x00, 0x00, 0x00, 0x00,
0x87, 0x04, 0x24, // xchg eax, [esp] (len:03)
0xc3 // ret (len:01)
#endif
};
2. Fill the address part there in (low Bytes first)
memcpy(&jmp\[jmpAddrIdx\], YOUR\_DESIRED\_ADDRESS, sizeof(DWORD\_PTR));
3. Take the pointer of an existing global function(void) (Long enough: see jmpLen above) 4. Mark the addressed space of the function as writeable
DWORD dwOldMode(0);
if (VirtualProtect(pfnYourShellFcn, jmpLen, PAGE_EXECUTE_READWRITE, &dwOldMode)) {
5. Write the jump into the function :)
memcpy(pfnOriginal, jmp, jmpLen);
6. Mark the space as original
VirtualProtect(pfnYourShellFcn, jmpLen, dwOldMode, &dwOldMode);
7. Call the pointed function :)
(*pfnYourShellFcn)()
8. Be thrilled.
They sought it with thimbles, they sought it with care; They pursued it with forks and hope; They threatened its life with a railway-share; They charmed it with smiles and soap. :)