wbenny / injdrv

proof-of-concept Windows Driver for injecting DLL into user-mode processes using APC
MIT License
1.14k stars 278 forks source link

PsWrapApcWow64Thread cause normalRoutine to become invalid. #4

Closed iradization closed 5 years ago

iradization commented 5 years ago

Hi,

I've got a question regarding the usage of the undocumented method PsWrapApcWow64Thread that is used to support regular 32bits normalRoutines to wow64 processes.

Basically i've used your project with replacing the section memory allocation with ZwProtectVirtualMemory for user-space memory allocation on the context of the process I wish to inject to. I'm using VM of windows 10 RS5.

reading the memory from winDbg, the candidate NormalRoutine function looked pretty much like a normal function in assembly code :

0: kd> u 0x00000000`00880000

00000000`00880000 55              push    rbp
00000000`00880001 8bec            mov     ebp,esp
00000000`00880003 83ec1c          sub     esp,1Ch

However, after calling the method PsWrapApcWow64Thread with this function I got the following wrapping :

0: kd> u 0x00000000`00880000

00000000`00880000 ac              lods    byte ptr [rsi]
00000000`00880001 d24df0          ror     byte ptr [rbp-10h],cl
00000000`00880004 4d8ce3          mov     r11,fs
00000000`00880007 e8fc000000      call    00000000`00880108
00000000`0088000c 00c7            add     bh,al
00000000`0088000e 45ec            in      al,dx
00000000`00880010 0000            add     byte ptr [rax],al

First, i thought that the original function was relocated to address 00880108, but when i read this section in memory i got all zeros

0: kd> dd 00000000`00880108
00000000`00880108  00000000 00000000 00000000 00000000
00000000`00880118  00000000 00000000 00000000 00000000
00000000`00880128  00000000 00000000 00000000 00000000
00000000`00880138  00000000 00000000 00000000 00000000
...

So it seems that the wrapping cause the code to jump to "zeroes" code. Any idea what went wrong ?

mrsshr commented 5 years ago

Post your code. I think you passed invalid parameters.

iradization commented 5 years ago

Ok, So i had some issue of the parameters, but i'm still experiencing an issue with the wow64 wrapper method.

So here's how i define my inputs :

    PVOID ApcContext = (PVOID)NULL;
    PVOID ApcRoutineAddress = memoryHandle;

    PsWrapApcWow64Thread(&ApcContext, &ApcRoutineAddress);

    PKNORMAL_ROUTINE ApcRoutine = (PKNORMAL_ROUTINE)(ULONG_PTR)ApcRoutineAddress;
    InjpQueueApc(UserMode, ApcRoutine, NormalContext, NULL, NULL);

Notice that in my case, the context and inputs are irrelevant and they are all initialized to NULL. I just want to see that the normal routine is running by itself (both 2 inputs and context are unused in my implementation).

After i call PsWrapApcWow64Thread, the value of ApcRoutineAddress is set to the inaccessible address of 0xfffffffffffc0000`.

The original method address however, is still in user-space and points to the method imeplemntation

1: kd> u 10000
00000000`00010000 55              push    rbp
00000000`00010001 8bec            mov     ebp,esp
00000000`00010003 83ec1c          sub     esp,1Ch

Perhaps you can tell me if you see any issues with my flow ?

Thanks !

wbenny commented 5 years ago

After i call PsWrapApcWow64Thread, the value of ApcRoutineAddress is set to the inaccessible address of 0xfffffffffffc0000

This seems like correct behavior. KiUserApcDispatcher will recognize this value and decode it as "wow64 APC routine".

iradization commented 5 years ago

However, i cannot reach the break point of the normal routine (I set break point of the address it was allocated in from the context of the injected process).

It seems like the process is stuck. When i tried to analyzed it I saw that one of the threads' call-stack is stuck on wow64ApcRoutine. any ideas how to further debug this issue ?

        Child-SP          RetAddr           : Args to Child                                                           : Call Site
        ffffd708`1295f680 fffff802`cab3a3c6 : 00000000`00000000 ffffaf04`318f0580 00000000`00000000 00000000`00000000 : nt!KiSwapContext+0x76
        ffffd708`1295f7c0 fffff802`cab39bbb : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiSwapThread+0x2c6
        ffffd708`1295f890 fffff802`cab392df : 00000000`00000000 00000000`00000000 00000000`00000000 ffffaf04`318f06c0 : nt!KiCommitThreadWait+0x13b
        ffffd708`1295f930 fffff802`caf9fd3c : ffffaf04`2f7de580 fffff802`00000006 00000000`00000001 00000000`00000000 : nt!KeWaitForSingleObject+0x1ff
        ffffd708`1295fa10 fffff802`cac5d743 : ffffaf04`318f0580 00000000`003ef000 00000000`00000000 ffffaf04`2f7de580 : nt!NtWaitForSingleObject+0xfc
        ffffd708`1295fa80 00000000`77811e4c : 00000000`77811cad 00000023`7790b48c 00000000`00000000 00000000`ffffffff : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffd708`1295fa80)
        00000000`0009e828 00000000`77811cad : 00000023`7790b48c 00000000`00000000 00000000`ffffffff 00000000`00000011 : wow64cpu!CpupSyscallStub+0xc
        00000000`0009e830 00000000`77811389 : 00000000`0009fd24 00000000`0009fff0 00000000`0009fd24 00000000`0009fd20 : wow64cpu!Thunk0ArgReloadState+0x5
        00000000`0009e8e0 00000000`777bcec6 : 00000000`7790cc00 00000000`0019f9d0 00000000`0009f060 00000000`00000000 : wow64cpu!BTCpuSimulate+0x9
        00000000`0009e920 00000000`777c3eb5 : 00000000`ffff014c 00000000`0009014c 00000000`0009fd24 00000000`00000001 : wow64!RunCpuSimulation+0xa
        00000000`0009e950 00000000`777c3dbf : 00000000`ffffffff 00000000`0019fd00 00000000`003ef000 00000000`00000000 : wow64!Wow64ApcRoutineInternal+0xf5
        00000000`0009e9d0 00007ffd`71f4e5e9 : ffffd708`1295f3b8 00000000`00000000 00000000`00000000 ffffffff`fffc0000 : wow64!Wow64ApcRoutine+0x1f
        00000000`0009ea10 00000000`77811e4c : 00000000`77811cad 00000023`7790c24c 00007ffd`71ef0023 00000000`0019fc00 : ntdll!KiUserApcDispatch+0x69 (TrapFrame @ 00000000`0009ed78)
        00000000`0009ef08 00000000`77811cad : 00000023`7790c24c 00007ffd`71ef0023 00000000`0019fc00 00000000`0019fd14 : wow64cpu!CpupSyscallStub+0xc
        00000000`0009ef10 00000000`77811389 : 00000000`0019fd24 00000000`777bcf95 00000000`0009efe0 00000000`777bbecb : wow64cpu!Thunk0ArgReloadState+0x5
        00000000`0009efc0 00000000`777bcec6 : 00000000`003ec000 00000000`00400108 00000000`00000000 00000000`0009f820 : wow64cpu!BTCpuSimulate+0x9
        00000000`0009f000 00000000`777bcdb0 : 00000000`00000000 00000000`005f2178 00000000`005f2178 00000000`00000000 : wow64!RunCpuSimulation+0xa
        00000000`0009f030 00007ffd`71f7f637 : 00007ffd`71fc82f8 00007ffd`71fc82f8 00000000`00000010 00007ffd`71fc8290 : wow64!Wow64LdrpInitialize+0x120
        00000000`0009f2e0 00007ffd`71f6fa45 : 00000000`00000001 00000000`00000000 00000000`00000000 00000000`00000001 : ntdll!LdrpInitializeProcess+0x1887
        00000000`0009f700 00007ffd`71f24feb : 00000000`0009f820 00000000`00000000 00000000`00000000 00000000`003ed000 : ntdll!_LdrpInitialize+0x4aa45
        00000000`0009f7a0 00007ffd`71f24f9e : 00000000`0009f820 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrpInitialize+0x3b
        00000000`0009f7d0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe
mrsshr commented 5 years ago

PsWrapApcWow64Thread result is normal. Is 32bit ntdll loaded in target process?

iradization commented 5 years ago

Yes, i guess that's was the problem. now it's fixed. thanks you.