好友
阅读权限35
听众
最后登录1970-1-1
|
本帖最后由 KaQqi 于 2019-8-9 17:33 编辑
视频版本正在审核,敬请关注: https://www.bilibili.com/video/av62942317/
一、游戏简介
《蜘蛛纸牌》是由Oberon Games开发的一款休闲益智类游戏,该游戏已由Microsoft于2010年发行。
同时该游戏也是Windows ME及后续版本所自带的小游戏,游戏的目标是以最少的移动次数将牌面中的十叠牌以及待发的五组,共计八副牌整理移除。当所有牌被移除整理到界面的左下方,游戏获胜。
在“游戏”菜单上,单击“开局”开始游戏。牌面上有十叠牌,前四叠每叠6张,后六叠每叠5张,只有每叠的第一张正面朝外,其他均为正面朝内。界面的右下角有五组共计50张牌,没有全部翻开。windows xp版本中,界面的中下方的方框中显示的得分分数(开局为500分)和已操作数。vista版本中,没有该框,分数及操作数显示在界面的最下方。
规则:https://baike.baidu.com/item/%E8%9C%98%E8%9B%9B%E7%BA%B8%E7%89%8C/877244?fr=aladdin
二、简单的一批的无限分数和0移牌
之所以要水这么容易的内容
是因为
想要实现真正的随意移牌 需要找个位置下手
每次移牌之后分数和次数都会变
从这里回溯 才能找到关键位置
使用Cheat Engine 四字节模式 搜索分数或者移牌数 多次改变搜到结果
会搜到2个 一个是真正的移动次数 一个是移动成功的次数
我们要移动成功的次数
然后f6 找到修改地址
0102ABFC - FF 40 0C - inc [eax+0C]
nop掉即可实现分数自定义、步数不增加
简单的一批,不多说
三.随意摆放
在od中找到这个地址。下断点。移动牌,断下
函数很小 还没我手写的红警科技全开函数大..
所以关键函数应该不在这里
我们回溯
出来之后注明这个call是增加步数的。
然后在段首下断点 重新移动牌。我们发现 无论是成功移动还是失败移动 都会断下来。我们将这里定义为移动牌的关键函数。
我们的第一反应就是找跳过这里的跳转,发现无法找到。
成功会增加步数 失败则不会 而是否增加步数取决于 0102D3C4 |. 385D 0B cmp byte ptr ss:[ebp+0xB],bl
所以我们向上寻找bl 看看有没有和bl有关的跳转 或者修改bl的语句
很快,我们就找到了第一个和bl有关的大跳转,下断点测试,发现成功时不跳 失败时跳
跳过的内容里还有一个字符串
0102D38C |. 68 6C600001 push SpiderSo.0100606C ; InvalidSequenceDropMove
二话不说 直接jmp 测试效果
我们发现 牌是移动了 但是移动的牌卡在那里动不了 新的牌也不能往那个牌上移动 即使新的牌是合法的。。
这个挑战只是控制是否移动的 而移动后很多功能没有添加
就像我们搞红警里的随处建造一样 修改跳转需要修改很多处 而如果修改关键call则只需要修改1处
所以我们决定修改关键call
根据跟踪发现 bl的值是在上面一个超大循环中赋值的
[Asm] 纯文本查看 复制代码 0102D2DB |> /3B45 D4 /cmp eax,[local.11]
0102D2DE |. |73 71 |jnb short SpiderSo.0102D351
0102D2E0 |. |8B4D E0 |mov ecx,[local.8]
0102D2E3 |. |8B3C81 |mov edi,dword ptr ds:[ecx+eax*4]
0102D2E6 |. |3BFB |cmp edi,ebx
0102D2E8 |. |74 58 |je short SpiderSo.0102D342
0102D2EA |. |3B7D E8 |cmp edi,[local.6]
0102D2ED |. |74 53 |je short SpiderSo.0102D342
0102D2EF |. |8BCF |mov ecx,edi
0102D2F1 |. |E8 D9230300 |call SpiderSo.0105F6CF
0102D2F6 |. |85C0 |test eax,eax
0102D2F8 |. |76 0C |jbe short SpiderSo.0102D306
0102D2FA |. |8BCF |mov ecx,edi
0102D2FC |. |E8 83290300 |call SpiderSo.0105FC84
0102D301 |. |3858 0D |cmp byte ptr ds:[eax+0xD],bl
0102D304 |. |74 3C |je short SpiderSo.0102D342
0102D306 |> |3B7E 50 |cmp edi,dword ptr ds:[esi+0x50]
0102D309 |. |74 37 |je short SpiderSo.0102D342
0102D30B |. |57 |push edi
0102D30C |. |FF75 08 |push [arg.1]
0102D30F |. |8BCE |mov ecx,esi
0102D311 |E8 95E9FFFF call SpiderSo.0102BCAB
0102D316 |. |84C0 |test al,al
0102D318 |. |75 11 |jnz short SpiderSo.0102D32B
0102D31A |. |C645 F3 01 |mov byte ptr ss:[ebp-0xD],0x1
0102D31E |. |885D F2 |mov byte ptr ss:[ebp-0xE],bl
0102D321 |. |395D EC |cmp [local.5],ebx
0102D324 |. |75 1C |jnz short SpiderSo.0102D342
0102D326 |. |897D EC |mov [local.5],edi
0102D329 |. |EB 17 |jmp short SpiderSo.0102D342
0102D32B |> |57 |push edi
0102D32C |. |FF76 50 |push dword ptr ds:[esi+0x50]
0102D32F |. |8BCE |mov ecx,esi
0102D331 |. |FF75 E8 |push [local.6]
0102D334 |. |E8 9FFAFFFF |call SpiderSo.0102CDD8
0102D339 |. |885D F3 |mov byte ptr ss:[ebp-0xD],bl
0102D33C |. |885D F2 |mov byte ptr ss:[ebp-0xE],bl
0102D33F |. |885D F1 |mov byte ptr ss:[ebp-0xF],bl
0102D342 |> |8B45 E4 |mov eax,[local.7]
0102D345 |. |8B7D EC |mov edi,[local.5] ; ntdll.77F46F6C
0102D348 |. |40 |inc eax
0102D349 |> |8945 E4 mov [local.7],eax
0102D34C |. |385D F1 |cmp byte ptr ss:[ebp-0xF],bl
0102D34F |.^\75 8A \jnz short SpiderSo.0102D2DB
由于这个循环比较复杂 我决定上IDA
我们很快找到了上面所说的循环、跳转、增加步数的函数 并分别给他们重命名
[Asm] 纯文本查看 复制代码 if ( v21 || v22 ) // 0
{
v24 = 0;
if ( v22
&& v9 != *(Concurrency::details::SchedulingRing **)(v3 + 48)
&& v9 != *(Concurrency::details::SchedulingRing **)(v3 + 80) )
{
if ( v9 && Concurrency::details::SchedulingRing::Id(v9) && sub_105FC84(v9) )
sub_102AF7C(v3, L"InvalidSequenceDropMove", 0);
sub_10315B6(7, 0, 0);
LABEL_36:
v24 = 0;
goto LABEL_37;
}
if ( v21 )
{
if ( v13 )
*(_BYTE *)a3 = 1;
goto LABEL_36;
}
}
我们发现 这个跳转是由v21和v22控制的 都为0则执行 而v21 22的初始值分别为1、0 所以我们只需找到给他们赋值0的地方就行了
在超大循环之中 我们找到了给v21和v22赋值的地方。而有一处,直接给他们俩都赋值为0。
而这一处是否执行 是由 sub_102BCAB的返回值控制的
于是我们直接在汇编里把call sub_102BCAB nop掉 mov eax,1
然后崩溃了。。
那就说明这个函数还做了别的事情
我们继续反编译 sub_102BCAB 看看怎么修改返回值
这个函数的返回值就是sub_1029FF5的返回值 我们继续反编译sub_1029FF5
我们需要返回值是1 只需要不让那个if(a2)执行即可。在汇编中找到对应代码 直接jmp
搞定。
这样就可以不管谁在上谁在下 直接随便移动了
四、随意移牌
我们玩了一会之后发现 这样移动牌还是不够随意。。
因为:
而我们刚刚在逆向的过程中发现 无论是sub_102BCAB 还是sub_102D1DF 都是类SpiderGame的函数。
我们看看这个类内有没有别的函数 能直接从名字入手 达到随意移牌
经过10分钟的筛选 我们发现有一个可疑字符串:
这就是判断能否drag的函数了。
在下方发现一个可疑跳转
改成jmp 完事!
这次没有出现功能不完全的情况..
然后 我们就能快快乐乐开开心心的玩了!!
结束语:
这是腐朽的终结 也是新生的萌芽
开启的是黑暗 也是茫然
其实之前逆向了很多游戏 比如扫雷、植物大战僵尸 但是这些论坛里已经有人逆向过了 所以视频就没有发..
只有逆向别人没有逆向的 或许才能获得新生的萌芽8
视频版本已经在上传 正在审核 审核通过将发过来。
https://www.bilibili.com/video/av62942317/ |
免费评分
-
查看全部评分
本帖被以下淘专辑推荐:
- · 分析示例|主题: 622, 订阅: 108
- · 好帖|主题: 550, 订阅: 86
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|