如题。
EncryptPE v2006.1.15 脱壳
【作    者】: netsowell
【软件名称】:EncryptPE v2006.1.15
【下载地址】: http://www.encryptpe.com
【加壳方式】: 自己
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
EncryptPE简介:

1. EncryptPE 能加密保护常规PE文件(EXE、DLL、OCX等一般程序或NT服务程序),防静态分析修改,反动态跟踪调试,有效地保护软件,防止盗版。除常规的对抗调试器(SoftIce、TRW、OllyDbg等)、监视器、DUMP工具方法外,EncryptPE采用的加密保护的手段还有:随机加密算法、CRC校验、变形、代码替换、进程注入、APIHOOK、多线程、调试运行、全程监控等。
【详细过程】
  写个教程不容易,再加上我现在只会用ABC了,难免有些地方会出点这样或者那样的Bug,尽请见谅。
初步的分析我就不用写了,EPE把壳的代码放到了一个DLL里面,运行的时候先解压这个DLL到%windir%\system32目录下,经过分析都是使用的标准windows api,windows api对于权限管理都是很严格的,所以我们可以通过修改这个DLL的属性来防止EPE一次次覆盖,然后我们就可以修改v2006115.EPE本身了。
  V2006115.EPE是用upx加密的,至于怎么脱我就不介绍了,但是注意IAT修复的时候要注意IAT跳转表有两段,不然容易无法跨平台。效验我们就不说了,直接入壳最精彩的部分。
/*711E46F2*/  push    ebp
/*711E46F3*/  push    711E4856
/*711E46F8*/  push    dword ptr fs:[eax]
/*711E46FB*/  mov     fs:[eax], esp
/*711E46FE*/  xor     edi, edi
/*711E4700*/  test    bl, bl
/*711E4702*/  jnz     short 711E4711  //nop
/*711E4704*/  mov     edx, [ebp-8]
/*711E4707*/  mov     eax, [ebp-4]
/*711E470A*/  call    711DAE08 //这里取得正确的函数地址,所以上面我们要nop掉
/*711E470F*/  mov     edi, eax
/*711E4711*/  mov     [ebp-C], edi
/*711E4714*/  test    bl, bl
/*711E4716*/  je      711E480B  //magic jmp*** //直接jmp,IAT修复完毕
/*711E471C*/  push    40
/*711E471E*/  push    3000
/*711E4723*/  push    78
/*711E4725*/  push    0
/*711E4727*/  call    7112724C
/*711E472C*/  mov     ebx, eax
/*711E472E*/  test    ebx, ebx
/*711E4730*/  je      711E480B
/*711E4736*/  mov     eax, [esi+368]
/*711E473C*/  call    71125BAC
/*711E4741*/  inc     eax
/*711E4742*/  push    eax
/*711E4743*/  lea     eax, [esi+368]
/*711E4749*/  mov     ecx, 1
/*711E474E*/  mov     edx, [711DFED4]
/*711E4754*/  call    71125D68
/*711E4759*/  add     esp, 4
/*711E475C*/  mov     eax, [esi+368]
/*711E4762*/  call    71125BAC
/*711E4767*/  mov     edx, [esi+368]
/*711E476D*/  mov     [edx+eax*4-4], ebx
/*711E4771*/  mov     byte ptr [ebx], 0E8
/*711E4774*/  mov     eax, ebx
/*711E4776*/  mov     esi, eax
/*711E4778*/  inc     esi
/*711E4779*/  mov     edx, 711DB708
/*711E477E*/  sub     edx, esi
/*711E4780*/  sub     edx, 4
/*711E4783*/  mov     [esi], edx
/*711E4785*/  mov     byte ptr [ebx+5], 0FF
/*711E4789*/  mov     byte ptr [ebx+6], 25
/*711E478D*/  mov     esi, eax
/*711E478F*/  add     esi, 7
/*711E4792*/  add     eax, 0B
/*711E4795*/  mov     [esi], eax
/*711E4797*/  cmp     dword ptr [ebp-8], 0FFFF
/*711E479E*/  jbe     short 711E47B8
/*711E47A0*/  lea     eax, [ebp-10]
/*711E47A3*/  mov     edx, [ebp-8]
/*711E47A6*/  call    71124A00
/*711E47AB*/  mov     eax, [ebp-10]
/*711E47AE*/  call    71124AC8
/*711E47B3*/  cmp     eax, 64
/*711E47B6*/  jle     short 711E47C7
/*711E47B8*/  mov     edx, [ebp-8]
/*711E47BB*/  mov     eax, [ebp-4]
/*711E47BE*/  call    711DAE08
/*711E47C3*/  mov     edi, eax
/*711E47C5*/  jmp     short 711E47F8
/*711E47C7*/  mov     eax, ebx
/*711E47C9*/  mov     esi, eax
/*711E47CB*/  add     esi, 0F
/*711E47CE*/  mov     edx, [ebp-4]
/*711E47D1*/  mov     [esi], edx
/*711E47D3*/  mov     esi, eax
/*711E47D5*/  add     esi, 13
/*711E47D8*/  lea     eax, [ebp-14]
/*711E47DB*/  mov     edx, [ebp-8]
/*711E47DE*/  call    71124A00
/*711E47E3*/  mov     eax, [ebp-14]
/*711E47E6*/  call    71124AC8
/*711E47EB*/  mov     ecx, eax
/*711E47ED*/  inc     ecx
/*711E47EE*/  mov     edx, [ebp-8]
/*711E47F1*/  mov     eax, esi
/*711E47F3*/  call    71127B00
/*711E47F8*/  mov     eax, ebx
/*711E47FA*/  mov     esi, eax
/*711E47FC*/  add     esi, 0B
/*711E47FF*/  mov     edx, eax
/*711E4801*/  add     edx, 5
/*711E4804*/  xor     edi, edx
/*711E4806*/  mov     [esi], edi
/*711E4808*/  mov     [ebp-C], eax
/*711E480B*/  cmp     dword ptr [ebp+C], 0
/*711E480F*/  je      short 711E483B
/*711E4811*/  xor     eax, eax
/*711E4813*/  push    ebp
/*711E4814*/  push    711E4831
/*711E4819*/  push    dword ptr fs:[eax]
/*711E481C*/  mov     fs:[eax], esp
/*711E481F*/  mov     esi, [ebp+C]
/*711E4822*/  mov     eax, [ebp-C]
/*711E4825*/  mov     [esi], eax //////////填入函数地址
/*711E4827*/  xor     eax, eax
/*711E4829*/  pop     edx
/*711E482A*/  pop     ecx
/*711E482B*/  pop     ecx
/*711E482C*/  mov     fs:[eax], edx
/*711E482F*/  jmp     short 711E483B
/*711E4831*/  jmp     71123E78
/*711E4836*/  call    711241E0
/*711E483B*/  xor     eax, eax
/*711E483D*/  pop     edx
/*711E483E*/  pop     ecx
/*711E483F*/  pop     ecx
/*711E4840*/  mov     fs:[eax], edx
/*711E4843*/  push    711E485D
/*711E4848*/  lea     eax, [ebp-14]
/*711E484B*/  mov     edx, 2
/*711E4850*/  call    71124834
/*711E4855*/  retn

于是乎,IAT处理完毕。由于效验我们都去完了,所以效验我们就不管拉。
/*711E6749*/  call    7112C7D4
/*711E674E*/  mov     eax, [711FFB9C]
/*711E6753*/  cmp     byte ptr [eax], 0
/*711E6756*/  jnz     short 711E676E
/*711E6758*/  add     edi, 14
/*711E675B*/  inc     dword ptr [ebp-1C]
/*711E675E*/  cmp     dword ptr [edi+C], 0
/*711E6762*/  jbe     short 711E676E
/*711E6764*/  cmp     dword ptr [edi+10], 0
/*711E6768*/  ja      711E64EE  //IAT是否处理完毕。
/*711E676E*/  push    0
/*711E6770*/  lea     eax, [ebp-40]
/*711E6773*/  mov     ecx, 1
/*711E6778*/  mov     edx, [711E501C]
/*711E677E*/  call    71125D68
/*711E6783*/  add     esp, 4
/*711E6786*/  xor     eax, eax
/*711E6788*/  call    711E6DB4
/*711E678D*/  test    al, al
/*711E678F*/  jnz     short 711E679C
/*711E6791*/  xor     eax, eax
/*711E6793*/  call    711DFBD4

下面开始精彩部分,MOV和其他代码加密
/*711E67E6*/  mov     edx, [eax+80]
/*711E67EC*/  mov     [ebp-34], edx
/*711E67EF*/  mov     edx, [eax+84]
/*711E67F5*/  mov     [ebp-30], edx
/*711E67F8*/  test    edi, edi
/*711E67FA*/  jle     711E6AD5//判断加密地址数目。
/*711E6800*/  mov     eax, [71200710]
/*711E6805*/  mov     eax, [eax+3C]
/*711E6808*/  add     eax, [71200710]



/*711E68E5*/  sub     ebx, 2
/*711E68E8*/  mov     ax, [ebx] //IAT跳转表加密的三种类型的处理
/*711E68EB*/  sub     ax, 0CCE9  //cmp ax,cce9 //CCE9型 对应 jmp [xxxx]
/*711E68EF*/  je      short 711E68FF
/*711E68F1*/  sub     ax, 1BA7  //cmp ax,90e8 //90E8 型  对应 call [xxxxx]
/*711E68F5*/  je      short 711E693B
/*711E68F7*/  sub     ax, 100
/*711E68FB*/  je      short 711E693B  //cmp ax,90e9 对应 jmp [xxxxx]
/*711E68FD*/  jmp     short 711E6976
/*711E68FF*/  call    711DBBD0  //申请一段内存
/*711E6904*/  mov     word ptr [eax], 25FF //放如正确的跳转指令到申请的内存。所以我们在这里动手,修改为
 mov word ptr [ebx],25ff 
add ebx,2
mov dword ptr [ebx],esi
下面的代码没用了,所以跳开
Jmp 711e6a9d
/*711E6909*/  mov     [eax+2], esi //esi里面有正确的函数跳转地址
/*711E690C*/  mov     edx, eax
/*711E690E*/  mov     ebx, [ebp-10]
/*711E6911*/  add     ebx, 6
/*711E6914*/  mov     eax, [ebp-18]
/*711E6917*/  add     eax, eax
/*711E6919*/  add     ebx, eax
/*711E691B*/  mov     eax, [ebp-10]
/*711E691E*/  mov     eax, [eax]
/*711E6920*/  movzx   ecx, word ptr [ebx]
/*711E6923*/  sub     ecx, 3000
/*711E6929*/  add     eax, ecx
/*711E692B*/  add     eax, [ebp-20]
/*711E692E*/  dec     eax
/*711E692F*/  sub     edx, eax
/*711E6931*/  sub     edx, 4
/*711E6934*/  mov     [eax], edx
/*711E6936*/  jmp     711E6A9D
/*711E693B*/  call    711DBBD0//同样申请内存
/*711E6940*/  mov     word ptr [eax], 25FF//这里有所不同,应为call [xxxx]和jmp [xxxx]都在这里处理了,所以我们要先判断。
修改为
cmp     byte ptr [ebx+1], 0E9
je      short 711E6948
mov     word ptr [ebx], 15FF//是call [xxxx]
jmp     short 711E694D
mov     word ptr [ebx], 25FF //是 jmp [xxxx]
mov     [ebx+2], esi
jmp     711E6A9D


/*711E6945*/  mov     [eax+2], esi
/*711E6948*/  mov     edx, eax
/*711E694A*/  mov     ebx, [ebp-10]
/*711E694D*/  add     ebx, 6
/*711E6950*/  mov     eax, [ebp-18]
/*711E6953*/  add     eax, eax
/*711E6955*/  add     ebx, eax
/*711E6957*/  mov     eax, [ebp-10]
/*711E695A*/  mov     eax, [eax]
/*711E695C*/  movzx   ecx, word ptr [ebx]
/*711E695F*/  sub     ecx, 3000
/*711E6965*/  add     eax, ecx
/*711E6967*/  add     eax, [ebp-20]
/*711E696A*/  sub     edx, eax
/*711E696C*/  sub     edx, 4
/*711E696F*/  mov     [eax], edx
/*711E6971*/  jmp     711E6A9D
/*711E6976*/  mov     edx, [711FFD94]
/*711E697C*/  mov     edx, [edx]


下面还有一些类型的加密,包括MOV,但是我们不需要了解其详细,直接命中要害。
/*711E69BA*/  cmp     ax, 500
/*711E69BE*/  je      short 711E6A0C
/*711E69C0*/  cmp     ax, 1500
/*711E69C4*/  je      short 711E6A0C
/*711E69C6*/  cmp     ax, 2500
/*711E69CA*/  je      short 711E6A0C
/*711E69CC*/  cmp     ax, 3500
/*711E69D0*/  je      short 711E6A0C
/*711E69D2*/  cmp     ax, 0D00
/*711E69D6*/  je      short 711E6A0C
/*711E69D8*/  cmp     ax, 1D00
/*711E69DC*/  je      short 711E6A0C
/*711E69DE*/  cmp     ax, 2D00
/*711E69E2*/  je      short 711E6A0C
/*711E69E4*/  cmp     ax, 3D00
/*711E69E8*/  je      short 711E6A0C
/*711E69EA*/  mov     ax, [ebx]
/*711E69ED*/  and     ax, 0FF00
/*711E69F1*/  cmp     ax, 8000
/*711E69F5*/  jb      711E6A9D
/*711E69FB*/  mov     ax, [ebx]
/*711E69FE*/  and     ax, 0FF00
/*711E6A02*/  cmp     ax, 0C000
/*711E6A06*/  jnb     711E6A9D
/*711E6A0C*/  mov     ax, [ebx]
/*711E6A0F*/  and     ax, 0FF
/*711E6A13*/  cmp     ax, 89
/*711E6A17*/  je      short 711E6A26
/*711E6A19*/  mov     ax, [ebx]
/*711E6A1C*/  and     ax, 0FF
/*711E6A20*/  cmp     ax, 8B
/*711E6A24*/  jnz     short 711E6A9D
/*711E6A26*/  call    711DBBD0
/*711E6A2B*/  mov     dx, [ebx]
/*711E6A2E*/  and     dx, 0FF
/*711E6A33*/  cmp     dx, 89
/*711E6A38*/  jnz     short 711E6A4C
/*711E6A3A*/  mov     dx, [ebx]
/*711E6A3D*/  and     dx, 0FF00
/*711E6A42*/  add     dx, 8B
/*711E6A47*/  mov     [eax], dx
/*711E6A4A*/  jmp     short 711E6A5C
/*711E6A4C*/  mov     dx, [ebx]
/*711E6A4F*/  and     dx, 0FF00
/*711E6A54*/  add     dx, 89
/*711E6A59*/  mov     [eax], dx //这里写如加密代码。我们在这里动手
// 修改为mov [ebx],dx

/*711E6A5C*/  mov     [eax+2], esi
//修改为 mov [ebx+2],esi
于是乎。基本信息处理完毕。现在往下找OEP.
/*711E6A5F*/  mov     word ptr [eax+6], 0E990
/*711E6A65*/  mov     edx, ebx
/*711E6A67*/  sub     edx, eax
/*711E6A69*/  sub     edx, 6
/*711E6A6C*/  mov     [eax+8], edx
/*711E6A6F*/  mov     edx, eax
/*711E6A71*/  mov     word ptr [ebx], 0E990
/*711E6A76*/  mov     ebx, [ebp-10]
到达
/*711E4DEE*/  cmp     eax, 0//判断OEP是否为0, 是就出错。
/*711E4DF1*/  je      short 711E4E45
/*711E4DF3*/  mov     bl, [7121272B] //是否是S加密方式。
/*711E4DF9*/  call    V2200611.05007EC0
/*711E4DFE*/  xor     eax, FFFFFFFF//如果是,解密OEP
/*711E4E03*/  mov     [esp+34], eax
/*711E4E07*/  add     esp, 10
/*711E4E0A*/  pop     dword ptr fs:[0]
/*711E4E11*/  pop     eax
/*711E4E12*/  and     eax, 100
/*711E4E17*/  cmp     eax, 100
/*711E4E1C*/  je      short 711E4E45
/*711E4E1E*/  call    711DB074 //飞向光明之颠。(盗版一下fly老大的。)
/*711E4E23*/  jmp     short 711E4E45
/*711E4E25*/  mov     [esp+34], eax //如果不是,那么用4个int3 通知explorer里面的处理过程,OEP 到了。OEP加密方式,仍然为xor oep,ffffffff
/*711E4E29*/  add     esp, 10
/*711E4E2C*/  pop     dword ptr fs:[0]
/*711E4E33*/  pop     eax
/*711E4E34*/  and     eax, 100
/*711E4E39*/  cmp     eax, 100
/*711E4E3E*/  je      short 711E4E45
/*711E4E40*/  call    711DB150
/*711E4E45*/  call    711DD288
/*711E4E4A*/  push    10
/*711E4E4C*/  mov     eax, [711FFBB4]



于是乎,强制结束程序,然后再运行。dump,修复IAT,优化,收工。有SDK的,记得再在IAT添加一个v22006114.epe如果有。没有就用原版的v22006115.epe 附上主脱后的主程序和修改后的dll.
附件太大。。。我分。