MmGetSystemRoutineAddress 函数实现代码
来源:互联网 发布:女用催情药 知乎 编辑:程序博客网 时间:2024/05/21 21:40
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;
- /* 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;
- }
函数主要是遍历PsLoadedModuleList查找"ntoskrnl.exe"与"hal.dll"模块基址,然后调用MiFindExportedRoutineByName在两个模块中查找函数地址,查看下MiFindExportedRoutineByName实现
- PVOID
- MiFindExportedRoutineByName (
- 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;
- }
在函数MiFindExportedRoutineByName中,利用RtlImageDirectoryEntryToData 函数得到模块的导出表地址,然后二分遍历导出表,查看是否有指定的字符串导出,还用了Ordinal值判断(PE解析的内容~)
0 0
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
- MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
- MmGetSystemRoutineAddress函数
- MmGetSystemRoutineAddress实现
- MmGetSystemRoutineAddress 函数源码
- MmGetSystemRoutineAddress
- MmGetSystemRoutineAddress函数获取内存地址
- MmGetSystemRoutineAddress routine
- calloc函数的实现代码
- 欧拉函数代码实现
- atof函数实现代码,原理
- 欧拉函数代码实现
- 自主实现sleep函数(代码实现)
- C函数atoi,itoa的实现代码
- 泊松融合
- 技术进步与管理创新
- 【Hibernate】Hibernate多表查询后,将查询结果转化为实体
- centos7的安装及配置
- setTimeout
- MmGetSystemRoutineAddress 函数实现代码
- Java进阶(十六)使用new Date()和System.currentTimeMillis()获取当前时间戳
- java使用map去重复
- 网络中的一些专业名词解释
- 每一天短信发送次数每一分钟发送频率发送限制 hibernate数据库框架
- objective-c中实现函数重载(黑魔法:__attribute__((overloadable)))
- Oracle数据类型
- 关于文章说明
- larave5 生成数据库测试数据