安全中国首页 > 文章中心 > 脱壳技术
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

Armadillo-手动脱变种的壳(图)

更新时间:2008-5-14 0:43:26
责任编辑:果果龙
热 点:

正如你能猜到的,Armadillo 储存了已经解码的内存块数量,以确保在任何时刻,并非所有的块都被同时解码到内存中。如果你查看"允许解码块数的最大值",你将会看到Armadillo通过把.text size除以1000h (单个内存块的大小)然后再除以2,来获得此值。这里你有两种方法, 给跳转打补丁以确保它始终跳转或者我们可以改变"允许解码块数的最大值"某些很大的值如1000h!!!!

看一下dump窗口

006106A4  C5 00 00 00 00 00 00 00  Å...

.text size187D90/1000/2=C5

 

做完这些后,按F12我们将在Armadillo"server"的调试循环中了。调试循环代码将产生页面异常的地址进行页对齐,并在005F7831 CALL 005F87A8解码。

注意:这是在找到OEP后单步顺着走下来的。

 

005F7773                     LOOP:                       

; 从这里开始强迫循环

005F7773   . 8B8D 2CFAFFFF  MOV ECX,DWORD PTR SS:[EBP-5D4]

; 解码整个代码段

005F7779   . 3B0D C43A6100  CMP ECX,DWORD PTR DS:[613AC4]

005F777F   . 0F8D C7000000  JGE getright.005F784C

;change to "jmp eip"当完成后进入死循环

005F7785   . 8B95 9CFAFFFF  MOV EDX,DWORD PTR SS:[EBP-564]

;SS:[EBP-564] =[ebp+trap_flag_not_set_flag]

;armadillo在开始之前设置了一个flag可以解码时ECX被置0

005F778B   . 81E2 FF000000  AND EDX,0FF

005F7791   . 85D2           TEST EDX,EDX

;its debug loop to check if it is being traced(edx=edx and 0FFh=000h)

005F7793   . 0F84 A9000000  JE getright.005F7842

; 现在检测flag!

005F7799   . 6A 00          PUSH 0

; instruct to 解码 code

005F779B   . 8BB5 2CFAFFFF  MOV ESI,DWORD PTR SS:[EBP-5D4]

SS:[EBP-5D4]= [ebp+mem_]

005F77A1   . C1E6 04        SHL ESI,4

005F77A4   . 8B85 2CFAFFFF  MOV EAX,DWORD PTR SS:[EBP-5D4]

SS:[EBP-5D4]= [ebp+mem_]

----------SNIP--------------- ; 解码 key Generation

005F781B   . 83E7 0F        AND EDI,0F                          

005F781E   . 03F7           ADD ESI,EDI 

 ;反汇编                       

005F7820   . 8B15 B43A6100  MOV EDX,DWORD PTR DS:[613AB4]          

005F7826   . 8D04B2         LEA EAX,DWORD PTR DS:[EDX+ESI*4]        

005F7829   . 50               PUSH EAX   

 ; push crypt_flag                         

005F782A   . 8B8D 2CFAFFFF  MOV ECX,DWORD PTR SS:[EBP-5D4]

SS:[EBP-5D4][ebp+mem_]

005F7830   . 51               PUSH ECX                                005F7831   . E8 720F0000    CALL getright.005F87A8

 call了005F87A8解码,进入这个call,走几步就到了005F88C7

也就是API WriteProcessMemory返回的地方<, /P>

005F7836   . 83C4 0C         ADD ESP,0C

你应该回到这里

005F7839   . 25 FF000000    AND EAX,0FF

005F783E   . 85C0            TEST EAX,EAX

这里打补丁去增加内存块的数量,变值强迫解码下一个内存块,然后跳回循坏

005F7840   . 74 0A           JE SHORT getright.005F784C

 

现在我们知道Armadillo如何为每个内存块 generates keys,然后把它传递解码routine 同样的, 我们可以理解为什么当我们单步跟踪调试"server-debugger code"Armadillo会悄无声息的退出了。这里,我们应该使得包含key generation routine的大loop去强迫armadillo 解码整个代码段。

 

首先,应该修改计数 byte 005F88EE   83C0 01 ADD EAX,1改为ADD EDX0,只改了一个byte。目的就是防止父进程把解码过的页面从新加密,并且确保005F8944   0F8E FA000000  JLE getright.005F8A44始终跳转去继续解码。DS:[6106A4]存放着允许解码块数的最大值,如果将其改为某个很大的值,那么内存会崩溃的。而且这个值本来就是对的正好对应了代码段的大小,所以不要动它。然后,在地址005F783E处,打两行补丁代码:

INC DWORD PTR SS:[EBP-5D4]

JMP LOOP:005F7773 ;跳回循环头

然后我们edit"ebp+mem_"处的值为0 (告诉Armadillo从第一个内存块开始解码) 并且设置终止点于 005F777F 通过改变那儿的指针为"jmp eip"。这儿Armadillo在检查内存块是否超过了代码段,我们简单的设了一个无限循环在那儿。让程序运行, 等一会儿以后启动LordPE dump 整个内存映像 如果LordPE 报告"Can’t grab memory"那么你可能做错了什么,Armadillo 没有完全解码代码段。完成这一步, 我们进入下一阶段rebuild IAT

另外,还有一个地方要注意,最好在OEP处挂起进程再dump,因为这时程序的初始化变量还没有被修改。大家可对比一下,当程序运行后dump出的文件和在OEPdump出的有何不同。

有时会修改PE头(本例未使用) 被加壳的程序运行后,用procdump没法dump出,会非法操作。用ring3的调试器没法 “attach”,用peditor dump出的文件是无效的exe。为什么呢?通过比较dump出的PE头, 发现偏移0x3C处被修改。重新装入,7ffdf002改字节。Bp WriteProcessMemory运行一下,断下后,设断400003c内存写入 ,运行 共修改3C和FE两处,参考有关PE头的资料,可知偏移3C的DWORD是PE表头的偏移(原值是F8)。偏移FE的WORD是sections 的个数(原值是8)。Armadillo故意将PE头改错,难怪没法dump出。解决方法:在41EF80下断点。中断后,将PE头改回,40003C处是000000F8,4000FE处是0008,注意高位在前!!! 

第二关Rebuild Import data

(四)修复IAT 

没什么方便的方法!:( 

我的方法是用peditor查看,得知IAT在426000处,下断点“bpm 426000 w” 在这停下: 

然后把[ESI]前后的内容保存下来,以后手工修复IAT时参考。 

LordPE打开dump 下来的文件然后研究section header 你将会发现import data应该在section.idata1 为什么因为名字name已经告诉了……你可以再确认一下,用Hex Workshop打开文件然后去那个section的偏移地址,你将会看到诸如"kernel32.dll" "user32.dll" 等等分散的字符…… Import data应该就在那儿!

我们的任务是找到API redirection routine 研究它,然后在此基础rebuild Import

为了找到IAT redirection routine,使用softice "addr"命令进入被保护子进程的领空,然后bpm IAT_address W(一旦中断,disable 这个断点)
bpx GetProcAddress(
一旦中断,disable 这个断点)
F12
两次,我们现在应该在这儿。

10006622 39 3D E8 C7 01 10          cmp dll_handle_tableedi                  

 00A4A496    load_next_dl_import:

那个dll_handle_Table看起来象这样的:

1001C7E8 18 C8 01 10     dd offset strKernel32_dll       

上一页 1 2 3 4 下一页

 
相关文章
一日一文章
 
一日一软件
一日一动画