MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
来源:互联网 发布:脊柱侧弯 知乎 编辑:程序博客网 时间:2024/06/16 08:09
MmGetSystemRoutineAddress这个函数也是比较有用的,是得到系统导出函数的地址,不过网上都是写了一堆汇编代码在哪里,根本没有可读性,还不如用IDA看呢。
下面的函数是摘自ReactOS项目的代码:
PVOID NTAPI MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName) { PVOID ProcAddress = NULL; ANSI_STRING AnsiRoutineName; NTSTATUS Status; PLIST_ENTRY NextEntry; PLDR_DATA_TABLE_ENTRY LdrEntry; BOOLEAN Found = FALSE; UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe"); UNICODE_STRING HalName = RTL_CONSTANT_STRING(L"hal.dll"); ULONG Modules = 0; ERESOURCE PsLoadedModuleResource; /* Convert routine to ansi name */ Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName, SystemRoutineName, TRUE); if (!NT_SUCCESS(Status)) return NULL; /* Lock the list */ KeEnterCriticalRegion(); ExAcquireResourceSharedLite(&PsLoadedModuleResource, TRUE); /* Loop the loaded module list */ NextEntry = PsLoadedModuleList.Flink; while (NextEntry != &PsLoadedModuleList) { /* Get the entry */ LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); /* Check if it's the kernel or HAL */ if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE)) { /* Found it */ Found = TRUE; Modules++; } else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE)) { /* Found it */ Found = TRUE; Modules++; } /* Check if we found a valid binary */ if (Found) { /* Find the procedure name */ ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase, &AnsiRoutineName); /* Break out if we found it or if we already tried both modules */ if (ProcAddress) break; if (Modules == 2) break; } /* Keep looping */ NextEntry = NextEntry->Flink; } /* Release the lock */ ExReleaseResourceLite(&PsLoadedModuleResource); KeLeaveCriticalRegion(); /* Free the string and return */ RtlFreeAnsiString(&AnsiRoutineName); return ProcAddress; }
MiFindExportedRoutineByName——EAT中定位到指定函数
MmGetSystemRoutineAddress实际调用的MiFindExportedRoutineByName
PVOIDMiFindExportedRoutineByName ( IN PVOID DllBase, IN PANSI_STRING AnsiImageRoutineName ){ USHORT OrdinalNumber; PULONG NameTableBase; PUSHORT NameOrdinalTableBase; PULONG Addr; LONG High; LONG Low; LONG Middle; LONG Result; ULONG ExportSize; // 保存表项的大小 PVOID FunctionAddress; PIMAGE_EXPORT_DIRECTORY ExportDirectory; PAGED_CODE(); ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData ( DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize); if (ExportDirectory == NULL) { return NULL; } NameTableBase = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNames); NameOrdinalTableBase = (PUSHORT)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals); //二分查找法 Low = 0; Middle = 0; High = ExportDirectory->NumberOfNames - 1; while (High >= Low) { Middle = (Low + High) >> 1; Result = strcmp (AnsiImageRoutineName->Buffer, (PCHAR)DllBase + NameTableBase[Middle]); if (Result < 0) { High = Middle - 1; } else if (Result > 0) { Low = Middle + 1; } else { break; } } // 如果High < Low,表明没有在EAT中找到这个函数;否则,返回此函数的索引 if (High < Low) { return NULL; } OrdinalNumber = NameOrdinalTableBase[Middle]; // 如果索引值大于EAT中已有的函数数量,则查找失败 if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) { return NULL; } Addr = (PULONG)((PCHAR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions); FunctionAddress = (PVOID)((PCHAR)DllBase + Addr[OrdinalNumber]); ASSERT ((FunctionAddress <= (PVOID)ExportDirectory) || (FunctionAddress >= (PVOID)((PCHAR)ExportDirectory + ExportSize))); return FunctionAddress;}
在模块中定位指定函数名的地址,这个算法挺不错的
- MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
- MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress函数
- MmGetSystemRoutineAddress实现
- MmGetSystemRoutineAddress 函数源码
- MmGetSystemRoutineAddress
- MmGetSystemRoutineAddress函数获取内存地址
- strcpy函数和memcpy函数的实现代码
- str系列函数的用法和实现代码
- 自己编写代码实现atoi和itoa函数的功能
- 自己编写代码实现atoi和itoa函数的功能
- calloc函数的实现代码
- MmGetSystemRoutineAddress routine
- 用setitimer函数和signal信号处理函数实现简单的timer的代码
- 自动装箱拆箱_享元模式
- Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (三) —— SharePreferences
- Win7+VS2010编译WebKit总结
- POJ 3278 Catch That Cow
- SecureCRT 实用配置
- MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
- VS2010单词高亮插件免费下载
- jquery 图表插件highcharts & highstock
- 到底是main还是WinMain?
- 隐式转换导致索引失效
- 算法导论求n个点的最小距离
- PI问题1
- js向html中的下拉框赋值
- Play Framework配置Mysql