MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
来源:互联网 发布:有了源码怎么架设游戏 编辑:程序博客网 时间:2024/06/08 10:24
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
- 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;
- }
在模块中定位指定函数名的地址,这个算法挺不错的
0 0
- 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的代码
- Codeforces 609B The Best Gift 【水题】
- HIBERNATE 的乐观锁@VERSION和 MYSQL 的两个小问题
- Hibernate与Mysql 5.5创建表出错--table doesn't exist
- Ant+jmeter配置
- Android之.XML布局
- MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
- stat函数讲解
- CSS3:伪对象选择器
- Zlib库的使用实现对zip文件的解压缩(二)
- 新浪实时股票数据接口http://hq.sinajs.cn/list=code
- Android Studio界面介绍
- 蓝牙HC05模块探究-设置AT指令
- Android TextView内容过长加省略号,点击显示全部内容
- 数据结构Java语言实现之链表