核心特徵碼搜尋 獲取未匯出函式
阿新 • • 發佈:2018-11-10
無聊寫了下
有Bug 注意下就好啦~
#include "GetUndocumentFunctionAdress.h" #pragma warning(disable : 4047) PVOID GetCallPoint(PVOID pCallPoint) { ULONG dwOffset = 0; ULONG_PTR returnAddress = 0; LARGE_INTEGER returnAddressTemp = { 0 }; PUCHAR pFunAddress = NULL; if (pCallPoint == NULL || !MmIsAddressValid(pCallPoint)) return NULL; pFunAddress = pCallPoint; // 函式偏移 RtlCopyMemory(&dwOffset, (PVOID)(pFunAddress + 1), sizeof(ULONG)); // JMP向上跳轉 if ((dwOffset & 0x10000000) == 0x10000000) { dwOffset = dwOffset + 5 + pFunAddress; returnAddressTemp.QuadPart = (ULONG_PTR)pFunAddress & 0xFFFFFFFF00000000; returnAddressTemp.LowPart = dwOffset; returnAddress = returnAddressTemp.QuadPart; return (PVOID)returnAddress; } returnAddress = (ULONG_PTR)dwOffset + 5 + pFunAddress; return (PVOID)returnAddress; } PVOID GetUndocumentFunctionAddress(IN PUNICODE_STRING pFunName, IN PUCHAR pStartAddress, IN UCHAR* pFeatureCode, IN ULONG FeatureCodeNum, ULONG SerSize ,UCHAR SegCode, ULONG AddNum, BOOLEAN ByName) { ULONG dwIndex = 0; PUCHAR pFunAddress = NULL; ULONG dwCodeNum = 0; if (pFeatureCode == NULL) return NULL; if (FeatureCodeNum >= 15) return NULL; if (SerSize > 0x1024) return NULL; if (ByName) { if (pFunName == NULL || !MmIsAddressValid(pFunName->Buffer)) return NULL; pFunAddress = (PUCHAR)MmGetSystemRoutineAddress(pFunName); if (pFunAddress == NULL) return NULL; } else { if (pStartAddress == NULL || !MmIsAddressValid(pStartAddress)) return NULL; pFunAddress = pStartAddress; } for (dwIndex = 0; dwIndex < SerSize; dwIndex++) { __try { if (pFunAddress[dwIndex] == pFeatureCode[dwCodeNum] || pFeatureCode[dwCodeNum] == SegCode) { dwCodeNum++; if (dwCodeNum == FeatureCodeNum) return pFunAddress + dwIndex - dwCodeNum + 1 + AddNum; continue; } dwCodeNum = 0; } __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } } return 0; }
#ifndef _GetUndocumentFunctionAdress_h_ #define _GetUndocumentFunctionAdress_h_ 1 #include <ntddk.h> /* 獲取Call的地址 考慮了向上跳的問題 引數:e8 開始的地址 */ PVOID GetCallPoint(PVOID pCallPoint); /* 獲取未匯出函式所在地址(沒有計算call 和跳轉) 得到的地址需要計算偏移 支援模糊搜尋 可用分隔符代替未知 存在問題:記憶體重疊時出現問題(見例子) 實際此函式為特徵碼搜尋函式 引數: PUNICODE_STRING pFunName : 函式名稱(需要是匯出函式) PUCHAR pStartAddress: 開始搜尋的地址 UCHAR* pFeatureCode: 特徵碼 不能超過15個 ULONG FeatureCodeNum: 特徵碼個數 ULONG SerSize: 搜尋範圍大小 不能超過0x1024 UCHAR SegCode: 分割符 用於支援模糊搜尋 ULONG AddNum: 預設返回特徵碼開始的地址 可利用這個數值進行調整 BOOLEAN ByName: 是否是通過函式名搜尋 返回: 失敗返回NULL 成功返回搜尋到的地址 */ PVOID GetUndocumentFunctionAddress(IN PUNICODE_STRING pFunName, IN PUCHAR pStartAddress, IN UCHAR* pFeatureCode, IN ULONG FeatureCodeNum, ULONG SerSize, UCHAR SegCode, ULONG AddNum, BOOLEAN ByName); #endif // _GetUndocumentFunctionAdress_h_ /* 使用例子: 例子: nt!NtOpenProcess: fffff800`041b62ec 4883ec38 sub rsp,38h fffff800`041b62f0 65488b042588010000 mov rax,qword ptr gs:[188h] fffff800`041b62f9 448a90f6010000 mov r10b,byte ptr [rax+1F6h] fffff800`041b6300 4488542428 mov byte ptr [rsp+28h],r10b fffff800`041b6305 4488542420 mov byte ptr [rsp+20h],r10b <--如果使用44 ?? ?? ?? ?? e8 做特徵碼 會失敗 原因是前面出現了44 並且特徵碼長度大於了此段程式碼 類似於記憶體重疊 fffff800`041b630a e851fcffff call nt!PsOpenProcess (fffff800`041b5f60) <-- 使用e8開頭做特徵碼就不會存在此問題 fffff800`041b630f 4883c438 add rsp,38h fffff800`041b6313 c3 ret UCHAR shellcode[11] = "\xe8\x60\x60\x60\x60" "\x48\x60\x60\x60" "\xc3"; PVOID p = GetUndocumentFunctionAddress(NULL, (PUCHAR)0xfffff800041b62ec, shellcode, 10, 0x300, 0x60, 0, FALSE); if (p != NULL) { DbgPrint("CallFrom:0x%p -- CallPoint:0x%p\n", p, GetCallPoint(p)); } */
使用例子:
#include <ntddk.h> #include "GetUndocumentFunctionAdress.h" VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) { UNICODE_STRING usFunc = { 0 }; UCHAR shellcode2[13] = "\x4c\x60\x60\x60\x60" "\xe8\x60\x60\x60\x60" "\x41\xbd"; /* nt!NtOpenProcess: fffff800`041b62ec 4883ec38 sub rsp,38h fffff800`041b62f0 65488b042588010000 mov rax,qword ptr gs:[188h] fffff800`041b62f9 448a90f6010000 mov r10b,byte ptr [rax+1F6h] fffff800`041b6300 4488542428 mov byte ptr [rsp+28h],r10b fffff800`041b6305 4488542420 mov byte ptr [rsp+20h],r10b fffff800`041b630a e851fcffff call nt!PsOpenProcess (fffff800`041b5f60) fffff800`041b630f 4883c438 add rsp,38h fffff800`041b6313 c3 ret */ UCHAR shellcode[11] = "\xe8\x60\x60\x60\x60" "\x48\x60\x60\x60" "\xc3"; PVOID p = GetUndocumentFunctionAddress(NULL, (PUCHAR)0xfffff800041b62ec, shellcode, 10, 0x300, 0x60, 0, FALSE); if (p != NULL) { DbgPrint("CallFrom:0x%p -- CallPoint:0x%p\n", p, GetCallPoint(p)); } else DbgBreakPoint(); pDriverObject->DriverUnload = DriverUnload; return STATUS_SUCCESS; }