cocop 发表于 2020-4-17 18:28:05

通过HOOK 常见api监视内存偷检测思路及易语言实现附成品和源码

本帖最后由 cocop 于 2020-4-17 18:52 编辑

无聊逛论坛时,偶然发现了关于偷 内存检测的帖子,于是思考了下偷内存的实现。    最先想到的方法肯定是内存对比,但因需要对比游戏全部内存,效率差强人意,而且内存对比需要不断的改变需要获取的内存以过滤无关数据,大部分检测又是只写一次,不会重写多次,根本无法从海量数据中挑出自己需要的。
    之后查询相关资料了解到内存监视器的原理是Hook kernel32.dll中的WriteProcessMemory实现监视更改内存的作用。对于我这种菜鸡来说,Hook是仅仅了解过但又从未自己去实现过的新奇事物,自然勾动着我的好奇心。于是我去查阅了相关的资料、代码明白了hook监视内存的实现方法。在这里做下笔记加深理解。
   下面是hook的实现过程,大牛就别看了{:cry:},这里拿WriteProcessMemory做示范
    1.保存系统函数入口处的代码,此步骤的目的是便于恢复。
WriteProcessMemory_.钩子地址 = GetProcAddress (GetModuleHandleA (“kernel32.dll”), “WriteProcessMemory”)
这里GetModuleHandleA获取了kernel32.dll的模块地址,接着GetProcAddress获取WriteProcessMemory的地址。
VirtualProtect (WriteProcessMemory_.钩子地址, 8, 64, WriteProcessMemory_.OldProtect)
改变要hook地址的虚拟内存页保护属性为64
WriteProcessMemory_.原始数据 = 指针到字节集 (WriteProcessMemory_.钩子地址, 8)
保存原始数据

    2.替换掉进程中的系统函数入口指向我们的函数
.版本 2

置汇编代码 ({})
清空汇编代码 ()
Mov_EAX (到整数 (&_WriteProcessMemory))
JMP_EAX ()
WriteProcessMemory_.代码 = 取汇编代码 ()
写到内存 (WriteProcessMemory_.代码, WriteProcessMemory_.钩子地址, 8)

因为我对机器语言不了解,拼接颇为费劲,故利用的超级模块,转换为字节集后写到hook函数的入口。
Mov_EAX (到整数 (&_WriteProcessMemory)),这里_WriteProcessMemory是我们重写的WriteProcessMemory,意思是将这个地址赋值给EAX寄存器
JMP_EAX () 跳转到我们编写的函数地址。
    3.当系统函数被调用,立即跳转到我们的函数
.版本 2

.子程序 _WriteProcessMemory, 逻辑型
.参数 进程句柄, 整数型
.参数 内存地址, 整数型
.参数 缓冲指针, 整数型, 参考
.参数 内存长度, 整数型
.参数 实际长度, 整数型, 参考
.局部变量 result, 逻辑型

R_WriteProcessMemory ()
result = WriteProcessMemory (进程句柄, 内存地址, 缓冲指针, 内存长度, 实际长度)

.如果 (PID > 0)
    R_ReadProcessMemory ()' 暂时屏蔽读
    Write (“WriteProcessMemory”, “进程句柄:” + 到文本 (进程句柄) + tab + “内存地址:” + Get_Base_Address (内存地址) + tab + “内存长度:” + 到文本 (内存长度) + tab + “写入数据:” + _字节集_到十六进制 (读内存字节集 (PID, 内存地址, 内存长度)), 到文本 (result))
    写到内存 (ReadProcessMemory_.代码, ReadProcessMemory_.钩子地址, 8)

.否则
    Write (“WriteProcessMemory”, “进程句柄:” + 到文本 (进程句柄) + tab + “内存地址:” + Get_Base_Address (内存地址) + tab + “内存长度:” + 到文本 (内存长度) + tab + “写入数据因为未获取到Crossfire进程ID而无法获取”, 到文本 (result))
.如果结束
写到内存 (WriteProcessMemory_.代码, WriteProcessMemory_.钩子地址, 8)
返回 (result)

.版本 2

.子程序 R_WriteProcessMemory

.如果真 (取字节集长度 (WriteProcessMemory_.原始数据) > 0)
    写到内存 (WriteProcessMemory_.原始数据, WriteProcessMemory_.钩子地址, )
.如果真结束


首先调用子程序R_WriteProcessMemory,还原入口,毕竟还是要调用WriteProcessMemory实现功能的,我们只是获取数据,不是破坏功能。
之后调用正经的WriteProcessMemory API,得到结果result,将参数带result输出,若要获取写入了什么,调用读内存获取即可。
这里暂时屏蔽ReadProcessMemory是因为同时hook了ReadProcessMemory会干扰结果。
    4.再修改系统函数入口指向我们的函数,便于下次调用
写到内存 (WriteProcessMemory_.代码, WriteProcessMemory_.钩子地址, 8)


但是只hook一个API怎么可能满足的了我呢?于是便写了GetModuleHandleA,ReadProcessMemory,VirtualAllocEx,VirtualProtect,VirtualProtectEx。
file:///C:\Users\coco\AppData\Roaming\Tencent\Users\794087777\TIM\WinTemp\RichOle\2NSCS%H4I3I35NA}SPWD))M.png


再一次无聊逛论坛时发现,他们的监视器居然能通过内存找到对应的静态地址!那我肯定坐不住了啊,写起来。
目前只有获取一级基址的思路,多级不能调试游戏估计莫得办法,望各位大哥指点。

.版本 2

.子程序 Get_Base_Address, 文本型, , 输入10进制地址,返回16进制一级基址
.参数 address, 整数型
.局部变量 i, 整数型

.计次循环首 (取数组成员数 (模块信息), i)
    .如果真 (address ≥ 模块信息 .基地址 且 address < 模块信息 .基地址 + 模块信息 .大小)
      返回 (模块信息 .文件名 + “+” + 十到十六 (address - 模块信息 .基地址))
    .如果真结束

.计次循环尾 ()
返回 (到文本 (address))


用timeSetEvent开启了一个时钟监测是否存在游戏,若有游戏则获取PID并用超级模块提供的取进程模块获取模块信息。
XF_Timer = timeSetEvent (500, 0, &Judge_XF_Timer, 1, 1)
.版本 2

.子程序 Judge_XF_Timer
.局部变量 P_ID, 整数型

P_ID = XF_PID ()
.如果 (P_ID > 0)
    PID = P_ID
    取进程模块 (PID, 模块信息)
    timeKillEvent (XF_Timer)

.否则
    PID = -1
.如果结束


Get_Base_Address的作用便是输入一个内存,循环比较模块信息,若在模块内,返回对应基址,若找不到则返回原地址。


编译为dll,注入 进程测试,这里就不拿XF测试了,自己随便写了个测试程序把名字改成了crossfire.exe测试。

测试还算挺W美的。至于读写之前为什么要VirtualProtectEx应该是得改内存的属性,避免读写不了。若有错误,希望指正!谢谢各位大佬!{:titter:}

使用方法:dll注入相关 即可,怕成品有毒的就自己编译,模块也只是个超级模块,还是不放心就用自己的超级模块。
理论上注入游戏的 dll也能获取数据,把自己的dll也注入游戏就行。但得过了游戏的保护,我菜,就不注入游戏献丑了{:2_28:}。需要的大佬自己拿着源码改一改过一下保护应该就可以。
还需要hook其他api稍稍改一下就行,不费劲~


最后附上源码模块和成品!**** Hidden Message *****

SystemRc 发表于 4 天前

学习学习。。。。。。

xp6688 发表于 5 天前

学习一下看看

ycsyywl 发表于 2025-3-19 16:12:24

学习一下看看

zhiyua 发表于 2024-12-24 22:47:41

学习一下看看

ekai528 发表于 2024-11-10 20:51:37

好东西需要下来看一下,不知道能不能用

a459223418 发表于 2024-11-5 22:38:32

谢谢学习谢谢学习

chu0832 发表于 2024-10-16 23:45:35

联系我时,请说是在 挂海论坛 上看到的,谢谢!

1622313889 发表于 2024-8-18 00:00:40

看看,学学,支持楼主

Kaito 发表于 2024-8-12 21:53:04

正好需要 感谢楼主正好需要 感谢楼主

YZT_1104 发表于 2024-8-11 00:58:54

正好需要 感谢楼主
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 通过HOOK 常见api监视内存偷检测思路及易语言实现附成品和源码