阅读:2777回复:8
自己写的GetProcAddress,驱动里用用..最近不好玩.. 写了这个东西. 通过分析PE格式得到. LPVOID FindProcAddress( LPVOID hBaseAddress, PSTR strProcName, UINT ProcNameSize ) /* FindProcAddress: 获取动态库的导出函数位于内存中的地址. 版本: N/A 描述: hBaseAddress: 动态库的基址 strProcName: 函数名 ProcNameSize: 函数名长度 编写: Liio ,08/10 */ { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER) hBaseAddress; PIMAGE_FILE_HEADER pNtHeader = NULL; PIMAGE_OPTIONAL_HEADER pOptHeader = NULL; PIMAGE_EXPORT_DIRECTORY pExpHeader = NULL; PSTR ModuleName = NULL; ULONG NumberOfFunctions = 0; ULONG Offset = 0; ULONG CurrentFunOffset = 0; PSTR CurrentFunName = NULL; ULONG CurrentFunAddressOffset = 0; ULONG CurrentFunAddress = 0; if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) { // Is Not Real PE File. return NULL; } pNtHeader = (PIMAGE_FILE_HEADER) ((PUCHAR) hBaseAddress + (pDosHeader->e_lfanew + 4)); pOptHeader = (PIMAGE_OPTIONAL_HEADER) ((PUCHAR)pNtHeader + sizeof(IMAGE_FILE_HEADER)); if (pOptHeader->DataDirectory[0].VirtualAddress == 0) { // The Export Table is NULL. return NULL; } pExpHeader = (PIMAGE_EXPORT_DIRECTORY) ((PUCHAR)hBaseAddress + pOptHeader->DataDirectory[0].VirtualAddress); ModuleName = (PSTR) ((PUCHAR)hBaseAddress + pExpHeader->Name); NumberOfFunctions = pExpHeader->NumberOfFunctions; while(NumberOfFunctions) { NumberOfFunctions--; CurrentFunOffset = *(ULONG *) ((PUCHAR)hBaseAddress + (pExpHeader->AddressOfNames + (Offset * sizeof(ULONG)))); CurrentFunName = (PSTR) ((PUCHAR)hBaseAddress + CurrentFunOffset); if(RtlCompareMemory(CurrentFunName ,strProcName,ProcNameSize) == ProcNameSize) { CurrentFunAddressOffset = *(ULONG *) ((PUCHAR)hBaseAddress + (pExpHeader->AddressOfFunctions + (Offset * sizeof(ULONG)))); return ((PUCHAR)hBaseAddress + CurrentFunAddressOffset); } Offset++; } return NULL; } |
|
沙发#
发布于:2008-10-05 03:00
效率太低,用2叉搜索啊~
|
|
|
板凳#
发布于:2008-10-05 13:08
MmGetXXX很好用~
|
|
|
地板#
发布于:2008-10-05 15:30
....
对对对。。 回头再写个2叉叉的搜索放上来 MmGetSystemRoutineAddress貌似只能返回Hal.dll等里导出的地址? |
|
地下室#
发布于:2008-10-05 21:04
友情客串 不过貌似我也是这样干的 2分法没有必要吧 哈哈
该函数又不是经常要调用的,我的原则是只优化最需要优化的地方,其他越简单越好 |
|
5楼#
发布于:2008-10-05 21:05
哇靠 !!!!我啥时候变成驱动肿瘤啊???
幸福啊 兴奋啊 种牛啊 可耻的拼音输入法 |
|
6楼#
发布于:2008-10-05 22:25
偶也实现过一个
用的是2叉 嘿嘿 |
|
7楼#
发布于:2008-10-06 04:44
没有处理forwarder么....
// // check for a forwarder. // if(ThunkEntry->u1.Function > reinterpret_cast<ULONG>(ExportDirectory) && ThunkEntry->u1.Function < Add2Ptr(ExportDirectory,ExportSize,ULONG)) { CHAR ForwardDllName[10]; RtlCopyMemory(ForwardDllName,reinterpret_cast<PVOID>(ThunkEntry->u1.Function),sizeof(ForwardDllName)); *strchr(ForwardDllName,'.') = '\0'; // // should load the referenced DLL here, just return failure for now. // PLDR_DATA_TABLE_ENTRY DataTableEntry = 0; if(!BlCheckForLoadedDll(ForwardDllName,&DataTableEntry)) return EINVAL; ULONG TargetExportSize = 0; PVOID Temp = RtlImageDirectoryEntryToData(DataTableEntry->DllBase,TRUE,IMAGE_DIRECTORY_ENTRY_EXPORT,&TargetExportSize); PIMAGE_EXPORT_DIRECTORY TargetExportDirectory = static_cast<PIMAGE_EXPORT_DIRECTORY>(Temp); if(!TargetExportDirectory) return EINVAL; IMAGE_THUNK_DATA ThunkData; UCHAR Buffer[128]; PCHAR ImportName = strchr(reinterpret_cast<PCHAR>(ThunkEntry->u1.Function),'.') + 1; ...................... |
|
8楼#
发布于:2008-10-06 06:53
写得匆忙。。
谢谢大家的提醒。。 转发输出确实没有处理。 有时间补上后再发上来 |
|