expriment: 找API的特征码

Demo中的例子是找 PspTerminateProcess, 基于WinXp的.

虚拟机是Win7X86家庭普通版, ring0中没有这个API.

kd> u PspTerminateProcess
Couldn't resolve error at 'PspTerminateProcess'

在 nt! 中模糊查找, 找到另外一个API PsTerminateProcess, 参数也相同.


kd> x nt!*terminate*
83f090cd nt!KeTerminateThread = <no type information>
8404736f nt!NtTerminateJobObject = <no type information>
84140ac2 nt!SeUnregisterLogonSessionTerminatedRoutine = <no type information>
83e54220 nt!_imp__ClfsTerminateReadLog = <no type information>
8405d7e8 nt!PsTerminateSystemThread = <no type information>
83e90428 nt!ZwTerminateJobObject = <no type information>
840a2fe7 nt!PspTerminateThreadByPointer = <no type information>
840afbf1 nt!PspTerminateAllThreads = <no type information>
83f5ff1d nt!SmKmStoreTerminateWorker = <no type information>
83ebaddf nt!MiTerminateWsle = <no type information>
840e58d9 nt!PsTerminateProcess = <no type information>
8413209c nt!NtRegisterThreadTerminatePort = <no type information>
840af9bf nt!NtTerminateProcess = <no type information>
83f6a23e nt!InbvPortTerminate = <no type information>
840cd334 nt!NtTerminateThread = <no type information>
83e8fd5c nt!ZwRegisterThreadTerminatePort = <no type information>
83e9043c nt!ZwTerminateProcess = <no type information>
83f5698b nt!SMKM_STORE_MGR<SM_TRAITS>::SmStoreTerminate = <no type information>
83fe75fb nt!SeRegisterLogonSessionTerminatedRoutine = <no type information>
83e627e5 nt!ClfsTerminateReadLog = <no type information>
83e90450 nt!ZwTerminateThread = <no type information>
840473c6 nt!PspTerminateAllProcessesInJob = <no type information>

kd> uf nt!PsTerminateProcess
nt!PsTerminateProcess:
840e58d9 8bff            mov     edi,edi
840e58db 55              push    ebp
840e58dc 8bec            mov     ebp,esp
840e58de 51              push    ecx
840e58df 51              push    ecx
840e58e0 53              push    ebx
840e58e1 56              push    esi
840e58e2 648b3524010000  mov     esi,dword ptr fs:[124h]
840e58e9 66ff8e84000000  dec     word ptr [esi+84h]
840e58f0 57              push    edi
840e58f1 c745fc01000000  mov     dword ptr [ebp-4],1
840e58f8 6a08            push    8
840e58fa 5a              pop     edx
840e58fb 8db970020000    lea     edi,[ecx+270h]
840e5901 8b07            mov     eax,dword ptr [edi]

nt!PsTerminateProcess+0x2a:
840e5903 8bd8            mov     ebx,eax
840e5905 0bda            or      ebx,edx
840e5907 f00fb11f        lock cmpxchg dword ptr [edi],ebx
840e590b 75f6            jne     nt!PsTerminateProcess+0x2a (840e5903)

nt!PsTerminateProcess+0x34:
840e590d 84c2            test    dl,al
840e590f 7409            je      nt!PsTerminateProcess+0x41 (840e591a)

nt!PsTerminateProcess+0x38:
840e5911 c745fc03000000  mov     dword ptr [ebp-4],3
840e5918 eb0e            jmp     nt!PsTerminateProcess+0x4f (840e5928)

nt!PsTerminateProcess+0x41:
840e591a a900000040      test    eax,40000000h
840e591f 7407            je      nt!PsTerminateProcess+0x4f (840e5928)

nt!PsTerminateProcess+0x48:
840e5921 c745fc05000000  mov     dword ptr [ebp-4],5

nt!PsTerminateProcess+0x4f:
840e5928 ff75fc          push    dword ptr [ebp-4]
840e592b ff7508          push    dword ptr [ebp+8]
840e592e 56              push    esi
840e592f 51              push    ecx
840e5930 e8bca2fcff      call    nt!PspTerminateAllThreads (840afbf1)
840e5935 8bf8            mov     edi,eax
840e5937 66ff8684000000  inc     word ptr [esi+84h]
840e593e 0fb78684000000  movzx   eax,word ptr [esi+84h]
840e5945 6685c0          test    ax,ax
840e5948 7516            jne     nt!PsTerminateProcess+0x87 (840e5960)

nt!PsTerminateProcess+0x71:
840e594a 8d4640          lea     eax,[esi+40h]
840e594d 3900            cmp     dword ptr [eax],eax
840e594f 740f            je      nt!PsTerminateProcess+0x87 (840e5960)

nt!PsTerminateProcess+0x78:
840e5951 6683be8600000000 cmp     word ptr [esi+86h],0
840e5959 7505            jne     nt!PsTerminateProcess+0x87 (840e5960)

nt!PsTerminateProcess+0x82:
840e595b e8395bd9ff      call    nt!KiCheckForKernelApcDelivery (83e7b499)

nt!PsTerminateProcess+0x87:
840e5960 8bc7            mov     eax,edi
840e5962 5f              pop     edi
840e5963 5e              pop     esi
840e5964 5b              pop     ebx
840e5965 c9              leave
840e5966 c20400          ret     4


取API特征码

kd> dd nt!PsTerminateProcess L4
840e58d9  8b55ff8b 535151ec 358b6456 00000124

整理API特征码
    /**
    kd> dd nt!PsTerminateProcess L4
    840e58d9  8b55ff8b 535151ec 358b6456 00000124
    */
    ULONG ulApiSignature_PsTerminateProcess[] = {0x8b55ff8b, 0x535151ec, 0x358b6456, 0x00000124};

函数原型:

NTSTATUS PsTerminateProcess(
                            IN OUT  PEPROCESS pEProcessHandle,
                            IN      NTSTATUS exitStatus);


在驱动层代码中找ApiSignature封装了一个函数.

BOOLEAN MmIsAddressValid_Util(ULONG ulMemAddr)
{
    /// 地址有效才去操作, MmIsAddressValid只能检测到一个字节.
    /// 这样检测4次好使, 原来读无效的内存地址被忽略
    size_t  nIndex  =   0;

    for (nIndex = 0; nIndex < sizeof(ULONG); nIndex++)
    {
        if (!MmIsAddressValid((BYTE *)ulMemAddr + nIndex))
            return FALSE;
    }

    return TRUE;
}

BOOLEAN FindApiSignature(ULONG ulMemAddr, ULONG * pulApiSignature, size_t nCntApiSignature)
{
    BOOLEAN bRc         =   FALSE;
    size_t  nIndex      =   0;

    /// 找到的API特征码的内容个数, 如果等于nCntApiSignature, 说明完全匹配特征码
    size_t  nFindCnt    =   0;

    if (NULL == pulApiSignature)
        return FALSE;

    for (nIndex = 0; nIndex < nCntApiSignature; nIndex++)
    {
        if ((!MmIsAddressValid_Util(ulMemAddr))
            || (*((ULONG *)ulMemAddr + nIndex) != *(pulApiSignature + nIndex)))
        {
            break;
        }

        nFindCnt ++;
    }

    bRc = (nFindCnt == nCntApiSignature);
    if (bRc)
        DbgPrint("find Api Signature\r\n");

    return bRc;
}

调用 FindApiSignature的代码

	for (ulIndex = curAddr; ulIndex < (ntosknlEndAddr - sizeof(ulApiSignature)); ulIndex++)
	{
        if (FindApiSignature(ulIndex, ulApiSignature, sizeof(ulApiSignature) / sizeof(ULONG)))
		{
			retAddr=ulIndex;
			DbgPrint("GetFunctionAddressFromKernelMemory adress is:%x",retAddr);

            KeLowerIrql(irqlOld);
			return (PVOID)retAddr;
		}
	}

实验发现: 用16Bytes的特征码不行, Win7X86下要32Bytes的特征码才靠谱.

    ULONG ulApiSignature[] = {
        0x8b55ff8b, 0x535151ec, 0x358b6456, 0x00000124, 
        0x848eff66, 0x57000000, 0x01fc45c7, 0x6a000000};



你可能感兴趣的:(expriment: 找API的特征码)