I have a user-mode driver (DLL) with several exported functions. Some of
these functions are stubs that redirect to the appropriate function defined
in another module. Since I don’t know the function prototypes for all the
functions that I need stubs for, I’ve implemented the stubs using ASM so I
can more easily pass the arguments along.
A stub roughly goes like this:
* Stub gets called.
* Call a C function that loads the appropriate target module and returns the
function pointer to the desired function.
* Execute a jmp to the returned function pointer.
Doing it this way has the benefit that the real function in the target
module does the “ret” since it knows the actual number and size of the
function arguments.
All of this is easy to do for x86:
DrvSomeFunction proc
INVOKE GetTargetFunc, ADDR DrvSomeFunctionName
; The address of the target function is in eax
jmp eax
; The target function will take care of returning for us
;ret
DrvSomeFunction endp
Implementing the same functionality on x64 requires a little more work since
INVOKE isn’t supported by ml64. The code below takes care of saving off the
volatile registers and then calls the same function to resolve the target
function as in the x86 example.
DrvSomeFunction proc
; Save off registers potentially used as function arguments
push rcx
push rdx
push r8
push r9
; TODO: We also want to save off XMM0-3
sub rsp, 20h ; Make room on the stack for “spilling” arguments
lea rcx, DrvSomeFunctionName
call GetTargetFunc
add rsp, 20h
pop r9
pop r8
pop rdx
pop rcx
; The address of the target function is in rax
jmp rax
; The target function will take care of returning for us
;ret
DrvSomeFunction endp
This also works as expected, but I’m stuck on saving off the XMM0-3
registers. I know ksamd64.inc has helper macros for pushing volatile
registers on the stack, such as .SAVEREG and .SAVEXMM128, but according to
MSDN they have to be called in the proc’s prologue
(http://msdn.microsoft.com/en-us/library/3cwzs27h.aspx). However, since my
stubs aren’t real frame functions with a ret instruction, I’m unsure if I’m
able to make use of these macros.
And if I can’t use them, how do I push the 128 bit XMM0-3 on the stack (I
assume I need to split them up into two 64 bit parts but am unclear on the
right way to do that).
Any thoughts are much appreciated.
Thanks,
Soren