Replacement for Inline Assembly
-
Since 64-bit C++ code does not allow inline assembly instructions, how can I execute a
jmp
instruction when I need to?The difficult we do right away... ...the impossible takes slightly longer.
-
Since 64-bit C++ code does not allow inline assembly instructions, how can I execute a
jmp
instruction when I need to?The difficult we do right away... ...the impossible takes slightly longer.
-
Since 64-bit C++ code does not allow inline assembly instructions, how can I execute a
jmp
instruction when I need to?The difficult we do right away... ...the impossible takes slightly longer.
"Real men drive manual transmission" - Rajesh.
-
Since 64-bit C++ code does not allow inline assembly instructions, how can I execute a
jmp
instruction when I need to?The difficult we do right away... ...the impossible takes slightly longer.
// 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. :)
-
// 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. :)
That's a great answer. Thanks! :)
The difficult we do right away... ...the impossible takes slightly longer.
-
Richard MacCutchan wrote:
Why would you need to?
I want to transfer control to a different function without disturbing the stack. (Without
push
ing anything more onto it.The difficult we do right away... ...the impossible takes slightly longer.
-
// 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. :)
-
Since 64-bit C++ code does not allow inline assembly instructions, how can I execute a
jmp
instruction when I need to?The difficult we do right away... ...the impossible takes slightly longer.
-
I did think of that, however I don't know if it works across functions.
The difficult we do right away... ...the impossible takes slightly longer.