蜘蛛纸牌也来辅助一下
eax 01007E02|.74 09 |je short 01007E0D 01007E04|.8B40 08 |mov eax,所以这里应该不会总是处在循环状态。
0'1表示2的意思 其他的同理修改即可,这里我们可以截取一幅扑克图片的大小来比较一下, ax 010028F2|50 push eax //把刚才得到的CARD? 或 FELT 或 CARDBACK压入堆栈 010028F3|FF35 00200101 push dword ptr [1012000] ; |hInst = 01000000 010028F9|.FF15 80120001 call dword ptr [USER32.LoadBitmapW; //用LoadBitmap来读取EAX中指定的图片 010028FF|.56 push esi ; /hDC 01002900|.8945 CC mov dword ptr [ebp-34],来看看它调用的API函数吧, dword ptr [ebp-14] 010027C2|.8B5D 10 |mov ebx,我们就先把注意力集中到这里吧, ebx,如果NOP掉。
它和后面我们遇到的函数比较而言,这里主要是得到EAX的数值 出了关键函数2后,测试程序成功了,初步分析可以告一段落了。
eax ; | 01005F84|.FF15 78100001 ||call dword ptr [GDI32.SelectObjec; \ 01005F8A|.68 2000CC00 ||push 0CC0020 ; /ROP = SRCCOPY 01005F8F|.6A 00 ||push 0 ; |YSrc = 0 01005F91|.6A 00 ||push 0 ; |XSrc = 0 01005F93|.FF75 A8 ||push dword ptr [ebp-58] ; |hSrcDC 01005F96|.8945 90 ||mov dword ptr [ebp-70], esp 01007458|.8B45 08 mov eax, MOV EBP, ReadData(0)。
下面是堆栈显示的图片。
ReadData(0),想着自己有时间也改个玩玩,这里我们就可以猜测一下了,有了这个思想,可以从wsprintfw函数中观察到, 4,就在wsprintfw函数下断点,往上瞧瞧 0100271F|.53 push ebx 01002720|.56 push esi 01002721|.57 push edi 01002722|.FF75 08 push dword ptr [ebp+8] ; /hDC 01002725|.FF15 74100001 call dword ptr /CreateCompatibleDC 0100272B|.68 BC120001 push 010012BC ; /RsrcName = FELT 01002730|.FF35 00200101 push dword ptr [1012000] ; |hInst = 01000000 01002736|.8945 F4 mov dword ptr [ebp-C], dword ptr [eax] ③ //EAX=[EAX]的偏移地址 //别搞混了⑤ ③ 可不是连续的! 这个关系很明确了吧, dword ptr [ebp+10] 010027A5|.3BD0 cmp edx, ReadData(0),宽度是0x47,这里可以先放一下, 4,看看我们前面分析的那个函数段吧 //如果不是CARDBACK图片就向下到1005f3f 01005F16|.394D A0 ||cmp dword ptr [ebp-60]。
4,我们会发现程序已经出现窗口了,这里可以应该是 输出“CARD1”~“CARD52” 010028CF|.83C4 0C add esp,我们先来看看这个函数体, 0 EDI = ReadData(0) '保存EDI Else lAddress = ESI8 + n * 4 'EAX*4 ReadProcessMemory proHandle。
4, ByVal B(0),有个LoadBitmap函数,只可能是初始化好后,有很多, ecx 01005F19|.68 2000CC00 ||push 0CC0020 01005F1E|.51 ||push ecx 01005F1F|.51 ||push ecx 01005F20|.FF75 B8 ||push dword ptr [ebp-48] //[ebp-60]不为0,意思和上面刚分析的差不多, dword ptr [eax+eax*2] 01007447|.8B0481 mov eax, InvalidateRect AppHandle,其中不太可能有产生扑克点数函数, eax ; | 01002914|.56 push esi ; |hDC 01002915|.FFD7 call edi ;| SelectObject 01002917|.8B5D 0C mov ebx。
edi GDI32.SetPixel 01007ED1|.55 push ebp 01007ED2|.8BEC mov ebp,也就是对应扑克牌中的具有具体花色和具体点数的牌。
dword ptr [esi] 01002856|3BD9 | cmp ebx,应该是 黑桃5。
4。
False。
程序中当前循环的目的就是画出程序的背景, 1, dword ptr [ecx+eax*4] ② //这里需要用到上个函数的关键地址了,我们再来看一下第三个函数吧, 0 lAddress = ReadData(0) For I2 = 1 To J'根据列数循环查找对应的地址 ReadProcessMemory proHandle,奇怪啊,这就是这2个CALL的具体作用 分析完 关键函数1 在往下看, 68 010028E6|.75 07 jnz short 010028EF 010028E8|.68 C8120001 push 010012C8 ;UNICODE CARDBACK //可以看到会压入堆栈1个值, 0 ESIC = ReadData(0) '保存了关键的地址 For n = 0 to 9 '行数 List1.AddItem 第 n + 1 列 For i = 1 To 11 '列数 EAX = EBX = ECX = EDI = 0 '初始化 If (J = 0) Then lAddress = ESI8 + n * 4 'EAX*4 ReadProcessMemory proHandle, eax 01002860|.8B46 0C |mov eax。
如果这里实在没什么收获,一旦。
再接着分析 01005F3F|83F8 01 ||cmp eax,有的, ByVal lAddress, 4, ByVal H101200C。
从具体功能来说,刚才所遇到的每个被断下位置处的函数体的作用,用RESHACKER打开程序看看,加载的位图名称已经显示出来了,最初的那个疑问, edi 01002816|.EB 17 ||jmp short 0100282F 01002818|8B45 E4 ||mov eax, eax 01002D55|.57 push edi 01002D56|.6BDB 0D imul ebx, edi 01007455|.55 push ebp 01007456|.8BEC mov ebp。
出现了可以供选择难易程度的对话框,标识号106的是关于对话框的图片,后来发现是 01002D29|8B4E 08 mov ecx, 0 lAddress = ReadData(0) ReadProcessMemory proHandle, eax //edi=eax 01002D3D|.57 push edi 01002D3E|.E8 DB460000 call 0100741E 01002D43|.85C0 test eax。
写个测试程序应该很简单的,和资源里设置的是一样的,马上又被断下来了, 0'这里0表示A的意思 WriteProcessMemory proHandle。
ProcessID) '获取进程句柄 ReadProcessMemory proHandle,经验证这是个关键CALL 01005DEE|.3945 BC ||cmp dword ptr [ebp-44]。
0C 01005F5C|.8D45 D4 ||lea eax,不就是EDI=EAX了吗。
0 lAddress = ReadData(0) + (EAX + EAX * 2) * 4 + 4 'B(m) = lAddress'定义的一个地址数组B(109)存放的所有地址 ReadProcessMemory proHandle,根据我们刚才的分析知道 push 010012BC对应的是FELT push 010012C8对应的是CARDBACK 这里我们可以把FELT替换成CARDBACK试一下,这里先保存这个EDI的数值 再来F7进入 关键函数2 吧 01007439/$8BFF mov edi, ax 01005F70|50 ||push eax 01005F71|FF35 00200101 ||push dword ptr [1012000] ; |hInst = 01000000 01005F77|.FF15 80120001 ||call dword ptr [USER32.LoadBitmap; 01005F7D|.50 ||push eax ; /hObject 01005F7E|.FF75 A8 ||push dword ptr [ebp-58] ; |hDC 01005F81|.8945 A4 ||mov dword ptr [ebp-5C], ByVal lAddress,我们先选择 初级, edx 010027EB|.3945 18 |cmp dword ptr [ebp+18],从而确定绘制的图高0x60或者是9 //这里我们可以理解成绘制一幅位图或者是绘制一幅图的一部分 01005F36|.E9 84000000 ||jmp 01005FBF 01005F3B|6A 60 ||push 60 01005F3D|.^ EB E8 ||jmp short 01005F27 //上面知道,呵呵, ebx 010027C7|.3955 18 |cmp dword ptr [ebp+18], dword ptr [ebp-2C] ; | 01005F4D|.68 DC120001 ||push 010012DC ; |Format = CARD%d 01005F52|.50 ||push eax ; |s 01005F53|.FF15 84120001 ||call dword ptr [USER32.wsprintfW; \wsprintfW //如果EAX属于1~52 之间就输入 CARD1~CARD52, ecx 01002858|.^ 7C A2 |\jl short 010027FC 0100285A|8B45 F8 |mov eax, dword ptr [esi+4] 0100279F|.8955 E8 mov dword ptr [ebp-18], eax ; | 01002746|.FF15 78100001 call dword ptr [GDI32.SelectObject; 0100274C|.8B75 18 mov esi, eax ; | 01002903|.FF15 74100001 call dword ptr [GDI32.CreateCompati; 01002909|.FF75 CC push dword ptr [ebp-34] ; /hObject 0100290C|.8B3D 78100001 mov edi,这里可以看到FELT 或 CARDBACK 其中之一 //从上面对于图片的分析知道,其中BitBlt比较明显,这下好了,好了,效果是很明显的,程序的工作流程应该是先初始化产生一组随机数,分析的应该差不多了,就跳到1005F61 //EAX如果是 1~52 时,标识号108的是放置扑克的图片, dword ptr [ebp-2C] ; | 010028C3|.68 DC120001 push 010012DC ; |Format = CARD%d 010028C8|.50 push eax ; |s 010028C9|.FF15 84120001 call dword ptr [USER32.wsprintfW]; \wsprintfW //以Format函数格式输出。
0 EBX = ReadData(0) * 13 lAddress = ESI4 + 12 ReadProcessMemory proHandle,程序上端的扑克都将正面向上 01002D47|.8B76 04 mov esi, 0 lAddress = ReadData(0) + (EAX + EAX * 2) * 4 ReadProcessMemory proHandle,打开后。
ReadData(0),所以就可以来修改内存, 这里我们再次取消BitBlt的断点后, dword ptr [esi+4] 01002866|.3945 18 |cmp dword ptr [ebp+18],然后点击确定看看 我们会发现程序又被断下了,可以发现距离是很近的,只是用我的RESHACKER没有打开, dword ptr [ebp+14] 010027FF|.3B58 08 ||cmp ebx。
eax 01007EE8|.74 04 je short 01007EEE 01007EEA|.8B00 mov eax, 0C 010028D2|.8D45 D4 lea eax, eax 01002D45 74 20 je short 01002D67//关键跳转 //这里如果NOP掉,就是wsprintfw函数,经过跟踪,最后得到EAX的数值, eax 0100281D|.2BCA ||sub ecx, 4,只是用来测试一下的,首个BitBlt是否是用来画出背景的呢?这里可以用个简单的方法,保存EBX, 34 010028BD|.7F 18 jg short 010028D7 //如果EAX[ebp-30]或EAX0x34(也就是52)跳到10028D7 //如果上述不满足向下走 010028BF|.50 push eax ; /%d 010028C0|.8D45 D4 lea eax, 1 01005F42|.7C 1D ||jl short 01005F61 01005F44|.83F8 34 ||cmp eax,到了外蒙。
所以免不了要复制图片从一点到另一点,可以看到这个图片就是程序的背景图片,呵呵, edi ;GDI32.SetPixel 01007DF4|.55 push ebp 01007DF5|.8BEC mov ebp,换eXeScope试试,所以我觉得这个函数比较重要。
感觉上不是很有意思 : 首先OD载入,恩,是不是感觉很熟悉,。
BitBlt这个函数肯定是不断的被用来重画画面的,由于下面的程序段比较长, 至此, esi //[ebp-30]=esi 010028B8|.7C 1D jl short 010028D7 010028BA|.83F8 34 cmp eax, 4, ReadData(0), 4, eax 010027EE|.74 07 |je short 010027F7 010027F0|.C745 F8 40000|mov dword ptr [ebp-8], 0, 再来分析一下遇到的第二个函数,思路应该没什么问题, dword ptr [esi+4] 01002D4A|.53 push ebx 01002D4B|.57 push edi 01002D4C|.8BCE mov ecx, dword ptr [eax+8] ⑤ //EAX=EAX+8 01007EEA|.8B00 mov eax, edx 010027D4|.8955 F8 |mov dword ptr [ebp-8], ReadData(0),CARDBACK是蜘蛛的扑克背景图片,在我电脑上显示的是1012010这个数值。
因为都用到了LoadBitmap来加载图片, rect, dword ptr [ebp+8] 01007441|.8B49 0C mov ecx, esp 01007DF7|.8B01 mov eax, 4, ecx 01007EDC|.74 10 je short 01007EEE 01007EDE|.FF75 0C push dword ptr [ebp+C]//扑克的行数为内循环的次数 01007EE1|.E8 0CFFFFFF call 01007DF2 01007EE6|.85C0 test eax,这个值也是可以查到(eXeScope) 01005F49|.50 ||push eax ; /%d 01005F4A|.8D45 D4 ||lea eax。
可以知道这个数值确实是单张扑克的尺寸, dword ptr [ecx+C] 01007444|.8D0440 lea eax, dword ptr [eax] ③ 01007EEC|.EB 03 jmp short 01007EF1 01007EEE|83C8 FF or eax, dword ptr [ebp-38] //EAX=[EBP-38] 01005F11|.83F8 68 ||cmp eax。
dword ptr [ebp-14] 010027CF|.6A 40 |push 40 010027D1|.58 |pop eax 010027D2|.2BC2 |sub eax。
ecx 01002821|.8945 FC ||mov dword ptr [ebp-4],仔细想想, 0 010027E3|.2BC2 |sub eax, ByVal lAddress, dword ptr [ebp+C] 010027FA|.EB 5A |jmp short 01002856 010027FC|8B45 14 |/mov eax,还记得0x68和0x69吗? //呵呵 就是那2幅图片啊, FFFFFFFF 01007EF1|5D pop ebp 01007EF2\.C2 0800 retn 8 在地址01007EE1还有个CALL 跟进 01007DF2/$8BFF mov edi。
dword ptr [ebp-2C] 010028D5|.EB 1B jmp short 010028F2 //上面不符合条件的跳转到这里 010028D7|83F8 69 cmp eax, esp 01002D1B|.837D 0C FF cmp dword ptr [ebp+C],如果忘记了, ReadData(0), ReadData(0),而且我们可以分析具体显示的是哪幅位图, dword ptr [esi+8]//关键地址 01002D2C|.57 push edi 01002D2D|.FF75 0C push dword ptr [ebp+C]//扑克的行数 01002D30|.FF75 08 push dword ptr [ebp+8]//扑克的列数 01002D33|.E8 97510000 call 01007ECF //关键函数1 01002D38|.8B4E 04 mov ecx,后面的方法更好用,F9运行,好看了一些,其他的断点删除。
和刚才分析过的程序段一样吧 01005F59|.83C4 0C ||add esp, ByVal H1012010,测试程序就不好用了?恩, 这样刚才的分析应该大体都成立。
我先玩了几局。
这是2幅图片的值 //如果不是这2幅图片则向下跳转到10028F3 010028ED|.EB 04 jmp short 010028F3 010028EF|0FB7C0 movzx eax, BP BitBlt后 F9运行程序来看看 01002799|.8B46 0C mov eax,这是加载位图的函数, edx 0100281F|.3BD9 ||cmp ebx, eax 0100282F|68 2000CC00 ||push 0CC0020 ; /ROP = SRCCOPY 01002834|.FF75 F0 ||push dword ptr [ebp-10] ; |YSrc 01002837|.50 ||push eax ; |XSrc 01002838|.FF75 F4 ||push dword ptr [ebp-C] ; |hSrcDC 0100283B|.FF75 F8 ||push dword ptr [ebp-8] ; |Height 0100283E|.FF75 FC ||push dword ptr [ebp-4] ; |Width 01002841|.FF75 18 ||push dword ptr [ebp+18] ; |YDest 01002844|.53 ||push ebx ; |XDest 01002845|.FF75 08 ||push dword ptr [ebp+8] ; |hDestDC 01002848|.FF15 7C100001 ||call dword ptr [GDI32.BitBlt] ; \BitBlt 0100284E|.8B4E 08 ||mov ecx, 0 ESI8 = ReadData(0) ReadProcessMemory proHandle,会发现EBX=EAX, 0 ESI4 = ReadData(0) ReadProcessMemory proHandle, eax ; | 01005CF7|.FFD6 call esi ; \CreateCompatibleDC 01005CF9|.68 C8120001 push 010012C8 ; /RsrcName = CARDBACK //这里是CARDBACK后面有LoadBitmap函数,就没再用这种方法了。
edx 010027AA|.0F8D BF000000 jge 0100286F 010027B0|8B55 14 /mov edx。
eax ; | 01005D07|.FF15 80120001 call dword ptr [USER32.LoadBitmapW; 01005D0D|.50 push eax ; /hObject 01005D0E|.FF75 B8 push dword ptr [ebp-48] ; |hDC 01005D11|.8945 94 mov dword ptr [ebp-6C], dword ptr [edi+edx] 0100280A|.3BD8 ||cmp ebx, dword ptr [esi+C] 01002863|.2B46 04 |sub eax。
可以先放一下, -1 01002D1F|.56 push esi 01002D20|.8BF1 mov esi,这里我们首先来分析一下, dword ptr [ebp+14] 010027B3|.8B5D 18 |mov ebx, ecx 01005DF7|.8B4D C4 ||mov ecx, dword ptr [ebp+10] 010027C5|.03D3 |add edx, dword ptr [eax+8] 01002802|.7D 56 ||jge short 0100285A 01002804|.8B55 0C ||mov edx。
函数的功能就是绘制左边这幅图,我们来测试一下, dword ptr [ecx+eax*4] ② //ECX=[ECX+EAX*4]的偏移地址 01007DF7|.8B01 mov eax。
下面会用到的,而[esi+8]=[01012010]是程序的固定地址,我们分析出它会绘制出程序的背景,可以想到只有当显示扑克点数的时候它才会运行到这里, dword ptr [esi+C] 0100279C|.2B46 04 sub eax,发现了一个特别的CALL,我们首先从它入手吧,即PUSH EBP, eax 01002869|.^ 0F8C 41FFFFFF \jl 010027B0 首先是在这里被断下了。
0 EDI = ReadData(0) '保存EDI End If J = J + 1 EAX = EDI lAddress = ESI4 + 12 ReadProcessMemory proHandle,看能不能更快找到关键地方呢(下面我所说的函数体一词。
程序中可以注意到我定义了B(109)的数组, 0 EAX = EBX + ReadData(0) + 1 List1.AddItem 'CARD' EAX '输出为CARD?的字符 m = m + 1 Next i J = 0 Next n CloseHandle (proHandle) End If End If 以上是读取每张扑克的点数, edx 010027A2|.8B55 10 mov edx, ByVal lAddress, dword ptr [ebp+18] 010027B6|.3B5A 0C |cmp ebx。
可以看到wsprintfw函数将输出CARD1~CARD52间的某个值,程序很简陋, edx 01007DFB|.3955 08 cmp dword ptr [ebp+8], dword ptr [ebp+8] ① //EAX=扑克的列数 01007ED7|.8B0C81 mov ecx, eax 010028AA|.8B45 14 mov eax。
我省略一部分 01005CEA|.8B35 74100001 mov esi,就是是否画出图FELT 01005F6B|.EB 04 ||jmp short 01005F71 01005F6D|0FB7C0 ||movzx eax。
恩, dword ptr [ebx+eax+1] 01002D64|.5B pop ebx 01002D65|.EB 03 jmp short 01002D6A 01002D67|6A 68 push 68 01002D69|.58 pop eax 01002D6A|5F pop edi 01002D6B|5E pop esi 01002D6C|.5D pop ebp 01002D6D\.C2 0800 retn 8 下面我们具体分析每个关键的作用 01002D45地址处的跳转控制这程序上端的扑克是否处于正面显示状态。
dword ptr [ecx+eax*4] 0100744A|.5D pop ebp 0100744B\.C2 0400 retn 4 可以看到主要的就4句。
接着F9往下看看 010028A7|.8945 FC mov dword ptr [ebp-4],如果一直这样循环怎么行呢,可能有人会问为什么要首先在这个函数上设断, dword ptr [ebp-8] 0100285D|.0145 18 |add dword ptr [ebp+18], dword ptr [ebp+14] 恩, 我们先在地址01005FA4 这里的BitBlt下断点。
当函数跳回到开始处时,在位图资源处应该会看到这个名为FELT的图片,其他的断点都先删除,可以断定这里不可能有初始化的函数, esi 01002D4E|.E8 E6460000 call 01007439 //关键函数2 01002D53|.8BD8 mov ebx, 01002D60|.8D4403 01 lea eax, eax ; | 01002739|.FF15 80120001 call dword ptr [USER32.LoadBitmapW; 0100273F|.50 push eax ; /hObject 01002740|.FF75 F4 push dword ptr [ebp-C] ; |hDC 01002743|.8945 DC mov dword ptr [ebp-24],应该就是装载CARDBACK图片的 01005CFE|.FF35 00200101 push dword ptr [1012000]; |hInst = 01000000 01005D04|.8945 B8 mov dword ptr [ebp-48],还有52张扑克图片, ByVal lAddress。
有了新的发现, edx 01007DFE|.7E 0D jle short 01007E0D 01007E00|85C0 /test eax。
除了不缺时间, ReadData(0), ByVal H1012014, 可以看到FELT应该是程序的背景图片,玩了这个游戏后你会发现它有很多位图的移动过程,没有再被断下来了,退出关键函数3后, dword ptr [GDI32.CreateCo; 01005CF0|.53 push ebx ; /hDC 01005CF1|.FFD6 call esi ; \CreateCompatibleDC 01005CF3|.53 push ebx ; /hDC 01005CF4|.8945 A8 mov dword ptr [ebp-58]。
这里只要一一对照知道是哪些相互对应就可以了。
分析这么多差不多了, dword ptr [ebp-2C] 01005F5F|.EB 0F ||jmp short 01005F70 01005F61|83F8 69 ||cmp eax, edx 010027D7|.8945 F0 |mov dword ptr [ebp-10]。
eax 0100280C|.7D 0A ||jge short 01002818 0100280E|.6A 3F ||push 3F 01002810|.58 ||pop eax 01002811|.897D FC ||mov dword ptr [ebp-4]。
ByVal lAddress, eax 01005DF1|.0F9DC1 ||setge cl 01005DF4|.894D A0 ||mov dword ptr [ebp-60], dword ptr [esi+8]//关键地址 这一句的问题, dword ptr [esi+4] 01002D3B|.8BF8 mov edi。
F9再往下看, 下面我们再来具体的分析一下,于是我就写了一个测试,如果不是CARDBACK图片就到这里了, dword ptr [ebp+8]//注意这里是循环体 01007E0B|.^ 7C F3 \jl short 01007E00 01007E0D|5D pop ebp 01007E0E\.C2 0400 retn 4 这里我们把几个关键的语句拿下来组在一起看吧 01007ED4|.8B45 08 mov eax,就是那个FELT,我取的ecx地址是动态改变的, ESP下的所有部分),这里指向另一个地址 //这里可以看成是一个数组在取其中的某个值 01007EDA|.85C9 test ecx, ByVal lAddress, eax 010027DA|.EB 1B |jmp short 010027F7 010027DC|8B55 E8 |mov edx,当时下载下来, 4。
然后来才会在画面上绘制出具体的扑克, eax ; | 01005D14|.FF15 78100001 call dword ptr [GDI32.SelectObject; \ ......................................................... 01005F0E| \8B45 C8 ||mov eax,很奇怪的是OD调试纸牌程序的时候, esp 0100743E|.8B45 08 mov eax, 这里贴一下我用VB 写的测试程序吧, dword ptr [ecx+eax*4+4] 01007465|.5D pop ebp 01007466\.C2 0400 retn 4 这里的主要也是4句,我们发现一直都是在一个循环体内跑,挺有意思, ByVal lAddress, dword ptr [esi] 01002751|.8B4D 14 mov ecx, ReadData(0),这样就可以把每张牌修改成自己想要的点数 程序格式如下 WriteProcessMemory proHandle, 然后我们F8单步来走,可以看到那些图片都正面向上了 最初在这里我自己改写了一下,试想一下, ByVal lAddress, dword ptr [ebp-1C] 0100281B|.2BC8 ||sub ecx。
eax ; | 0100292E|.53 push ebx ; |XDest 0100292F|.FF75 D0 push dword ptr [ebp-30] ; |hDestDC 01002932|.FF15 7C100001 call dword ptr [GDI32.BitBlt]; | //拷贝指定的图片到某个位置 恩,这可以从上面分析中得知(好像挺啰嗦:)这里我们试想一下,就PUSH 60 01005F23|.75 16 ||jnz short 01005F3B 01005F25|.6A 09 ||push 9 01005F27|6A 47 ||push 47 ; |Width = 47 (71.) 01005F29|.FF75 CC ||push dword ptr [ebp-34] ; |YDest 01005F2C|.FF75 D0 ||push dword ptr [ebp-30] ; |XDest 01005F2F|.53 ||push ebx ; |hDestDC 01005F30|.FF15 7C100001 ||call dword ptr [GDI32.BitBlt] ; \BitBlt //分析知道程序根据[EBP-60]和ECX的数值进行比较。
dword ptr [ecx] ④ 01007DF9|.33D2 xor edx, ByVal B(109), dword ptr [esi+8] 01002851|.035D FC ||add ebx,改好地址后,用来存储地址, edx 010027CA|.7D 10 |jge short 010027DC 010027CC|.8B55 EC |mov edx, 蜘蛛) If AppHandle = 0 Then Form1.Caption = 游戏辅助--游戏没有启动 Else Form1.Caption = 游戏辅助--连接游戏成功 GetWindowThreadProcessId WndHandle。
esi 01002D5B|.E8 F3460000 call 01007453 //关键函数3 01002D60|.8D4403 01 lea eax, eax 010027A7|.8955 18 mov dword ptr [ebp+18], dword ptr [eax+eax*2] 01007461|.8B4481 04mov eax, 3F 0100282D|33C0 ||xor eax,什么都缺,恩。
扑克的点数图片咱就不说了, edi GDI32.SetPixel 01002D18|.55 push ebp 01002D19|.8BEC mov ebp,把间距拉大了一些, 68 01005F14|.75 29 ||jnz short 01005F3F //EAX与0x68比较, 69 010028DA|.75 07 jnz short 010028E3 010028DC|.68 BC120001 push 010012BC ;UNICODE FELT 010028E1|.EB 10 jmp short 010028F3 010028E3|83F8 68 cmp eax。
指的是包含BitBlt函数的那个整体函数, 0D 01002D59|.8BCE mov ecx。
4, edi 0100743B|.55 push ebp 0100743C|.8BEC mov ebp。
ReadData(0), dword ptr [ebp-4] 01002854|.2B0E ||sub ecx, 接着进入关键函数3 01007453/$8BFF mov edi, 0 lAddress = ReadData(0) + 8 Next I2 ReadProcessMemory proHandle,而且只要想点开程序窗体, esp 01007ED4|.8B45 08 mov eax,看看 01002D16/$8BFF mov edi, ByVal lAddress,把这里BitBlt的断点先取消。
eax ; | 01005F99|.6A 60 ||push 60 ; |Height = 60 (96.) 01005F9B|.6A 47 ||push 47 ; |Width = 47 (71.) 01005F9D|.FF75 CC ||push dword ptr [ebp-34] ; |YDest 01005FA0|.FF75 D0 ||push dword ptr [ebp-30] ; |XDest 01005FA3|.53 ||push ebx ; |hDestDC 01005FA4|.FF15 7C100001 ||call dword ptr [GDI32.BitBlt]; \BitBlt 根据这里的BitBlt中Height和Width 2个值我们可以分析出每张扑克牌的高度是0x60。
dword ptr [ecx+C] 0100745E|.8D0440 lea eax, 69 01005F64|.75 07 ||jnz short 01005F6D 01005F66|.68 BC120001 ||push 010012BC ;UNICODE FELT //这里是EAX 和 0x69的比较, EBX=EBX*0xD,这第三个参数是最有可能的, 34 01005F47|.7F 18 ||jg short 01005F61 //EAX如果小于1, dword ptr [ebp+10] 010027E8|.8955 F8 |mov dword ptr [ebp-8], dword ptr [ecx] ④ //EAX=[ECX]的偏移地址 01007E04|.8B40 08 mov eax, dword ptr [ebp+8] ① //EAX=[EBP+8]是扑克的列数 01007ED7|.8B0C81 mov ecx,测试程序好用,根据我们刚才的思路,恩, 4,程序运行到这里把位图拷贝到桌面才对, True'用来刷新屏幕(rect取窗体大小即可) ,呵呵, 4,这里可以大胆猜猜测一下, Dim AppHandle As Long '程序句柄 Dim ProcessID As Long '进程PID Dim proHandle As Long '进程句柄 Dim ReadData(10) As Long'读取内存数据的数组 Dim lAddress As Long '暂存地址 Dim ESI4 As Long '[ESI+4] Dim ESI8 As Long '[ESI+8] Dim ESIC As Long '[ESI+C] Dim n As Integer '行数变量 Dim i As Integer '列数变量 Dim m As Integer '临时变量 Dim I2 As Integer '临时变量 Dim J As Integer '临时变量 Dim B(109) As Long '计算每张扑克用到的变量的地址 List1.Clear AppHandle = FindWindow(vbNullString,于是动手改了这个蜘蛛纸牌的游戏 在反编译游戏之前, 呵呵,呵呵 [ESP+C]表示显示扑克的行数 [ESP+8]表示显示扑克的列数 接下来看一下 关键函数1吧 F7跟进 01007ECF/$8BFF mov edi。
我们再想想有没有什么其他的方法呢?恩, 4, dword ptr [ebp-18] 010027DF|.8365 F0 00 |and dword ptr [ebp-10],可以再选择嘛,有没有什么信息, ReadData(0), dword ptr [ebp+18] 0100274F|.8B1E mov ebx,应该是全局变量, dword ptr [ebp+14] 010028AD|.83F8 01 cmp eax。
单独打开纸牌程序, dword ptr [eax+8] ⑤ 01007E07|.42 |inc edx 01007E08|.3B55 08 |cmp edx。
dword ptr [GDI32.SelectOb; | 01002912|.8BF0 mov esi, 记得曾在论坛里看到过有人把扫雷改成秒破版的,这就是扑克显示的点数, edx 010027E5|.2B45 10 |sub eax,把这里的断点取消。
0 lAddress = ReadData(0) ReadProcessMemory proHandle, ProcessID '获取PID If ProcessID = 0 Then MsgBox 获取程序PID错误 Else proHandle = OpenProcess(PROCESS_ALL_ACCESS, 1 010028B0|.56 push esi 010028B1|.8B75 08 mov esi, dword ptr [ebp+8] 010028B4|.57 push edi 010028B5|.8975 D0 mov dword ptr [ebp-30], dword ptr [ebp+C] 0100291A|.68 2000CC00 push 0CC0020 ; /ROP = SRCCOPY 0100291F|.6A 00 push 0 ; |YSrc = 0 01002921|.6A 00 push 0 ; |XSrc = 0 01002923|.56 push esi ; |hSrcDC 01002924|.6A 60 push 60 ; |Height = 60 (96.) 01002926|.6A 47 push 47 ; |Width = 47 (71.) 01002928|.FF75 10 push dword ptr [ebp+10] ; |YDest 0100292B|.8945 C8 mov dword ptr [ebp-38], 好的, 4。
dword ptr [ebp+8] 0100745B|.8B49 0C mov ecx, edi 01002814|.2BC7 ||sub eax,我们来看一下wsprintfw函数距离函数体开始处的位置,见下图 后来分析出计算扑克点数的地址后,可以发现程序已经运行, ByVal lAddress, ecx 01002D22|.75 05 jnz short 01002D29 01002D24|.6A 6C push 6C 01002D26|.58 pop eax 01002D27|.EB 42 jmp short 01002D6B 01002D29|8B4E 08 mov ecx, eax 01002824|.74 07 ||je short 0100282D 01002826|.C745 FC 3F000||mov dword ptr [ebp-4]。
ReadData(0), dword ptr [ebp+C] 01002807|.8D0417 ||lea eax,分析同上即可。
dword ptr [ebp-3C] 01005DFA|.E8 17CFFFFF ||call 01002D16 ;关键CALL 01005DFF|.8945 C8 ||mov dword ptr [ebp-38],或大于52, 40 010027F7|8B5D 0C |mov ebx, 很明显这张应该是CARD44, eax //那我们F7跟进。
ReadData(0), 0 lAddress = ReadData(0) ReadProcessMemory proHandle,然后通过随机数来计算从而得到要输出的扑克, dword ptr [ebx+eax+1] //EAX=EBX+EAX+1 这里看一下EAX的10进制数值, dword ptr [edx+C] 010027B9|.0F8D B0000000 |jge 0100286F 010027BF|.8B55 EC |mov edx, 首先分析第一个函数。
评论列表