MmGetSystemRoutineAddress 函数实现代码
来源:互联网 发布:如何自己出书 知乎 编辑:程序博客网 时间:2024/06/05 18:32
MmGetSystemRoutineAddress这个函数也是比较有用的,是得到系统导出函数的地址,不过网上都是写了一堆汇编代码在哪里,根本没有可读性,还不如用IDA看呢。
下面的函数是摘自ReactOS项目的代码:
PVOIDNTAPIMmGetSystemRoutineAddress(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实现
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;}
在函数MiFindExportedRoutineByName中,利用RtlImageDirectoryEntryToData 函数得到模块的导出表地址,然后二分遍历导出表,查看是否有指定的字符串导出,还用了Ordinal值判断(PE解析的内容~)
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress 函数实现代码
- MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
- MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
- MmGetSystemRoutineAddress函数
- MmGetSystemRoutineAddress实现
- MmGetSystemRoutineAddress 函数源码
- MmGetSystemRoutineAddress
- MmGetSystemRoutineAddress函数获取内存地址
- MmGetSystemRoutineAddress routine
- calloc函数的实现代码
- 欧拉函数代码实现
- atof函数实现代码,原理
- 欧拉函数代码实现
- 自主实现sleep函数(代码实现)
- C函数atoi,itoa的实现代码
- log4cpuls在vc2010上编译的问题
- django模型4
- django模型5
- ContentProvider
- ASP.NET中下载的几种方式
- MmGetSystemRoutineAddress 函数实现代码
- 郁闷的晚上啊
- android应用程序发布和运行分析
- Delphi数据库编程新手指南(目录)
- 网络协议及网络软件框架设计网络协议
- MTK手机系统
- 稳定婚姻问题和Gale-Shapley算法
- WordPress分类页面获取当前分类的ID
- MTK Nucleus OS之初识