ACProtect 1.22b脱壳手记----NOTEPAD.EXE

[ 来源:http://www.91now.com/down/ | 作者: | 时间:2008-4-18 | 浏览: 人次 ]

来源:安全中国

ACProtect 1.22b脱壳手记----NOTEPAD.EXE 


目标:NOTEPAD.EXE,自己用ACProtect 1.22b专业版加壳,Compress Opetions里选Opetion1,Advanced Opetions的六个选项全选;加壳前49.7 KB,加壳后143 KB 

工具:OllyDbg Beta110b原版; ImportREC 1.6 FINAL 

破解平台:Win2000SP4 Chinese 

主要目的:跳过IAT加密,快速到达伪OEP,Replace Code的一些处理; 
    由于ASProtect的Stolen code已经被各位老大们搞的很透彻了,ACProtect的Stolen code的分析和修复没多大差别,所以我就不在罗嗦了(省的敲不少字呢,呵呵) 
     
    废话少说,开工 
——————————————————————————————————— 

用OllyDbg加载目标后,忽略所有异常,用插件IsDebuggerPresent隐藏调试器标志,程序停在这: 
01010000 >  60              PUSHAD 
01010001    66:8BCA         MOV CX,DX 
01010004    87C8            XCHG EAX,ECX 
01010006    41              INC ECX 
01010007    72 01           JB SHORT NOTEPAD_.0101000A 
01010009    43              INC EBX 
0101000A    48              DEC EAX 
0101000B    FC              CLD 
0101000C    50              PUSH EAX 
0101000D    E8 01000000     CALL NOTEPAD_.01010013 
01010012    7A 83           JPE SHORT NOTEPAD_.0100FF97 
01010014    C40458          LES EAX,FWORD PTR DS:[EAX+EBX*2] 
01010017    66:8BEE         MOV BP,SI 
0101001A    E8 01000000     CALL NOTEPAD_.01010020 
.                 ;从开头到01010BB6都是壳的分段解密,可以看准 
.            ;每段循环结束位置0F85 xxFFFFFF,用F4直接跳到下一循环 




01010BB6    4F              DEC EDI 
01010BB7    81F3 0503C769   XOR EBX,69C70305 
01010BBD    68 4F460000     PUSH 464F 
01010BC2    4E              DEC ESI 
01010BC3    59              POP ECX      ;ECX=464Fh,这段循环解密的dword数 
01010BC4    8B28            MOV EBP,DWORD PTR DS:[EAX]  ;循环开始,这是一个大循环,解密了从01010BEA 
01010BC6    03EB            ADD EBP,EBX      ;开始的(464Fh-1)*4=11938h字节 
01010BC8    C1C5 12         ROL EBP,12 
01010BCB    83C0 04         ADD EAX,4 
01010BCE    0328            ADD EBP,DWORD PTR DS:[EAX] 
01010BD0    83C0 FC         ADD EAX,-4 
01010BD3    8928            MOV DWORD PTR DS:[EAX],EBP 
01010BD5    81F3 B2A9C00F   XOR EBX,0FC0A9B2 
01010BDB    81C0 04000000   ADD EAX,4 
01010BE1    83E9 01         SUB ECX,1 
01010BE4  ^ 0F85 DAFFFFFF   JNZ NOTEPAD_.01010BC4 
01010BEA    116C95 AB       ADC DWORD PTR SS:[EBP+EDX*4-55],EBP   ;在这下硬件执行断点 
01010BEE    53              PUSH EBX 
01010BEF  ^ 79 91           JNS SHORT NOTEPAD_.01010B82 

上面的循环结束后01010BEA处变为 
01010BEA   /E9 A9180100     JMP NOTEPAD_.01022498  ;这个JMP远距离跳到壳真正开始工作的地方 
01010BEF   |0000            ADD BYTE PTR DS:[EAX],AL 
01010BF1   |0000            ADD BYTE PTR DS:[EAX],AL 
01010BF3   |0000            ADD BYTE PTR DS:[EAX],AL 
01010BF5   |0000            ADD BYTE PTR DS:[EAX],AL 
01010BF7   |0000            ADD BYTE PTR DS:[EAX],AL 


在01010BEA上点右键,Folllow Dump->Selection,在内存窗口里搜索HEX:4D4D4D4D,找到如下: 
01010F19  4D 4D 4D 4D C5 73 FE FF D2 73 FE FF 00 00 00 00  MMMM舠?襰?.... 
01010F29  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
01010F39  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
01010F49  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
01010F59  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 

01010F19就是ACProtect在后面开始处理Stolen code时放置0006FFF0(即OD刚加载程序时的EBP,一般程序多数是0012FFF0,NOTEPAD.EXE有点特殊),在01010F19下硬件访问断点,目的是快速到达处理Stolen code的地方 


——————————————————————————————————— 

2.跳过IAT加密 

在GetProcAddress入口处下硬件断点,也可以在GetProcAddress入口处跳过一字节后用F2下普通断点.F9运行,会在GetProcAddress上断下,堆栈显示的是GlobalAlloc,这是壳自己用到的API,一共23个,依次是 
GlobalAlloc.GlobalFree.GetCurrentProcessId.CreateToolhelp32Snapshot.Process32First.Process32Next.CloseHandle.CreateFileA.TerminateProcess.IsDebuggerPresent.OpenProcess.ReadFile.WriteFile.FreeLibrary.GetTempPathA.UnhandledExceptionFilter.GetThreadContext.SetThreadContext.GetCurrentThread.EnumWindows.GetWindowTextA.GetClassNameA.PostMessageA 
     一直按F9运行,在处理过PostMessageA后,就开始处理程序的API,堆栈和寄存器都会有个较大的变化,断下后,是处IsProcessorFeaturePresent,Return to msvcrt.78001EAA,继续F9,直到堆栈第一次显示Return to NOTEPAD.XXXXX,这时处理的是FindTextW,取消GetProcAddress的硬件执行断点,Ctrl+F9运行返回到壳里 

PS:如果被加壳的程序是用Delphi或BCB写的话,在PostMessageA后处理的下一个API,堆栈显示就是返回到壳程序,但VC++的程序在处理完PostMessageA后还会由Kenrel调用GetProcAddress处理一些msvcrt,COMCTL32等里的一 
些API,所以必须等处理完这些API后,在壳调用GetProcAddress处理程序原来的API时才能Ctrl+F9返回到壳里 

Ctrl+F9运行返回后: 
0102201B    53               PUSH EBX 
0102201C    FFB5 29DE4000    PUSH DWORD PTR SS:[EBP+40DE29]    
01022022    FF95 80B04100    CALL DWORD PTR SS:[EBP+41B080]   ;Call GetProcAddress 
01022028    3B9D 31DE4000    CMP EBX,DWORD PTR SS:[EBP+40DE31];Ctrl+F9返回到这里,EBP=00C0F000 
0102202E    7C 0F            JL SHORT NOTEPAD_.0102203F        ;所以GetProcAddress的地址是 
01022030    90               NOP            ;EBP+41B080=102A080,记下这个地址! 
01022031    90               NOP 
01022032    90               NOP 
01022033    90               NOP 
01022034    60               PUSHAD 
01022035    2BC0             SUB EAX,EAX 
01022037    8803             MOV BYTE PTR DS:[EBX],AL 
01022039    43               INC EBX 
0102203A    3803             CMP BYTE PTR DS:[EBX],AL 
0102203C  ^ 75 F9            JNZ SHORT NOTEPAD_.01022037 
0102203E    61               POPAD 
0102203F    0BC0             OR EAX,EAX 
01022041  ^ 0F84 21FFFFFF    JE NOTEPAD_.01021F68    ;EAX=刚才GetProcAddress得到的API的入口 
01022047    3B85 90B04100    CMP EAX,DWORD PTR SS:[EBP+41B090];EBP+41B090指向MessageBox 
0102204D    75 0A            JNZ SHORT NOTEPAD_.01022059   ;① 这里把得到的API入口与MessageBox 
0102204F    90               NOP                      ;比较,相等就用壳的MessageBox来代替 
01022050    90               NOP                      ;程序的MessageBox,把①处的JNZ改为JMP 
01022051    90               NOP                      ;即可跳过ACProtect对MessageBox作的手脚 
01022052    90               NOP 
01022053    8D85 D4E34000    LEA EAX,DWORD PTR SS:[EBP+40E3D4] 
01022059    56               PUSH ESI 
0102205A    FFB5 29DE4000    PUSH DWORD PTR SS:[EBP+40DE29] 
01022060    5E               POP ESI 
01022061    39B5 FA234000    CMP DWORD PTR SS:[EBP+4023FA],ESI 
01022067    74 15            JE SHORT NOTEPAD_.0102207E 
01022069    90               NOP 
0102206A    90               NOP 
0102206B    90               NOP 
0102206C    90               NOP 
0102206D    39B5 FE234000    CMP DWORD PTR SS:[EBP+4023FE],ESI 
01022073    74 09            JE SHORT NOTEPAD_.0102207E 
01022075    90               NOP 
01022076    90               NOP 
01022077    90               NOP 
01022078    90               NOP 
01022079    EB 63            JMP SHORT NOTEPAD_.010220DE 
0102207B    90               NOP 
0102207C    90               NOP 
0102207D    90               NOP 
0102207E    80BD 90304100 00 CMP BYTE PTR SS:[EBP+413090],0 
01022085    74 57            JE SHORT NOTEPAD_.010220DE 
01022087    90               NOP 
01022088    90               NOP 
01022089    90               NOP 
0102208A    90               NOP 
0102208B    EB 07            JMP SHORT NOTEPAD_.01022094 
0102208D    90               NOP 
0102208E    90               NOP 
0102208F    90               NOP 
01022090    0100             ADD DWORD PTR DS:[EAX],EAX 
01022092    0000             ADD BYTE PTR DS:[EAX],AL 
01022094    8BB5 F6DE4000    MOV ESI,DWORD PTR SS:[EBP+40DEF6]       ;EBP+40DEF6指向Acpr要转移API的地方 
0102209A    83C6 0D          ADD ESI,0D 
0102209D    81EE EA1B4000    SUB ESI,401BEA 
010220A3    2BF5             SUB ESI,EBP 
010220A5    83FE 00          CMP ESI,0 
010220A8    7F 34            JG SHORT NOTEPAD_.010220DE  ;② 不跳就把API转移到[EBP+40DEF6] 
010220AA    90               NOP                      ;所以把②处的JG改为JMP即可跳过Acpr 
010220AB    90               NOP                      ;对IAT的加密! 

广告位