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

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

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

0012F010  40 85 53 00 )

附录:附上部分DEBUG_EVENT结构的声明:(注释是我加的) 

typedef struct _DEBUG_EVENT {  

  DWORD dwDebugEventCode;  //偏移0x0  

  DWORD dwProcessId;      //偏移0x4 

  DWORD dwThreadId;        //偏移0x8 

  union { 

      EXCEPTION_DEBUG_INFO Exception;    //偏移0xC 

      CREATE_THREAD_DEBUG_INFO CreateThread; 

      CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; 

      EXIT_THREAD_DEBUG_INFO ExitThread; 

      EXIT_PROCESS_DEBUG_INFO ExitProcess; 

      LOAD_DLL_DEBUG_INFO LoadDll; 

      UNLOAD_DLL_DEBUG_INFO UnloadDll; 

      OUTPUT_DEBUG_STRING_INFO DebugString; 

      RIP_INFO RipInfo;  

  } u; 

} DEBUG_EVENT, *LPDEBUG_EVENT; 

 

typedef struct _EXCEPTION_DEBUG_INFO { //即异常代码是0x00000001时的结构 

  EXCEPTION_RECORD ExceptionRecord;      //偏移0xC;0x80000001为STATUS_GUARD_PAGE_VIOLATION(NT) 

                                        //0xC0000005为STATUS_ACCESS_VIOLATION(WIN (win 9x) 

  DWORD dwFirstChance; 

} EXCEPTION_DEBUG_INFO, *LPEXCEPTION_DEBUG_INFO; 

 

typedef struct _EXCEPTION_RECORD { 

  DWORD ExceptionCode;              //偏移0xc 

  DWORD ExceptionFlags;              //偏移0x10 

  struct _EXCEPTION_RECORD *ExceptionRecord;  //偏移0x14 

  PVOID ExceptionAddress;              //偏移0x18 

  DWORD NumberParameters; 

  ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; 

} EXCEPTION_RECORD, *PEXCEPTION_RECORD;

 

[方法三]bpx SetProcessWorkingSetSize(使用DriverSuite2.7中的softice4.2.7

bpx SetProcessWorkingSetSize去找OEP 一旦softice中断了,检查softice是否在Get Right的领空,如果不在则按F5直到softiceGet Right 的领空中断。然后按F12辅之以F10跟踪过去一些指令,直到你看到一个"call edi"指令,停在那儿,然后写下edi的值。那就是OEP

 

第三步,进入调试循环并打补丁

移除所有断点,然后"bpx WriteProcessMemory"。按F5,一旦softice中断按F12 两次你将会在通常所谓的Armadillo的解码routine 这个你在先前的Armadillo版本中已经见过的。                

005F88C7   6A 00           PUSH 0      

 flag如果是0表明解码如果是1 encrypt

005F88C9   8B4D 0C        MOV ECX,DWORD PTR SS:[EBP+C]

mov ecx [ebp+key_address]         

005F88CC   51              PUSH ECX                                

005F88CD   8B55 08        MOV EDX,DWORD PTR SS:[EBP+8]

mov edx [ebp+]           

005F88D0   52              PUSH EDX                                

005F88D1   E8 76010000   CALL getright.005F8A4C 

<--这里CALL 005F8A4C对异常页解码,005F8A4C其实是用来加解码的,还有另外一个地方调用了它,用来重新加密或者破坏已使用的块来避免被dump解码 CALL= 5F88D1 加密 CALL = 5F8A24

005F88D6   83C4 0C        ADD ESP,0C

;==你应该返回到这里!!!!

005F88D9   25 FF000000    AND EAX,0FF

005F88DE   85C0           TEST EAX,EAX

005F88E0   75 07          JNZ SHORT getright.005F88E9

;解码成功?

005F88E2   32C0           XOR AL,AL

005F88E4   E9 5D010000    JMP getright.005F8A46

 

简要分析005F88D1处的解码函数“CALL getright.005F8A4C”。以下是它的流程: 

1。调用VirtualProtectEx将异常页面属性改为PAGE_READWRITE 

2。调用ReadProcessMemory,将异常页面读入 

3。解码。 

4。调用WriteProcessMemory,写入正确代码。 

5。调用VirtualProtectEx将页面属性改为PAGE_EXECUTE_READ

 

试着在这些指令间循环以迫使它解码所有的代码段然后你将会得到一堆垃圾,因为现在每1000h bytes 的内存块都有一个不同的解码 key。所以我们将必须去找出解码 key的产生routine。再继续跟踪你将会看到:

 

005F88E9   A1 C83A6100    MOV EAX,DWORD PTR DS:[613AC8]

;<==注意!!! DS:[613AC8]存放有已解码的块数,[613AC8]是一个记数器,解码成功后加一,有什么用呢?看后面

005F88EE   83C0 01        ADD EAX,1

005F88F1   A3 C83A6100    MOV DWORD PTR DS:[613AC8],EAX

已经解码内存块数量加1

--------SNIP-----------

005F8938   8B15 C83A6100  /MOV EDX,DWORD PTR DS:[613AC8]

把已经解码的块的数量给  EDX,用于当解码块时比较

005F893E   3B15 A4066100  |CMP EDX,DWORD PTR DS:[6106A4]

DS:[6106A4]存放着允许解码块数的最大值

005F8944   0F8E FA000000  |JLE getright.005F8A44

当小于时继续解码,如果大于,则不跳,前往5F8A24执行加密CALL

上一页 1 2 3 4 下一页

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