龙马谷

 找回密码
 立即注册

QQ登录

只需一步,快速开始

龙马谷VIP会员办理客服QQ:82926983(如果临时会话没有收到回复,请先加QQ好友再发。)
1 [已完结] GG修改器新手入门与实战教程 31课 2 [已完结] GG修改器美化修改教程 6课 3 [已完结] GG修改器Lua脚本新手入门教程 12课
4 [已完结] 触动精灵脚本新手入门必学教程 22课 5 [已完结] 手游自动化脚本入门实战教程 9课 6 [已完结] C++射击游戏方框骨骼透视与自瞄教程 27课
7 [已完结] C++零基础UE4逆向开发FPS透视自瞄教程 29课 8 [已完结] C++零基础大漠模拟器手游自动化辅助教程 22课
以下是天马阁VIP教程,本站与天马阁合作,赞助VIP可以获得天马阁对应VIP会员,名额有限! 点击进入天马阁论坛
1 [已完结] x64CE与x64dbg入门基础教程 7课 2 [已完结] x64汇编语言基础教程 16课 3 [已完结] x64辅助入门基础教程 9课
4 [已完结] C++x64内存辅助实战技术教程 149课 5 [已完结] C++x64内存检测与过检测技术教程 10课 6 [已完结] C+x64二叉树分析遍历与LUA自动登陆教程 19课
7 [已完结] C++BT功能原理与x64实战教程 29课 8 [已完结] C+FPS框透视与自瞄x64实现原理及防护思路
查看: 431|回复: 0

Windows驱动开发:取进程模块的函数地址

[复制链接]

28

主题

3

回帖

38

积分

编程入门

Rank: 1

龙马币
73

在笔者上一篇文章《驱动开发:内核取应用层模块基地址》中简单为大家介绍了如何通过遍历PLIST_ENTRY32链表的方式获取到32位应用程序中特定模块的基地址,由于是入门系列所以并没有封装实现太过于通用的获取函数,本章将继续延申这个话题,并依次实现通用版GetUserModuleBaseAddress()取远程进程中指定模块的基址和GetModuleExportAddress()取远程进程中特定模块中的函数地址,此类功能也是各类安全工具中常用的代码片段。

首先封装一个lyshark.h头文件,此类头文件中的定义都是微软官方定义好的规范,如果您想获取该结构的详细说明文档请参阅微软官方,此处不做过多的介绍。
  1. #include <ntifs.h>
  2. #include <ntimage.h>
  3. #include <ntstrsafe.h>

  4. // 导出未导出函数
  5. NTKERNELAPI PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process);
  6. NTKERNELAPI PVOID NTAPI PsGetProcessWow64Process(IN PEPROCESS Process);

  7. typedef struct _PEB32
  8. {
  9.   UCHAR InheritedAddressSpace;
  10.   UCHAR ReadImageFileExecOptions;
  11.   UCHAR BeingDebugged;
  12.   UCHAR BitField;
  13.   ULONG Mutant;
  14.   ULONG ImageBaseAddress;
  15.   ULONG Ldr;
  16.   ULONG ProcessParameters;
  17.   ULONG SubSystemData;
  18.   ULONG ProcessHeap;
  19.   ULONG FastPebLock;
  20.   ULONG AtlThunkSListPtr;
  21.   ULONG IFEOKey;
  22.   ULONG CrossProcessFlags;
  23.   ULONG UserSharedInfoPtr;
  24.   ULONG SystemReserved;
  25.   ULONG AtlThunkSListPtr32;
  26.   ULONG ApiSetMap;
  27. } PEB32, *PPEB32;

  28. typedef struct _PEB_LDR_DATA
  29. {
  30.   ULONG Length;
  31.   UCHAR Initialized;
  32.   PVOID SsHandle;
  33.   LIST_ENTRY InLoadOrderModuleList;
  34.   LIST_ENTRY InMemoryOrderModuleList;
  35.   LIST_ENTRY InInitializationOrderModuleList;
  36. } PEB_LDR_DATA, *PPEB_LDR_DATA;

  37. typedef struct _PEB
  38. {
  39.   UCHAR InheritedAddressSpace;
  40.   UCHAR ReadImageFileExecOptions;
  41.   UCHAR BeingDebugged;
  42.   UCHAR BitField;
  43.   PVOID Mutant;
  44.   PVOID ImageBaseAddress;
  45.   PPEB_LDR_DATA Ldr;
  46.   PVOID ProcessParameters;
  47.   PVOID SubSystemData;
  48.   PVOID ProcessHeap;
  49.   PVOID FastPebLock;
  50.   PVOID AtlThunkSListPtr;
  51.   PVOID IFEOKey;
  52.   PVOID CrossProcessFlags;
  53.   PVOID KernelCallbackTable;
  54.   ULONG SystemReserved;
  55.   ULONG AtlThunkSListPtr32;
  56.   PVOID ApiSetMap;
  57. } PEB, *PPEB;


  58. typedef struct _PEB_LDR_DATA32
  59. {
  60.   ULONG Length;
  61.   UCHAR Initialized;
  62.   ULONG SsHandle;
  63.   LIST_ENTRY32 InLoadOrderModuleList;
  64.   LIST_ENTRY32 InMemoryOrderModuleList;
  65.   LIST_ENTRY32 InInitializationOrderModuleList;
  66. } PEB_LDR_DATA32, *PPEB_LDR_DATA32;

  67. typedef struct _LDR_DATA_TABLE_ENTRY32
  68. {
  69.   LIST_ENTRY32 InLoadOrderLinks;
  70.   LIST_ENTRY32 InMemoryOrderLinks;
  71.   LIST_ENTRY32 InInitializationOrderLinks;
  72.   ULONG DllBase;
  73.   ULONG EntryPoint;
  74.   ULONG SizeOfImage;
  75.   UNICODE_STRING32 FullDllName;
  76.   UNICODE_STRING32 BaseDllName;
  77.   ULONG Flags;
  78.   USHORT LoadCount;
  79.   USHORT TlsIndex;
  80.   LIST_ENTRY32 HashLinks;
  81.   ULONG TimeDateStamp;
  82. } LDR_DATA_TABLE_ENTRY32, *PLDR_DATA_TABLE_ENTRY32;


  83. typedef struct _LDR_DATA_TABLE_ENTRY
  84. {
  85.   LIST_ENTRY InLoadOrderLinks;
  86.   LIST_ENTRY InMemoryOrderLinks;
  87.   LIST_ENTRY InInitializationOrderLinks;
  88.   PVOID DllBase;
  89.   PVOID EntryPoint;
  90.   ULONG SizeOfImage;
  91.   UNICODE_STRING FullDllName;
  92.   UNICODE_STRING BaseDllName;
  93.   ULONG Flags;
  94.   USHORT LoadCount;
  95.   USHORT TlsIndex;
  96.   LIST_ENTRY HashLinks;
  97.   ULONG TimeDateStamp;
  98. } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
复制代码

GetUserModuleBaseAddress(): 实现取进程中模块基址,该功能在《驱动开发:内核取应用层模块基地址》中详细介绍过原理,这段代码核心原理如下所示,此处最需要注意的是如果是32位进程则我们需要得到PPEB32 Peb32结构体,该结构体通常可以直接使用PsGetProcessWow64Process()这个内核函数获取到,而如果是64位进程则需要将寻找PEB的函数替换为PsGetProcessPeb(),其他的枚举细节与上一篇文章中的方法一致。

游客,如果您要查看本帖隐藏内容请回复


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

龙马谷| C/C++辅助教程| 安卓逆向安全| 论坛导航| 免责申明|Archiver|
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表龙马谷立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2018-2021 All Right Reserved.
在线客服
快速回复 返回顶部 返回列表