1. 了解Windows API 消息框:MessageBoxA/W(Ansi[ASCII]/WideChar[Unicode])
弹页面:
ShellExecuteA/W:open url——控制台执行
WinExec:explorer.exe url——Windows执行
CreateProcessA/W:PATH url——创建进程
注册表相关:RegCreateKeyExA/W、RegOpenKeyExA/W、RegDeleteKeyExA/W
创建线程:CreateThread
2. 实例一 简单的UPX壳,先脱壳才能查找字符串、去除弹窗。
脱壳后程序运行,出现一个弹窗,再出现弹页面。弹窗点确定后,出现主程序,不一会儿又弹出一个页面,再一会儿后又弹出一个页面。
目标:去除NAG,只剩一个主程序(课程介绍的链接不用去除)。
首先去除弹窗。弹窗关键字符串“来试试我的程序啊”。脱壳后的程序载入OD,右键->中文搜索引擎->智能搜索。双击关键字符串去到反汇编窗口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 004014BA C3 retn;上个函数结束 004014BB 56 push esi;关键字符串函数开始 004014BC 57 push edi 004014BD 6A 67 push 0x67 004014BF 6A 00 push 0x0 004014C1 FF15 3C204000 call dword ptr ds:[<&kernel32.#GetNamedPipeHa>; kernel32.GetModuleHandleW 004014C7 50 push eax 004014C8 FF15 E8204000 call dword ptr ds:[<&user32.#445>] ; user32.LoadIconW 004014CE 8B75 08 mov esi,dword ptr ss:[ebp+0x8] ; dumped_.<ModuleEntryPoint> 004014D1 50 push eax 004014D2 6A 00 push 0x0 004014D4 68 80000000 push 0x80 004014D9 56 push esi 004014DA FF15 F4204000 call dword ptr ds:[<&user32.#577>] ; user32.SendMessageW 004014E0 6A 00 push 0x0 004014E2 68 70214000 push dumped_.00402170 ; 52PoJie 004014E7 68 80214000 push dumped_.00402180 ; 来试试我的程序啊 004014EC 56 push esi 004014ED FF15 EC204000 call dword ptr ds:[<&user32.#484>] ; user32.MessageBoxW 004014F3 8B3D 18204000 mov edi,dword ptr ds:[<&kernel32.#CreateThrea>; kernel32.CreateThread 004014F9 6A 00 push 0x0 004014FB 6A 00 push 0x0 004014FD 6A 00 push 0x0 004014FF 68 A0104000 push dumped_.004010A0 00401504 6A 00 push 0x0 00401506 6A 00 push 0x0 00401508 FFD7 call edi 0040150A 6A 00 push 0x0 0040150C 6A 00 push 0x0 0040150E 6A 00 push 0x0 00401510 68 90124000 push dumped_.00401290 00401515 6A 00 push 0x0 00401517 6A 00 push 0x0 00401519 FFD7 call edi 0040151B 68 98214000 push dumped_.00402198 ; 吾爱破解培训第二课实例一\r\n本程序会有一个弹窗和三次弹网页操作\r\n请把广告去除,加油! 00401520 68 E9030000 push 0x3E9 00401525 56 push esi 00401526 FF15 F0204000 call dword ptr ds:[<&user32.#597>] ; user32.SetDlgItemTextW 0040152C 5F pop edi ; kernel32.7C817077 0040152D 5E pop esi ; kernel32.7C817077 0040152E 33C0 xor eax,eax 00401530 5D pop ebp ; kernel32.7C817077 00401531 C3 retn;关键字符串函数结束
从上面的代码可知,NAG窗口函数与主程序函数在一个父函数中,父函数中没有跳转语句,所以不能靠跳转绕过NAG,试一下nop掉NAG相关代码。
程序运行到NAG的call指令,堆栈窗口显示
1 2 3 4 0012FCB8 002A074C |hOwner = 002A074C ('吾爱破解培训第二课实例一',class='#32770') 0012FCBC 00402180 |Text = "来试试我的程序啊" 0012FCC0 00402170 |Title = "52PoJie" 0012FCC4 00000000 \Style = MB_OK|MB_APPLMODAL
即运行这个函数前有4个参数压栈,也就是call前面的4个push
指令。
1 2 3 4 5 004014E0 6A 00 push 0x0 004014E2 68 70214000 push dumped_.00402170 ; 52PoJie 004014E7 68 80214000 push dumped_.00402180 ; 来试试我的程序啊 004014EC 56 push esi 004014ED FF15 EC204000 call dword ptr ds:[<&user32.#484>] ; user32.MessageBoxW
重载,将这5条指令用nop填充,运行,发现NAG窗口消失了。复制到可执行文件,保存。在此程序的基础上去除页面。
3个NAG页面分别为:https://www.52pojie.cn/ 、https://www.52pojie.cn/forum-5-1.html 、http://www.52pojie.cn/forum-68-1.html 。
查找关键字符串,可看到其中一个NAG页面 https://www.52pojie.cn/ 。同样,没有跳转指令,用nop填充,操作与NAG弹窗一样。保存,载入新程序。
我们知道,弹页面用的是ShellExecuteA/W、WinExec、CreateProcessA/W几个函数。Ctrl+G搜索这些函数下断。F9运行,等待一会儿,程序断在某个函数处。Alt+F9返回,程序运行到用户领空的下一指令,看到弹出页面 https://www.52pojie.cn/forum-5-1.html ,也看到了函数调用。由于又没有跳转指令,依旧用nop。
1 2 3 0040125C 6A 05 push 0x5 0040125E 53 push ebx 0040125F FF15 10204000 call dword ptr ds:[<&kernel32.#WriteCons>; kernel32.WinExec
保存,载入新程序。
依旧那几个函数,Alt+F9返回后弹出页面 http://www.52pojie.cn/forum-68-1.html 。将刚才几个函数的断点去掉,在call指令处下断。
1 0040143B FF15 20204000 call dword ptr ds:[<&kernel32.#CreatePro>; kernel32.CreateProcessA
F9运行,查看堆栈窗口
1 2 3 4 5 6 7 8 9 10 00C3FEC4 00000000 |ModuleFileName = NULL 00C3FEC8 003A4210 |CommandLine = "C:\Program Files\Internet Explorer\iexplore.exe http://www.52pojie.cn/forum-68-1.html" 00C3FECC 00000000 |pProcessSecurity = NULL 00C3FED0 00000000 |pThreadSecurity = NULL 00C3FED4 00000000 |InheritHandles = FALSE 00C3FED8 00000000 |CreationFlags = 0 00C3FEDC 00000000 |pEnvironment = NULL 00C3FEE0 00000000 |CurrentDir = NULL 00C3FEE4 00C3FEF8 |pStartupInfo = 00C3FEF8 00C3FEE8 00C3FF3C \pProcessInfo = 00C3FF3C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 00401403 E8 C2090000 call <jmp.&msvcr100.#1492> 00401408 83C4 0C add esp,0xC 0040140B 8D55 88 lea edx,dword ptr ss:[ebp-0x78] 0040140E 52 push edx 0040140F 8D85 44FFFFFF lea eax,dword ptr ss:[ebp-0xBC] 00401415 50 push eax 00401416 6A 00 push 0x0 00401418 6A 00 push 0x0 0040141A 6A 00 push 0x0 0040141C 6A 00 push 0x0 0040141E 6A 00 push 0x0 00401420 6A 00 push 0x0 00401422 53 push ebx 00401423 B9 01000000 mov ecx,0x1 00401428 6A 00 push 0x0 0040142A C785 70FFFFFF 0>mov dword ptr ss:[ebp-0x90],0x1 00401434 66:898D 74FFFFF>mov word ptr ss:[ebp-0x8C],cx 0040143B FF15 20204000 call dword ptr ds:[<&kernel32.#CreatePro>; kernel32.CreateProcessA
将push edx
及下面的指令全都nop掉,保存。至此,所有NAG都被清除。
3. 实例二 ASPack壳,用ESP定律很快到达OEP,脱壳,用FixRes重构一下资源。
运行程序,程序会将IE主页修改为 http://www.52pojie.cn/ ,主程序中央内置了广告,过了一会儿桌面右下角会闪出广告。
目标:取消主页修改,去除广告。
载入OD,查找字符串看看。
1 2 3 4 5 6 7 8 9 10 11 地址 反汇编 文本字符串 0040193D push dumped_.004034D0 SeDebugPrivilege 004019E2 mov [local.14],dumped_.004034F8 SOFTWARE\microsoft\Internet Explorer\Main;微软浏览器、IE浏览器 004019EE mov esi,dumped_.0040354C http://www.52pojie.cn;广告地址 00401A15 push dumped_.00403578 Start Page;开始页 00401A4B push dumped_.00403590 Start Page 00401A81 push dumped_.004035A8 Default_Page_URL;默认页 00401B4F push dumped_.004035CC 我就是广告\r\n来把我干掉啊\r\n加油!;右下角的广告 00401BA9 push dumped_.004035F4 explorer.exe http://www.52pojie.cn/thread-384195-1-1.html 00401C4A push dumped_.00403630 http://www.52pojie.cn/portal.php;主程序中间的广告 00401DA9 push dumped_.00403674 explorer.exe http://www.52pojie.cn/thread-384195-1-1.html
先去掉IE、微软的默认广告主页。双击进去,发现整个函数都是修改浏览器的主页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 004019D0 /$ 55 push ebp 004019D1 |. 8BEC mov ebp,esp 004019D3 |. 83EC 38 sub esp,0x38 004019D6 |. A1 28504000 mov eax,dword ptr ds:[0x405028] 004019DB |. 33C5 xor eax,ebp 004019DD |. 8945 F8 mov [local.2],eax 004019E0 |. 56 push esi 004019E1 |. 57 push edi 004019E2 |. C745 C8 F8344>mov [local.14],dumped_.004034F8 ; SOFTWARE\microsoft\Internet Explorer\Main 004019E9 |. B9 0B000000 mov ecx,0xB 004019EE |. BE 4C354000 mov esi,dumped_.0040354C ; http://www.52pojie.cn 004019F3 |. 8D7D CC lea edi,[local.13] 004019F6 |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds> 004019F8 |. 8D45 FC lea eax,[local.1] 004019FB |. 50 push eax ; /pHandle = NULL 004019FC |. 8B4D C8 mov ecx,[local.14] ; | 004019FF |. 51 push ecx ; |Subkey = "?粒灴粁..." 00401A00 |. 68 02000080 push 0x80000002 ; |hKey = HKEY_LOCAL_MACHINE 00401A05 |. FF15 10304000 call dword ptr ds:[<&advapi32.#465>] ; \RegCreateKeyW 00401A0B |. 6A 2C push 0x2C ; /BufSize = 2C (44.) 00401A0D |. 8D55 CC lea edx,[local.13] ; | 00401A10 |. 52 push edx ; |Buffer = ntdll.KiFastSystemCallRet 00401A11 |. 6A 01 push 0x1 ; |ValueType = REG_SZ 00401A13 |. 6A 00 push 0x0 ; |Reserved = 0x0 00401A15 |. 68 78354000 push dumped_.00403578 ; |Start Page 00401A1A |. 8B45 FC mov eax,[local.1] ; | 00401A1D |. 50 push eax ; |hKey = 0x0 00401A1E |. FF15 00304000 call dword ptr ds:[<&advapi32.#509>] ; \RegSetValueExW 00401A24 |. 8B4D FC mov ecx,[local.1] 00401A27 |. 51 push ecx ; /hKey = 0012FFB0 00401A28 |. FF15 08304000 call dword ptr ds:[<&advapi32.#459>] ; \RegCloseKey 00401A2E |. 8D55 FC lea edx,[local.1] 00401A31 |. 52 push edx ; /pHandle = ntdll.KiFastSystemCallRet 00401A32 |. 8B45 C8 mov eax,[local.14] ; | 00401A35 |. 50 push eax ; |Subkey = NULL 00401A36 |. 68 01000080 push 0x80000001 ; |hKey = HKEY_CURRENT_USER 00401A3B |. FF15 10304000 call dword ptr ds:[<&advapi32.#465>] ; \RegCreateKeyW 00401A41 |. 6A 2C push 0x2C ; /BufSize = 2C (44.) 00401A43 |. 8D4D CC lea ecx,[local.13] ; | 00401A46 |. 51 push ecx ; |Buffer = 0012FFB0 00401A47 |. 6A 01 push 0x1 ; |ValueType = REG_SZ 00401A49 |. 6A 00 push 0x0 ; |Reserved = 0x0 00401A4B |. 68 90354000 push dumped_.00403590 ; |Start Page 00401A50 |. 8B55 FC mov edx,[local.1] ; | 00401A53 |. 52 push edx ; |hKey = 0x7C92E4F4 00401A54 |. FF15 00304000 call dword ptr ds:[<&advapi32.#509>] ; \RegSetValueExW 00401A5A |. 8B45 FC mov eax,[local.1] 00401A5D |. 50 push eax ; /hKey = NULL 00401A5E |. FF15 08304000 call dword ptr ds:[<&advapi32.#459>] ; \RegCloseKey 00401A64 |. 8D4D FC lea ecx,[local.1] 00401A67 |. 51 push ecx ; /pHandle = 0012FFB0 00401A68 |. 8B55 C8 mov edx,[local.14] ; | 00401A6B |. 52 push edx ; |Subkey = "跃?" 00401A6C |. 68 01000080 push 0x80000001 ; |hKey = HKEY_CURRENT_USER 00401A71 |. FF15 10304000 call dword ptr ds:[<&advapi32.#465>] ; \RegCreateKeyW 00401A77 |. 6A 2C push 0x2C ; /BufSize = 2C (44.) 00401A79 |. 8D45 CC lea eax,[local.13] ; | 00401A7C |. 50 push eax ; |Buffer = NULL 00401A7D |. 6A 01 push 0x1 ; |ValueType = REG_SZ 00401A7F |. 6A 00 push 0x0 ; |Reserved = 0x0 00401A81 |. 68 A8354000 push dumped_.004035A8 ; |Default_Page_URL 00401A86 |. 8B4D FC mov ecx,[local.1] ; | 00401A89 |. 51 push ecx ; |hKey = 0x12FFB0 00401A8A |. FF15 00304000 call dword ptr ds:[<&advapi32.#509>] ; \RegSetValueExW 00401A90 |. 8B55 FC mov edx,[local.1] 00401A93 |. 52 push edx ; /hKey = 7C92E4F4 00401A94 |. FF15 08304000 call dword ptr ds:[<&advapi32.#459>] ; \RegCloseKey 00401A9A |. 5F pop edi ; kernel32.7C817077 00401A9B |. 5E pop esi ; kernel32.7C817077 00401A9C |. 8B4D F8 mov ecx,[local.2] ; kernel32.7C817080 00401A9F |. 33CD xor ecx,ebp 00401AA1 |. E8 380B0000 call dumped_.004025DE 00401AA6 |. 8BE5 mov esp,ebp 00401AA8 |. 5D pop ebp ; kernel32.7C817077 00401AA9 \. C3 retn
这时可以直接将第1行代码修改为retn
,但必须保证这个retn
与段尾的retn
状态一致,否则会导致堆栈不平衡。或者运行到段尾,执行返回,将父函数nop掉。保存,载入新程序。
去除桌面右下角的广告。在CreateWindowExA/W、DialogBoxParamA/W下断运行。会自动停很多次,因为有很多窗口,但有些很明显不是,比如主程序还没出来就断下的肯定不是。主程序出来后要等一会儿才会出现右下角广告,所以需要等待一点时间才会断下。
最后找到堆栈窗口为这个时,是右下角广告。
1 2 3 4 5 6 015FFF9C 00401BFB /CALL 到 DialogBoxParamW 来自 dumped_1.00401BF5 015FFFA0 00400000 |hInst = 00400000 015FFFA4 00000084 |pTemplate = 0x84 015FFFA8 00000000 |hOwner = NULL 015FFFAC 00401B00 |DlgProc = dumped_1.00401B00 015FFFB0 00000000 \lParam = NULL
选中堆栈窗口的第1行,回车返回调用函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 00401BD0 /. 55 push ebp 00401BD1 |. 8BEC mov ebp,esp 00401BD3 |. 68 204E0000 push 0x4E20 ; /Timeout = 20000. ms 00401BD8 |. FF15 60304000 call dword ptr ds:[<&kernel32.#SystemTimeToFileTime_83>; \Sleep 00401BDE |. 6A 00 push 0x0 ; /lParam = NULL 00401BE0 |. 68 001B4000 push dumped_1.00401B00 ; |DlgProc = dumped_1.00401B00 00401BE5 |. 6A 00 push 0x0 ; |hOwner = NULL 00401BE7 |. 68 84000000 push 0x84 ; |pTemplate = 0x84 00401BEC |. 6A 00 push 0x0 ; |/pModule = NULL 00401BEE |. FF15 1C304000 call dword ptr ds:[<&kernel32.#GetNamedPipeHandleState>; |\GetModuleHandleW 00401BF4 |. 50 push eax ; |hInst = 00400000 00401BF5 |. FF15 E4304000 call dword ptr ds:[<&user32.#160>] ; \DialogBoxParamW 00401BFB |. 5D pop ebp ; dumped_1.00401BFB 00401BFC \. C3 retn
整个函数的意思是sleep20s弹出广告,那就直接在开头retn
。保存,载入新程序。
去掉中央内置广告。查找字符串跟进
1 00401C4A |. 68 30364000 push dumped_1.00403630 ; http://www.52pojie.cn/portal.php
在数据窗口跟随403630
,用00填充 http://www.52pojie.cn/portal.php ,保存。但是主程序还是有这个框框,只是不显示页面而已。如果想要美观一点。可以用Restorator软件,将中间的框框的“可视”取消,F8提交更改,保存。
4. 修改版权和资源 用实例二DIY。
4.1 利用资源编辑器修改版权 同样用Restorator/ResEdit/ResHacker,修改主程序的文字信息。(因为在OD看不到主程序的文字信息)
4.2 利用API修改版权 修改右下角广告的文字信息。
SetDlgItemTextA/W:DialogBox控件设置文本
在中文搜索引擎找到关键句去到反汇编窗口
1 0040282F 68 181A5500 push 1_备份.00551A18 ; 我就是广告\r\n来把我干掉啊\r\n加油!
在命令窗口输入d 551A18
定位字符串,将想要写入的文字找个网页转换成十六进制。
1 62 11 4e 0d 66 2f 5e 7f 54 4a ff 0c 62 11 53 ea 66 2f 5c 0f 53 ef 72 31
由于PE文件是小端序的,所以将“6211”在OD里必须“1162”存放,以此类推。
1 11 62 0d 4e 2f 66 7f 5e 4a 54 0c ff 11 62 ea 53 2f 66 0f 5c ef 53 31 72
将多余的文字用00填充,写入的最好不要超过原本文字大小,以防产生各种问题。
4.3 利用十六进制编辑器修改 用C32asm/WinHEX修改。找到位置直接打16进制进去,目前我还没找到粘贴二进制数据的地方,所以只能手打。修改完后保存即可。
5. 汉化 在汉化时,要注意保留快捷键,比如&D、&F。
6. 增加弹窗 用Stud_PE载入程序,在函数那里找user32模块的MessageBoxA
函数,如果没有则右键->add new import,dll选择user32.dll的路径(在吾爱虚拟机中路径为C:\WINDOWS\system32\user32.dll),选择MessageBoxA
函数,添加到列表。RVA为1C3173
。
在区段那里新增一个区段。原始大小、虚拟大小为1000,区段数据选择“用空字节填充区段”。区段的RVA为1C4000
。再用OD载入去到5C4000
处编写代码。
MeaagexBoxA有4个参数:
1 2 3 4 5 WINUSERAPI int WINAPI MessageBoxA ( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) ;
在OD中,是从下往上push参数的。
1 2 3 4 5 push 0 ;0表示只有一个确认键 push 地址 ;标题 push 地址 ;文本 push 0 ;0表示没有父句柄 call dword ptr ds:[5C3173] ;MessageBoxA的VA地址
地址可以是这个区段任意某个位置。标题和文本在数据窗口修改。修改完后会自动在反汇编窗口补上代码。别忘了执行完MessageBoxA
后跳回OEP执行主程序。
复制到可执行文件,保存,用LoadPE或Stud_PE修改入口点为1C4000
。
MessageBoxW一样操作。