挂海论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
 友情提示:文字/图片广告均非网站意见,请担保交易勿直接付款,由此产生的责任自负
玩游戏来117游戏网(H5不下载也能玩手游传奇,吃鸡,竞技都有)不懂社区·好资源不错过·各位资源站大佬欢迎来采集搬运寻找会做《单机》游戏修改器的开发作者长期合作,价格不是问题!联系QQ:1874088565 JD寻实力长期勤快开发,来实力代理,DMA内存,项目讨论群 ██【我要租此广告位】██
查看: 1544|回复: 0
打印 上一主题 下一主题

[辅助源码] 极其方便的多极指针读取封装

[复制链接]

51

积分

15

主题

5

听众
已帮网友解决0 个问题
好评
0
贡献
36
海币
183
交易币
0
跳转到指定楼层
楼主
发表于 2020-6-12 19:09:44 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式
提醒:若下载的软件是收费的"请不要付款",可能是骗子,请立即联系本站举报,执意要付款被骗后本站概不负责。(任何交易请走第三方中介,请勿直接付款交易以免被骗!切记).

友情提示:文字/图片广告均非本站意见,请担保交易勿直接付款,由此产生的责任自负!!!↑↑


极其方便的多极指针读取封装
任鸟飞 任鸟飞逆向 今天
我想你或许写过这样的代码:
DWORD a = *(DWORD*)0x12345678;
a = *(DWORD*)(a+0xXX);
a = *(DWORD*)(a+0xXX);
a = *(DWORD*)(a+0xXX);
或者这样的:
DWORD a = NULL;
ReadProcessMemory(hProcess, (DWORD*)(a), &a, sizeof(DWORD), 0);
ReadProcessMemory(hProcess, (DWORD*)(a+0xXX), &a, sizeof(DWORD), 0);
ReadProcessMemory(hProcess, (DWORD*)(a+0xXX), &a, sizeof(DWORD), 0);
ReadProcessMemory(hProcess, (DWORD*)(a+0xXX), &a, sizeof(DWORD), 0);
ReadProcessMemory(hProcess, (DWORD*)(a+0xXX), &a, sizeof(DWORD), 0);
如果你为这玩意烦恼过,下面的代码或者思路或许可以帮到你。
后面写出的代码可以如这样般简洁:
xyGet(0x12345678,0x403,0xC,0x8);
让我们来看看代码:
XyGet.h
#include <Windows.h>
void F输出调试信息(char * pszFormat, ...);
DWORD xyGet(char* szpCHAR, int index, DWORD nd基质, DWORD nd中间值);
template<typename... Types>
DWORD xyGet(char* szpCHAR, int index, DWORD nd基质, DWORD nd中间值, int ndIndex,const Types&... args)
{
__try
{
return xyGet(szpCHAR, index, nd基质, *(DWORD*)(nd中间值 + ndIndex), args...);
}
__except (1)
{
F输出调试信息("%s xyGet,基址:%4X 第%d层偏移:%X 读取异常\r\n", szpCHAR, nd基质,index - sizeof...(args) + 1, ndIndex);
return 0;
}
}
template<typename... Types>
DWORD xyGet(char* szpCHAR, DWORD nd基质, const Types&... args)
{
__try
{
//int ndIndex =
return xyGet(szpCHAR, (int)sizeof...(args), nd基质, *(DWORD*)nd基质, args...);
}
__except (1)
{
F输出调试信息("%s xyGet,基址:%4X 异常!请传入有效基地址\r\n", szpCHAR, nd基质);
return 0;
}
}
template<typename... Types>
DWORD xyGet(DWORD nd基质, const Types&... args)
{
return xyGet("调试头", nd基质, args...);
}
xyGet.cpp
#include "xyGet.h"
void F输出调试信息(char * pszFormat, ...)
{
#ifdef _DEBUG
char szbufFormat[0x1000];
char szbufFormat_Game[0x1100] = "";
va_list argList;
va_start(argList, pszFormat);
vsprintf_s(szbufFormat, pszFormat, argList);
strcat_s(szbufFormat_Game, szbufFormat);
OutputDebugStringA(szbufFormat_Game);
va_end(argList);
#endif
}
DWORD xyGet(char* szpCHAR, int index, DWORD nd基质, DWORD nd中间值)
{
return nd中间值;
}
例子:xyGet(0x12345678,0x403,0xC,0x8);
使用方法第一个参数传入基地址,后面跟任意多个偏移
使用了C++ 11的新特性,任意类型任意个数的函数模板,如果你的编译器无法通过编译,或许需要手动开启C++ 11,如下。
现在我们一起来看看 例子:xyGet(0x12345678,0x403,0xC,0x8); 是怎么执行的。
PS:需要一些C++ 理论知识。
首先4个重载函数和我们的例子匹配度最高的肯定是:
第一步:
template<typename... Types>
DWORD xyGet(DWORD nd基质, const Types&... args)
{
return xyGet("调试头", nd基质, args...);
}
我们看它接受什么参数,一个DWORD  和 const Types&... args(一包东西)
然后调用了另外一个重载函数,第一个参数传入了一个字符串,然后把剩下2个参数原封不动的传入。为什么?主要我是担心我的程序出异常,指针读取非常危险的动作,我们必须时刻小心,所以传入一个调试头 ,以便出异常方便使用 Dbgview 捕捉异常所打印的信息,以此知道我们的程序 在读取那一个基地址 那一级偏移 产生了错误。如
接下来显而易见的程序走到了这,
第二步:
template<typename... Types>
DWORD xyGet(char* szpCHAR, DWORD nd基质, const Types&... args)
{
__try
{
//int ndIndex =
return xyGet(szpCHAR, (int)sizeof...(args), nd基质, *(DWORD*)nd基质, args...);
}
__except (1)
{
F输出调试信息("%s xyGet,基址:%4X 异常!请传入有效基地址\r\n", szpCHAR, nd基质);
return 0;
}
}
接收一个字符串,一个DWORD ,还有一包东西,嗯100%匹配,看看它做了什么处理。
调用了重载函数,传入一个字符串原封不动,计算一包东西还有多少个,DWORD基地址,把基地址里面的值读取出来传入,还有一包东西。
有什么参数?Char* int DWORD DWORD 加 args...(一包东西)
好像现在没有W美匹配的重载函数了,是的。但是编译器非常聪明,它把那一包东西拆解一下,变成char* int DWORD DWORD int 加 args...(一包东西) 显而易见的:
第三步:
DWORD xyGet(char* szpCHAR, int index, DWORD nd基质, DWORD nd中间值, int ndIndex,const Types&... args)
{
__try
{
return xyGet(szpCHAR, index, nd基质, *(DWORD*)(nd中间值 + ndIndex), args...);
}
__except (1)
{
F输出调试信息("%s xyGet,基址:%4X 第%d层偏移:%4X 读取异常\r\n", szpCHAR, nd基质,index - sizeof...(args) + 1, ndIndex);
return 0;
}
}
看它干了什么,再次调用了重载函数。前3个参数原封不动的传入,但是传入的第4个参数是什么?
nd中间值 是什么?没记住的去看第二步,它基地址里面读取出来的值把,ndIndex又是什么?它是那一包东西中的第一个数值,那一包东西是什么?可以去看第一步  一包东西 是那一堆偏移,显然我们读取了一层偏移。
看看我们现在传入调用函数什么东西: char* int DWORD DOWRD加 一包东西。很熟悉把,和第三步一样 编译器有会从一包东西里面取一样东西出来 变成char* int DWORD DWORD int 加 args...(一包东西)
那么很明显又会调用第三步的那货:
DWORD xyGet(char* szpCHAR, int index, DWORD nd基质, DWORD nd中间值, int ndIndex,const Types&... args)
程序陷入了递归循环,什么时候结束呢? 一包东西一个一个的取出来,总有一次递归会取干净。那么传入重载函数的参数会变成:szpCHAR, index, nd基质, *(DWORD*)(nd中间值 + ndIndex)
也就是 char* int DWORD DWORD , 这一堆参数有W美匹配的重载函数:
DWORD xyGet(char* szpCHAR, int index, DWORD nd基质, DWORD nd中间值)
{
return nd中间值;
}
看看他内部做了什么:
哦,直接返回了nd中间值,如果一包东西被消耗干净了,那么说明所有的偏移都被读取完毕,没错 这里返回了我们要的东西。
总结
本文章所提到的思路以及代码,是我在学习C++ 11新特性时 无意想到的,相对于C++ 98的半成品产品,C++ 11新标准明显更现代更经典更好用。
文章中所提到的代码已经经过测试 可以正常使用,或许会有轻微的效率和内存损失,强迫症们 务必不要在循环中调用。由于本人习惯问题,并未经常使用以上代码。所有我相信它肯定还有很多不足之处 和 提升优化的空间,在这里为大家提供思路,相信大家能有更加优秀的解决方案, 比如“[[[0x12345678]+0x40C]+0x8]+0xC” 通过解析这类字符串来得到我们想要的,到时候分享出来我们一起交流和进步!
逆向交流qun:453769015



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



上一篇:分享JD最新读写模块 带保护进程可解决解密开发问题
下一篇:高价求一套可以用的香肠派对模拟器源码
免责声明:
1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关。一切关于该内容及资源商业行为与www.52ghai.com无关。

2、本站提供的一切资源内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。

3、本站信息来自第三方用户,非本站自制,版权归原作者享有,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

4、如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵犯你版权的,请邮件与我们联系删除(邮箱:xhzlw@foxmail.com),本站将立即改正。

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

本版积分规则

免责声明|Archiver|手机版|小黑屋|挂海论坛

GMT+8, 2025-5-5 02:37 , Processed in 0.100816 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.2

本站资源来自互联网用户收集发布,如有侵权请邮件与我们联系处理。xhzlw@foxmail.com

快速回复 返回顶部 返回列表