版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuhuibeishadiao/article/details/73468346
无聊写了下
有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;
}