admin管理员组文章数量:1648369
QQ连连看单机版:qqllk.exe
题目:
1. 找到程序本身的exe
2. 去掉程序中的广告
3. 写一个QQ连连看的外挂
使用到的工具:
OD
PEID
ImpREC
VS2013
测试环境:
虚拟机win7平台32位
1.初始界面
我们发现打开一个真正程序经过了了两层广告。
当我们直接点击真正程序
qqllk.exe(大广告)->qqllk.ocx(小广告)->kyodai.exe(真正代码,但是它代码给抽取了),套路一层接着一层
1.1:使用PE工具查询基本信息
切记:当我们拿到一个程序后先用PE工具全面分析,尽量收集多点信息
程序是VC6写的MFC程序
OD打开发现wmain函数的代码都错误的
2:OD跟踪程序
思路:
我们通过测试软件发现程序是通过打开2个广告,再运行真正的程序。
那么就下CreateProcessA或则W断点
2.1:大广告(QQ连连看启动器)
总结:
发现大广告调用小广告
2.2:小广告(百度连接)
思路:
直接下CreateProcessA或则W断点
可疑地方:
这里线程挂起很可疑,我们之前直接打开主程序发现PE文件给修改,然而通过广告间接打开主程序却可以正常运行,我们可以怀疑是(小广告百度连接)把PE文件代码给还原的。
2.3当程序挂起的时候用OD附加主程序(最好在恢复线程之前附加)
我们发现这软件是典型的VC6.0编写的:
找到wmain函数
此时wmain的代码还没被修复
2.4当我们通过广告二(百度连接)运行起来再附加
总结:
我们可以推测程序是通过这两个广告修复才可以正常运行的。因为我们在第二个广告发现线程停,
当运行完广告二(百度连接)程序的时候代码再附加代码就发现修复完毕,那么我们就可以判断程序是通过广告二(百度连接)在挂起线程与恢复线程之间修复完成的。
通过以上的特征:
我们可以大胆推断程序大概用到的API:
一般远程修改对方内存数据都是用到
//1.打开进程
OpenProcess 打开进程
//2.写入到对方进程空间中
参数说明:
BOOL WINAPI WriteProcessMemory(
_In_ HANDLE hProcess, //进程句柄
_In_ LPVOID lpBaseAddress, //要写的数据的指针
_In_ LPCVOID lpBuffer, //缓冲区地址
_In_ SIZE_T nSize, //要写入的字节
_Out_ SIZE_T *lpNumberOfBytesWritten //返回实际读取,写入字节
);
SuspendThread 暂停线程
ResumeThread 恢复线程
注意:
OD附加失败处理方法
2.5:开两个其中一个OD附加kyodai.exe在winmain下个断点,方便知道什么时候对它修改过
2.6:开两个OD其中一个OD附加广告二(百度链接)下WriteProcessMemory断点
并且记住修改的地址:43817A
转到另外一个附加的kyodai.exe主程序查看修改的地方 (刚好是wmain函数call里面)
跟进wmaincall里面发现代码给修复了
2.7:可以在程序执行完WriteProcessMemory就把主程序Dump出来或则在恢复线程ResumeThread恢复线程之前Dump出来
因为在OEP处dump出来比较干净,没有给污染,记住OEP地址438048-基地址400000=38048
2.8:使用ImportREC修复IAT表
转到到文件就是你刚才用OD插件dump出来的来个覆盖上去就可以了
2. 9 去掉程序中的广告
3.写一个QQ连连看的外挂:
逆向找的是数据,只要找到操作地图数据的代码即可
3.1:首先判断程序是什么编写的
VC6 release动态
3.2:用PE工具分析找到关键API
rand关键API
3.3:在rand处下手
我们发现调用rand地方很多处,我们只能够一次次筛选找到最像的地方
第一处未发现关键代码待定
第二处.kml是专门保存地标的文件还有跟memcpy很可疑哦
重要数据:
483AC8 地图模板
12BB50 地图模板(483AC8内存拷贝给它的)
[Esi+0x195C]=12BB50 地图模板
地图宽19
地图高11
跟进call
call作用:
①:申请堆空间
②:把堆空间随机生成数据
③:把堆空间随机生成的数据给12BB50地图模板(非零的数据全部填充掉)
④:释放堆空间
3.4为了判断地图游戏数据是否操作一张地图还是多张地图,直接开始游戏观察12BB50数据
我们观察地图数据刚好是D1(209 =宽19*高11)大小
思路:
我们发现有个道具是指南针自动帮我们找到两个可以消除的地方,我们可以通过修改指南针下手,就可以不用去逆算法。
实现:
在地图数据处下硬件断点
栈返回
栈保存的值不是固定的,所以要找一些固定的值
ESI = [45DCF8]
取地址
MOV ECX,DWORD PTR DS:[ESI+0x1E84]
取地址=
ECX = [ESI+0X1E84] 地图缓冲区 = [ECX+4] 地图开始处 = 地图缓冲区+8
ECX = [[45DCF8]+ 0x1E84]
总结 dd [[[45DCF8]+0x1e84]+4]+8
3.5注入DLL实现模拟指南针的call
/*
0041DE53 | . 8D8E 94040000 lea ecx, dword ptr ds : [esi + 0x494]
0041DE59 | . 52 push edx
0041DE5A | . 53 push ebx
0041DE5B | . 53 push ebx
0041DE5C | .FF50 28 call dword ptr ds : [eax + 0x28]
*/
_asm
{
mov eax,0x45DCF8
mov eax, dword ptr[eax]
lea ecx, dword ptr[eax+0x494]
push 0xf0
push 0
push 0
mov eax,0x0041E691
call eax
}
3.6寻找指南针定位的数组下标
[Ebp-0x28]129d8c
[Ebp-0x20]129d94
然后我们直接对外面传入的两个参数下硬件写入断点
发现断下来了
那么我们模拟里面的call吧
对比下我们的程序
我们利用dll注入模拟了
这几句代码 具体实现:
//模拟call代码
//我们发现esi+0x19F0的esi不存在基地址
//但是esi+0x19f0跟用[ESI+0X1E84],得到的结果都是一样的
//那么我们就用esi+0x1E84(esi有基地址)代替esi+0x19f0
/*
0041E75E > \8B8E F0190000 mov ecx, dword ptr ds : [esi + 0x19F0]; ecx = this指针 首地址虚函数标 + 4地图数组首地址; Case F0(BM_GETCHECK) of switch 0041E749
0041E764 . 8D45 D8 lea eax, dword ptr ss : [ebp - 0x28]; POINT结构
0041E767 . 50 push eax
0041E768 . 8D45 E0 lea eax, dword ptr ss : [ebp - 0x20]; POINT
0041E76B . 50 push eax
0041E76C.E8 CEAA0000 call dumo_.0042923F; 返回两个可以消除的旗子坐标
*/
POINT FirstDot = { 0 }; //第一个消消乐的XY坐标点
POINT SecondDot = { 0 }; //第二个消消乐的XY坐标点
MessageBox(0, L"找到了注入点", 0, 0);
_asm{
mov eax, 0x45DCF8
mov eax, dword ptr[eax] //取45DCF8里的值 12A1F4
mov ecx, dword ptr[eax + 0x1E84] //取12C078里的值 013A83D0 里面首4个字节是虚函数表 +4是地图首地址
//以上三句等价于mov ecx,[esi+0x19F0]
lea eax, dword ptr[FirstDot]
push eax
lea eax, dword ptr[SecondDot]
push eax
mov eax, 0x42923F
call eax //函数返回两个可以消除棋子的下标
}
3.7现在数组下标都有了就找到消除的调用API就可以了
只要模拟这6个参数就可以了
//模拟代码
//6个参数
//00129BB8 00000000 无视
//00129BBC 0012BB50 地图首地址
//00129BC0 00129BEC 棋子地址A
//00129BC4 00129BF4 棋子地址B
//00129BC8 019B8400 这个地址是13683D0+30得来的
//公式
//mov eax, 0x45DCF8
//mov eax, dword ptr[eax]
//mov ecx, dword ptr[eax + 0x1E84]
//00129BCC 00000004 固定值
push 4 //固定值
mov ebx,ReEcx
add ebx,0x30
push ebx //13683D0+30
lea eax,[FirstDot] //坐标A
lea ebx, [SecondDot] //坐标B
push ebx
push eax
/******************获取到12BB50地图首地址***************************/
mov eax, 0x45DCF8
mov ecx, dword ptr[eax]
lea eax, dword ptr[ecx + 0x1e84]
mov eax, dword ptr[eax]
mov eax, dword ptr[eax + 4]
push eax
/*******************获取到12BB50地图首地址**************************/
push 0 //死值0
mov eax,0x41C68E
call eax //不支持call 立即数
版权声明:本文标题:单机连连看破解 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1729499787a1203227.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论