首页
社区
课程
招聘
[原创]Pe-Panzer外壳分析
2012-5-19 17:38 8491

[原创]Pe-Panzer外壳分析

2012-5-19 17:38
8491
Pe-Panzer分析

今天看见这个帖子被莫名其妙的顶了上来。所以下载下来分析一下。
原贴:http://bbs.pediy.com/showthread.php?t=142151

对作者的友情提醒:
---------------
push    4    //PAGE_READWRITE,请修改为40(PAGE_EXECUTE_READWRTE),这样记事本就不会崩溃了。
push    1000
push    dword ptr [ebp+D0]
push    0
call    dword ptr [ebp+F9]  ; kernel32.VirtualAlloc,您的第一次新加入的区段代码中的第一次调用。
------------------------------------------------
以下是正文:

新加的区段比较好过。以主程序为例:
00440079 >  60              pushad
0044007A    2BD2            sub     edx, edx
0044007C    85D2            test    edx, edx
0044007E    74 03           je      short 00440083
00440080    75 00           jnz     short 00440082
00440082    E8 E8000000     call    0044016F
00440087    005F 8D         add     byte ptr [edi-73], bl
0044008A    7F 23           jg      short 004400AF
0044008C    8BF7            mov     esi, edi
0044008E    33C9            xor     ecx, ecx
00440090    8D89 05040000   lea     ecx, dword ptr [ecx+405]
00440096    C1E9 02         shr     ecx, 2
00440099    BA 60140000     mov     edx, 1460
0044009E    83FA 00         cmp     edx, 0
004400A1    74 08           je      short 004400AB
004400A3    AD              lods    dword ptr [esi]
004400A4    33C2            xor     eax, edx
004400A6    33C1            xor     eax, ecx
004400A8    AB              stos    dword ptr es:[edi]
004400A9  ^ E2 F8           loopd   short 004400A3
004400AB    8961 00         mov     dword ptr [ecx], esp  在这里F4再F7

继续往下到这里:

004401C2    55              push    ebp
004401C3    FFB5 BC000000   push    dword ptr [ebp+BC]
004401C9    53              push    ebx
004401CA    E8 57000000     call    00440226  F7进入
004401CF    50              push    eax
004401D0    53              push    ebx
004401D1    E8 2F020000     call    00440405
004401D6    5A              pop     edx
004401D7    55              push    ebp
004401D8    FFE2            jmp     edx    等我们从上面440226返回之后在这里点F4再F8

00440226    60              pushad
00440227    8B6C24 2C       mov     ebp, dword ptr [esp+2C]
0044022B    8D85 C4000000   lea     eax, dword ptr [ebp+C4]
00440231    8B10            mov     edx, dword ptr [eax]
00440233    8D85 C0000000   lea     eax, dword ptr [ebp+C0]
00440239    8B18            mov     ebx, dword ptr [eax]
0044023B    52              push    edx
0044023C    B9 00000000     mov     ecx, 0
00440241    8D89 8C030000   lea     ecx, dword ptr [ecx+38C]
00440247    C1E9 02         shr     ecx, 2
0044024A    BA D686C60D     mov     edx, 0DC686D6
0044024F    8DB5 24010000   lea     esi, dword ptr [ebp+124]
00440255    AD              lods    dword ptr [esi]
00440256    33C2            xor     eax, edx
00440258    33C1            xor     eax, ecx
0044025A    8BD0            mov     edx, eax
0044025C  ^ E2 F7           loopd   short 00440255
0044025E    95              xchg    eax, ebp
0044025F    5A              pop     edx
00440260    8B4C24 28       mov     ecx, dword ptr [esp+28]
00440264    C1E9 02         shr     ecx, 2
00440267    8B7C24 24       mov     edi, dword ptr [esp+24]
0044026B    8B7424 24       mov     esi, dword ptr [esp+24]
0044026F    8D80 DA010000   lea     eax, dword ptr [eax+1DA]
00440275    50              push    eax
00440276    64:FF35 0000000>push    dword ptr fs:[0]
0044027D    64:8925 0000000>mov     dword ptr fs:[0], esp
00440284    92              xchg    eax, edx      F4到这里
00440285    60              pushad         
00440286    66:9C           pushfw
00440288    804C24 01 01    or      byte ptr [esp+1], 1
0044028D    66:9D           popfw
0044028F    61              popad
00440290    90              nop          新建EIP
00440291    33D3            xor     edx, ebx
00440293    33D1            xor     edx, ecx
00440295    33D5            xor     edx, ebp
00440297    AD              lods    dword ptr [esi]
00440298    33C2            xor     eax, edx
0044029A    AB              stos    dword ptr es:[edi]
0044029B  ^ E2 F4           loopd   short 00440291
0044029D    64:8F05 0000000>pop     dword ptr fs:[0]
004402A4    83C4 04         add     esp, 4
004402A7    61              popad
004402A8    C2 0C00         retn    0C        F4到这里再F8返回。

然后就是真正的壳处理部分了。详细写太麻烦,我就简单的贴笔记了。

003C0000    E8 00000000     call    003C0005
003C0005    5A              pop     edx
003C0006    83EA 05         sub     edx, 5    这段自定位就不说了。
003C0009    5D              pop     ebp
003C000A    8B82 A3050000   mov     eax, dword ptr [edx+5A3]  这里看起来像一个结构,中间我们会不断地得出这个结构的部分成员信息。
003C0010    0BC0            or      eax, eax
003C0012    74 06           je      short 003C001A
003C0014    61              popad
003C0015    E9 1C040000     jmp     003C0436
003C0436    68 00000000     push    0
003C043B    C3              retn

[edx+5A3]  bIsInitialized
----------------------------------------------
003C001A    B9 03000000     mov     ecx, 3
003C001F    8D75 28         lea     esi, dword ptr [ebp+28]
003C0022    8DBA 7F050000   lea     edi, dword ptr [edx+57F]
003C0028    8B06            mov     eax, dword ptr [esi]
003C002A    8907            mov     dword ptr [edi], eax
003C002C    83C6 04         add     esi, 4
003C002F    83C7 04         add     edi, 4
003C0032  ^ E2 F4           loopd   short 003C0028

ebp+28  440028  pfn_GetProcAddress
  44002C  pfn_GetModuleHandleA
  440030  pfn_LoadLibraryA
copy to edx+57F
  3C057F  pfn_GetProcAddress
  3C0583  pfn_GetModuleHandleA
  3C0587  pfn_LoadLibraryA
------------------------------------------------
003C00D3    8B82 CC050000   mov     eax, dword ptr [edx+5CC]
003C00D9    83E0 01         and     eax, 1
003C00DC    0BC0            or      eax, eax
003C00DE    74 0E           je      short 003C00EE
003C00E0    0F31            rdtsc
003C00E2    91              xchg    eax, ecx
003C00E3    0F31            rdtsc
003C00E5    2BC1            sub     eax, ecx
003C00E7    3D FF000000     cmp     eax, 0FF
003C00EC    7F 1B           jg      short 003C0109  //GameOver if jump
利用时间差检测是否在虚拟机种运行。
---------------------------------------------

下面基本的思路是看汇编代码,然后还原为C实现,然后推断成员的含义。

3C00BB:
if([ebp+4AB]==0) [ebp+59B]=pfn_GetModuleHandleA(NULL)
ebp+59B  ThisImageBase

3C00EE:
if (!(hKernel32=pfn_GetModuleHandleA((ebp+5AB)))) hKernel32=pfn_LoadLibraryA((ebp+5AB))
ebp+5AB  "KERNEL32.dll"

3C0108:
[ebp+5A7]=pfn_GetProcAddress(hKernel32,(ebp+5B8))
ebp+5B8 "VirtualFree"

ebp+5A7 pfn_VirtualFree

3C0141:
unsigned int i=0;
while(!(orgSectionDescribeTable[i].VirtualSize))
{
  pDecodeBuffer=pfn_VirtualAlloc(NULL,orgSectionDescribeTable[i].VirtualSize,MEM_COMMIT,PAGE_READWRITE);
  pDeCryptCodeRoutine(ThisImageBase+orgSectionDescribeTable[i].VirtualAddress,orgSectionDescribeTable[i].CryptedBufferSize,pPackerStart);
  pDecompressRoutine(ThisImageBase+orgSectionDescribeTable[i].VirtualAddress,pDecodeBuffer);
  memcpyn(ThisImageBase+orgSectionDescribeTable[i].VirtualAddress,pDecodeBuffer,orgSectionDescribeTable[i].VirtualSize);
  pfn_VirtualFree(pDecodeBuffer,0,MEM_RELEASE);
  i++;
}

3C017F:
[ebp+5D4]=[ebp+4A3]  2DB
pAPI_Steal_Buffer

[ebp+5D8]=[ebp+4A3]  2DB
saved_pAPI_Steal_Buffer

3C0191:
if (*pAPI_Steal_Buffer==2DB) PBYTE pAPI_Steal_Buffer=(PBYTE)pfn_VirtualAlloc

(NULL,0x2E7C,MEM_COMMIT,PAGE_READWRITE);
ebp+5D4  pAPI_Steal_Buffer

[ebp+5DC]=[ebp+5D8];
dAPI_StealMark

3C01BD:
if (!Is_ImportHooked)
{
  run when option IsImportTableHOOK is not checked
}

3C025B:
PBYTE pstrName;
if (pstrName=((*pInformationTable)pIAT+pInformationTable))  //first 0xc008
{
  DWORD* pImportAddr=ThisImageBase+*((*pInformationTable).pIAT+pInformationTable);
  pstrName+=5;
  if (*(pstrName+6)=='3' ||*(pstrName+6)=='2')  (*pInformationTable).FucntionStealMark='2'; //ebp+5E4,对抗策略,方式1
  DWORD hLibrary=Macro_GMH_LB(pstrName); //if GetModuleHandle Failed, then call LoadLibraryA
  pstrName+=*(pstrName-1);
  DWORD APICount=*(DWORD*)(pstrName);
  pstrName+=sizeof(DWORD);
  do
  {
    if(*(pstrName))  //Length of this API Name
    {  //Ordinal value Mode
      pstrName++;
      *pImportAddr=pMyGetProcAddress(hLibrary,pstrName,pfn_LoadLibrayA);
      pstrName+=sizeof(DWORD);
    }
    else
    {  //Name Mode
      pstrName++;
      *pImportAddr=pMyGetProcAddress(hLibrary,*(DWORD*)(pstrName),pfn_LoadLibrayA);
      pstrName+=*(pstrName-1)+1;
    }
    if ((*pInformationTable).dAPI_StealMark==2DB || (*pInformationTable).FucntionStealMark)
    {
      *pAPI_Steal_Buffer=0x60;  //pushad
      *(pAPI_Steal_Buffer+1)=0xe8;  //call Imm32
      *(DWORD*)(pAPI_Steal_Buffer+2)=pApiJmpRoutine-(pAPI_Steal_Buffer+2);  //pApiJmpRoutine=(ebp+46c)
      *(DWORD*)(pAPI_Steal_Buffer+6)=ApiAddrXorKey ^ *pImportAddr;
      *pImportAddr=pAPI_Steal_Buffer;//对抗策略,方式2
      pAPI_Steal_Buffer+=10;
    }
    if (!Is_ImportHooked)//[ebp+5e0]
    {
      saved_pAPI_Steal_Buffer=pAPI_Steal_Buffer-10;
      Is_ImportHooked=Ture;
    }
    pImportAddr++;
    APICount--;
  }while(APICount)
  
}
--------------------------------------------------

3C0374:
PBYTE RelocInfo=RelocDescribeTable+ThisImageBase;
DWORD RelocAdder=ThisImageBase-org_ImageBase;
do
{
  PBYTE* prevRelocAddr=0
  if (*RelocInfo==3)
  {
    RelocInfo++;
    prevRelocAddr=(PBYTE)(*(DWORD*)RelocInfo+ThisImageBase)
    *(DWORD*)prevRelocAddr+=RelocAdder;
    RelocInfo+=sizeof(DWORD);
  }
  else
  {
    RelocInfo++;
    prevRelocAddr+=*(RelocInfo-1);
    *(DWORD*)prevRelocAddr+=RelocAdder;
  }
}
while (*RelocInfo)
--------------------------------------------------
3C03B1:
__asm{
push    dword ptr fs:[30]
pop     eax        //TEB.PEB
mov     eax, dword ptr [eax+C]    //PEB.LoaderData
mov     eax, dword ptr [eax+C]    //PEB.LoaderData.InLoadOrderModuleList
mov     dword ptr [eax+20], 1000  //LDR_MODULE.SizeOfImage=1000,antidump
}
do anti via PEB. if Failed, used GetModuleHandle(0), if still failed(edx < 80000000), skip this anti.
---------------------------------------------------
3C03E8:JMP via SEH
003C03E8    55              push    ebp
003C03E9    8D85 13040000   lea     eax, dword ptr [ebp+413]  //3C0413
003C03EF    50              push    eax
003C03F0    8D85 3C040000   lea     eax, dword ptr [ebp+43C]  //3C043C
003C03F6    50              push    eax
003C03F7    64:FF35 0000000>push    dword ptr fs:[0]
003C03FE    64:8925 0000000>mov     dword ptr fs:[0], esp
003C0405    CD 02           int     2        //异常,触发3C043C的处理函数
003C0407    90              nop

003C043C    55              push    ebp
003C043D    8BEC            mov     ebp, esp
003C043F    60              pushad
003C0440    8B75 08         mov     esi, dword ptr [ebp+8]
003C0443    8B7D 10         mov     edi, dword ptr [ebp+10]
003C0446    8B45 0C         mov     eax, dword ptr [ebp+C]
003C0449    FF70 08         push    dword ptr [eax+8]    //3C0413
003C044C    8F87 B8000000   pop     dword ptr [edi+B8]    //改写EIP
003C0452    FF70 0C         push    dword ptr [eax+C]
003C0455    8F87 B4000000   pop     dword ptr [edi+B4]
003C045B    50              push    eax
003C045C    8F87 C4000000   pop     dword ptr [edi+C4]
003C0462    61              popad
003C0463    B8 00000000     mov     eax, 0
003C0468    C9              leave
003C0469    C2 1000         retn    10

003C0413    64:8F05 0000000>pop     dword ptr fs:[0]
003C041A    83C4 0C         add     esp, 0C
003C041D    FF85 A3050000   inc     dword ptr [ebp+5A3]    //bIsInitialized=1,避免重复执行
003C0423    8B85 9F040000   mov     eax, dword ptr [ebp+49F]
003C0429    0385 9B050000   add     eax, dword ptr [ebp+59B]
003C042F    0185 37040000   add     dword ptr [ebp+437], eax         ; PE-panze.00407370
003C0435    61              popad
003C0436    68 00000000     push    0        //上面的数值改写到了这里。
003C043B    C3              retn        //jmp oep

---------------------------------------------------
成员整理:
003C049F  00007370  OrgEntryPoint
003C04A3  000002DB  ImportTableHOOK_Mark
003C04A7  000005E8  pImportTable
003C04AB  00000000  
003C04AF  0003F000  RelocDescribeTable  //这里的数据含义请参照代码3C0374的C语言实现。
003C04B3  00400000  org_ImageBase
003C04B7  0000B000  orgSectionDescribeTable[org_NumofSection]
struct SectionDescribeTable
{
  DWORD  VirtualSize;
  DWORD  VirtualAddress;
  DWORD  CompressedBufferSize;
  DWORD  CryptedBufferSize;
}
003C04BB  00001000  
003C04BF  00007000  
003C04C3  000061CD  
003C04C7  00002000  第二个区段
003C04CB  0000C000  
003C04CF  00001000  
003C04D3  00000243  
003C04D7  00005000  第三个区段
003C04DB  0000E000  
003C04DF  00001000  
003C04E3  000007D9  
003C04E7  00021418  第4个区段
003C04EB  000133B0  
003C04EF  0001E62C  
003C04F3  0001E62C  
003C04F7  00001000  第5个区段
003C04FB  0003F000  
003C04FF  00001000  
003C0503  0000001E  
003C0507  00000000  
003C050B  00000000  
003C050F  00000000  
003C0513  00000000  
003C0517  00000000  
003C051B  00000000  
003C051F  00000000  
003C0523  00000000  
003C0527  00000000  
003C052B  00000000  
003C052F  00000000  
003C0533  00000000  
003C0537  00000000  
003C053B  00000000  
003C053F  00000000  
003C0543  00000000  
003C0547  00000000  
003C054B  00000000  
003C054F  00000000  
003C0553  00000000  
003C0557  00000000  
003C055B  00000000  
003C055F  00000000  
003C0563  00000000  
003C0567  00000000  
003C056B  00000000  
003C056F  00000000  
003C0573  00000000  
003C0577  00000000  
003C057B  00000000  
003C057F  7C80AE40  pfn_GetProcAddress
003C0583  7C80B741  pfn_GetModuleHandleA
003C0587  7C801D7B  pfn_LoadLibraryA
003C058B  004402AB  MyGetProcAddress(hLibrary,pstrName,pfn_LoadLibrayA)
003C058F  00440226  pDeCryptCodeRoutine
003C0593  77D507EA  pfn_MessageBoxA   
003C0597  7C809AF1  pfn_VirtualAlloc
003C059B  00400000  ThisImageBase
003C059F  00440405  pDecompressRoutine  //aPLib
003C05A3  00000001  bIsInitialized
003C05A7  7C809B84  pfn_VirtualFree
003C05AB  "KERNEL32.dll"
003C05B8  "VirtualFree"
003C05C4  00001062  unknown,unused
003C05C8  00000FC9  ApiAddrXorKey
003C05CC  0000003F  Mark_FutureUsed  
High bit
0
1  IsSelfFileCheck
1  IsConfusePEHeader
1  IsImportTableHOOK
1  IsSDK
1  IsRandomKEY
1  IsAntiVM, vm detect via rdtsc
Low bit

003C05D0  00440000  pPackerStart
003C05D4  003D02EE  pAPI_Steal_Buffer
003C05D8  003D0000  saved_pAPI_Steal_Buffer  
003C05DC  000002DB  dAPI_StealMark
003C05E0  0000004B  Is_ImportHooked
003C05E4  00000000  
003C05E8  0000C008  API填充位置
003C05EC  0C        下一个字符串的长度
003C05ED  "KERNEL32.dll"
003C05FA  00000049  这个DLL中需要导入的函数数目
003C05FE  15        下一个字符串的长度
003C05FD  "GetPrivateProfileIntA"
003C0615  1A        下一个字符串的长度
003C0616  "WritePrivateProfileStringA"
...
END

SDK是内联函数,这个可以使用SDK的字节代码去匹配起止地址,然后调用SDKOnlyOnceStart相同的代码去解码。

文章结束。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 6
打赏
分享
最新回复 (12)
雪    币: 316
活跃值: (128)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
心如止境 2 2012-5-19 18:03
2
0
占楼膜拜!!!!!!!!!
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
liuyq 2012-5-19 18:28
3
0
楼主 辛苦了。
雪    币: 23
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小P孩儿 2012-5-19 18:29
4
0
好吧占个二楼。。。
雪    币: 1689
活跃值: (380)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
hackerlzc 10 2012-5-19 20:21
5
0
只能后排了,今天被人拉走了。哎,不过还算幸运。
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mumaren 2012-5-19 21:23
6
0
楼主 辛苦了。

3q
雪    币: 408
活跃值: (151)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
小小的心 2 2012-5-20 12:42
7
0
这个贴有含量~~~
雪    币: 219
活跃值: (738)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
viphack 4 2012-5-21 08:21
8
0
mark  一下
雪    币: 6
活跃值: (980)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lookzo 2012-5-21 16:05
9
0
膜拜lz,占楼学习
雪    币: 10332
活跃值: (2370)
能力值: ( LV5,RANK:71 )
在线值:
发帖
回帖
粉丝
joker陈 2012-5-21 17:59
10
0
无聊的菜鸟真“无聊”。
膜拜啦。
雪    币: 182
活跃值: (111)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Aaah 2012-5-21 21:27
11
0
分析的真详细,写作风格真是清晰,好到极点
雪    币: 107
活跃值: (311)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Fido 2012-5-22 14:48
12
0
不懂...看起来好晕..............
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cjteam 2012-7-12 23:43
13
0
果然不懂编程很悲剧
游客
登录 | 注册 方可回帖
返回