stub SEGMENT READ WRITE EXECUTELoaderStubCode PROC ; Get function base offset to access "local" data into r10 call lblStart lblStart: pop r10 mov rax, offset lblStart sub r10, rax ; Store registers, then use rbp for var offsets mov [r10+varOldRBP], rbp mov [r10+varOldRCX], rcx mov [r10+varOldRDX], rdx mov [r10+varOldR8], r8 mov [r10+varOldR9], r9 mov rbp, r10 ; Store function return address pop rax mov [rbp+varFuncRetAddr], rax ; Call LoadLibrary() to load target DLL and store HMODULE mov rcx, 101010101010101h ; DLLNAME_TOKEN mov rax, 0202020202020202h ; LOADLIB_TOKEN call rax mov [rbp+varTargetHMod], rax ; Call GetProcAddress() mov rcx, [rbp+varTargetHMod] mov rdx, 0303030303030303h ; FUNCNAME_TOKEN mov rax, 0404040404040404h ; GETPROCADDRESS_TOKEN call rax ; Restore fastcall regs and call target function mov rcx, [rbp+varOldRCX] ; rcx = first arg mov rdx, [rbp+varOldRDX] ; rdx = second arg mov r8, [rbp+varOldR8] ; r8 = third arg mov r9, [rbp+varOldR9] ; r9 = fourth arg call rax ; rax = address from GetProcAddress ; Call FreeLibrary to free the target DLL mov rcx, [rbp+varTargetHMod] mov rax, 0505050505050505h ; FREELIB_TOKEN call rax ; Restore function return addresss push [rbp+varFuncRetAddr] ; Restore RBP mov rbp, [rbp+varOldRBP] ; Return ret ; "Local variables"varTargetHMod: dq 0000000000000000hvarFuncRetAddr: dq 0000000000000000h ; Save old stack framevarOldRBP: dq 0000000000000000h ; Save fastcall registersvarOldRCX: dq 0000000000000000hvarOldRDX: dq 0000000000000000hvarOldR8: dq 0000000000000000hvarOldR9: dq 0000000000000000h ; Loader code EOF token dq 0a0a0a0a0a0a0a0ah;LoaderStubCode ENDPEND
Yup. That's ugly. I'm not really sure if I'm "allowed" to use r10 for my own stuff, the MSDN docs aren't that clear: "R10:R11 - Volatile - Must be preserved as needed by caller; used in syscall/sysret instructions" What does it mean "as needed", exactly?
Also, the x64 calling convetion (fastcall hybrid) annoys me. I loose most of my registers :(