一份兼容32位和64位的MmGetSystemRoutineAddressEx实现 委员长 · · Windows程序设计
1 0 0

本文共计1129个字,预计阅读时长4.5分钟。

获得任意模块任意导出函数的地址,不再受限于MmGetSystemRoutineAddress的鸡肋功能。代码从WRK里摘出。

PVOID MiFindExportedRoutine2
(
IN PVOID DllBase,
PIMAGE_EXPORT_DIRECTORY ExportDirectory,
ULONG ExportSize,
BOOL ByName,
IN char *RoutineName,
DWORD Ordinal
)
{
USHORT OrdinalNumber;
PULONG NameTableBase;
PUSHORT NameOrdinalTableBase;
PULONG AddressTableBase;
PULONG Addr;
LONG High;
LONG Low;
LONG Middle;
LONG Result;
PVOID FunctionAddress;
if (ExportDirectory == NULL || ExportSize == 0)
{
return NULL;
}
NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
AddressTableBase=(PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions);
if (!ByName)
{
return (PVOID)AddressTableBase[Ordinal];
}
Low = 0;
Middle = 0;
High = ExportDirectory->NumberOfNames - 1;
while (High >= Low)
{
Middle = (Low + High) >>1;
Result = strcmp (RoutineName,
(PCHAR)DllBase + NameTableBase[Middle]);
if (Result <0)
{
High = Middle - 1;
}
else if (Result >0)
{
Low = Middle + 1;
}
else
{
break;
}
}
if (High (ULONG_PTR)ExportDirectory &&
(ULONG_PTR)FunctionAddress <((ULONG_PTR)ExportDirectory + ExportSize))
{
FunctionAddress = NULL;
}
return FunctionAddress;
}

PVOID NativeGetProcAddress64(SIZE_T uModBase, CHAR cSearchFnName) { IMAGE_DOS_HEADER doshdr; IMAGE_OPTIONAL_HEADER64 opthdr; IMAGE_EXPORT_DIRECTORY pExportTable; ULONG size; SIZE_T uFnAddr=0; // doshdr = (IMAGE_DOS_HEADER ?uModBase; if (NULL == doshdr) { goto exit; } opthdr = (IMAGE_OPTIONAL_HEADER64 ?(uModBase + doshdr->e_lfanew + sizeof(ULONG)+sizeof(IMAGE_FILE_HEADER)); if (NULL == opthdr) { goto __exit; } pExportTable = (IMAGE_EXPORT_DIRECTORY ?(uModBase + opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); if (NULL == pExportTable) { goto exit; } size = opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; uFnAddr = (SIZE_T)MiFindExportedRoutine2((PVOID)uModBase,pExportTable,size,TRUE,cSearchFnName,0); __exit: return (PVOID)uFnAddr; }

PVOID NativeGetProcAddress32(SIZE_T uModBase, CHAR cSearchFnName) { IMAGE_DOS_HEADER doshdr; IMAGE_OPTIONAL_HEADER32 opthdr; IMAGE_EXPORT_DIRECTORY pExportTable; ULONG size; SIZE_T uFnAddr=0; // doshdr = (IMAGE_DOS_HEADER ?uModBase; if (NULL == doshdr) { goto exit; } opthdr = (IMAGE_OPTIONAL_HEADER32 ?(uModBase + doshdr->e_lfanew + sizeof(ULONG)+sizeof(IMAGE_FILE_HEADER)); if (NULL == opthdr) { goto __exit; } pExportTable = (IMAGE_EXPORT_DIRECTORY ?(uModBase + opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); if (NULL == pExportTable) { goto exit; } size = opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; uFnAddr = (SIZE_T)MiFindExportedRoutine2((PVOID)uModBase,pExportTable,size,TRUE,cSearchFnName,0); __exit: return (PVOID)uFnAddr; }

最后于 2023-2-26 被admin编辑 ,原因:

最新回复 ( 1 )
全部楼主
  • bbc @Ta
    0 2
     Error LNK2019: 无法解析的外部符号 MmGetSystemRoutineAddressEx。MmGetSystemRoutineAddressEx这个函数怎么链接编译啊