亿图V1.5.6
一、手工脱壳
使用ollydbg载入后,提示程序和所调用的dll被压缩
停留在此处
005B7001 > 60 pushad <---- 很眼熟吧?
005B7002 E8 03000000 call 亿图.005B700A <--跟进
005B7007 - E9 EB045D45 jmp 45B874F7
005B700C 55 push ebp
005B700D C3 retn
005B700E E8 01000000 call 亿图.005B7014
005B7013 EB 5D jmp short 亿图.005B7072
跟进 亿图.005B700A 后F7 F8轮换着使,最后跟踪到这里了
『 注:这一个过程是需要经验和耐心的,我当初也是跳了好几遍,才用熟练了。F7多了太耗时间,F8多了一不小心就跳过了自解压过程。
我的经验就是,找一个壳,自己联系它七八遍就ok了。我第一次手工脱壳就是照着kanxue的教程拿亿图V1.5开刀的。』
005B73A6 59 pop ecx
005B73A7 0BC9 or ecx,ecx
005B73A9 8985 A8030000 mov dword ptr ss:[ebp+3A8],eax
005B73AF 61 popad <-------- 解压完了,继续往下走
005B73B0 75 08 jnz short 亿图.005B73BA
005B73B2 B8 01000000 mov eax,1
005B73B7 C2 0C00 retn 0C
005B73BA 68 44E15400 push 亿图.0054E144 <------ 准备进入到真正的入口处,即所谓的OEP
005B73BF C3 retn
005B73C0 8B85 26040000 mov eax,dword ptr ss:[ebp+426]
005B73C6 8D8D 3B040000 lea ecx,dword ptr ss:[ebp+43B]
0054E144 /. 55 push ebp <-----终于找到了真正的入口,开始dump吧
0054E145 |. 8BEC mov ebp,esp
0054E147 |. 6A FF push -1
0054E149 |. 68 50705700 push 亿图.00577050
0054E14E |. 68 A2E25400 push 亿图.0054E2A2 ; jmp to MSVCRT._except_handler3; SE 句柄安装
0054E153 |. 64:A1 0000000>mov eax,dword ptr fs:[0]
0054E159 |. 50 push eax
dump时使用ollydbg插件ollydump即可,注意不要选择“重建出入表",一会直接用importREC来完成。
CGdi.dll的脱壳过程同上
1000F000 90 nop
1000F001 > 60 pushad <---------------
1000F002 E8 03000000 call orig_CGd.1000F00A <----跟入
1000F007 - E9 EB045D45 jmp 555DF4F7
1000F00C 55 push ebp
1000F00D C3 retn
1000F00E E8 01000000 call orig_CGd.1000F014
1000F013 EB 5D jmp short orig_CGd.1000F072
1000F3A6 59 pop ecx
1000F3A7 0BC9 or ecx,ecx
1000F3A9 8985 A8030000 mov dword ptr ss:[ebp+3A8],eax
1000F3AF 61 popad <--------------------解压完
1000F3B0 75 08 jnz short orig_CGd.1000F3BA
1000F3B2 B8 01000000 mov eax,1
1000F3B7 C2 0C00 retn 0C
1000F3BA 68 9F2E0010 push orig_CGd.10002E9F <---------真正的入口
1000F3BF C3 retn
1000F3C0 8B85 26040000 mov eax,dword ptr ss:[ebp+426]
1000F3C6 8D8D 3B040000 lea ecx,dword ptr ss:[ebp+43B]
10002E99 6A 01 push 1
10002E9B 58 pop eax
10002E9C C2 0C00 retn 0C
10002E9F 55 push ebp <------------------ OEP ,dump出来,然后重建输入表
10002EA0 8BEC mov ebp,esp
10002EA2 53 push ebx
10002EA3 8B5D 08 mov ebx,dword ptr ss:[ebp+8]
10002EA6 56 push esi
10002EA7 8B75 0C mov esi,dword ptr ss:[ebp+C]
10002EAA 57 push edi
10002EAB 8B7D 10 mov edi,dword ptr ss:[ebp+10]
10002EAE 85F6 test esi,esi
二、破除自校验
脱壳完毕后,启动主程序,提示文件被修改
很简单:暂停执行,然后选择”执行到用户代码“,然后沿着程序停留的地方往前走
00497FF8 /0F85 4E020000 jnz 亿图up_f.0049824C ; 判断是否被修改 改为jnz
继续执行,又提示被修改,同样的方法
0049820C /0F84 DA000000 je 亿图up_f.004982EC ; 修改为je
文件保存和另存时仍提示被修改
保存时提示文件被修改
004BCD23 E8 EA050900 call <jmp.&mfc42.#1168_AfxGetModule>
004BCD28 8B48 04 mov ecx,dword ptr ds:[eax+4]
004BCD2B E8 E384F4FF call 亿图up_f.00405213
004BCD30 85C0 test eax,eax
004BCD32 74 4E je short 亿图up_f.004BCD82 ; 关键比较处 改为jz
004BCD34 8D4C24 04 lea ecx,dword ptr ss:[esp+4]
004BCD38 E8 3DFE0800 call <jmp.&mfc42.#540_CString::CStr>
004BCD3D 68 4DC90000 push 0C94D
004BCD42 8D4C24 08 lea ecx,dword ptr ss:[esp+8]
004BCD46 C74424 14 00000>mov dword ptr ss:[esp+14],0
004BCD4E E8 5DFE0800 call <jmp.&mfc42.#4160_CString::Loa>
004BCD53 8B4424 04 mov eax,dword ptr ss:[esp+4]
004BCD57 6A 00 push 0
004BCD59 6A 00 push 0
004BCD5B 50 push eax
004BCD5C E8 8F000900 call <jmp.&mfc42.#1200_AfxMessageBo>; 提示文件被修改
004BCD61 8D4C24 04 lea ecx,dword ptr ss:[esp+4]
004BCD65 C74424 10 FFFFF>mov dword ptr ss:[esp+10],-1
004BCD6D E8 FCFD0800 call <jmp.&mfc42.#800_CString::~CSt>
004BCD72 5E pop esi
0049C426 E8 E88DF6FF call 亿图up_f.00405213
0049C42B 85C0 test eax,eax
0049C42D 74 49 je short 亿图up_f.0049C478 ; 跳转处,改为jz
0049C42F 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
0049C433 E8 42070B00 call <jmp.&mfc42.#540_CString::CStr>
0049C438 68 4DC90000 push 0C94D
0049C43D 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
0049C441 C68424 08070000>mov byte ptr ss:[esp+708],5
0049C449 E8 62070B00 call <jmp.&mfc42.#4160_CString::Loa>
0049C44E 8B4424 10 mov eax,dword ptr ss:[esp+10]
0049C452 53 push ebx
0049C453 53 push ebx
0049C454 50 push eax
0049C455 E8 96090B00 call <jmp.&mfc42.#1200_AfxMessageBo>; 提示文件被修改
0049C45A 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
0049C45E C68424 04070000>mov byte ptr ss:[esp+704],3
0049C466 E8 03070B00 call <jmp.&mfc42.#800_CString::~CSt>
0049C46B C68424 04070000>mov byte ptr ss:[esp+704],6
0049C473 E9 04140000 jmp 亿图up_f.0049D87C
三、注册
进入到注册页面 ,随便输入用户名和注册码,点确定后弹出序列号错误的对话框。追到程序里
004DCB47 . E8 7C310700 call <jmp.&cgdi.CCrypter::RegeditSoft> ; 进行校验
004DCB4C . 85C0 test eax,eax
004DCB4E . 74 79 je short 亿图up_f.004DCBC9 ; 判断校验结果,如果仅修改此处是没用的,
需要进入到上面调用的函数里
004DCB50 . 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
跟入
004DCB47 . E8 7C310700 call <jmp.&cgdi.CCrypter::RegeditSoft> ; 进行校验
来到这里了
10001350 > 6A FF push -1 ; 校验的主程序
10001352 68 17870010 push cgdi.10008717
10001357 64:A1 00000000 mov eax,dword ptr fs:[0]
往下走
1000168E 894424 20 mov dword ptr ss:[esp+20],eax
10001692 894424 14 mov dword ptr ss:[esp+14],eax
10001696 7E 2B jle short cgdi.100016C3
10001698 8B4C24 20 mov ecx,dword ptr ss:[esp+20]
1000169C 0FBE940C 900000>movsx edx,byte ptr ss:[esp+ecx+90]
100016A4 52 push edx
100016A5 FF15 98910010 call dword ptr ds:[<&msvcrt.isxdigit>] ; MSVCRT.isxdigit <----判断输入的序列号是否全为数字
100016AB 83C4 04 add esp,4
100016AE 85C0 test eax,eax
100016B0 0F84 D0000000 je cgdi.10001786
100016B6 8B4424 20 mov eax,dword ptr ss:[esp+20]
10001795 |. 8D4C24 5C lea ecx,dword ptr ss:[esp+5C]
10001799 |. 50 push eax ; /String2 <--- 某个运算结果
1000179A |. 51 push ecx ; |用户名
1000179B |. FF15 24900010 call dword ptr ds:[<&kernel32.lstrc>; \lstrcmpA <-------------比较
100017A1 |. 85C0 test eax,eax
100017A3 |. 5D pop ebp
100017A4 /75 26 jnz short cgdi.100017CC ; 很关键的跳转,改为jz。看到下面的CCrypter::WriteRegeditInfo了么?
100017A6 |. 8B4424 10 mov eax,dword ptr ss:[esp+10]
100017AA |. BB 01000000 mov ebx,1
100017AF |. 3BC3 cmp eax,ebx
100017B1 |. 74 19 je short cgdi.100017CC
100017B3 |. 85FF test edi,edi
100017B5 |. 74 15 je short cgdi.100017CC
100017B7 |. 8B5424 3C mov edx,dword ptr ss:[esp+3C]
100017BB |. 8B7424 18 mov esi,dword ptr ss:[esp+18]
100017BF |. 52 push edx ; /Arg1
100017C0 |. 8BCE mov ecx,esi ; |
100017C2 |. E8 A9070000 call cgdi.CCrypter::WriteRegeditInf>; \CCrypter::WriteRegeditInfo <-------写入注册信息,跟入看看
100017C7 |. 895E 04 mov dword ptr ds:[esi+4],ebx
100017CA |. EB 0D jmp short cgdi.100017D9
100017CC |> 8B4424 18 mov eax,dword ptr ss:[esp+18]
100017D0 |. 8BF0 mov esi,eax
100017D2 |. C740 04 00000>mov dword ptr ds:[eax+4],0
100017D9 |> 8B76 04 mov esi,dword ptr ds:[esi+4]
100017DC |. 8D4C24 2C lea ecx,dword ptr ss:[esp+2C]
一路走来,看到这个
100020CE |. 81E2 FFFF0000 and edx,0FFFF
100020D4 |. 25 FFFF0000 and eax,0FFFF
100020D9 |. 52 push edx ; /<%X>
100020DA |. 81E1 FFFF0000 and ecx,0FFFF ; |
100020E0 |. 50 push eax ; |<%X>
100020E1 |. 51 push ecx ; |<%X>
100020E2 |. 8D5424 34 lea edx,dword ptr ss:[esp+34] ; |
100020E6 |. 68 F4A00010 push offset cgdi.`string' ; |format = "%X-%X-%X"
100020EB |. 52 push edx ; |s
100020EC |. FF15 90910010 call dword ptr ds:[<&msvcrt.sprintf>; \sprintf <----^_^,很显然的东西
100020F2 |. 83C4 14 add esp,14
结果是这个-----> 0012E4E0 0012E51C ASCII "2E4E-6326-A1C4"
至此已经搞定了。无论你怎么输入,都会说注册成功
四、分析
软件的加密方法是将序列号经过运算后的结果与用户名对比(前几个版本是计算机ID号,不知为什么这次采用用户名)
对比结果如果吻合的话,则认为注册成功了。然后再进行一次运算,生成password存入到注册表
物联网安全入门