View Single Post
  #4  
Old 01-05-2022, 06:33
DavidXanatos DavidXanatos is offline
Family
 
Join Date: Jun 2018
Posts: 168
Rept. Given: 2
Rept. Rcvd 40 Times in 27 Posts
Thanks Given: 54
Thanks Rcvd at 311 Times in 106 Posts
DavidXanatos Reputation: 40
I ran into a really strange issue, for some impossible reason the above code on windows 64 bit, while working fine when the app is 64 bit, fails if its a 32 bit app running under WOW64.

To my understanding this should not be possible as under WOW64 the 32 to 64 translation is done in user mode and the falls to the kernel are all 64 bit so from the kernels viewpoint everything is 64 bit.

I have monkeyed around with the code and narrowed the issue down to calls with 4 or less and 5 arguments for 6 and more the code works fine.
for 0-4 I crafted a different code that seams to work fine

Code:
Sbie_InvokeSyscall4_asm PROC

 mov         r11, rdx ; args
 mov         rax, rcx ; func

 mov         r9,  qword ptr [r11+18h]
 mov         r8,  qword ptr [r11+10h]
 mov         rdx, qword ptr [r11+08h]
 mov         rcx, qword ptr [r11+00h]

 jmp         rax

Sbie_InvokeSyscall4_asm ENDP
but for 5 arguments something is somehow broken

when I use C code to implement a caller for the 5 args case

Code:
typedef NTSTATUS (*P_SystemService05)(
ULONG_PTR arg01, ULONG_PTR arg02, ULONG_PTR arg03, ULONG_PTR arg04,
ULONG_PTR arg05);

_FX NTSTATUS Sbie_InvokeSyscall5(void* func, ULONG_PTR *stack) {

P_SystemService05 nt = (P_SystemService05)func;
return nt(stack[0], stack[1], stack[2], stack[3], stack[4]);

}
it works just fine, when I take the driver to idea, copy the ASM code of this function and put it into an ASM file

Code:
Sbie_InvokeSyscall5_asm PROC

sub rsp, 38h
mov rax, [rdx+20h]
mov r10, rdx
mov r9, [rdx+18h]
mov r11, rcx
mov r8, [rdx+10h]
mov rdx, [rdx+8]
mov rcx, [r10]
mov [rsp+38h-18h], rax
call r11
add rsp, 38h
ret

Sbie_InvokeSyscall5_asm ENDP
and use this instead, 32 bit apps fail again.

And yes I have looked in IDA on the driver with the asm version and its byte for byte same as the output of the C compiler, I even tried adding some int 3 before and after to have it aligned the same way with no result.

The only apparent difference is that its located in a different plaice of the driver image file.

Now the way the 32 bit apps fail is also quiet peculiar, they all fail with an access violation at location 0x0...0 and an empty stack trace, somehow the return from the syscall gets messed up and I have no idea how.
Reply With Quote