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

Blaze Media Pro5.05脱壳+基本修复CC(int3)+破解(二)

更新时间:2008-4-23 0:26:11
责任编辑:池天
热 点:
下面我尝试着来修复CC。cc实际上就是int3指令,armadillo把程序中的一些跳转指令改成int3。子进程运行到int3时发生异常,父进程可以捕捉到,然后计算出子进程该不该跳转,如果跳转,跳转量是多少,如果不跳转,下一条指令应从哪里开始。通过getthreadcontext和setthreadcontext函数来干预子进程的运行。因此程序脱壳后,里面的int3指令不修复成原本的跳转指令,程序是不可能运行起来的。 

但问题是:脱壳程序中哪些cc是int3指令,哪些cc是数据呢?原先版本的armardillo可以完全区分开来,但现在的版本好像不能够区分,至少我没有找到方法,不知高手们是采用什么办法的。从技术角度来讲,armadillo可以不用区分。我们试想一下:armardillo可以把原程序中所有跳转指令都改成int3,然后连同程序中的cc数据一起进行计算得到一张总表。在加壳时却只随机选一些跳转指令改成int3,但使用的还是那张总表。程序完全可以运行。但我们怎么才能知道总表中哪些是跳转指令呢?我觉得不能,因此也就很难完美修复。 

我想到修复的方法有两种,一是在OD中运行加壳程序,设置条件记录断点,然后把程序所有的功能都运行一遍,得到子进程发生int3的地址。二是设计一代码分析器,分析脱壳程序中哪些是int3指令,哪些不是。这两种方法都不能算是完美修复。我的方法是借用OD来找到int3。 


我们的目标是得到四个表:int3地址表、跳转类型表、跳转量表及跳转指令长度表。有了这四个表,我们就可以修复cc了。 


我们先看第一张int3地址表。在od中打开脱壳程序,从401000~98cfff都是程序的内容,包括代码和资源。armadillo把它们放在同一节中。查找二进制55 8b ec(PUSH EBP  MOV EBP, ESP)找到代码开始的部分在5fe660。把5fe660~98cfff选上然后复制到文件中,用ultraedit打开文件,选上“列出包含字符串的行”,查找文本int3。ok,找到如下形式的int3: 

0060063E    CC              INT3 
0060063F    CC              INT3 
0060D481    CC              INT3 
0060D482    CC              INT3 
0060D483    CC              INT3 
..... 

使用ultraedit的列编辑功能编辑成: 

3E 06 60 00  
3F 06 60 00  
81 D4 60 00  
82 D4 60 00  
83 D4 60 00  
84 D4 60 00  
..... 

当然这里面有很多都是不符合条件的,是int3原始表。先保存好,下面要用。 


在OD中重新打开BMP.exe。下he GetThreadContext,运行,第二次停住时,看堆栈窗: 

0012DA78   009EBC88  /CALL to GetThreadContext from BMP.009EBC82 
0012DA7C   00000050  |hThread = 00000050 (window) 
0012DA80   0012E10C  \pContext = 0012E10C 

在follow in dump 来到0012E10C。按alt+f9回到用户空间。 


0012E1AC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................ 
0012E1BC  00 00 00 00 64 EE 12 00 DC 37 79 00 1B 00 00 00  ....d?.?y.... 
0012E1CC  46 02 00 00 24 EE 12 00 23 00 00 00 00 00 00 00  F..$?.#....... 

12e1c4处的7937dc就是子进程发生的第一个int3地址+1,我们可以用OD把脱壳程序打开看看,运行出的第一个错也是那。 0012E1CC处的246是子进程的Flag寄存器内容。 


009EBC82    CALL DWORD PTR DS:[<&KERNEL32.GetThreadC>;  
009EBC88    PUSH EAX                                  //停在这,这条指令到009EBCCA都是垃圾指令 
009EBC89    NOT EAX 
009EBC8B    BSWAP EAX 
009EBC8D    POP EAX 
009EBC8E    JNB SHORT BMP.009EBC90 
009EBC90    PUSHFD 
009EBC91    PUSHAD 


009EBCC1    MOV EAX, C80F9D61 
009EBCC6    NOT ECX 
009EBCC8    BSWAP EAX 
009EBCCA    NOT ECX 
009EBCCC    MOV DWORD PTR SS:[EBP-1468], 0 
009EBCD6    PUSH -1 
009EBCD8    PUSH 4 
009EBCDA    LEA EDX, DWORD PTR SS:[EBP-13AC]         ; [12e1c4]=7937dc,子进程发生int3的地址+1 
009EBCE0    PUSH EDX 
009EBCE1    CALL BMP.009D4F90                        ; 对int3地址运算 
009EBCE6    ADD ESP, 0C 
009EBCE9    MOV DWORD PTR SS:[EBP-1194], EAX         ; 运算结果 
009EBCEF    MOV EAX, DWORD PTR SS:[EBP-1194] 
009EBCF5    XOR EDX, EDX 
009EBCF7    MOV ECX, 10 
009EBCFC    DIV ECX                                  ; 运算结果除以10 
009EBCFE    MOV DWORD PTR SS:[EBP-1198], EDX         ; 取余数 
009EBD04    MOV EDX, DWORD PTR SS:[EBP-13AC]         ; int3地址+1 
009EBD0A    PUSH EDX 
009EBD0B    MOV EAX, DWORD PTR SS:[EBP-1198]         ; 前面得到的余数 
009EBD11    CALL DWORD PTR DS:[EAX*4+A15838]         ; 再次运算。 
009EBD18    ADD ESP, 4 
009EBD1B    MOV DWORD PTR SS:[EBP-1468], EAX         ; 运算结果,将用于在table1(int3地址计算结果表)中查找 
009EBD21   >MOV DWORD PTR SS:[EBP-146C], 0 
009EBD2B    MOV ECX, DWORD PTR SS:[EBP-1198] 
009EBD31    MOV EDX, DWORD PTR DS:[ECX*4+A176D4] 
009EBD38    MOV DWORD PTR SS:[EBP-118C], EDX 
009EBD3E    MOV EAX, DWORD PTR SS:[EBP-146C] 
009EBD44    CMP EAX, DWORD PTR SS:[EBP-118C] 
009EBD4A    JGE SHORT BMP.009EBDA8 
009EBD4C    MOV EAX, DWORD PTR SS:[EBP-118C] 
009EBD52    SUB EAX, DWORD PTR SS:[EBP-146C] 
009EBD58    CDQ 
009EBD59    SUB EAX, EDX 
009EBD5B    SAR EAX, 1 
009EBD5D    MOV ECX, DWORD PTR SS:[EBP-146C] 
009EBD63    ADD ECX, EAX 
009EBD65    MOV DWORD PTR SS:[EBP-1470], ECX 
009EBD6B    MOV EDX, DWORD PTR SS:[EBP-1198]         ; 前面得到的余数 
009EBD71    MOV EAX, DWORD PTR DS:[EDX*4+A1768C]     ; [A1768C]开始的是table1地址表,根据前面得到的余数找到table1的地址 
009EBD78    MOV ECX, DWORD PTR SS:[EBP-1470] 
009EBD7E    MOV EDX, DWORD PTR SS:[EBP-1468] 
009EBD84    CMP EDX, DWORD PTR DS:[EAX+ECX*4] 
009EBD87    JBE SHORT BMP.009EBD9A 
009EBD89    MOV EAX, DWORD PTR SS:[EBP-1470] 
009EBD8F    ADD EAX, 1 
009EBD92    MOV DWORD PTR SS:[EBP-146C], EAX 
009EBD98    JMP SHORT BMP.009EBDA6 
009EBD9A    MOV ECX, DWORD PTR SS:[EBP-1470] 
009EBDA0    MOV DWORD PTR SS:[EBP-118C], ECX 
009EBDA6    JMP SHORT BMP.009EBD3E 
009EBDA8    PUSHAD                                   ; eax=查表结果(前面运算结果在table1中的序号) 
009EBDA9    NOP                                                               
      
.......                                              //nop掉垃圾指令 
                                                          
009EBDCB    NOP                                                               
009EBDCC    NOP                                                               
009EBDCD    POPAD                                                            
009EBDCE    MOV EDX, DWORD PTR SS:[EBP-1198]          前面的余数                             
009EBDD4    MOV EAX, DWORD PTR DS:[EDX*4+A1768C]     ; table1地址             
009EBDDB    MOV ECX, DWORD PTR SS:[EBP-146C]                                  
009EBDE1    MOV EDX, DWORD PTR DS:[EAX+ECX*4]                                 
009EBDE4    CMP EDX, DWORD PTR SS:[EBP-1468]         ; 再比较一下,看是否相等 
009EBDEA    JNZ BMP.009EC102                                                  
   
........                                              // 垃圾指令      

  
009EBE47    MOV EAX, DWORD PTR SS:[EBP-1198]          前面的余数  
009EBE4D    MOV ECX, DWORD PTR DS:[EAX*4+A17714]     ; table2(跳转类型代号表) 
009EBE54    MOV EDX, DWORD PTR SS:[EBP-146C] 
009EBE5A    XOR EAX, EAX 
009EBE5C    MOV AL, BYTE PTR DS:[ECX+EDX]            ; 得到跳转类型代号 
009EBE5F    MOV DWORD PTR SS:[EBP-1488], EAX 
009EBE65    MOV EAX, DWORD PTR SS:[EBP-1488] 
009EBE6B    CDQ 
009EBE6C    AND EDX, 0F 
009EBE6F    ADD EAX, EDX 
009EBE71    SAR EAX, 4 
009EBE74    MOV DWORD PTR SS:[EBP-1480], EAX 
009EBE7A    MOV ECX, DWORD PTR SS:[EBP-1488] 
009EBE80    AND ECX, 8000000F 
009EBE86    JNS SHORT BMP.009EBE8D 
009EBE88    DEC ECX 
009EBE89    OR ECX, FFFFFFF0 
009EBE8C    INC ECX 
009EBE8D    MOV DWORD PTR SS:[EBP-1484], ECX 
009EBE93    MOV EDX, DWORD PTR SS:[EBP-1480] 
009EBE99    CMP EDX, DWORD PTR SS:[EBP-1484] 
009EBE9F    JNZ SHORT BMP.009EBEBC 
009EBEA1    MOV EAX, DWORD PTR SS:[EBP-1484] 
009EBEA7    ADD EAX, 1 
009EBEAA    AND EAX, 8000000F 
009EBEAF    JNS SHORT BMP.009EBEB6 
009EBEB1    DEC EAX 
009EBEB2    OR EAX, FFFFFFF0 
009EBEB5    INC EAX 
009EBEB6    MOV DWORD PTR SS:[EBP-1484], EAX 
009EBEBC    MOV ECX, DWORD PTR SS:[EBP-1488] 
009EBEC2    MOV EDX, DWORD PTR SS:[EBP-1480] 
009EBEC8    MOV EAX, DWORD PTR DS:[ECX*4+A16ED0] 
009EBECF    XOR EAX, DWORD PTR DS:[EDX*4+A1125C] 
009EBED6    MOV ECX, DWORD PTR SS:[EBP-1484] 
009EBEDC    XOR EAX, DWORD PTR DS:[ECX*4+A1125C] 
009EBEE3    MOV DWORD PTR SS:[EBP-1478], EAX 
009EBEE9    MOV EDX, DWORD PTR SS:[EBP-13A4]         ; 子进程context的flag寄存器内容 
009EBEEF    AND EDX, 0FD7 
009EBEF5    PUSH EDX 
009EBEF6    MOV EAX, DWORD PTR SS:[EBP-1488]         ; 跳转类型代号 
009EBEFC    MOVSX ECX, BYTE PTR DS:[EAX+A15730] 
009EBF03    CALL DWORD PTR DS:[ECX*4+A15838] 
009EBF0A    ADD ESP, 4 
009EBF0D    MOV DWORD PTR SS:[EBP-1474], EAX 
009EBF13    MOV EDX, DWORD PTR SS:[EBP-13B8]          子进程context的ecx内容         
009EBF19    PUSH EDX 
009EBF1A    MOV EAX, DWORD PTR SS:[EBP-1474] 
009EBF20    PUSH EAX 
009EBF21    CALL DWORD PTR SS:[EBP-1478] 
009EBF27    ADD ESP, 8 
009EBF2A    PUSH EAX 
009EBF2B    MOV ECX, DWORD PTR SS:[EBP-1488] 
009EBF31    MOVSX EDX, BYTE PTR DS:[ECX+A15730] 
009EBF38    CALL DWORD PTR DS:[EDX*4+A15878]            
009EBF3F    ADD ESP, 4 
009EBF42    MOV DWORD PTR SS:[EBP-147C], EAX 
009EBF48    MOV EAX, DWORD PTR SS:[EBP-147C] 
009EBF4E    AND EAX, 1 
009EBF51    TEST EAX, EAX                            //经过若干次复杂计算最后得到子进程在7937dc处是跳呢(eax=1),还是不跳(eax=0) 
009EBF53    JE BMP.009EC007 
009EBF59    PUSHAD 


009EBF7E    POPAD                      
009EBF7F    MOV ECX, DWORD PTR SS:[EBP-1198]           //如果eax=1,到这 
009EBF85    MOV ECX, DWORD PTR DS:[ECX*4+A1764C] 
009EBF8C    MOV EAX, DWORD PTR SS:[EBP-146C] 
009EBF92    XOR EDX, EDX 
009EBF94    MOV ESI, 10 
009EBF99    DIV ESI 
009EBF9B    MOV EAX, DWORD PTR SS:[EBP-146C] 
009EBFA1    MOV ECX, DWORD PTR DS:[ECX+EAX*4] 
009EBFA4    XOR ECX, DWORD PTR SS:[EBP+EDX*4-1170]    //得到跳转量 
009EBFAB    MOV EDX, DWORD PTR SS:[EBP-13AC]            
009EBFB1    ADD EDX, ECX 
009EBFB3    MOV DWORD PTR SS:[EBP-13AC], EDX          //重新设置context 

1 2 3 4 下一页

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