Notice these C++ local variable instruction lengths are 8-bytes within the red box
48 c7 45 f8 00 00 00 00
...
However, the instruction lengths are 11-bytes within the green box
48 c7 85 78 ff ff ff 00 00 00 00
...
https://godbolt.org/z/bTsxx63rT
I was working on some shellcode that required patching API addresses but noticed errors because the local variable instructions lengths jumped from 8 to 11 bytes. Anyhow, thru trial and error, to enforce all the instructions to be 11 bytes, I added a local array
char enforce_mov_long_form[128];
to avoid accessing locals in the range [rbp-0x8]
to [rbp-0x80]
DWORD WINAPI shellcode_start(void)
{
char enforce_mov_long_form[128];
// ------------------------------------------------------------
QWORD start_shellcode = 0xAAAAAAAAAAAAAAAA;
DWORD sizeofshellcode = 0xAAAAAAAA;
QWORD start_shellcode_injector = 0xAAAAAAAAAAAAAAAA;
DWORD pid_injector = 0xAAAAAAAA;
QWORD WinExec = 0xAAAAAAAAAAAAAAAA;
QWORD Sleep = 0xAAAAAAAAAAAAAAAA;
QWORD CreateToolhelp32Snapshot = 0xAAAAAAAAAAAAAAAA;
QWORD Process32First = 0xAAAAAAAAAAAAAAAA;
QWORD Process32Next = 0xAAAAAAAAAAAAAAAA;
QWORD CloseHandle = 0xAAAAAAAAAAAAAAAA;
QWORD OpenProcess = 0xAAAAAAAAAAAAAAAA;
QWORD VirtualAllocEx = 0xAAAAAAAAAAAAAAAA;
QWORD VirtualFreeEx = 0xAAAAAAAAAAAAAAAA;
QWORD WriteProcessMemory = 0xAAAAAAAAAAAAAAAA;
QWORD CreateRemoteThread = 0xAAAAAAAAAAAAAAAA;
QWORD CompareStringA = 0xAAAAAAAAAAAAAAAA;
QWORD GetCurrentProcessId = 0xAAAAAAAAAAAAAAAA;
// ------------------------------------------------------------
Why is there a sudden transition from 8-byte to 11-byte instruction lengths for local variables?
Are there any micro optimizations gained by confining local variables within [rbp-0x8]
to [rbp-0x80]
?
Promoting comments to answer:
x86-64 addressing modes encode the displacement as either a signed 8-bit (1 byte) or signed 32-bit (4 bytes) value, which in either case is sign-extended to 64 bits. Since the range of a signed 8-bit integer is [-128..127]
or [-0x80..0x7f]
, displacements outside this range must use the 32-bit form instead, making the instruction three bytes longer.
For more on how addressing modes are encoded, see https://wiki.osdev.org/X86-64_Instruction_Encoding and Referencing the contents of a memory location. (x86 addressing modes).