Patafix
October 13th, 2009, 09:33
Hi guys,
I'm trying to implement my own KeStackAttachProcess (obliviously to evade some hooks...). 
My first step is to understand how it works.
Atm, I don't want to reinvent the wheel but just to call KiAttachProcess from my own function.
I'm working on a XP sp2 VM to make my tests.
windbg listing:
0: kd> uf KeStackAttachProcess
nt!KeStackAttachProcess:
804f8ada 8bff            mov     edi,edi
804f8adc 55              push    ebp
804f8add 8bec            mov     ebp,esp
804f8adf 56              push    esi
804f8ae0 57              push    edi
804f8ae1 64a124010000    mov     eax,dword ptr fs:[00000124h]
804f8ae7 8bf0            mov     esi,eax
804f8ae9 64a194090000    mov     eax,dword ptr fs:[00000994h]
804f8aef 85c0            test    eax,eax
804f8af1 741c            je      nt!KeStackAttachProcess+0x35 (804f8b0f)
nt!KeStackAttachProcess+0x19:
804f8af3 64a194090000    mov     eax,dword ptr fs:[00000994h]
804f8af9 50              push    eax
804f8afa 0fb68665010000  movzx   eax,byte ptr [esi+165h]
804f8b01 50              push    eax
804f8b02 ff7644          push    dword ptr [esi+44h]
804f8b05 ff7508          push    dword ptr [ebp+8]
804f8b08 6a05            push    5
804f8b0a e8c1120000      call    nt!KeBugCheckEx (804f9dd0)
nt!KeStackAttachProcess+0x35:
804f8b0f 8b7d08          mov     edi,dword ptr [ebp+8]
804f8b12 397e44          cmp     dword ptr [esi+44h],edi
804f8b15 750c            jne     nt!KeStackAttachProcess+0x49 (804f8b23)
nt!KeStackAttachProcess+0x3d:
804f8b17 8b450c          mov     eax,dword ptr [ebp+0Ch]
804f8b1a c7401001000000  mov     dword ptr [eax+10h],1
804f8b21 eb3b            jmp     nt!KeStackAttachProcess+0x84 (804f8b5e)
nt!KeStackAttachProcess+0x49:
804f8b23 33c9            xor     ecx,ecx
804f8b25 ff1588804d80    call    dword ptr [nt!_imp_KeAcquireQueuedSpinLockRaiseToSynch (804d8088)]
804f8b2b 80be6501000000  cmp     byte ptr [esi+165h],0
804f8b32 884508          mov     byte ptr [ebp+8],al
804f8b35 740f            je      nt!KeStackAttachProcess+0x6c (804f8b46)
nt!KeStackAttachProcess+0x5d:
804f8b37 ff750c          push    dword ptr [ebp+0Ch]
804f8b3a ff7508          push    dword ptr [ebp+8]
804f8b3d 57              push    edi
804f8b3e 56              push    esi
804f8b3f e86cfdffff      call    nt!KiAttachProcess (804f88b0)
804f8b44 eb18            jmp     nt!KeStackAttachProcess+0x84 (804f8b5e)
nt!KeStackAttachProcess+0x6c:
804f8b46 8d864c010000    lea     eax,[esi+14Ch]
804f8b4c 50              push    eax
804f8b4d ff7508          push    dword ptr [ebp+8]
804f8b50 57              push    edi
804f8b51 56              push    esi
804f8b52 e859fdffff      call    nt!KiAttachProcess (804f88b0)
804f8b57 8b450c          mov     eax,dword ptr [ebp+0Ch]
804f8b5a 83601000        and     dword ptr [eax+10h],0
nt!KeStackAttachProcess+0x84:
804f8b5e 5f              pop     edi
804f8b5f 5e              pop     esi
804f8b60 5d              pop     ebp
804f8b61 c20800          ret     8
In this Windows version, we can see KiAttachProcess is preceded by a push edi and push esi. So it's pretty easy to scan KeStackAttachProcess to get the KiAttachProcess address:
VOID (*pKiAttachProcess)(PKTHREAD, PKPROCESS, KIRQL, PKAPC_STATE);
VOID ScanForKiAttachProcess(ULONG pAddress)
{
    int i;
    for(i = 0; i < 0x84; i++)
    {
        if( *((UCHAR*)pAddress + i) == 0x57 && *((UCHAR*)pAddress + i + 1) == 0x56)
        {
            pKiAttachProcess = (VOID (*)(PKTHREAD, PKPROCESS, KIRQL, PKAPC_STATE))((ULONG)( pAddress + i + 7) + (*((PULONG)(pAddress + i + 3))));
        
            break;
        }
    }    
}
On my system, I have KiAttachProcess address = 0x804f88b0
So ok... I'm trying to call it like that in my MyStackAttachProcess function:
VOID MyKeStackAttachProcess(PKPROCESS pkProcess, PKAPC_STATE pKapc_State)
{
    KIRQL OldIRQL;
    PRKTHREAD Thread;
    if(KeGetCurrentIrql() > DISPATCH_LEVEL) return;
    Thread = KeGetCurrentThread();
    KeRaiseIrql(DISPATCH_LEVEL, &OldIRQL);
    if(KeIsExecutingDpc() != FALSE) 
    {
        KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
                     (ULONG_PTR)pkProcess,
                     (ULONG_PTR)Thread->ApcState.Process,
                     (ULONG)Thread->ApcStateIndex,
                     (ULONG)KeIsExecutingDpc());
    }
    if(Thread->ApcState.Process == pkProcess)
    {
        KeLowerIrql(OldIRQL);
        pKapc_State->Process = (PKPROCESS)1;
        return;
    }
    if (Thread->ApcStateIndex != 0)
    {
        pKiAttachProcess(Thread, pkProcess, OldIRQL, pKapc_State);
    }
    else
    {
        pKiAttachProcess(Thread, pkProcess, OldIRQL, &Thread->SavedApcState);
        pKapc_State->Process = NULL;
    }
    
    KeLowerIrql(OldIRQL);
}
Actually i'm not yet using KeAcquireQueuedSpinLockRaiseToSynch in my function... Do you think it's why my system freeze?
No bugcheck... it's just than when pKiAttachProcess is called, it never return.
Do you have any suggestions?
Regards,
Orkblutt



