第一步:IDA查看這個函式的交叉參考,看到PspAlloCateThread 呼叫了該函式


二. 繼續查看有誰呼叫了PspAllocateThread 這個函式

看到了一個匯出函式 NtCreateUserProcess ,思路就是 NtCreateUserProcess --> PspAllocateThread --> PspUserThreadStartup 這樣子就能找到 PspUserThreadStartup 函式的地址
記錄一下特征碼 這里我在 NtCreateUserProcess 呼叫 PspAllocateThread 的call 附加尋找特征碼 ,我尋找的特征碼是 94 24 18 01 其實這種特征碼不靠譜 但這個函式很小而且從函式頭到呼叫的位置只出現一次
這里順便記錄一下 94這個位元組 距離真正呼叫call 相差 9 個位元組 ,

接下來尋找 PspAllocateThread 呼叫 PspUserThreadStartup 附加的特征碼,8B 86 10 06 這里距離 lea r8,PspUserThreadStartup 相差16個位元組

接下來撰寫一個函式暴力列舉出來
PVOID GetPspUserThreadStartup2(ULONG64 函式地址, 暴力掃描* 資訊, UCHAR 特征碼[]) { if (!MmIsAddressValid(&函式地址)) { return 0; } INT code1 = NULL; ULONG64 addr = NULL; ULONG64 回傳地址 = NULL; for (size_t i = 0; i < 0x1BF8CA; i++) { if (memcmp((PVOID)(函式地址 + i), 特征碼, 資訊->特征碼長度) == 0) { addr = 函式地址 + i + 資訊->特征碼距離函式地址偏移; 資訊->偏移 = __insn_len_x86((PVOID)addr, __b64); //資訊->偏移 可以理解為地址的匯編長度 比如 0x123456 E8 01 這個0x123456地址長度就是 2 for (int i = 資訊->偏移; i >= 4; i--) { if (i == 4) { 資訊->偏移 = 資訊->偏移 - i; //這里演算法可以計算出函式呼叫位置的后四位元組 break; } } memcpy(&code1, (PVOID)(addr + 資訊->偏移), 4); //這里拷貝 呼叫的位置后四個位元組 比如上面看到的 call PspAllocateThread E8 0D 4E 0C 00 這里需要拿到后四個位元組計算函式真正地址 計算公式 函式真正地址=當前地址+后四位元組地址+地址長度 函式地址 = (addr + code1 + __insn_len_x86((PVOID)addr, __b64)); 回傳地址 = 函式地址; break; } } return (PVOID)回傳地址; }
使用方法,可以定義一個結構體


上面GetFUnaddr 是 NtcreateUserProcess 在SSDT中的編號 獲取它在SSDT中的地址獲取
結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/52307.html
標籤:Windows
