注:分析的过程借鉴了吾爱论坛的一篇文章 文章地址: https://www.52pojie.cn/thread-366291-1-1.html
首先打开软件,界面如下:
(软件加了upx的壳,先找个upx脱壳机脱壳,或者OD加载后,右击ESP寄存器下硬件断点,然后F9运行,断在jmp指令后再F8运行调到程序OEP处)
输入用户名点击注册按钮没有任何反应,因为有了第四题的经验,直接用Dark打开软件分析事件函数:
可以看到,这个软件注册的函数有:窗口创建完毕、按钮鼠标按下、面板单击、编辑框2双击、面板鼠标移动、图片鼠标按下(四个)、按钮单击、时钟事件(两个)。
打开OD,智能搜索字符串,找到关键字符串如下:
定位到关键字符串处代码如下:
004473E4 . 53 push ebx ; 时钟的函数
004473E5 . 8BD8 mov ebx,eax
004473E7 . 81BB 04030000>cmp dword ptr ds:[ebx+0x304],0xC34 ; 第一个判断
004473F1 . 0F84 88000000 je CKme002.0044747F
004473F7 . 81BB 08030000>cmp dword ptr ds:[ebx+0x308],0x230D
00447401 . 74 7C je short CKme002.0044747F
00447403 . 81BB 10030000>cmp dword ptr ds:[ebx+0x310],0xF94
0044740D . 75 70 jnz short CKme002.0044747F
0044740F . 8B83 18030000 mov eax,dword ptr ds:[ebx+0x318]
00447415 . 3B83 14030000 cmp eax,dword ptr ds:[ebx+0x314]
0044741B . 75 62 jnz short CKme002.0044747F
0044741D . 81BB 1C030000>cmp dword ptr ds:[ebx+0x31C],0x3E7
00447427 . 74 56 je short CKme002.0044747F
00447429 . 33D2 xor edx,edx
0044742B . 8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8]
00447431 . 8B08 mov ecx,dword ptr ds:[eax]
00447433 . FF51 5C call dword ptr ds:[ecx+0x5C]
00447436 . 33D2 xor edx,edx
00447438 . 8B83 DC020000 mov eax,dword ptr ds:[ebx+0x2DC]
0044743E . 8B08 mov ecx,dword ptr ds:[eax]
00447440 . FF51 5C call dword ptr ds:[ecx+0x5C]
00447443 . 33D2 xor edx,edx
00447445 . 8B83 E0020000 mov eax,dword ptr ds:[ebx+0x2E0]
0044744B . 8B08 mov ecx,dword ptr ds:[eax]
0044744D . FF51 5C call dword ptr ds:[ecx+0x5C]
00447450 . 33D2 xor edx,edx
00447452 . 8B83 E4020000 mov eax,dword ptr ds:[ebx+0x2E4]
00447458 . 8B08 mov ecx,dword ptr ds:[eax]
0044745A . FF51 5C call dword ptr ds:[ecx+0x5C]
0044745D . A1 A8984400 mov eax,dword ptr ds:[0x4498A8]
00447462 . 83C0 70 add eax,0x70
00447465 . BA 8C744400 mov edx,CKme002.0044748C ; 厉害厉害真厉害!佩服佩服真佩服!!
0044746A . E8 EDC4FBFF call CKme002.0040395C
0044746F . BA B8744400 mov edx,CKme002.004474B8 ; 注册了
00447474 . 8B83 EC020000 mov eax,dword ptr ds:[ebx+0x2EC]
0044747A . E8 3DCCFDFF call CKme002.004240BC
0044747F > 5B pop ebx ; CKme002.00442274
00447480 . C3 retn
很明显这里是注册成功的地方,通过地址和Dark软件的分析结果,这里是时钟2的事件处理函数,如下:
从上图可以看出,时钟2每隔8秒执行一次时钟事件,从汇编代码可以看出,时钟事件检测是否注册成功了,在时钟事件的内部,有几个关键的比较: [ebx+304] 与 0xC34 、[ebx+308] 与 0x230D 、[ebx+310] 与 0xF94 、[ebx+318] 与 [ebx+314] 、[ebx+31c] 与 3E7。
先看 [ebx+304]是什么时候赋值的,通过W32Dasm搜索,发现有两处对该地址进行了赋值操作,如下:
那么我们找到地址00446DB8处,我们把这个段的代码复制下来如下:
00446C1C /. 55 push ebp ; 窗口创建
00446C1D |. 8BEC mov ebp,esp
00446C1F |. 81C4 30FEFFFF add esp,-0x1D0
00446C25 |. 53 push ebx
00446C26 |. 33C9 xor ecx,ecx
00446C28 |. 894D FC mov [local.1],ecx
00446C2B |. 8BD8 mov ebx,eax
00446C2D |. 33C0 xor eax,eax
00446C2F |. 55 push ebp
00446C30 |. 68 D86D4400 push CKme002.00446DD8
00446C35 |. 64:FF30 push dword ptr fs:[eax]
00446C38 |. 64:8920 mov dword ptr fs:[eax],esp
00446C3B |. 33D2 xor edx,edx
00446C3D |. 8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8]
00446C43 |. E8 5CD3FDFF call CKme002.00423FA4
00446C48 |. 33D2 xor edx,edx
00446C4A |. 8B83 DC020000 mov eax,dword ptr ds:[ebx+0x2DC]
00446C50 |. E8 4FD3FDFF call CKme002.00423FA4
00446C55 |. 33D2 xor edx,edx
00446C57 |. 8B83 E0020000 mov eax,dword ptr ds:[ebx+0x2E0]
00446C5D |. E8 42D3FDFF call CKme002.00423FA4
00446C62 |. 33D2 xor edx,edx
00446C64 |. 8B83 E4020000 mov eax,dword ptr ds:[ebx+0x2E4]
00446C6A |. E8 35D3FDFF call CKme002.00423FA4
00446C6F |. 33D2 xor edx,edx
00446C71 |. 8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8]
00446C77 |. E8 28D3FDFF call CKme002.00423FA4
00446C7C |. 33D2 xor edx,edx
00446C7E |. 8B83 FC020000 mov eax,dword ptr ds:[ebx+0x2FC]
00446C84 |. E8 1BD3FDFF call CKme002.00423FA4
00446C89 |. 33D2 xor edx,edx
00446C8B |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0]
00446C91 |. 8B08 mov ecx,dword ptr ds:[eax] ; CKme002.00446954
00446C93 |. FF51 5C call dword ptr ds:[ecx+0x5C]
00446C96 |. 33D2 xor edx,edx
00446C98 |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0]
00446C9E |. E8 01D3FDFF call CKme002.00423FA4
00446CA3 |. BA 01000000 mov edx,0x1
00446CA8 |. 8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8]
00446CAE |. E8 19CCFDFF call CKme002.004238CC
00446CB3 |. BA C0FEFFFF mov edx,-0x140
00446CB8 |. 8B83 D8020000 mov eax,dword ptr ds:[ebx+0x2D8]
00446CBE |. E8 E9CBFDFF call CKme002.004238AC
00446CC3 |. BA 01000000 mov edx,0x1
00446CC8 |. 8B83 DC020000 mov eax,dword ptr ds:[ebx+0x2DC]
00446CCE |. E8 F9CBFDFF call CKme002.004238CC
00446CD3 |. BA 7E000000 mov edx,0x7E
00446CD8 |. 8B83 DC020000 mov eax,dword ptr ds:[ebx+0x2DC]
00446CDE |. E8 C9CBFDFF call CKme002.004238AC
00446CE3 |. BA 01000000 mov edx,0x1
00446CE8 |. 8B83 E0020000 mov eax,dword ptr ds:[ebx+0x2E0]
00446CEE |. E8 B9CBFDFF call CKme002.004238AC
00446CF3 |. BA 7A000000 mov edx,0x7A
00446CF8 |. 8B83 E0020000 mov eax,dword ptr ds:[ebx+0x2E0]
00446CFE |. E8 C9CBFDFF call CKme002.004238CC
00446D03 |. BA 01000000 mov edx,0x1
00446D08 |. 8B83 E4020000 mov eax,dword ptr ds:[ebx+0x2E4]
00446D0E |. E8 99CBFDFF call CKme002.004238AC
00446D13 |. BA C0FEFFFF mov edx,-0x140
00446D18 |. 8B83 E4020000 mov eax,dword ptr ds:[ebx+0x2E4]
00446D1E |. E8 A9CBFDFF call CKme002.004238CC
00446D23 |. C783 08030000>mov dword ptr ds:[ebx+0x308],0x28E
00446D2D |. C783 0C030000>mov dword ptr ds:[ebx+0x30C],0x9 ; 这个值必须要改变
00446D37 |. C783 14030000>mov dword ptr ds:[ebx+0x314],0xB
00446D41 |. 33C0 xor eax,eax
00446D43 |. 8983 18030000 mov dword ptr ds:[ebx+0x318],eax
00446D49 |. BA EC6D4400 mov edx,CKme002.00446DEC ; X:\ajj.126.c0m\j\o\j\o\ok.txt
00446D4E |. 8D85 30FEFFFF lea eax,[local.116]
00446D54 |. E8 EDE7FBFF call CKme002.00405546
00446D59 |. 8D85 30FEFFFF lea eax,[local.116]
00446D5F |. E8 07EAFBFF call CKme002.0040576B
00446D64 |. E8 8BBAFBFF call CKme002.004027F4
00446D69 |. 85C0 test eax,eax ; 应该是判断有没有文件,有返回0
00446D6B |. 75 4B jnz short CKme002.00446DB8 ; 不能跳
00446D6D |. 8D55 FC lea edx,[local.1]
00446D70 |. 8D85 30FEFFFF lea eax,[local.116]
00446D76 |. E8 5DD1FBFF call CKme002.00403ED8
00446D7B |. E8 44BAFBFF call CKme002.004027C4 ; 应该是读取文件内容,没有会出错
00446D80 |. 8B45 FC mov eax,[local.1] ; 读出来的文件内容
00446D83 |. BA 146E4400 mov edx,CKme002.00446E14
00446D88 |. E8 0BCFFBFF call CKme002.00403C98 ; 应该是比较内容
00446D8D |. 74 0A je short CKme002.00446D99 ; 为0跳转,相同为0
00446D8F |. C783 04030000>mov dword ptr ds:[ebx+0x304],0xC34
00446D99 |> 8D85 30FEFFFF lea eax,[local.116]
00446D9F |. E8 44E8FBFF call CKme002.004055E8
00446DA4 |. E8 1BBAFBFF call CKme002.004027C4
00446DA9 |. B2 01 mov dl,0x1
00446DAB |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0] ; 禁用编辑框2
00446DB1 |. E8 EED1FDFF call CKme002.00423FA4
00446DB6 |. EB 0A jmp short CKme002.00446DC2
00446DB8 |> C783 04030000>mov dword ptr ds:[ebx+0x304],0xC34
00446DC2 |> 33C0 xor eax,eax
00446DC4 |. 5A pop edx ; 01D1593C
00446DC5 |. 59 pop ecx ; 01D1593C
00446DC6 |. 59 pop ecx ; 01D1593C
00446DC7 |. 64:8910 mov dword ptr fs:[eax],edx
00446DCA |. 68 DF6D4400 push CKme002.00446DDF
00446DCF |> 8D45 FC lea eax,[local.1]
00446DD2 |. E8 31CBFBFF call CKme002.00403908
00446DD7 \. C3 retn
段首地址为00446C1C,通过与Dark软件分析的结果对比,发现这是窗口创建完毕事件的处理函数,整个程序对地址[ebx+304]赋值的地方就在这个函数里,而且两处都是把0xC34存在这个地址里,要保证注册成功,必须让这两个语句不被执行。
这个函数前面先对各个控件进行了初始化,然后对 [ebx+308]=28E、[ebx+30C]=9 、[ebx+314]=B ,然后并判断是否存在文件X:\ajj.126.c0m\j\o\j\o\ok.txt ,并且文件内容是否是指定的内容,如果有一项不符合,则跳转对[ebx+304]赋值为C34,因此我们跟进call查看其要比较的内容是什么:
00403C98 /$ 53 push ebx
00403C99 |. 56 push esi
00403C9A |. 57 push edi
00403C9B |. 89C6 mov esi,eax
00403C9D |. 89D7 mov edi,edx
00403C9F |. 39D0 cmp eax,edx
00403CA1 |. 0F84 8F000000 je CKme002.00403D36
00403CA7 |. 85F6 test esi,esi
00403CA9 |. 74 68 je short CKme002.00403D13
00403CAB |. 85FF test edi,edi
00403CAD |. 74 6B je short CKme002.00403D1A
00403CAF |. 8B46 FC mov eax,dword ptr ds:[esi-0x4] ; 文本中字符的长度
00403CB2 |. 8B57 FC mov edx,dword ptr ds:[edi-0x4]
00403CB5 |. 29D0 sub eax,edx
00403CB7 |. 77 02 ja short CKme002.00403CBB
00403CB9 |. 01C2 add edx,eax
00403CBB |> 52 push edx
00403CBC |. C1EA 02 shr edx,0x2
00403CBF |. 74 26 je short CKme002.00403CE7
00403CC1 |> 8B0E /mov ecx,dword ptr ds:[esi]
00403CC3 |. 8B1F |mov ebx,dword ptr ds:[edi]
00403CC5 |. 39D9 |cmp ecx,ebx
00403CC7 |. 75 58 |jnz short CKme002.00403D21
00403CC9 |. 4A |dec edx
00403CCA |. 74 15 |je short CKme002.00403CE1 ; 从这里跳才正确
00403CCC |. 8B4E 04 |mov ecx,dword ptr ds:[esi+0x4]
00403CCF |. 8B5F 04 |mov ebx,dword ptr ds:[edi+0x4]
00403CD2 |. 39D9 |cmp ecx,ebx
00403CD4 |. 75 4B |jnz short CKme002.00403D21
00403CD6 |. 83C6 08 |add esi,0x8
00403CD9 |. 83C7 08 |add edi,0x8
00403CDC |. 4A |dec edx
00403CDD |.^ 75 E2 \jnz short CKme002.00403CC1
00403CDF |. EB 06 jmp short CKme002.00403CE7
00403CE1 |> 83C6 04 add esi,0x4
00403CE4 |. 83C7 04 add edi,0x4
00403CE7 |> 5A pop edx ; 01D1593C
在字符串比较的CALL里面,先判断字符串是否为空,再判断字符串的长度是否一致,然后再逐个比较每个字符是否正确,对比的字符串在数据窗口中可以看到如下:
要注意的是,这个字符串前面有一个字节为20,后面有两个字节为 FF FF,这三个字符不能再记事本中直接输入,我是用十六进制编辑工具直接写入的这段十六进制。
再次运行的时候发现多了一个文本框,但是不能编辑,因此在Dark中显示的文本框2双击事件无法响应。到此已经解决了第一个跳转,我们再来看第二个跳转 [ebx+308]。
在窗口创建完毕的事情处理函数中,有 [ebx+308] = 28E,不过我们还有继续搜索一下看哪里还有对其进行赋值
另一个地方的地址是446FDC,代码如下:
00446FA4 /. 55 push ebp ; 按钮鼠标按下
00446FA5 |. 8BEC mov ebp,esp
00446FA7 |. 8B90 08030000 mov edx,dword ptr ds:[eax+0x308]
00446FAD |. 81FA 0D230000 cmp edx,0x230D
00446FB3 |. 74 20 je short CKme002.00446FD5
00446FB5 |. 80F9 01 cmp cl,0x1 ; 左键 为 0 右键 为 1
00446FB8 |. 75 09 jnz short CKme002.00446FC3
00446FBA |. 8380 08030000>add dword ptr ds:[eax+0x308],0x3
00446FC1 |. EB 12 jmp short CKme002.00446FD5
00446FC3 |> 81FA 94020000 cmp edx,0x294
00446FC9 |. 7D 0A jge short CKme002.00446FD5
00446FCB |. C780 08030000>mov dword ptr ds:[eax+0x308],0x230D ; 这一行不能运行
00446FD5 |> 5D pop ebp ; CKme002.00442274
00446FD6 \. C2 0C00 retn 0xC
这个代码是按钮鼠标按下的事件处理函数,可以看到,其功能是,当cl的值为1时,对其加3,否则将其赋值为230D,即按钮右击一次对其加3,左键单击一次赋值为230D。但我们必须保证其值不为230D,因此只要不左键单击就行。至此通过了两个跳转,再来看第三个 [ebx+310],搜索结果如下:
要注册成功,[ebx+310]的值必须是F94,此处一段的汇编代码如下:
004470EC /. 55 push ebp ; 给 ebx+ 310赋值处 窗口鼠标移动
004470ED |. 8BEC mov ebp,esp
004470EF |. 6A 00 push 0x0
004470F1 |. 6A 00 push 0x0
004470F3 |. 53 push ebx
004470F4 |. 8BD8 mov ebx,eax
004470F6 |. 8B55 08 mov edx,[arg.1]
004470F9 |. 8B45 0C mov eax,[arg.2]
004470FC |. 33C9 xor ecx,ecx
004470FE |. 55 push ebp
004470FF |. 68 17724400 push CKme002.00447217
00447104 |. 64:FF31 push dword ptr fs:[ecx]
00447107 |. 64:8921 mov dword ptr fs:[ecx],esp
0044710A |. 8B8B E0020000 mov ecx,dword ptr ds:[ebx+0x2E0] ; 2E0可能是位置,性本善时从左下角移动
00447110 |. 8079 47 01 cmp byte ptr ds:[ecx+0x47],0x1 ; 根据移动的方向判断 ,第三张图片 右下角
00447114 |. 75 19 jnz short CKme002.0044712F
00447116 |. 3D E2000000 cmp eax,0xE2
0044711B |. 7E 12 jle short CKme002.0044712F
0044711D |. 81FA 2C010000 cmp edx,0x12C
00447123 |. 7E 0A jle short CKme002.0044712F
00447125 |. C783 10030000>mov dword ptr ds:[ebx+0x310],0x10 ; 赋值处 1
0044712F |> 8B8B DC020000 mov ecx,dword ptr ds:[ebx+0x2DC]
00447135 |. 8079 47 01 cmp byte ptr ds:[ecx+0x47],0x1
00447139 |. 75 6C jnz short CKme002.004471A7
0044713B |. 83F8 17 cmp eax,0x17
0044713E |. 7D 67 jge short CKme002.004471A7
00447140 |. 81FA 2C010000 cmp edx,0x12C
00447146 |. 7E 5F jle short CKme002.004471A7
00447148 |. 83BB 10030000>cmp dword ptr ds:[ebx+0x310],0x10 ; 比较处 1
0044714F |. 75 56 jnz short CKme002.004471A7
00447151 |. 83BB 0C030000>cmp dword ptr ds:[ebx+0x30C],0x9
00447158 |. 74 4D je short CKme002.004471A7
0044715A |. C783 10030000>mov dword ptr ds:[ebx+0x310],0xF94 ; 赋值处 2 关键 ,这里必须要执行
00447164 |. 8B83 0C030000 mov eax,dword ptr ds:[ebx+0x30C]
0044716A |. 83E8 01 sub eax,0x1 ; Switch (cases 1..3)
0044716D |. 72 0A jb short CKme002.00447179
0044716F |. 74 14 je short CKme002.00447185
00447171 |. 48 dec eax
00447172 |. 74 1D je short CKme002.00447191
00447174 |. 48 dec eax
00447175 |. 74 26 je short CKme002.0044719D
00447177 |. EB 2E jmp short CKme002.004471A7
00447179 |> C783 14030000>mov dword ptr ds:[ebx+0x314],0x41
00447183 |. EB 22 jmp short CKme002.004471A7
00447185 |> C783 14030000>mov dword ptr ds:[ebx+0x314],0x3D ; Case 1 of switch 0044716A
0044718F |. EB 16 jmp short CKme002.004471A7
00447191 |> C783 14030000>mov dword ptr ds:[ebx+0x314],0x34 ; Case 2 of switch 0044716A
0044719B |. EB 0A jmp short CKme002.004471A7
0044719D |> C783 14030000>mov dword ptr ds:[ebx+0x314],0xDF ; Case 3 of switch 0044716A
004471A7 |> 81BB 10030000>cmp dword ptr ds:[ebx+0x310],0xF94 ; Default case of switch 0044716A
004471B1 |. 75 46 jnz short CKme002.004471F9
004471B3 |. 8D55 FC lea edx,[local.1]
004471B6 |. 8B83 E8020000 mov eax,dword ptr ds:[ebx+0x2E8]
004471BC |. E8 CBCEFDFF call CKme002.0042408C
004471C1 |. 8B45 FC mov eax,[local.1]
004471C4 |. BA 30724400 mov edx,CKme002.00447230 ; ajj
004471C9 |. E8 CACAFBFF call CKme002.00403C98
004471CE |. 75 29 jnz short CKme002.004471F9
004471D0 |. B2 01 mov dl,0x1
004471D2 |. 8B83 FC020000 mov eax,dword ptr ds:[ebx+0x2FC]
004471D8 |. E8 C7CDFDFF call CKme002.00423FA4
004471DD |. 8D55 F8 lea edx,[local.2]
004471E0 |. 8B83 0C030000 mov eax,dword ptr ds:[ebx+0x30C]
004471E6 |. E8 AD0AFCFF call CKme002.00407C98
004471EB |. 8B55 F8 mov edx,[local.2]
004471EE |. 8B83 FC020000 mov eax,dword ptr ds:[ebx+0x2FC]
004471F4 |. E8 C3CEFDFF call CKme002.004240BC
004471F9 |> 33C0 xor eax,eax
004471FB |. 5A pop edx ; CKme002.00442274
004471FC |. 59 pop ecx ; CKme002.00442274
004471FD |. 59 pop ecx ; CKme002.00442274
004471FE |. 64:8910 mov dword ptr fs:[eax],edx
00447201 |. 68 1E724400 push CKme002.0044721E
00447206 |> 8D45 F8 lea eax,[local.2]
00447209 |. E8 FAC6FBFF call CKme002.00403908
0044720E |. 8D45 FC lea eax,[local.1]
00447211 |. E8 F2C6FBFF call CKme002.00403908
00447216 \. C3 retn
这里的是窗口鼠标移动事件的处理函数,为了保证将其赋值为F94,必须保证前面的 [ebx+30C]不等于9而且前面[ebx+310]=10都执行,测试发现当出现第三章图片"性相近"时,且鼠标从右下角进入程序里面,窗口鼠标移动事件处理函数中[ebx+2E0+47]的值才是1,这样可以接下来执行 [ebx+310]=10,接着当出现第二张图片 "性本善"时,且鼠标从左下角进入到程序里面,[ebx+2DC+47]处的值才为1,这样可以接下来执行[ebx+310]=F94,由此我们可以知道了ebx+2DC是第二个图片控件的ID。
但是这里还有最后一步 [ebx+30C]一开始就被赋值成了9,哪里可以让其改变值?,继续搜索[ebx+30C],得到下:
这里也是另外唯一地方对其赋值处,整段代码复制如下:
00446FF8 /. 55 push ebp ; 编辑框2双击
00446FF9 |. 8BEC mov ebp,esp
00446FFB |. 33C9 xor ecx,ecx
00446FFD |. 51 push ecx
00446FFE |. 51 push ecx
00446FFF |. 51 push ecx
00447000 |. 51 push ecx
00447001 |. 51 push ecx
00447002 |. 53 push ebx
00447003 |. 8BD8 mov ebx,eax
00447005 |. 33C0 xor eax,eax
00447007 |. 55 push ebp
00447008 |. 68 DF704400 push CKme002.004470DF
0044700D |. 64:FF30 push dword ptr fs:[eax]
00447010 |. 64:8920 mov dword ptr fs:[eax],esp
00447013 |. 8D55 FC lea edx,[local.1]
00447016 |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0]
0044701C |. E8 6BD0FDFF call CKme002.0042408C
00447021 |. 8B45 FC mov eax,[local.1] ; 编辑框2的内容
00447024 |. E8 5FCBFBFF call CKme002.00403B88 ; 长度
00447029 |. 83F8 08 cmp eax,0x8
0044702C |. 0F85 92000000 jnz CKme002.004470C4
00447032 |. 8D55 F8 lea edx,[local.2]
00447035 |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0]
0044703B |. E8 4CD0FDFF call CKme002.0042408C
00447040 |. 8B45 F8 mov eax,[local.2]
00447043 |. 8078 01 5F cmp byte ptr ds:[eax+0x1],0x5F ; 第二个字符为 _
00447047 |. 75 7B jnz short CKme002.004470C4
00447049 |. 8D55 F4 lea edx,[local.3]
0044704C |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0]
00447052 |. E8 35D0FDFF call CKme002.0042408C
00447057 |. 8B45 F4 mov eax,[local.3]
0044705A |. 8078 05 2C cmp byte ptr ds:[eax+0x5],0x2C ; 第六个字符为 ,
0044705E |. 75 64 jnz short CKme002.004470C4
00447060 |. 8D55 F0 lea edx,[local.4]
00447063 |. 8B83 E8020000 mov eax,dword ptr ds:[ebx+0x2E8]
00447069 |. E8 1ED0FDFF call CKme002.0042408C
0044706E |. 8B45 F0 mov eax,[local.4] ; CKme002.00406578
00447071 |. E8 12CBFBFF call CKme002.00403B88
00447076 |. 83C0 03 add eax,0x3
00447079 |. B9 03000000 mov ecx,0x3
0044707E |. 99 cdq
0044707F |. F7F9 idiv ecx
00447081 |. 85D2 test edx,edx
00447083 |. 75 3F jnz short CKme002.004470C4
00447085 |. 6A 00 push 0x0
00447087 |. 6A 04 push 0x4
00447089 |. 8D55 EC lea edx,[local.5]
0044708C |. 8B83 E8020000 mov eax,dword ptr ds:[ebx+0x2E8]
00447092 |. E8 F5CFFDFF call CKme002.0042408C
00447097 |. 8B45 EC mov eax,[local.5] ; 用户名
0044709A |. E8 E9CAFBFF call CKme002.00403B88 ; 长度
0044709F |. 99 cdq
004470A0 |. 52 push edx
004470A1 |. 50 push eax
004470A2 |. 33C0 xor eax,eax
004470A4 |. E8 E70EFCFF call CKme002.00407F90
004470A9 |. 030424 add eax,dword ptr ss:[esp]
004470AC |. 135424 04 adc edx,dword ptr ss:[esp+0x4]
004470B0 |. 83C4 08 add esp,0x8
004470B3 |. 83C0 02 add eax,0x2
004470B6 |. 83D2 00 adc edx,0x0
004470B9 |. E8 47ECFBFF call CKme002.00405D05 ; 这里返回了0
004470BE |. 8983 0C030000 mov dword ptr ds:[ebx+0x30C],eax
004470C4 |> 33C0 xor eax,eax
004470C6 |. 5A pop edx ; 00251738
004470C7 |. 59 pop ecx ; 00251738
004470C8 |. 59 pop ecx ; 00251738
004470C9 |. 64:8910 mov dword ptr fs:[eax],edx
004470CC |. 68 E6704400 push CKme002.004470E6
004470D1 |> 8D45 EC lea eax,[local.5]
004470D4 |. BA 05000000 mov edx,0x5
004470D9 |. E8 4EC8FBFF call CKme002.0040392C
004470DE \. C3 retn
这段代码是文本框2的双击事件的处理函数,但是目前我们的文本框2虽然显示了,但是还处于不能编辑状态,因此我们必须先将其激活,从已知的事件函数我们可以想到,可能在窗口创建完毕函数中,对文本框控件进行了处理,然后要以某种方式将其激活。此外还剩下面板双击函数和四个图片的鼠标按下函数。我们回头再看窗口创建完毕函数:在开始时,传入了各种控件的ID并对其进行了初始化,在末尾,又对某个控件进行了处理:
00446DA9 |. B2 01 mov dl,0x1
00446DAB |. 8B83 F0020000 mov eax,dword ptr ds:[ebx+0x2F0] ; 禁用编辑框2
00446DB1 |. E8 EED1FDFF call CKme002.00423FA4
那么这个控件ID:ebx+2F0,应该就是对文本框2的ID了,但是通过搜索发现其他地方引用ebx+ 2F0都是取值操作,不是设置它的属性,但是在其他事件中查找发现在面板双击事件中,引用了eax+2F0,传参使用了不同的寄存器,但是结果一样,面板双击的代码如下:
00446FD9 8D40 00 lea eax,dword ptr ds:[eax]
00446FDC . 81B8 08030000>cmp dword ptr ds:[eax+0x308],0x29D ; 面板双击
00446FE6 . 75 0D jnz short CKme002.00446FF5
00446FE8 . B2 01 mov dl,0x1
00446FEA . 8B80 F0020000 mov eax,dword ptr ds:[eax+0x2F0]
00446FF0 . 8B08 mov ecx,dword ptr ds:[eax]
00446FF2 . FF51 5C call dword ptr ds:[ecx+0x5C]
00446FF5 > C3 retn
它判断了 [eax+308]的值是否为0x29D,如果不是就直接返回了,这里的eax的值也就是前面的ebx的值,通过前面的分析我们知道,初始时,[ebx+308]=28E,而且按钮每右击一次就增加3,因此按钮右击5次就可以从28E+5*3=29D,那么现在我们可以知道,按钮右击五次,再双击面板就可以激活文本框2了。
那么我们继续看文本框2双击的代码,要想[ebx+30c]的值不为9,必须在这里面对其赋值,代码里首先判断了文本框2输入文本的长度,并且要求第二个字符为_,第六个字符为,,并在最后调用了一个call,并将结果给了[ebx+30c],到这里,地址[ebx+310]的值就可以赋值成0xF94了。
在这里我们先把前面的总结下:
1、先打开了文件 “ X:\ajj.126.c0m\j\o\j\o\ok.txt ”,并求文本内容为 ajj写的CKme真烂!(注意十六进制第一字节为20,最后两字节为FF FF 没有显示),此时显示文本框2但是不可编辑。
2、右键单击按钮五下,双击面板一下,文本框2出于可编辑状态。
3、当出现 “性相近” 图片时,鼠标从右下角进入程序,当出现“性本善”图片时,鼠标从左下角进入程序。
继续前面的分析,将[ebx+310]赋值成 F94后,下面紧接着有个switch语句如下:
00447164 |. 8B83 0C030000 mov eax,dword ptr ds:[ebx+0x30C]
0044716A |. 83E8 01 sub eax,0x1 ; Switch (cases 1..3)
0044716D |. 72 0A jb short CKme002.00447179
0044716F |. 74 14 je short CKme002.00447185
00447171 |. 48 dec eax
00447172 |. 74 1D je short CKme002.00447191
00447174 |. 48 dec eax
00447175 |. 74 26 je short CKme002.0044719D
00447177 |. EB 2E jmp short CKme002.004471A7
00447179 |> C783 14030000>mov dword ptr ds:[ebx+0x314],0x41
00447183 |. EB 22 jmp short CKme002.004471A7
00447185 |> C783 14030000>mov dword ptr ds:[ebx+0x314],0x3D ; Case 1 of switch 0044716A
0044718F |. EB 16 jmp short CKme002.004471A7
00447191 |> C783 14030000>mov dword ptr ds:[ebx+0x314],0x34 ; Case 2 of switch 0044716A
0044719B |. EB 0A jmp short CKme002.004471A7
0044719D |> C783 14030000>mov dword ptr ds:[ebx+0x314],0xDF ; Case 3 of switch 0044716A
004471A7 |> 81BB 10030000>cmp dword ptr ds:[ebx+0x310],0xF94 ; Default case of switch 0044716A
这里根据 [ebx+30c]的值,对[ebx+314]进行赋值,根据我在文章开始出给出参考文章里的分析,[ebx+30c]的值应该是和电脑硬盘剩余容量、输入的字符串等有关,但是我测试的返回结果是0,根据汇编代码可以看出,这里可能的返回值有0、1、2、3,具体那个call里的代码暂时没看。这里 [ebx+314]=0x41。
那么在时钟事件函数中还剩下 [ebx+314] 与 [ebx+318]的比较,要求这两个值要相等,已经知道了[ebx+314]的值为0x41 (或者说其它一个可能值)。
通过搜索知道了[ebx+318]赋值操作在四个图片的鼠标按下事件中,在第一张图片中如果鼠标左键按下,对其加2,如果鼠标右键按下对其加0x11,代码如下:
00447234 /. 55 push ebp ; 图片1鼠标放下
00447235 |. 8BEC mov ebp,esp
00447237 |. 53 push ebx
00447238 |. 56 push esi
00447239 |. 8BD9 mov ebx,ecx
0044723B |. 8BF0 mov esi,eax
0044723D |. 6A 00 push 0x0
0044723F |. 66:8B0D 70724>mov cx,word ptr ds:[0x447270]
00447246 |. B2 02 mov dl,0x2
00447248 |. B8 7C724400 mov eax,CKme002.0044727C ; 注册尚未成功,同志仍需努力! 8)
0044724D |. E8 42E4FFFF call CKme002.00445694
00447252 |. 84DB test bl,bl
00447254 |. 75 07 jnz short CKme002.0044725D
00447256 |. 8386 18030000>add dword ptr ds:[esi+0x318],0x2
0044725D |> 80FB 01 cmp bl,0x1
00447260 |. 75 07 jnz short CKme002.00447269
00447262 |. 8386 18030000>add dword ptr ds:[esi+0x318],0x11
00447269 |> 5E pop esi ; 00484000
0044726A |. 5B pop ebx ; 00484000
0044726B |. 5D pop ebp ; 00484000
0044726C \. C2 0C00 retn 0xC
其它三个图片与之类似,第二个图片中鼠标左键按下,对其加3,鼠标右键按下对其加0x13,第三个图片中鼠标左键按下对其加5,鼠标右键按下对其加0x17,第四个图片中鼠标左键按下对其加7,鼠标右键按下对其加0x18,因此要想结果为0x41,一种方案是:对第一个图片右键单击一次,对第四个图片右键单击两次。
最后一个跳转判断[ebx+31c]的值在处理过程中一直为0,因此不会跳转,那么到这里注册的过程就结束了
继续总结如下:
4、当出现 “人之初”图片时,对其右击一次,当出现“习相远”图片时,对其右击两次,那么再等下一个时钟处理函数执行完时,程序就注册成功。