Sign in to follow this  
  • entries
    557
  • comments
    1237
  • views
    420959

Untitled

Sign in to follow this  
Evil Steve

83 views

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 EXECUTE

LoaderStubCode 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 0000000000000000h
varFuncRetAddr:
dq 0000000000000000h

; Save old stack frame
varOldRBP:
dq 0000000000000000h

; Save fastcall registers
varOldRCX:
dq 0000000000000000h
varOldRDX:
dq 0000000000000000h
varOldR8:
dq 0000000000000000h
varOldR9:
dq 0000000000000000h

; Loader code EOF token
dq 0a0a0a0a0a0a0a0ah;

LoaderStubCode ENDP
END


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 :(
Sign in to follow this  


2 Comments


Recommended Comments

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..."

Share this comment


Link to comment
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 :(

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now