最近写一款赌博棋牌游戏的外挂...前提要知道牌的点数。。在经过从封包着手--------由于没找到解密的方法所以失败了。。。想从内存着手,用CE OD 等工具分析了很久,由于牌都是加了密的无从着手,失败 。。。最后想到的方法是从图片识别着手,在网上查了点资料但是发现有用的资料不多,而且精度肯定不是很高。。。所以放弃了............................正当我准备放弃的时候,一个美女从我眼前飘过 突然灵光一闪 于是有了下文
首先想到一个棋牌游戏的扑克有54张牌,而这些牌应该在本地某个文件中。于是一个一个dll找。。。终于功夫不负有心人,老天保佑。。。在一个dll文件中找到了传说中的扑克
当你找到这个时,你可以随便更改牌了。。就是把牌的编号更改了。。所有的牌就乱了。。呵呵 (开玩笑的)
我这个时候想有了牌的编号应该能在内存中找到这些牌了吧!实践证明我的猜想是错误的 用了CE这个强悍的数据分析工具+od这个牛B的调试工具,最后却还是徒劳的。。
我想他既然要调用牌,肯定在这个dll文件中有调用牌的函数。。。。于是od加载游戏,进入到带有牌的这个dll中,
上下看了一下这里有什么有用的东西没有。。。。当我看到user32.loadbitmapA 是就如哥伦布发现新大陆一样,显示图片肯定要加载图片。。果断下段,晕。。怎么一下就断下来了。。经过几次下端 发现了他是某个时候定时加载验证。。。
ecx=牌的序号。。。。。我想这下应该能够找到牌是放哪里的了吧。。。晕 跟上去怎么进入一个
call 一下断点就断下来。。这下是没法下断点了。。。。。没法分析了。。。
突然 一个天使对我说别灰心
于是我洗心革面重新做人
想既然ecx这里出项了牌的点数,我就把这个点数保持到指定位置,不就行了吗?呵呵想法不错,说做就做果断给dll加了个区段命名为 : .狼来了(开玩笑)。。。。。
于是在
改成
于是就跳到我指定的位置从而我就想做什么就做什么了。。。呵呵 .hl 中的代码 也就是我自己处理牌的代码。。。。而且我计算出了牌的点数<纯汇编>
10036000 - E9 A2B0FCFF jmp GamePoke.100010A7 返回到原来的地方
10036005 90 nop
10036006 90 nop
10036007 90 nop
10036008 90 nop
10036009 90 nop
1003600A 90 nop
1003600B 90 nop
1003600C 90 nop ; 先nop几个玩玩 跳到这里
1003600D 90 nop
1003600E 90 nop
1003600F 90 nop
10036010 83F8 00 cmp eax,0x0 ; 由于我分析道图片进入时第一次eax 都是 0 所以判断是不是加载第一张牌的时候
10036013 75 17 jnz short GamePoke.1003602C ; 不等就跳
10036015 C705 D0610310 0>mov dword ptr ds:[0x100361D0],0x5 ; 由于是5张牌所以给他定义一个数来计算牌数
1003601F 90 nop
10036020 90 nop
10036021 90 nop
10036022 ^ EB DC jmp short GamePoke.10036000
10036024 90 nop
10036025 90 nop
10036026 90 nop
10036027 90 nop
10036028 90 nop
10036029 90 nop
1003602A 90 nop
1003602B 90 nop
1003602C 81F9 00020000 cmp ecx,0x200 ; 看他是不是加载牌。。。由于我分析是牌的点数在0x200-0x300
10036032 7D 0C jge short GamePoke.10036040 ; 是 就继续下去 不是就跳回去
10036034 ^ EB CA jmp short GamePoke.10036000 ; 不是就跳回去
10036036 90 nop
10036037 90 nop
10036038 90 nop
10036039 90 nop
1003603A 90 nop
1003603B 90 nop
1003603C 90 nop
1003603D 90 nop
1003603E 90 nop
1003603F 90 nop
10036040 81F9 00030000 cmp ecx,0x300 ; 再次比教是不是牌
10036046 ^ 7D B8 jge short GamePoke.10036000
10036048 833D D0610310 0>cmp dword ptr ds:[0x100361D0],0x1 ; 看是不是最后一张牌
1003604F ^ 7C AF jl short GamePoke.10036000
10036051 50 push eax
10036052 A1 D0610310 mov eax,dword ptr ds:[0x100361D0]
10036057 890C85 D0610310 mov dword ptr ds:[eax*4+0x100361D0],ecx ; 把牌放入到指定位置 ecx就是牌
1003605E 48 dec eax ; 牌数减1
1003605F A3 D0610310 mov dword ptr ds:[0x100361D0],eax
10036064 58 pop eax
10036065 833D D0610310 0>cmp dword ptr ds:[0x100361D0],0x0 ; 看不是5张牌都调用完了
1003606C ^ 75 92 jnz short GamePoke.10036000
1003606E 90 nop
1003606F 90 nop
10036070 90 nop
10036071 50 push eax ; 下面是计算牌和把牌替换成我想要的
10036072 53 push ebx
10036073 51 push ecx
10036074 52 push edx
10036075 BB 00000000 mov ebx,0x0
1003607A A1 E4610310 mov eax,dword ptr ds:[0x100361E4] 把牌点数传给eax 由于这里的eax=牌的序号+0x200 这个时第一张牌
1003607F 2D 00020000 sub eax,0x200
10036084 E8 A5000000 call GamePoke.1003612E 调用除法call计算是几点
10036089 90 nop
1003608A 90 nop 计算出的eax=牌的点数 1 点。2 点..........
1003608B 90 nop
1003608C 90 nop
1003608D A3 00630310 mov dword ptr ds:[0x10036300],eax 把点数放入 到指定位置 第一张
10036092 A1 E0610310 mov eax,dword ptr ds:[0x100361E0]
10036097 2D 00020000 sub eax,0x200
1003609C E8 8D000000 call GamePoke.1003612E
100360A1 90 nop
100360A2 90 nop
100360A3 90 nop
100360A4 90 nop
100360A5 A3 04630310 mov dword ptr ds:[0x10036304],eax 第二张
100360AA A1 DC610310 mov eax,dword ptr ds:[0x100361DC]
100360AF 2D 00020000 sub eax,0x200
100360B4 E8 75000000 call GamePoke.1003612E
100360B9 90 nop
100360BA 90 nop
100360BB 90 nop
100360BC 90 nop
100360BD A3 08630310 mov dword ptr ds:[0x10036308],eax
100360C2 A1 D8610310 mov eax,dword ptr ds:[0x100361D8]
100360C7 2D 00020000 sub eax,0x200
100360CC E8 5D000000 call GamePoke.1003612E
100360D1 90 nop
100360D2 90 nop
100360D3 90 nop
100360D4 90 nop
100360D5 A3 0C630310 mov dword ptr ds:[0x1003630C],eax
100360DA A1 D4610310 mov eax,dword ptr ds:[0x100361D4]
100360DF 2D 00020000 sub eax,0x200
100360E4 E8 45000000 call GamePoke.1003612E
100360E9 90 nop
100360EA 90 nop
100360EB 90 nop
100360EC 90 nop
100360ED A3 10630310 mov dword ptr ds:[0x10036310],eax
100360F2 90 nop
100360F3 90 nop
100360F4 90 nop
100360F5 90 nop
100360F6 90 nop
100360F7 90 nop
100360F8 5A pop edx
100360F9 59 pop ecx
100360FA 5B pop ebx
100360FB 58 pop eax
100360FC ^ E9 FFFEFFFF jmp GamePoke.10036000
10036101 90 nop
10036102 0000 add byte ptr ds:[eax],al
10036104 0000 add byte ptr ds:[eax],al
10036106 0000 add byte ptr ds:[eax],al
10036108 0000 add byte ptr ds:[eax],al
1003610A 0000 add byte ptr ds:[eax],al
1003610C 0000 add byte ptr ds:[eax],al
1003610E 0000 add byte ptr ds:[eax],al
10036110 0000 add byte ptr ds:[eax],al
10036112 0000 add byte ptr ds:[eax],al
10036114 0000 add byte ptr ds:[eax],al
10036116 0000 add byte ptr ds:[eax],al
10036118 0000 add byte ptr ds:[eax],al
1003611A 0000 add byte ptr ds:[eax],al
1003611C 0000 add byte ptr ds:[eax],al
1003611E 0000 add byte ptr ds:[eax],al
10036120 0000 add byte ptr ds:[eax],al
10036122 0000 add byte ptr ds:[eax],al
10036124 0000 add byte ptr ds:[eax],al
10036126 0000 add byte ptr ds:[eax],al
10036128 0000 add byte ptr ds:[eax],al
1003612A 0000 add byte ptr ds:[eax],al
1003612C 0000 add byte ptr ds:[eax],al
1003612E 53 push ebx
1003612F 90 nop 这个时除法call 下面是我用div的变形。。由于用div是 不知道怎么会整数溢出。。。应该是汇编没学好。。。就用减法代替了10036130 BB 00000000 mov ebx,0x0
10036135 83E8 10 sub eax,0x10
10036138 43 inc ebx
10036139 83F8 10 cmp eax,0x10
1003613C ^ 7D F7 jge short GamePoke.10036135
1003613E 8BC3 mov eax,ebx eax=商 余数我就没弄出来了因为我不需要
10036140 5B pop ebx
10036141 C3 retn
10036142 0000 add byte ptr ds:[eax],al
10036144 0000 add byte ptr ds:[eax],al 由于我中间还要加很多处理代码 所以nop 了很多留着以后慢慢弄 到此我的就处理完了。。。我把牌的点数放到
mov dword ptr ds:[0x10036300],eax 1
mov dword ptr ds:[0x10036304],eax 2
mov dword ptr ds:[0x10036308],eax 3
mov dword ptr ds:[0x1003630c],eax 4
mov dword ptr ds:[0x10036310],eax 5
到此5张牌就放到这里了。。。我是计算出的牌点数。。。没弄花色。。。要弄花色中间加代码就行了 这个就小x了
把这个dll文件放到游戏目录下替换原来的文件,,,呵呵 自己写代码直接访问这个内存 点数就读出来了。。。连基址和偏移都不用找了。。。。。
过程不重要 关键是思路。。。在写外挂。。。免杀。。。都可能能用到,,,我只是用一个棋牌游戏的点数读取来阐述一下我的观点。。。。写外挂的时候数据来源找不到不妨用这个方法试一下。。。。其实不是什么都要按套路走。。。希望这篇文章能对你们有帮助
找美女去了(梦中情人)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)