本帖最后由 1364847132 于 2017-6-20 02:19 编辑
前几天看见吾爱的一个帖子:windows扫雷玩坏系列之各种玩 好像很好玩的样子。
反正高考完了没事做,然后我就继续改了一下这个。有不足之处请大家指出。
效果图:
增加了无敌这个选项。
需要工具:
1.资源工具,这里我用的Restorator(就是吾爱破解工具包里的那个)。
2.LordPE,用来加区段的。也可以用现成的工具:[PEtools] EXE区段添加,支持区段名 空间大小设置
3.od
首先用Restorator打开扫雷,按F6打开编辑模式改成这样
把每个选项后面的数字记下来(我也不知道那叫啥) 我们添加的选项后面是十进制的530,十六进制就是0x212.然后保存。
保存后打开发现菜单里已经有了这个选项,但是并没有什么实际作用。现在来给它添加点内容
od载入,下断bp SetMenu,F9运行。
停下来后取消断点Alt+F9执行到用户代码。来到了这里。
[Asm] 纯文本查看 复制代码 01003CE5 /$ 8B4424 04 mov eax,dword ptr ss:[esp+0x4]
01003CE9 |. A3 C4560001 mov dword ptr ds:[0x10056C4],eax
01003CEE |. E8 23D8FFFF call winmine.01001516
01003CF3 |. A1 C4560001 mov eax,dword ptr ds:[0x10056C4]
01003CF8 |. 24 01 and al,0x1
01003CFA |. F6D8 neg al
01003CFC |. 1BC0 sbb eax,eax
01003CFE |. F7D0 not eax
01003D00 |. 2305 945A0001 and eax,dword ptr ds:[0x1005A94]
01003D06 |. 50 push eax ; /hMenu = 00000001
01003D07 |. FF35 245B0001 push dword ptr ds:[0x1005B24] ; |hWnd = 01E7015A ('扫雷',class='扫雷')
01003D0D |. FF15 C4100001 call dword ptr ds:[<&USER32.SetMenu>] ; \SetMenu
01003D13 |. 6A 02 push 0x2
01003D15 |. E8 36DCFFFF call winmine.01001950
01003D1A \. C2 0400 retn 0x4
我们进第一个call看看。发现里面的所有call都指向了01003CC4,再看看push的参数是不是很熟悉。没错就是刚刚我叫你们记下的数字(上面红色字体)。
下面的代码我已经把注释打好了。
[Asm] 纯文本查看 复制代码 01001516 /$ 33C0 xor eax,eax
01001518 |. 66:3905 A0560>cmp word ptr ds:[0x10056A0],ax
0100151F |. 0F94C0 sete al
01001522 |. 50 push eax
01001523 |. 68 09020000 push 0x209 ; 初级
01001528 |. E8 97270000 call winmine.01003CC4
0100152D |. 33C0 xor eax,eax
0100152F |. 66:833D A0560>cmp word ptr ds:[0x10056A0],0x1
01001537 |. 0F94C0 sete al
0100153A |. 50 push eax
0100153B |. 68 0A020000 push 0x20A ; 中级
01001540 |. E8 7F270000 call winmine.01003CC4
01001545 |. 33C0 xor eax,eax
01001547 |. 66:833D A0560>cmp word ptr ds:[0x10056A0],0x2
0100154F |. 0F94C0 sete al
01001552 |. 50 push eax
01001553 |. 68 0B020000 push 0x20B ; 高级
01001558 |. E8 67270000 call winmine.01003CC4
0100155D |. 33C0 xor eax,eax
0100155F |. 66:833D A0560>cmp word ptr ds:[0x10056A0],0x3
01001567 |. 0F94C0 sete al
0100156A |. 50 push eax
0100156B |. 68 0C020000 push 0x20C ; 自定义
01001570 |. E8 4F270000 call winmine.01003CC4
01001575 |. FF35 C8560001 push dword ptr ds:[0x10056C8]
0100157B |. 68 11020000 push 0x211 ; 颜色
01001580 |. E8 3F270000 call winmine.01003CC4
01001585 |. FF35 BC560001 push dword ptr ds:[0x10056BC]
0100158B |. 68 0F020000 push 0x20F ; 标记
01001590 |. E8 2F270000 call winmine.01003CC4
01001595 |. FF35 B8560001 push dword ptr ds:[0x10056B8]
0100159B |. 68 0E020000 push 0x20E ; 声音
010015A0 |. E8 1F270000 call winmine.01003CC4
010015A5 \. C3 retn
我们在“标记”前面下断,就是 01001585。
F9运行,菜单—》游戏—》标记。 ok停下来了。
经过多次实验发现当这个0x10056BC的值为0就是取消,为1就是勾选。
就下来就需要找到是哪个地方更改了0x10056BC的值。
右键—》查找—》所有常量
把所有的都下断,
F9运行,菜单—》游戏—》标记。 ok停下来,再取消所有断点。
这里是很标准的switch语句,
[Asm] 纯文本查看 复制代码 01001DBC |> \0FB745 10 movzx eax,word ptr ss:[ebp+0x10] ; Case 111 (WM_COMMAND) of switch 01001D5B
01001DC0 |. B9 10020000 mov ecx,0x210
01001DC5 |. 3BC1 cmp eax,ecx
01001DC7 |. 0F8F 0F010000 jg winmine.01001EDC
01001DCD |. 0F84 FF000000 je winmine.01001ED2
01001DD3 |. 3D FE010000 cmp eax,0x1FE
01001DD8 |. 0F84 EA000000 je winmine.01001EC8
01001DDE |. 3BC6 cmp eax,esi
01001DE0 |. 0F84 B7000000 je winmine.01001E9D
01001DE6 |. 3D 08020000 cmp eax,0x208 ; Switch (cases 209..20F)
01001DEB |. 0F8E B8030000 jle winmine.010021A9
01001DF1 |. 3D 0B020000 cmp eax,0x20B
01001DF6 |. 7E 61 jle short winmine.01001E59
01001DF8 |. 3D 0C020000 cmp eax,0x20C
01001DFD |. 74 50 je short winmine.01001E4F
01001DFF |. 3D 0E020000 cmp eax,0x20E
01001E04 |. 74 20 je short winmine.01001E26
01001E06 |. 3D 0F020000 cmp eax,0x20F
01001E0B |. 0F85 98030000 jnz winmine.010021A9
01001E11 |. 33C0 xor eax,eax ; Case 20F of switch 01001DE6
01001E13 |. 3905 BC560001 cmp dword ptr ds:[0x10056BC],eax
01001E19 |. 0F94C0 sete al
01001E1C |. A3 BC560001 mov dword ptr ds:[0x10056BC],eax
01001E21 |. E9 24010000 jmp winmine.01001F4A
在01001DC0 下断。F9运行再随便点一下菜单内的选项,断下后看eax就是我们点的选项所对应的数字(见上)。
好了,现在所有要改的地方都找到了,但是程序并没有空间给我们写代码了。于是,添加区段。
这里我添加了两个区段,icode与IDAta
od载入Ctrl+G来到01001DC0。我们分析一下这个switch语句。
[Asm] 纯文本查看 复制代码 01001DC0 |. B9 10020000 mov ecx,0x210
01001DC5 |. 3BC1 cmp eax,ecx
01001DC7 |. 0F8F 0F010000 jg winmine.01001EDC ; eax>0x210 跳
而我们添加的选项是0x212,这个一定要跳的,所以我们跟着跳下去看看。
[Asm] 纯文本查看 复制代码 01001EDC |> \2D 11020000 sub eax,0x211 ; 颜色; Switch (cases 211..251)
01001EE1 |. 74 36 je short winmine.01001F19
01001EE3 |. 83E8 3D sub eax,0x3D ; 这下面是另一个菜单了
01001EE6 |. 74 23 je short winmine.01001F0B
01001EE8 |. 48 dec eax
01001EE9 |. 74 1A je short winmine.01001F05
01001EEB |. 48 dec eax
01001EEC |. 74 11 je short winmine.01001EFF
01001EEE |. 48 dec eax
01001EEF |. 0F85 B4020000 jnz winmine.010021A9
01001EF5 |. E8 231E0000 call winmine.01003D1D ; Case 251 of switch 01001EDC
01001EFA |.^ E9 5FFDFFFF jmp winmine.01001C5E
01001EFF |> 6A 00 push 0x0 ; Case 250 of switch 01001EDC
01001F01 |. 6A 04 push 0x4
01001F03 |. EB 0A jmp short winmine.01001F0F
01001F05 |> 6A 02 push 0x2 ; Case 24F of switch 01001EDC
01001F07 |. 6A 01 push 0x1
01001F09 |. EB 04 jmp short winmine.01001F0F
01001F0B |> 6A 00 push 0x0 ; Case 24E of switch 01001EDC
01001F0D |. 6A 03 push 0x3
01001F0F |> E8 621E0000 call winmine.01003D76
01001F14 |. E9 90020000 jmp winmine.010021A9
01001F19 |> 33C0 xor eax,eax ; Case 211 of switch 01001EDC
01001F1B |. 33FF xor edi,edi ; ntdll.7C93005D
01001F1D |. 393D C8560001 cmp dword ptr ds:[0x10056C8],edi ; ntdll.7C93005D
01001F23 |. 0F94C0 sete al
01001EE1 是判断是颜色选项就跳,而01001EE3是下一个菜单了,所以我们要把代码插这中间。但是这中间没有空间怎么办,这时候我们添加的区段就派上用场了。
改
[Asm] 纯文本查看 复制代码 01001DC7 - 0F8F 33D20100 jg winmine.0101F000 ; 跳转的地址改为我们添加区段的首地址
而0101F000这么写
[Asm] 纯文本查看 复制代码 0101F000 2D 11020000 sub eax,0x211
0101F005 - 0F84 0E2FFEFF je winmine.01001F19 ; 先把本来的两句抄过来
0101F00B 83F8 01 cmp eax,0x1 ; 因为这里我们的是0x212,减去0x211后就是0x1了,和0x1比较
0101F00E 74 05 je short winmine.0101F015
0101F010 - E9 CE2EFEFF jmp winmine.01001EE3 ; 不是0x212就跳回到之前的代码执行
0101F015 33C0 xor eax,eax
0101F017 3905 00000201 cmp dword ptr ds:[0x1020000],eax
0101F01D 0F94C0 sete al
0101F020 A3 00000201 mov dword ptr ds:[0x1020000],eax ; 这4句是给0x1020000值取反的,就是1变成0,0变成1
0101F025 - E9 202FFEFF jmp winmine.01001F4A
ps:0x1020000是我们添加的idata段的首地址,这个地址就是记录我们添加的选项是勾选还是没勾选。
Ctrl+G来到01001516
改
[Asm] 纯文本查看 复制代码 0100155D - E9 CEDA0100 jmp winmine.0101F030
对应的0101F030这么写
[Asm] 纯文本查看 复制代码 0101F030 33C0 xor eax,eax
0101F032 66:833D A056000>cmp word ptr ds:[0x10056A0],0x3
0101F03A 0F94C0 sete al
0101F03D 50 push eax
0101F03E 68 0C020000 push 0x20C
0101F043 E8 7C4CFEFF call winmine.01003CC4
0101F048 FF35 C8560001 push dword ptr ds:[0x10056C8]
0101F04E 68 11020000 push 0x211
0101F053 E8 6C4CFEFF call winmine.01003CC4
0101F058 FF35 BC560001 push dword ptr ds:[0x10056BC]
0101F05E 68 0F020000 push 0x20F
0101F063 E8 5C4CFEFF call winmine.01003CC4
0101F068 FF35 B8560001 push dword ptr ds:[0x10056B8]
0101F06E 68 0E020000 push 0x20E
0101F073 E8 4C4CFEFF call winmine.01003CC4 ; 这里之前都是把原来的抄过来
0101F078 FF35 00000201 push dword ptr ds:[0x1020000] ; 这里就是传入0x1020000的值
0101F07E 68 12020000 push 0x212 ; 这里是我们添加的选项的数字
0101F083 E8 3C4CFEFF call winmine.01003CC4
0101F088 - E9 1825FEFF jmp winmine.010015A5 ; 跳到刚刚call的返回处
到此我们已经改完了。运行一下没出错。
最后总结一下,改的地方一共三处
1.
[Asm] 纯文本查看 复制代码 01001DC7 - 0F8F 33D20100 jg winmine.0101F000 ; 地址改为我们添加区段的首地址
2.
[Asm] 纯文本查看 复制代码 0100155D - E9 CEDA0100 jmp winmine.0101F030
3.
[Asm] 纯文本查看 复制代码 0101F000 2D 11020000 sub eax,0x211
0101F005 - 0F84 0E2FFEFF je winmine.01001F19 ; 先把本来的两句抄过来
0101F00B 83F8 01 cmp eax,0x1 ; 因为这里我们的是0x212,减去0x211后就是0x1了,和0x1比较
0101F00E 74 05 je short winmine.0101F015
0101F010 - E9 CE2EFEFF jmp winmine.01001EE3 ; 不是0x212就跳回到之前的代码执行
0101F015 33C0 xor eax,eax
0101F017 3905 00000201 cmp dword ptr ds:[0x1020000],eax
0101F01D 0F94C0 sete al
0101F020 A3 00000201 mov dword ptr ds:[0x1020000],eax ; 这4句是给0x1020000值取反的,就是1变成0,0变成1
0101F025 - E9 202FFEFF jmp winmine.01001F4A
0101F02A 0000 add byte ptr ds:[eax],al
0101F02C 0000 add byte ptr ds:[eax],al
0101F02E 0000 add byte ptr ds:[eax],al
0101F030 33C0 xor eax,eax
0101F032 66:833D A056000>cmp word ptr ds:[0x10056A0],0x3
0101F03A 0F94C0 sete al
0101F03D 50 push eax
0101F03E 68 0C020000 push 0x20C
0101F043 E8 7C4CFEFF call winmine.01003CC4
0101F048 FF35 C8560001 push dword ptr ds:[0x10056C8]
0101F04E 68 11020000 push 0x211
0101F053 E8 6C4CFEFF call winmine.01003CC4
0101F058 FF35 BC560001 push dword ptr ds:[0x10056BC]
0101F05E 68 0F020000 push 0x20F
0101F063 E8 5C4CFEFF call winmine.01003CC4
0101F068 FF35 B8560001 push dword ptr ds:[0x10056B8]
0101F06E 68 0E020000 push 0x20E
0101F073 E8 4C4CFEFF call winmine.01003CC4 ; 这里之前都是把原来的抄过来
0101F078 FF35 00000201 push dword ptr ds:[0x1020000] ; 这里就是传入0x1020000的值
0101F07E 68 12020000 push 0x212 ; 这里是我们添加的选项的数字
0101F083 E8 3C4CFEFF call winmine.01003CC4
0101F088 - E9 1825FEFF jmp winmine.010015A5 ; 跳到刚刚call的返回处
下一期再把无敌的功能真正加进去,其实你们也可以参考最上面的链接,自己改.
附件里有原版和改后的。
1.zip
(154.98 KB, 下载次数: 171)
第二期:http://www.52pojie.cn/thread-618058-1-1.html |