将脱壳后的程序加载到pexplorer资源编辑工具中查看界面没出现问题,除了文字加载未成功.
初步推断,文字部分在程序的附加数据里调用的,在查找附加数据调用的方面,得到论坛xx大牛haileyuxin指点,首先感谢下
重新加载脱壳后的程序
00401DFC > 6A 00 push 0 ; 程序入口点(oep)
00401DFE E8 7B0F0000 call <jmp.&kernel32.GetModuleHandleA>
00401E03 A3 5C414000 mov dword ptr ds:[40415C],eax
00401E08 6A 64 push 64
00401E0A 68 261E4000 push cracked_.00401E26
00401E0F 6A 00 push 0
00401E11 6A 64 push 64
00401E13 FF35 5C414000 push dword ptr ds:[40415C]
00401E19 E8 520E0000 call <jmp.&user32.DialogBoxParamA> ;调用对话框的程序
00401E1E 6A 00 push 0
00401E20 E8 410F0000 call <jmp.&kernel32.ExitProcess>
00401E25 C3 retn
既然猜测是附加数据调用问题,那么程序肯定要读取文件,我们下个bp CreateFileA函数断点,F9让程序跑起来
7C801A24 > 8BFF mov edi,edi ;程序断下了在系统的领空,ALT+f9返回程序的领空
7C801A26 55 push ebp
7C801A27 8BEC mov ebp,esp
7C801A29 FF75 08 push dword ptr ss:[ebp+8]
7C801A2C E8 73C80000 call kernel32.7C80E2A4
7C801A31 85C0 test eax,eax
7C801A33 74 1E je short kernel32.7C801A53
7C801A35 FF75 20 push dword ptr ss:[ebp+20]
----------------------------------------------------------------
回到程序的领空,下面的代码是非常关键的地方
0040273E E8 17060000 call <jmp.&kernel32.CreateFileA> ;下断的函数
00402743 83F8 FF cmp eax,-1 ;回到程序的领空
00402746 75 07 jnz short cracked_.0040274F
00402748 33C0 xor eax,eax
0040274A 5F pop edi
0040274B 5E pop esi
0040274C 5B pop ebx
0040274D C9 leave
0040274E C3 retn
0040274F 8945 F8 mov dword ptr ss:[ebp-8],eax
00402752 6A 00 push 0
00402754 50 push eax
00402755 E8 18060000 call <jmp.&kernel32.GetFileSize> ;获取文件字节大小
0040275A 2D 00380000 sub eax,3800 ;这里3800,是加壳程序附加数据的起始位置,其中eax中是GetFileSize函数返回的脱壳后的文件的大小,文件大小减去附加数据的起始位置就得到了附加数据的大小,并保存到eax中.而实际我们脱壳后处理附加数据的起始位置是0E000,所以这里是原来加壳程序的附加数据起始位置,那么获取到的附加数据的大小就出现错误了.
0040275F 83F8 00 cmp eax,0
00402762 72 04 jb short cracked_.00402768
00402764 0BC0 or eax,eax
00402766 75 0F jnz short cracked_.00402777
00402768 FF75 F8 push dword ptr ss:[ebp-8]
0040276B E8 DE050000 call <jmp.&kernel32.CloseHandle>
00402770 33C0 xor eax,eax
00402772 5F pop edi
00402773 5E pop esi
00402774 5B pop ebx
00402775 C9 leave
00402776 C3 retn
00402777 8BD8 mov ebx,eax ;从这里开始程序要对附加数据进行处理了
00402779 6A 00 push 0
0040277B 6A 00 push 0
0040277D 68 00380000 push 3800 ;把附加数据的起始位置压入堆栈中,实际脱壳后的应该是0E000,我们不管,先记着就好
00402782 FF75 F8 push dword ptr ss:[ebp-8]
00402785 E8 30060000 call <jmp.&kernel32.SetFilePointer> ;从函数名知道是得到附加数据的起始点
0040278A E8 F5050000 call <jmp.&kernel32.GetProcessHeap>
0040278F A3 64414000 mov dword ptr ds:[404164],eax
00402794 81C3 C8000000 add ebx,0C8
0040279A 53 push ebx
0040279B 6A 0C push 0C
0040279D 50 push eax
0040279E E8 F3050000 call <jmp.&kernel32.HeapAlloc> ;在内存中分配附加数据所需要的空间
004027A3 A3 68414000 mov dword ptr ds:[404168],eax
004027A8 81EB C8000000 sub ebx,0C8
004027AE 6A 00 push 0
004027B0 8D45 FC lea eax,dword ptr ss:[ebp-4]
004027B3 50 push eax
004027B4 53 push ebx
004027B5 FF35 68414000 push dword ptr ds:[404168]
004027BB FF75 F8 push dword ptr ss:[ebp-8]
004027BE E8 DF050000 call <jmp.&kernel32.ReadFile> ;把附加数据读取到分配的内存空间
004027C3 FF75 F8 push dword ptr ss:[ebp-8]
004027C6 E8 83050000 call <jmp.&kernel32.CloseHandle>
004027CB 8B3D 68414000 mov edi,dword ptr ds:[404168]
004027D1 8B4D FC mov ecx,dword ptr ss:[ebp-4]
004027D4 03F9 add edi,ecx
004027D6 8BCB mov ecx,ebx
004027D8 49 dec ecx
004027D9 4F dec edi
004027DA 8BF7 mov esi,edi
004027DC 4F dec edi
004027DD 8A06 mov al,byte ptr ds:[esi]
004027DF 4E dec esi
004027E0 8A26 mov ah,byte ptr ds:[esi]
004027E2 4E dec esi
004027E3 32C4 xor al,ah ;对附加数据进行逐字节的异或解密
004027E5 8807 mov byte ptr ds:[edi],al ;解密后的字节写入到内存中
004027E7 4F dec edi
004027E8 ^ E2 F6 loopd short cracked_.004027E0 循环直到附加数据所有字节均完成解密
-------------------------------------------------------------------
原加密的附加数据部分代码
00B20020 05 15 15 53 03 00 1F 5A 18 08 06 62 CC 20 2C 07 S . Z b?,
00B20030 F2 05 7C 7D 6E 6E 01 02 00 F8 37 43 63 6F 0B 0F ?|}nn .?Cco
00B20040 17 A1 68 1C 00 04 4A 15 00 58 00 00 59 57 0D 1E . J .X..YW.
00B20050 1E 1E 10 16 42 4D 0C 02 42 2F 74 18 59 05 5C 5D BM. B/t Y \]
00B20060 71 71 03 04 18 4D 0C 02 6D B4 67 E2 01 02 03 F8 qq M. m磄?
00B20070 34 41 0A 03 08 8C 01 02 00 3F 07 07 07 BE 46 40 4A. ? .? 綟@
00B20080 0B 0F 17 66 77 77 2C 59 09 69 78 62 69 14 41 3B fww,Y.ixbi A;
00B20090 0D 01 25 53 71 72 62 6D 0D B9 07 07 07 BB 0F 0C . %Sqrbm.? ?.
00B200A0 0B 0F 17 77 6D 71 0D 14 10 03 74 65 01 6E 01 05 wmq. te n
00B200B0 77 1C 76 68 7F 13 0F 7D 1E 72 46 32 05 1F 10 CE w vh } rF2
00B200C0 07 07 07 BB 0F 0C 0B 0F 17 6B 3E 23 7F 7B 10 71 ?. k># { q
00B200D0 0B 0F 17 02 0F 7B 7D 1D 15 65 2C 3C 75 61 34 44 {} e,<ua4D
00B200E0 45 42 12 07 02 AE 07 07 07 C6 20 2C 07 F2 05 7C EB ? ?, ?|
00B200F0 7D E6 7F 7B 10 73 56 2C 37 43 63 6F 0B 0F 17 02 }?{ sV,7Cco
00B20100 0F 7D 1E 72 46 40 57 3F 10 C3 00 20 2A 12 18 C0 } rF@W? ? *
----------------------------------------------------------------------
附加数据解密后的部分代码
00B20020 64 61 74 61 32 31 31 2E 74 6C 64 62 00 CC EC C0 data211.tldb.天
00B20030 C7 35 30 4C 31 5F 31 30 32 32 CA FD BE DD B2 B9 ?0L1_1022数据补
00B20040 B6 A1 00 68 74 74 70 3A 2F 2F 77 77 77 2E 79 74 丁.http://www.yt
00B20050 6A 74 6A 7A 6C 2E 63 6F 6D 2F 00 74 6C 35 30 6C jtjzl.com/.tl50l
00B20060 31 40 31 32 36 2E 63 6F 6D 00 B4 D3 31 30 32 31 .从1021
00B20070 C9 FD BC B6 B5 BD 31 30 32 32 0D 0A 0D 0A B4 F2 升级到1022....打
00B20080 B2 B9 B6 A1 C7 B0 C7 EB B2 BB D2 AA C8 A1 B5 F4 补丁前请不要取掉
00B20090 CF C2 C3 E6 B5 C4 B6 D4 B9 B4 0D 0A 0D 0A B1 BE 下面的对勾....本
00B200A0 B2 B9 B6 A1 D6 BB CA C7 D3 C3 C0 B4 D1 D0 BE BF 补丁只是用来研究
00B200B0 BA CD D1 A7 CF B0 A3 AC D1 CF BD FB C9 CC D3 C3 和学习,严禁商用
00B200C0 0D 0A 0D 0A B1 BE B2 B9 B6 A1 CA F4 D7 A8 D3 C3 ....本补丁属专用
00B200D0 B2 B9 B6 A1 A3 AC D7 AA B7 A2 C7 EB D7 A2 C3 F7 补丁,转发请注明
00B200E0 B3 F6 B4 A6 A1 A3 0D 0A 0D 0A CC EC C0 C7 35 30 出处。....天狼50
00B200F0 4C 31 D7 A8 D3 C3 B0 E6 CA FD BE DD B2 B9 B6 A1 L1专用版数据补丁
00B20100 A3 AC D1 CF BD FB BB EC D3 C3 00 00 20 0A 18 00 ,严禁混用.. . .
从这段代码知道,程序对附加数据要逐字节进行xor解密,当获取到的附加数据的大小错误,那么解密自然就出现错误,我们脱壳后重新添加的附加数据起始位置在0e000这个地址,而加壳程序附加数据的起始地址是3800地址的位置,那么我们只要把3800改成0e000就能获取到正确的附加数据的长度.修改保存后,程序终于能正常运行了,到此脱壳部分也就圆满完成了.
但是..........发现个有趣的东西,从解密的附加数据看,程序的标题,网站邮箱等是调用附加数据写入到程序的,资源编辑器修改信息是无效的,如果要改掉这些信息,不是要重
新把附加数据修改再加密一次么,这样工程量十分的浩大,那怎么修改才最简便呢
以下内容只限于技术探讨,特此声明一下.
跟踪程序查找调用相关信息的地方
00401EA3 8B35 70414000 mov esi,dword ptr ds:[404170] ; 调用附加数据网站地址
00401EA9 8B3D 74414000 mov edi,dword ptr ds:[404174] ; 调用附加数据邮箱地址
00401EAF 803E 00 cmp byte ptr ds:[esi],0
00401EB2 75 05 jnz short cracked_.00401EB9
00401EB4 803F 00 cmp byte ptr ds:[edi],0
00401EB7 74 45 je short cracked_.00401EFE
00401EB9 6A 6E push 6E
00401EBB FF75 08 push dword ptr ss:[ebp+8]
00401EBE E8 DD0D0000 call <jmp.&user32.GetDlgItem>
00401EC3 803E 00 cmp byte ptr ds:[esi],0
00401EC6 74 09 je short cracked_.00401ED1
00401EC8 56 push esi
00401EC9 50 push eax
00401ECA E8 6D0E0000 call <jmp.&user32.SetWindowTextA> ;将获取的网站字符串写入到程序
00401ECF EB 08 jmp short cracked_.00401ED9
00401ED1 6A 00 push 0
00401ED3 50 push eax
00401ED4 E8 690E0000 call <jmp.&user32.ShowWindow>
00401ED9 6A 6F push 6F
00401EDB FF75 08 push dword ptr ss:[ebp+8]
00401EDE E8 BD0D0000 call <jmp.&user32.GetDlgItem>
00401EE3 803F 00 cmp byte ptr ds:[edi],0
00401EE6 74 0E je short cracked_.00401EF6
00401EE8 FF35 74414000 push dword ptr ds:[404174] ; 再次检查调用附加数据邮箱地址
00401EEE 50 push eax
00401EEF E8 480E0000 call <jmp.&user32.SetWindowTextA> ;将获取的邮箱字串写入到程序
00401EF4 EB 08 jmp short cracked_.00401EFE
00401EF6 6A 00 push 0
00401EF8 50 push eax
00401EF9 E8 440E0000 call <jmp.&user32.ShowWindow>
00401EFE A1 78414000 mov eax,dword ptr ds:[404178] ;调用附加数据标题栏名称和版权信息
00401F03 8038 00 cmp byte ptr ds:[eax],0
00401F06 74 09 je short cracked_.00401F11
00401F08 50 push eax
00401F09 FF75 08 push dword ptr ss:[ebp+8]
00401F0C E8 2B0E0000 call <jmp.&user32.SetWindowTextA> ;将获取的标题栏信息写入到程序
00401F11 FF35 68414000 push dword ptr ds:[404168]
00401F17 68 EA030000 push 3EA
..................
..................
004013D4 A1 78414000 mov eax,dword ptr ds:[404178] ;调用附加数据标题栏
004013D9 8038 00 cmp byte ptr ds:[eax],0
004013DC 75 08 jnz short 复件_cra.004013E6
004013DE 8D05 3D414000 lea eax,dword ptr ds:[40413D]
004013E4 EB 05 jmp short 复件_cra.004013EB
004013E6 A1 78414000 mov eax,dword ptr ds:[404178] ;调用附加数据标题栏
004013EB 6A 17 push 17
004013ED 50 push eax
004013EE 8D85 B8FEFFFF lea eax,dword ptr ss:[ebp-148]
004013F4 50 push eax
004013F5 E8 F0190000 call <jmp.&kernel32.lstrcpyn>
004013FA 6A 00 push 0
004013FC FF75 FC push dword ptr ss:[ebp-4]
004013FF E8 5E1A0000 call <jmp.&gdi32.SetTextColor>
好了,所有调用要修改的地方都找到了,我们可以在程序中找到一个区段间空白数据的位置,把要修改的字符串写到空白区域
00402E9A 这个空白区域填写网站代码
68 74 74 70 3A 2F 2F 77 77 77 2E 62 61 69 64 75 2E 63 6F 6D
的ascii码
00402EBB 这个空白区域填写邮箱代码
31 78 78 78 78 78 78 78 78 40 78 78 78 2E 63 6F 6D
00402ED5 这个空白区域填写标题栏信息
B3 CC D0 F2 C6 C6 BD E2 B2 E2 CA D4 00
程序xx测试
那么上面所有调用的地方相应改成
00401EA3 mov esi,dword ptr ds:[404170] ; 调用附加数据网站地址改成mov esi,00402E9A
00401EA9 mov edi,dword ptr ds:[404174] ; 调用附加数据邮箱地址改成mov edi,00402EBB
00401EFE mov eax,dword ptr ds:[404178] ;调用附加数据标题栏名称改成mov eax,00402ED5
只演示三条,其他要修改的一律如此这般修改调用字符串的地址,{zh1}修改完成的程序页面,见图