🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Untitled

posted in DruinkJournal
Published July 23, 2007
Advertisement
Well, I spent part of the weekend learning how to use MASM. Well, the 64-bit version at least. The end result is that now (finally) my API hooking code works in 32-bit and 64-bit. Time for a random dump:
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 :(
Previous Entry Untitled
Next Entry Untitled
0 likes 2 comments

Comments

xanin
From my limited memory of MASM (from about 3-4 years ago now), the "caller preserves as needed" comment implies that if you call another function (or whatever you'd like to call it) there is no guarantee that it will not overwrite those registers with some crap data of its own. Meaning if it matters to you, you have to copy it to a preserved register or a chunk of memory that you will preserve before you call outside. That bit me once or twice in the past. "Hmmm, thats odd, this drawing routine DID work last time, but now its all over the place..."
July 23, 2007 11:11 AM
Evil Steve
Balls. I had a feeling it might have been something like that... Unfortunately, I need two registers free to do my setup code because I can't seem to do:
pop rax
sub rax, offset lblStart
Since I get some error - I don't recall what it was now, something about the value being too large, presumably it's trying to use a 32-bit register or something odd.

Oh well, I'll see what I can do :(
July 23, 2007 12:25 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement