首页
社区
课程
招聘
[原创] 全文精华在最后一句
发表于: 2025-4-18 22:06 6107

[原创] 全文精华在最后一句

2025-4-18 22:06
6107

最近由于工作的需要,需要枚举消息钩子,总所周知的事是,很多ark工具都是有的, 那就选择直接逆向。本文选作了 openark 的驱动代码研究,openark 属于早期部分开源,后期不在开源。但是由于驱动没vmp保护 ,约等于源码么。 废话不多说直接开搞。
首先,直接进入openark的 内核模式,选择内核标签,进入gui管理的 消息钩子 ,然后使用 x64dbg 挂钩 ,对 deviceiocontrol 下断点,顺便把 参数打印出来。 最后如图:

其中这个暂停条件是 rdx== 0xa3632640 ,rdx 是 iocontrolcode ,我当时通过设置暂停条件为0 打印控制码 然后试出来的。
拿到这个控制码直接 就去驱动分析了, 三环没啥东西可看了。

进去直接分析消息通信相关,很标准的通信啊。直接干。

直接找到枚举消息钩子的功能函数的入口(这个里面的其他函数 对应这个gui管理的其他的功能,但是我懒得分析了,只看自己想要看的代码):

进来发现,很多未定义的东西啊(通过上下文可知 ,可能是win32k相关东西),到现在有两种思路 ,一种是直接vmware+VirtualKD-Redux 调试驱动,直接看他这些变量 到底是干什么的。还有一种思路是通过xref猜测他这个变量,其实也不用专门去调试。因为根据 ida 的交叉引用我们 一眼就能看出他是什么东西来了。

就这么标准的写法 模块名,具体的变量/函数 ,最后一个是我们引用查看的,闭着眼 猜是地址了。还原相关的变量名称,就和逆向没多大关系了。

通过泄露的源码和网上的公开信息,我们可以知道,gSharedInfo 是windows图形显示中很关键的一个内核变量,其中 gSharedInfo+8的位置存放的是aheList数组, 数组成员类型为_HANDLEENTRY,以及HANDLE_TYPE,tagHOOK等。
主要参考了看雪的帖子 https://bbs.kanxue.com/thread-261767.htm

真伪未辨 ,直接引用,酌情使用。

还是说一句,由于代码没有任何保护 , 所以只要把相应的变量符合重新命名,基本上就是源码了,这小节就是个人阅读时候的一些还原思路和对代码的理解,其实使用ai直接还原我感觉效果更好。

首先搞一个基础的检测 主要是看遍历所需的内核变量能否读,主要是针对 gsharedinfo变量来 还有 gSharedInfo+8 也就是 aheList,其中kprobe_read就是判断能不能读

上述检测通过之后 ,判断有没有要遍历的数量,如果有,则开始搞,没有的话就返回

主要说一下, 这个取 HANDLEENTRY ,win10 15063之前和 之后结构体是不同的,所以要对系统版本进行判断,取 htype 成员和 wuniq成员是为了下面的判断,所以需要做处理, 其中 htype 的类型是 HANDLE_TYPE ,这里面我们要遍历的是hook类型的,直接使用TYPE_HOOK = 5来过滤遍历我们想要的。

这里面调用了 HMValidateHandle 函数 来获取 taghook 类型的返回值,该返回值 存储了我们需要的信息

HMValidateHandle 函数原型为

其中第一个变量是我们根据句柄生成规则 生成的, 第二个是 HANDLE_TYPE ,因为我们要获取的是 HOOK类型的,所以填对应的5 ,对得到的返回值类型进行判断,如果返回不为NULL继续下一步的遍历

句柄 : 通过count | ((USHORT)wUniq << 16) 生成
类型: pobject_ret->iHook;// 钩子类型
flag: pobject_ret->flags;// flags
函数地址: 两种情况,一种是 ihmod = -1 直接获取pobject_ret->offPfn
另外一种是 ihmod != -1 等于 moudulebase+ pobject_ret->offPfn
模块名: 通过函数UserGetAtomNameFromAtomTable和句柄 UserLibmgmtAtomTableHandle 获取模块名
pid : 看代码,不想说了,基操
tid : 看代码,不想说了,基操
进程路径: 都拿到pid了, 这个还要问?

没啥总结,就是逆向别人的驱动,然后结合网上的资料,对ida的伪代码进行还原。
用正经话说就是,主要展示了一个逆向的思路过程,如何在碰到一个需要的功能,并且没有接触过这些知识的的情况下,通过逆向现有的产品功能,获取所需信息的过程。
用大佬说的话就是ida得了mvp,我是抄袭狗。

15063 之前的 
typedef struct _HANDLEENTRY
{
       PVOID phead;
       PVOID pOwner;
       UCHAR bType;
       UCHAR bFlags;
       USHORT wUniq;
} HANDLEENTRY, *PHANDLEENTRY;
 
15063 之后的
 
typedef struct _HANDLEENTRY
{
       PVOID Unknown1;
       PVOID UniqueThreadId;
       PVOID Unknown2;
       UCHAR bType;
       UCHAR bFlags;
       USHORT wUniq;
} HANDLEENTRY, *PHANDLEENTRY;
 
enum HANDLE_TYPE {
       TYPE_FREE = 0,
       TYPE_WINDOW = 1,
       TYPE_MENU = 2,
       TYPE_CURSOR = 3,
       TYPE_SETWINDOWPOS = 4,
       TYPE_HOOK = 5,
       TYPE_CLIPDATA = 6,
       TYPE_CALLPROC = 7,
       TYPE_ACCELTABLE = 8,
       TYPE_DDEACCESS = 9,
       TYPE_DDECONV = 10,
       TYPE_DDEXACT = 11,
       TYPE_MONITOR = 12,
       TYPE_KBDLAYOUT = 13,
       TYPE_KBDFILE = 14,
       TYPE_WINEVENTHOOK = 15,
       TYPE_TIMER = 16,
       TYPE_INPUTCONTEXT = 17,
       TYPE_HIDDATA = 18,
       TYPE_DEVICEINFO = 19,
       TYPE_TOUCHINPUT = 20,
       TYPE_GESTUREINFO = 21,
       TYPE_CTYPES = 22,
       TYPE_GENERIC = 255
};
typedef struct _THRDESKHEAD
{
      PVOID h;
      ULONG cLockObj;
      PVOID pti;
      PVOID rpdesk;
      PVOID pSelf;
}
 
typedef struct _tagHOOK
{
       _THRDESKHEAD head;   //0x0
       PVOID phkNext;       //0x28
       LONG iHook;         //0x30
       ULONG64 offPfn;     //0x38
       LONG flags;         //0x40
       LONG ihmod;        //0x44
       PVOID rpdesk;   //0x50
} tagHOOK, *PtagHOOK;
15063 之前的 
typedef struct _HANDLEENTRY
{
       PVOID phead;
       PVOID pOwner;
       UCHAR bType;
       UCHAR bFlags;
       USHORT wUniq;
} HANDLEENTRY, *PHANDLEENTRY;
 
15063 之后的
 
typedef struct _HANDLEENTRY
{
       PVOID Unknown1;
       PVOID UniqueThreadId;
       PVOID Unknown2;
       UCHAR bType;
       UCHAR bFlags;
       USHORT wUniq;
} HANDLEENTRY, *PHANDLEENTRY;
 
enum HANDLE_TYPE {
       TYPE_FREE = 0,
       TYPE_WINDOW = 1,
       TYPE_MENU = 2,
       TYPE_CURSOR = 3,
       TYPE_SETWINDOWPOS = 4,
       TYPE_HOOK = 5,
       TYPE_CLIPDATA = 6,
       TYPE_CALLPROC = 7,
       TYPE_ACCELTABLE = 8,
       TYPE_DDEACCESS = 9,
       TYPE_DDECONV = 10,
       TYPE_DDEXACT = 11,
       TYPE_MONITOR = 12,
       TYPE_KBDLAYOUT = 13,
       TYPE_KBDFILE = 14,

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 4
支持
分享
最新回复 (6)
雪    币: 2380
活跃值: (5705)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
openark不是开源的吗
2025-4-21 19:58
0
雪    币: 1553
活跃值: (2899)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
Oxygen1a1 openark不是开源的吗
前期开源,后期不开源了。
2025-4-22 13:11
0
雪    币: 227
活跃值: (791)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习了,我也抄ARK的驱动,哈哈
2025-4-22 13:21
0
雪    币: 241
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
学习了,nb plus
2025-4-24 15:28
0
雪    币: 207
活跃值: (55)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
好牛,
2025-4-24 17:18
0
雪    币: 12019
活跃值: (18869)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
 驱动模块逆向
2025-4-25 21:26
0
游客
登录 | 注册 方可回帖
返回