-
-
看雪CTF2016-10-liuwan.rar破解分析
-
发表于: 2016-11-22 01:50 3077
-
程序有反调试,先打掉反调试. 做补丁,在补丁的基础上,一直打到可以正常调试.
听老手说,不加反调试,攻击者没兴趣~, 好像很有道理啊:)
等反调试都打掉,这cm就等着挨宰吧 :P
看到的反调试:
* 不让cm窗口挪动
* 检测到调试器,连OD一块退了
* 自己修改代码区.
* 长Sleep
sub_40A45B Sleep
注释掉Sleep
.text:00401FC4 call ds:EnableWindow
注释掉
01171FAF . /75 02 jnz short CrackMe3.01171FB3
这里没打干净,需要手工将函数返回前的汇编指令都改成NOP
函数返回前的代码
00CA1FCA 5F pop edi
00CA1FCB 5E pop esi
00CA1FCC 5B pop ebx
00CA1FCD 8BE5 mov esp,ebp
00CA1FCF 5D pop ebp
00CA1FD0 . C3 retn
开始比用户输入开始有没有TrustMe
00CC6138 > > /8A06 mov al,byte ptr ds:[esi] ; loc_406138
00CC613A . |83C6 01 add esi,0x1
00CC613D > > |3AC2 cmp al,dl ; T 和 2 比
00CC613F . |74 0A je short <CrackMe4.loc_40614B>
00CC6141 . |84C0 test al,al
00CC6143 .^\75 F3 jnz short <CrackMe4.loc_406138>
注册码改成15个字符(前面的字符是TrustMe) TrustMe12345678
TrustMe12345678
就是要逆这里的算法
00C41E90 > $ 55 push ebp ; fnCalcRegSn_401E90
.text:0040219D push 9
.text:0040219F call sub_40529F ; 这里打印成功的信息
.text:004021A4 mov dword ptr [eax], 63637573h
.text:004021AA mov dword ptr [eax+4], 21737365h
.text:004021B1 mov byte ptr [eax+8], 0
.text:004021B5 mov edx, eax
.text:004021B7 call sub_403490
.text:004021BC push eax
.text:004021BD call sub_403980
.text:004021C2 push offset aPause ; "pause"
.text:004021C7 call fnPause_4061B0
算注册码
013C61A6 |. E8 766C0000 call <CrackMe4.sub_40CE21>
参数
0026F758 0043DFCF ASCII "12345678"
0026F75C 00000000
0026F760 0000000A
最后的注册算法
fnCalcRegSn_40CBFB(int KeyBuf, int pcRegSn, int a3_is_0, signed int a4_is_0xa, int a5_is_0)
002DFD74 01207080 offset <CrackMe4.off_427080>
002DFD78 003BDFCF ASCII "12345678"
002DFD7C 00000000
002DFD80 0000000A
002DFD84 00000000
给出了KeyBuf
01207080 >C8 6F 20 01 E8 6A 20 01 00 00 00 00 00 00 00 00 萶 鑚 ........
01207090 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF ........
012070A0 00 00 00 00 00 00 00 00 80 70 00 00 01 00 00 00 ........€p.....
012070B0 F0 F1 FF FF 00 00 00 00 50 53 54 00 00 00 00 00 瘃....PST.....
ebx 算出来必须是0x133A1FA才行
011E2051 3D FAA13301 cmp eax,0x133A1FA ; 注册码比对
最后显示的信息不是加密的,只要上面算出来是0x133A1FA就对了
password:TrustMe12345678
success!
确定了计算注册码的函数后,直接抠代码出来。
将注册函数用C语言翻译一遍, 写个8循环,跑一遍就出来了,30秒之内能全跑完,确实只有一个注册码,TrustMe20161018, 估计是作者做完cm的日期.
这个20161018虽然不是明文,在单步过程中,确实看到过.遗憾,没有先拿TrustMe+20161018先去试试,能不能将保险柜打开...
将注册函数抠出来后,因为不能原样的翻译(注册函数还会再调用其他函数),先按照后面是8个数字的流程走通。如果不行的话,再跟字母的流程。 还好作者怜悯攻击者.
下面是注册机实现, 写的匆忙,见谅
感谢liuwan制作的crackme.
听老手说,不加反调试,攻击者没兴趣~, 好像很有道理啊:)
等反调试都打掉,这cm就等着挨宰吧 :P
看到的反调试:
* 不让cm窗口挪动
* 检测到调试器,连OD一块退了
* 自己修改代码区.
* 长Sleep
sub_40A45B Sleep
注释掉Sleep
.text:00401FC4 call ds:EnableWindow
注释掉
01171FAF . /75 02 jnz short CrackMe3.01171FB3
这里没打干净,需要手工将函数返回前的汇编指令都改成NOP
函数返回前的代码
00CA1FCA 5F pop edi
00CA1FCB 5E pop esi
00CA1FCC 5B pop ebx
00CA1FCD 8BE5 mov esp,ebp
00CA1FCF 5D pop ebp
00CA1FD0 . C3 retn
开始比用户输入开始有没有TrustMe
00CC6138 > > /8A06 mov al,byte ptr ds:[esi] ; loc_406138
00CC613A . |83C6 01 add esi,0x1
00CC613D > > |3AC2 cmp al,dl ; T 和 2 比
00CC613F . |74 0A je short <CrackMe4.loc_40614B>
00CC6141 . |84C0 test al,al
00CC6143 .^\75 F3 jnz short <CrackMe4.loc_406138>
注册码改成15个字符(前面的字符是TrustMe) TrustMe12345678
TrustMe12345678
就是要逆这里的算法
00C41E90 > $ 55 push ebp ; fnCalcRegSn_401E90
.text:0040219D push 9
.text:0040219F call sub_40529F ; 这里打印成功的信息
.text:004021A4 mov dword ptr [eax], 63637573h
.text:004021AA mov dword ptr [eax+4], 21737365h
.text:004021B1 mov byte ptr [eax+8], 0
.text:004021B5 mov edx, eax
.text:004021B7 call sub_403490
.text:004021BC push eax
.text:004021BD call sub_403980
.text:004021C2 push offset aPause ; "pause"
.text:004021C7 call fnPause_4061B0
算注册码
013C61A6 |. E8 766C0000 call <CrackMe4.sub_40CE21>
参数
0026F758 0043DFCF ASCII "12345678"
0026F75C 00000000
0026F760 0000000A
最后的注册算法
fnCalcRegSn_40CBFB(int KeyBuf, int pcRegSn, int a3_is_0, signed int a4_is_0xa, int a5_is_0)
002DFD74 01207080 offset <CrackMe4.off_427080>
002DFD78 003BDFCF ASCII "12345678"
002DFD7C 00000000
002DFD80 0000000A
002DFD84 00000000
给出了KeyBuf
01207080 >C8 6F 20 01 E8 6A 20 01 00 00 00 00 00 00 00 00 萶 鑚 ........
01207090 FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FF ........
012070A0 00 00 00 00 00 00 00 00 80 70 00 00 01 00 00 00 ........€p.....
012070B0 F0 F1 FF FF 00 00 00 00 50 53 54 00 00 00 00 00 瘃....PST.....
ebx 算出来必须是0x133A1FA才行
011E2051 3D FAA13301 cmp eax,0x133A1FA ; 注册码比对
最后显示的信息不是加密的,只要上面算出来是0x133A1FA就对了
password:TrustMe12345678
success!
确定了计算注册码的函数后,直接抠代码出来。
将注册函数用C语言翻译一遍, 写个8循环,跑一遍就出来了,30秒之内能全跑完,确实只有一个注册码,TrustMe20161018, 估计是作者做完cm的日期.
这个20161018虽然不是明文,在单步过程中,确实看到过.遗憾,没有先拿TrustMe+20161018先去试试,能不能将保险柜打开...
将注册函数抠出来后,因为不能原样的翻译(注册函数还会再调用其他函数),先按照后面是8个数字的流程走通。如果不行的话,再跟字母的流程。 还好作者怜悯攻击者.
下面是注册机实现, 写的匆忙,见谅
// hw.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <crtdbg.h> const char szCharSet[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'/*, 'a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'*/ }; // 用户输入的字符*2作为索引在数组中取内容 // 011ECC7B |. 0FB70448 |movzx eax,word ptr ds:[eax+ecx*2] ; 表地址011FE4B8 + Ascii字符作为索引*2 BYTE ucAryKeyBufForRegSn[1800] = { 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x48, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x10, 0x00, 0x10, // '1'取的是0x62位置的WORD 0x0084 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x48, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x81, 0x01, 0x81, 0x01, 0x81, 0x01, 0x81, 0x01, 0x81, 0x01, 0x81, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x82, 0x01, 0x82, 0x01, 0x82, 0x01, 0x82, 0x01, 0x82, 0x01, 0x82, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x10, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; DWORD dword_428C48 = 0; DWORD dword_428C50 = 0; DWORD dword_428C58 = 0; char g_szRegSn[0x100] = {'\0'}; DWORD fnCalcRegSn_40CBFB(const char* pcRegSn); const char g_szCharSet[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; int main(int argc, char* argv[]) { unsigned __int64 ullRetryCnt = 0; DWORD nLenAryCharSet = sizeof(g_szCharSet); DWORD dwLoop1 = 0; DWORD dwLoop2 = 0; DWORD dwLoop3 = 0; DWORD dwLoop4 = 0; DWORD dwLoop5 = 0; DWORD dwLoop6 = 0; DWORD dwLoop7 = 0; DWORD dwLoop8 = 0; DWORD dwRegSnHash = 0; char szRegSnToCalc[0x10] = {'\0'}; // char c1 = '1'; // WORD* pBuf = (WORD*)(ucAryKeyBufForRegSn + c1 * 2); // WORD w1 = *pBuf; // printf("%x\r\n", w1); // TrustMe12345678 for (dwLoop1 = 0; dwLoop1 < nLenAryCharSet; dwLoop1++) { for (dwLoop2 = 0; dwLoop2 < nLenAryCharSet; dwLoop2++) { for (dwLoop3 = 0; dwLoop3 < nLenAryCharSet; dwLoop3++) { for (dwLoop4 = 0; dwLoop4 < nLenAryCharSet; dwLoop4++) { for (dwLoop5 = 0; dwLoop5 < nLenAryCharSet; dwLoop5++) { for (dwLoop6 = 0; dwLoop6 < nLenAryCharSet; dwLoop6++) { for (dwLoop7 = 0; dwLoop7 < nLenAryCharSet; dwLoop7++) { for (dwLoop8 = 0; dwLoop8 < nLenAryCharSet; dwLoop8++) { szRegSnToCalc[0] = g_szCharSet[dwLoop1]; szRegSnToCalc[1] = g_szCharSet[dwLoop2]; szRegSnToCalc[2] = g_szCharSet[dwLoop3]; szRegSnToCalc[3] = g_szCharSet[dwLoop4]; szRegSnToCalc[4] = g_szCharSet[dwLoop5]; szRegSnToCalc[5] = g_szCharSet[dwLoop6]; szRegSnToCalc[6] = g_szCharSet[dwLoop7]; szRegSnToCalc[7] = g_szCharSet[dwLoop8]; szRegSnToCalc[8] = '\0'; dwRegSnHash = fnCalcRegSn_40CBFB(szRegSnToCalc); if (dwRegSnHash == 0x133A1FA) { printf("regSn = %s\r\n", szRegSnToCalc); // 20161018, 至此一个注册码 // 那么完整的注册码为 TrustMe20161018 // 我在工程中见过这个立即数(20161018), 居然没去试一下, 那些搞得飞快的兄弟,可能是用TrustMe+20161018直接去试验的 ::MessageBox(NULL, "找到注册码", "成功", MB_OK); } else { ullRetryCnt++; if (ullRetryCnt > 10000) { ullRetryCnt = 0; printf("retry regSn... = %s\r\n", szRegSnToCalc); } } } } } } } } } } system("pause"); return 0; } DWORD fnCalcRegSn_40CBFB(const char* pcRegSn) { // 算法已经跟出来了 DWORD dwTmp = 0; DWORD dw_eax = 0; DWORD dw_ebx = 0; DWORD dw_ecx = 0; DWORD dw_edx = 0; DWORD dw_esi = 0; DWORD dw_edi = 0; DWORD dwVar24 = 0; DWORD dwVar1C = 0; DWORD dwVar18 = 0; DWORD dwVar14 = 0; DWORD dwVar10 = 0; DWORD dwVarC = 0; DWORD dwVar8 = 0; BYTE bVar1 = 0; DWORD dwParam10 = 0x0; DWORD dwParam14 = 0xA; DWORD dwParam18 = 0; // 011ECBFB >/$ 55 push ebp ; fnCalcRegSn_40CBFB // 011ECBFC |. 8BEC mov ebp,esp ; 最终算注册码的地方 // 011ECBFE |. 83EC 24 sub esp,0x24 // 011ECC01 |. 8D4D DC lea ecx,dword ptr ss:[ebp-0x24] // 011ECC04 |. FF75 08 push dword ptr ss:[ebp+0x8] // 011ECC07 |. E8 C6C9FFFF call <CrackMe4.fnSetKeyToClass_4095D2> // 011ECC0C |. 8B45 10 mov eax,dword ptr ss:[ebp+0x10] dw_eax = (DWORD)pcRegSn; // 011ECC0F |. 85C0 test eax,eax // 011ECC11 |. 74 05 je short <CrackMe4.loc_40CC18> ; 跳转已实现 // 011ECC13 |. 8B4D 0C mov ecx,dword ptr ss:[ebp+0xC] // 011ECC16 |. 8908 mov dword ptr ds:[eax],ecx // 011ECC18 >|> 8B45 0C mov eax,dword ptr ss:[ebp+0xC] ; loc_40CC18 // 011ECC1B |. 53 push ebx // 011ECC1C |. 56 push esi // 011ECC1D |. 57 push edi // 011ECC1E |. 85C0 test eax,eax // 011ECC20 |. 74 11 je short <CrackMe4.loc_40CC33> // 011ECC22 |. 8B7D 14 mov edi,dword ptr ss:[ebp+0x14] ; A dw_edi = 0xA; // 011ECC25 |. 85FF test edi,edi // 011ECC27 |. 74 1F je short <CrackMe4.loc_40CC48> // 011ECC29 |. 83FF 02 cmp edi,0x2 // 011ECC2C |. 7C 05 jl short <CrackMe4.loc_40CC33> // 011ECC2E |. 83FF 24 cmp edi,0x24 // 011ECC31 |. 7E 15 jle short <CrackMe4.loc_40CC48> ; 跳转实现 // 011ECC33 >|> E8 90D8FFFF call <CrackMe4.fnTls_40A4C8> ; loc_40CC33 // 011ECC38 |. C700 16000000 mov dword ptr ds:[eax],0x16 // 011ECC3E |. E8 65030000 call <CrackMe4.sub_40CFA8> // 011ECC43 |. E9 C1010000 jmp <CrackMe4.loc_40CE09> // 011ECC48 >|> 8B7D DC mov edi,dword ptr ss:[ebp-0x24] ; loc_40CC48 01206FC8 // 011ECC4B |. 8D70 01 lea esi,dword ptr ds:[eax+0x1] ; 数字RegSn第2个字符地址 dw_esi = (DWORD)(pcRegSn + 1); // 011ECC4E |. 33DB xor ebx,ebx // 011ECC50 |. 895D F4 mov dword ptr ss:[ebp-0xC],ebx ; 0 dwVarC = 0; // 011ECC53 |. 8A18 mov bl,byte ptr ds:[eax] ; 数字RegSn第一个字符'1' dw_ebx = (DWORD)(*(char*)dw_eax); do { // 011ECC55 >|> 837F 74 01 /cmp dword ptr ds:[edi+0x74],0x1 ; loc_40CC55 1 // 011ECC59 |. 7E 17 |jle short <CrackMe4.loc_40CC72> ; 跳转实现 // 011ECC5B |. 8D45 DC |lea eax,dword ptr ss:[ebp-0x24] // 011ECC5E |. 50 |push eax // 011ECC5F |. 0FB6C3 |movzx eax,bl // 011ECC62 |. 6A 08 |push 0x8 // 011ECC64 |. 50 |push eax // 011ECC65 |. E8 2E750000 |call <CrackMe4.sub_414198> // 011ECC6A |. 8B7D DC |mov edi,dword ptr ss:[ebp-0x24] // 011ECC6D |. 83C4 0C |add esp,0xC // 011ECC70 |. EB 10 |jmp short <CrackMe4.loc_40CC82> // 011ECC72 >|> 8B87 90000000 |mov eax,dword ptr ds:[edi+0x90] ; loc_40CC72 eax = 011FE4B8 dw_eax = (DWORD)&ucAryKeyBufForRegSn[0]; // 011ECC78 |. 0FB6CB |movzx ecx,bl ; 第一个字符 '1' dw_ecx = dw_ebx; // 011ECC7B |. 0FB70448 |movzx eax,word ptr ds:[eax+ecx*2] ; 表地址011FE4B8 + Ascii字符作为索引*2 dw_eax = (DWORD)(*(WORD*)(dw_eax + dw_ecx * 2)); // 011ECC7F |. 83E0 08 |and eax,0x8 ; 与8后, x084为0 dw_eax &= 8; // 011ECC82 >|> 85C0 |test eax,eax ; loc_40CC82 // 011ECC84 |. 74 05 |je short <CrackMe4.loc_40CC8B> ; 跳转已经实现 // 011ECC86 |. 8A1E |mov bl,byte ptr ds:[esi] // 011ECC88 |. 46 |inc esi // 011ECC89 |.^ EB CA \jmp short <CrackMe4.loc_40CC55> if (0 == dw_eax) { break; } dw_ebx = (DWORD)(*(BYTE*)dw_esi); } while (1); // 011ECC8B >|> 8B45 18 mov eax,dword ptr ss:[ebp+0x18] ; eax = 0 // 011ECC8E |. 885D FF mov byte ptr ss:[ebp-0x1],bl ; bl是第一个字符 dw_eax = dwParam18; bVar1 = (BYTE)dw_ebx; // 011ECC91 |. 80FB 2D cmp bl,0x2D if (bVar1 == 0x2D) { // 011ECC94 |. 75 0B jnz short <CrackMe4.loc_40CCA1> ; 跳转已经实现 // 011ECC96 |. 83C8 02 or eax,0x2 // 011ECC99 >|> 8A0E mov cl,byte ptr ds:[esi] ; loc_40CC99 // 011ECC9B |. 46 inc esi // 011ECC9C |. 884D FF mov byte ptr ss:[ebp-0x1],cl // 011ECC9F |. EB 08 jmp short <CrackMe4.loc_40CCA9> } else if (bVar1 == 0x2B) { // 011ECCA1 >|> 80FB 2B cmp bl,0x2B ; loc_40CCA1 // 011ECCA4 |.^ 74 F3 je short <CrackMe4.loc_40CC99> ; 跳转未实现 // 011ECC99 >|> 8A0E mov cl,byte ptr ds:[esi] ; loc_40CC99 // 011ECC9B |. 46 inc esi // 011ECC9C |. 884D FF mov byte ptr ss:[ebp-0x1],cl // 011ECC9F |. EB 08 jmp short <CrackMe4.loc_40CCA9> } else { // 011ECCA6 |. 8A4D FF mov cl,byte ptr ss:[ebp-0x1] ; 第一个字符 dw_ecx = (DWORD)bVar1; } // 011ECCA9 >|> 8B7D 14 mov edi,dword ptr ss:[ebp+0x14] ; A dw_edi = dwParam14; // 011ECCAC |. 8B5D F4 mov ebx,dword ptr ss:[ebp-0xC] ; 0 dw_ebx = dwVarC; // 011ECCAF |. 8945 F8 mov dword ptr ss:[ebp-0x8],eax ; 0 dwVar8 = dw_eax; do { if ((int)dw_edi < 0) { } else if ((int)dw_edi == 1) { } else if ((int)dw_edi > 0x24) { } else { // 011ECCB2 |. 85FF test edi,edi ; A // 011ECCB4 |. 0F88 43010000 js <CrackMe4.loc_40CDFD> ; not jump // 011ECCBA |. 83FF 01 cmp edi,0x1 // 011ECCBD |. 0F84 3A010000 je <CrackMe4.loc_40CDFD> ; not jump // 011ECCC3 |. 83FF 24 cmp edi,0x24 // 011ECCC6 |. 0F8F 31010000 jg <CrackMe4.loc_40CDFD> ; not jump // 011ECCCC |. 85FF test edi,edi if (dw_edi == 0) { // 011ECCCE |. 75 1D jnz short <CrackMe4.loc_40CCED> ; jump // 011ECCD0 |. 80F9 30 cmp cl,0x30 if (dw_ecx != 0x30) { // 011ECCD3 |. 74 05 je short <CrackMe4.loc_40CCDA> // 011ECCD5 |. 6A 0A push 0xA // 011ECCD7 >|> 5F pop edi ; loc_40CCD7 // 011ECCD8 |. EB 30 jmp short <CrackMe4.loc_40CD0A> dw_edi = 0xA; } else { // 011ECCDA >|> 8A06 mov al,byte ptr ds:[esi] ; loc_40CCDA dw_eax = (int)(*(char*)dw_esi); if ((dw_eax != 0x78) && (dw_eax != 0x58)) { // 011ECCDC |. 3C 78 cmp al,0x78 // 011ECCDE |. 74 08 je short <CrackMe4.loc_40CCE8> // 011ECCE0 |. 3C 58 cmp al,0x58 // 011ECCE2 |. 74 04 je short <CrackMe4.loc_40CCE8> // 011ECCE4 |. 6A 08 push 0x8 // 011ECCE6 |.^ EB EF jmp short <CrackMe4.loc_40CCD7> dw_edi = 0x8; } // 011ECCE8 >|> 6A 10 push 0x10 ; loc_40CCE8 // 011ECCEA |. 5F pop edi dw_edi = 0x10; // 011ECCEB |. EB 0A jmp short <CrackMe4.loc_40CCF7> // 011ECCF7 >|> 8A06 mov al,byte ptr ds:[esi] ; loc_40CCF7 dw_eax = (int)(*(BYTE*)dw_esi); if ((dw_eax == 0x78) || (dw_eax == 0x58)) { // 011ECCF9 |. 3C 78 cmp al,0x78 // 011ECCFB |. 74 04 je short <CrackMe4.loc_40CD01> // 011ECCFD |. 3C 58 cmp al,0x58 // 011ECCFF |. 75 09 jnz short <CrackMe4.loc_40CD0A> // 011ECD01 >|> 8A4E 01 mov cl,byte ptr ds:[esi+0x1] ; loc_40CD01 // 011ECD04 |. 83C6 02 add esi,0x2 // 011ECD07 |. 884D FF mov byte ptr ss:[ebp-0x1],cl dw_ecx = (DWORD)(*(BYTE*)(dw_esi + 1)); dw_esi += 2; bVar1 = (BYTE)dw_ecx; } } } else { // 011ECCED >|> 83FF 10 cmp edi,0x10 ; loc_40CCED // 011ECCF0 |. 75 18 jnz short <CrackMe4.loc_40CD0A> ; jmp // 011ECCF2 |. 80F9 30 cmp cl,0x30 // 011ECCF5 |. 75 13 jnz short <CrackMe4.loc_40CD0A> if ((dw_edi == 0x10) || ((BYTE)dw_ecx == 0x30)) { // 011ECCF7 >|> 8A06 mov al,byte ptr ds:[esi] ; loc_40CCF7 dw_eax = (int)(*(BYTE*)dw_esi); if ((dw_eax == 0x78) || (dw_eax == 0x58)) { // 011ECCF9 |. 3C 78 cmp al,0x78 // 011ECCFB |. 74 04 je short <CrackMe4.loc_40CD01> // 011ECCFD |. 3C 58 cmp al,0x58 // 011ECCFF |. 75 09 jnz short <CrackMe4.loc_40CD0A> // 011ECD01 >|> 8A4E 01 mov cl,byte ptr ds:[esi+0x1] ; loc_40CD01 // 011ECD04 |. 83C6 02 add esi,0x2 // 011ECD07 |. 884D FF mov byte ptr ss:[ebp-0x1],cl dw_ecx = (DWORD)(*(BYTE*)(dw_esi + 1)); dw_esi += 2; bVar1 = (BYTE)dw_ecx; } } } // 011ECD0A >|> 83C8 FF or eax,-0x1 ; eax = 0 => 0xffffffff dw_eax |= 0xffffffff; // 011ECD0D |. 33D2 xor edx,edx dw_edx = 0; // 011ECD0F |. F7F7 div edi ; eax = 0xffffffff, edi = a dwTmp = dw_eax; dw_eax = dwTmp / dw_edi; dw_edx = dwTmp % dw_edi; // 011ECD11 |. 8945 F4 mov dword ptr ss:[ebp-0xC],eax ; eax = 0x19999999, edx = 5 dwVarC = dw_eax; // 011ECD14 |. 8B45 DC mov eax,dword ptr ss:[ebp-0x24] dw_eax = dwVar24; // 011ECD17 |. 8955 F0 mov dword ptr ss:[ebp-0x10],edx dwVar10 = dw_edx; // 011ECD1A |. 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] dw_edx = dwVar8; // 011ECD1D |. 8B80 90000000 mov eax,dword ptr ds:[eax+0x90] ; 取KeyBuf首地址 dw_eax = (DWORD)&ucAryKeyBufForRegSn[0]; // 011ECD23 |. 8945 EC mov dword ptr ss:[ebp-0x14],eax dwVar14 = dw_eax; do { // 011ECD26 >|> 0FB6C9 /movzx ecx,cl ; 第一个字符 // 011ECD29 |. 0FB70448 |movzx eax,word ptr ds:[eax+ecx*2] ; 看起来像将字符串变成数字串 dw_eax = (DWORD)(*(WORD*)(dw_eax + dw_ecx * 2)); // 011ECD2D |. 8BC8 |mov ecx,eax ; 最后一个字符\0取出的是x020 dw_ecx = dw_eax; // 011ECD2F |. 83E1 04 |and ecx,0x4 ; ecx = 84 => 4 dw_ecx &= 0x4; // 011ECD32 |. 74 09 |je short <CrackMe4.loc_40CD3D> ; not jump,最后一个\0跳 if (dw_ecx != 0) { // 011ECD34 |. 0FBE45 FF |movsx eax,byte ptr ss:[ebp-0x1] ; 第一个字符 dw_eax = (DWORD)bVar1; // 011ECD38 |. 83E8 30 |sub eax,0x30 ; '1' to 1 dw_eax -= 0x30; // 011ECD3B |. EB 1A |jmp short <CrackMe4.loc_40CD57> } else { // 完全模拟算法不现实, 现在已经算完了,直接返回ebx return dw_ebx; // 011ECD3D >|> 25 03010000 |and eax,0x103 ; loc_40CD3D dw_eax &= 0x103; // 011ECD42 |. 74 44 |je short <CrackMe4.loc_40CD88> ; \0流程跳 if (0 == dw_eax) { goto LOC_40CD88; } // 011ECD44 |. 8A4D FF |mov cl,byte ptr ss:[ebp-0x1] dw_ecx = (DWORD)bVar1; // _ASSERT(0); // 数字字符串流程不来这,先放一下 // 011ECD47 |. 8D41 9F |lea eax,dword ptr ds:[ecx-0x61] // 011ECD4A |. 3C 19 |cmp al,0x19 // 011ECD4C |. 0FBEC1 |movsx eax,cl // 011ECD4F |. 77 03 |ja short <CrackMe4.loc_40CD54> // 011ECD51 |. 83E8 20 |sub eax,0x20 // 011ECD54 >|> 83C0 C9 |add eax,-0x37 ; loc_40CD54 } // 011ECD57 >|> 3BC7 |cmp eax,edi ; cmp 1, 0xa // 011ECD59 |. 73 2D |jnb short <CrackMe4.loc_40CD88> ; not jump if (dw_eax < dw_edi) { // 011ECD5B |. 8B4D F4 |mov ecx,dword ptr ss:[ebp-0xC] ; 0x19999999 to ecx dw_ecx = dwVarC; // 011ECD5E |. 83CA 08 |or edx,0x8 ; edx = 0 to 8 dw_edx |= 0x8; // 011ECD61 |. 3BD9 |cmp ebx,ecx ; cmp 0, 0x19999999 // 011ECD63 |. 72 13 |jb short <CrackMe4.loc_40CD78> ; jmp if (dw_ebx >= dw_ecx) { // 011ECD65 |. 75 05 |jnz short <CrackMe4.loc_40CD6C> if (dw_ebx == dw_ecx) { // 011ECD67 |. 3B45 F0 |cmp eax,dword ptr ss:[ebp-0x10] // 011ECD6A |. 76 0C |jbe short <CrackMe4.loc_40CD78> if (dw_eax <= dwVar10) { // 011ECD78 >|> 0FAFDF |imul ebx,edi ; imul 0, 0xa dw_ebx = dw_ebx * dw_edi; // 011ECD7B |. 03D8 |add ebx,eax ; add 0, 1 dw_ebx += dw_eax; } } else { // 011ECD6C >|> 8B45 10 |mov eax,dword ptr ss:[ebp+0x10] ; loc_40CD6C dw_eax = (DWORD)pcRegSn; // 011ECD6F |. 83CA 04 |or edx,0x4 dw_edx |= 0x4; // 011ECD72 |. 85C0 |test eax,eax // 011ECD74 |. 74 15 |je short <CrackMe4.loc_40CD8B> if (0 == dw_eax) { break; } // 011ECD76 |. EB 05 |jmp short <CrackMe4.loc_40CD7D> } } else { // 011ECD78 >|> 0FAFDF |imul ebx,edi ; imul 0, 0xa dw_ebx = dw_ebx * dw_edi; // 011ECD7B |. 03D8 |add ebx,eax ; add 0, 1 dw_ebx += dw_eax; } // 011ECD7D >|> 8A0E |mov cl,byte ptr ds:[esi] ; loc_40CD7D dw_ecx = (DWORD)(*(BYTE*)dw_esi); // 011ECD7F |. 46 |inc esi ; 指向下一个字符 dw_esi++; // 011ECD80 |. 8B45 EC |mov eax,dword ptr ss:[ebp-0x14] ; KeyBuf首地址 dw_eax = dwVar14; // 011ECD83 |. 884D FF |mov byte ptr ss:[ebp-0x1],cl ; 保存第2个字符 bVar1 = (BYTE)dw_ecx; // 011ECD86 |.^ EB 9E \jmp short <CrackMe4.loc_40CD26> ; 跳上去了 } } while (1); LOC_40CD88: // 011ECD88 >|> 8B45 10 mov eax,dword ptr ss:[ebp+0x10] ; ebx = 00BC614E, 算完了 dw_eax = dwParam10; // 011ECD8B >|> 4E dec esi ; loc_40CD8B dw_esi--; // 011ECD8C |. 8955 F8 mov dword ptr ss:[ebp-0x8],edx ; edx = 8 // 011ECD8F |. 8955 F8 mov dword ptr ss:[ebp-0x8],edx dwVar8 = dw_edx; // 011ECD92 |. F6C2 08 test dl,0x8 ; 8个字符 // 011ECD95 |. 75 0B jnz short <CrackMe4.loc_40CDA2> ; jump if (0x8 == dw_edx) { // 011ECD97 |. 85C0 test eax,eax // 011ECD99 |. 74 03 je short <CrackMe4.loc_40CD9E> if (0 != dw_eax) { // 011ECD9B |. 8B75 0C mov esi,dword ptr ss:[ebp+0xC] dw_esi = dwVarC; } // 011ECD9E >|> 33DB xor ebx,ebx ; loc_40CD9E dw_ebx = dw_ebx; // 011ECDA0 |. EB 49 jmp short <CrackMe4.loc_40CDEB> } else { // 011ECDA2 >|> BF FFFFFF7F mov edi,0x7FFFFFFF ; edit = 0xfffffff dw_edi = 0x7FFFFFFF; // 011ECDA7 |. F6C2 04 test dl,0x4 ; dl = 8 // 011ECDAA |. 75 1C jnz short <CrackMe4.loc_40CDC8> ; not jump if (1 == dw_edx) { // 011ECDAC |. F6C2 01 test dl,0x1 // 011ECDAF |. 75 3A jnz short <CrackMe4.loc_40CDEB> ; not jump // 011ECDB1 |. 8BC2 mov eax,edx dw_eax = dw_edx; // 011ECDB3 |. 83E0 02 and eax,0x2 ; eax = 8 => 0 dw_eax &= 0x2; // 011ECDB6 |. 74 08 je short <CrackMe4.loc_40CDC0> ; jmp if (0 != dw_eax) { // 011ECDB8 |. 81FB 00000080 cmp ebx,0x80000000 // 011ECDBE |. 77 08 ja short <CrackMe4.loc_40CDC8> if (dw_ebx > 0x80000000) { goto LOC_40CDC8; } } // 011ECDC0 >|> 85C0 test eax,eax ; loc_40CDC0 // 011ECDC2 |. 75 27 jnz short <CrackMe4.loc_40CDEB> ; not jump if (0 != dw_eax) { goto LOC_40CDEB; } else if (dw_ebx <= dw_edi) { // 011ECDC4 |. 3BDF cmp ebx,edi ; ebx = 00BC614E, edi = 7FFFFFFF // 011ECDC6 |. 76 23 jbe short <CrackMe4.loc_40CDEB> ; jmp goto LOC_40CDEB; } goto LOC_40CDC8; } else if (4 != dw_edx) { LOC_40CDC8: _ASSERT(0); // 数字字符串逻辑没有走到这里 // 011ECDC8 >|> E8 FBD6FFFF call <CrackMe4.fnTls_40A4C8> ; loc_40CDC8 // 011ECDCD |. 8B55 F8 mov edx,dword ptr ss:[ebp-0x8] // 011ECDD0 |. C700 22000000 mov dword ptr ds:[eax],0x22 // 011ECDD6 |. F6C2 01 test dl,0x1 // 011ECDD9 |. 74 05 je short <CrackMe4.loc_40CDE0> // 011ECDDB |. 83CB FF or ebx,-0x1 // 011ECDDE |. EB 0B jmp short <CrackMe4.loc_40CDEB> // 011ECDE0 >|> F6C2 02 test dl,0x2 ; loc_40CDE0 // 011ECDE3 |. 6A 00 push 0x0 // 011ECDE5 |. 5B pop ebx // 011ECDE6 |. 0F95C3 setne bl // 011ECDE9 |. 03DF add ebx,edi } } LOC_40CDEB: // 011ECDEB >|> 8B45 10 mov eax,dword ptr ss:[ebp+0x10] ; 0 dw_eax = (DWORD)pcRegSn; // 011ECDEE |. 85C0 test eax,eax // 011ECDF0 |. 74 02 je short <CrackMe4.loc_40CDF4> ; jmp if (0 != dw_eax) { // 011ECDF2 |. 8930 mov dword ptr ds:[eax],esi } // 011ECDF4 >|> F6C2 02 test dl,0x2 ; edx = 8 // 011ECDF7 |. 74 12 je short <CrackMe4.loc_40CE0B> ; jmp if (2 == dw_edx) { goto LOC_40CE0B; } // 011ECDF9 |. F7DB neg ebx dw_ebx = ~dw_ebx; if (0 != dw_edx) { // 011ECDFB |. EB 0E jmp short <CrackMe4.loc_40CE0B> goto LOC_40CE0B; } } // 011ECDFD >|> 8B45 10 mov eax,dword ptr ss:[ebp+0x10] ; loc_40CDFD dw_eax = (DWORD)pcRegSn; if (0 != dw_eax) { // 011ECE00 |. 85C0 test eax,eax // 011ECE02 |. 74 05 je short <CrackMe4.loc_40CE09> // 011ECE04 |. 8B4D 0C mov ecx,dword ptr ss:[ebp+0xC] // 011ECE07 |. 8908 mov dword ptr ds:[eax],ecx dw_ecx = dwVarC; } // 011ECE09 >|> 33DB xor ebx,ebx ; loc_40CE09 dw_ebx = 0; } while (0); LOC_40CE0B: if (dwVar18 != 0) { // 这里是更新类中的变量, 不用翻译 // 011ECE0B >|> 807D E8 00 cmp byte ptr ss:[ebp-0x18],0x0 ; 0 // 011ECE0F |. 74 07 je short <CrackMe4.loc_40CE18> ; jmp // 011ECE11 |. 8B4D E4 mov ecx,dword ptr ss:[ebp-0x1C] dw_ecx = dwVar1C; // 011ECE14 |. 8361 70 FD and dword ptr ds:[ecx+0x70],-0x3 } // 011ECE18 >|> 5F pop edi ; loc_40CE18 // 011ECE19 |. 5E pop esi // 011ECE1A |. 8BC3 mov eax,ebx dw_eax = dw_ebx; // 011ECE1C |. 5B pop ebx // 011ECE1D |. 8BE5 mov esp,ebp // 011ECE1F |. 5D pop ebp // 011ECE20 \. C3 retn return dw_eax; }
感谢liuwan制作的crackme.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: