获得任意模块任意导出函数的地址,不再受限于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 < Low) { return NULL; } OrdinalNumber = NameOrdinalTableBase[Middle]; if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) { return NULL; } Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions); FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]); if ((ULONG_PTR)FunctionAddress > (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; }