jisheng 发表于 2006-7-9 12:39:35

Private exe Protector 1.8 IAT 加密分析

Private exe Protector 1.8 IAT 加密分析
水平有限,只有IAT加密分析,其他的保护一律没开,也没分析。实例程序用的加密解密光盘里面的MD5calc.加壳方式是可选的加密方式都不开.( IAT加密是默认的)

加壳后的程序的IAT被完全清空了,运行后,壳直接向IAT中填充壳IAT解密函数的地址。然后,通过计算得到正确的API地址,直接进入API然后返回。
OD载入,文件被作过手脚。只能停在system breakpoint.   //晕,今天又停在了正常的OEP.不知道是怎么搞得。
He GetVersion.
F9运行。第二次断下后。运行到返回。向上看看就是OEP.
随便找一个call ,在数据窗口中跟随,看到IAT了。
这是这个例子的IAT
00405000004121A6MD5calcu.004121A6
0040500400412221MD5calcu.00412221
0040500800412287MD5calcu.00412287
0040500C004122E8MD5calcu.004122E8
004050100041231CMD5calcu.0041231C
0040501400412391MD5calcu.00412391
0040501800412415MD5calcu.00412415
0040501C0041248CMD5calcu.0041248C
0040502000412522MD5calcu.00412522
0040502400412589MD5calcu.00412589
0040502800412630MD5calcu.00412630
0040502C0041269EMD5calcu.0041269E
0040503000412709MD5calcu.00412709
0040503400412784MD5calcu.00412784
004050380041280DMD5calcu.0041280D
0040503C00412887MD5calcu.00412887
00405040004128F8MD5calcu.004128F8
0040504400412928MD5calcu.00412928
00405048004129BDMD5calcu.004129BD
0040504C00412A42MD5calcu.00412A42
0040505000412AC3MD5calcu.00412AC3
0040505400412B69MD5calcu.00412B69
0040505800412BD3MD5calcu.00412BD3
0040505C00412C01MD5calcu.00412C01
0040506000412CA2MD5calcu.00412CA2
0040506400412CF4MD5calcu.00412CF4
0040506800412D8BMD5calcu.00412D8B
0040506C00412DEBMD5calcu.00412DEB
0040507000412E32MD5calcu.00412E32
0040507400412ECEMD5calcu.00412ECE
0040507800412F4DMD5calcu.00412F4D
0040507C00412FD5MD5calcu.00412FD5
0040508000413023MD5calcu.00413023
0040508400413047MD5calcu.00413047
0040508800413097MD5calcu.00413097
0040508C0041312BMD5calcu.0041312B
0040509000000000
0040509400411D92MD5calcu.00411D92
0040509800411DE8MD5calcu.00411DE8
0040509C00411E6FMD5calcu.00411E6F
004050A000411F03MD5calcu.00411F03
004050A400411F99MD5calcu.00411F99
004050A80041201FMD5calcu.0041201F
004050AC0041204FMD5calcu.0041204F
004050B0004120C2MD5calcu.004120C2
004050B40041212EMD5calcu.0041212E

可见,全部被壳的函数填充了,每个函数都不一样。
多跟踪几个解密过程。可以发现如下的规律。

解密的过程:
一共有三层
第一层:
每个API函数,对应一段相应的解密函数。
刚进入的这段函数,都是执行下面的过程
1.push 一个unsigned int立即数。
2.计算进一步解密函数的地址(第二层解密函数地址).
3.进入第二层函数。
其中步骤1有3种实现方式:
(1)
push xxxxxxxx
mov xxxxxxxx
(2)
push r32
mov xxxxxxxx
(3)
push xxxxxxxx
步骤2也有若干种实现方式
但是变化仅仅是使用不同的寄存器。而且总是得到同一个地址(对同一个程序,同一台机器来说)
步骤3是通过在堆栈上写入步骤2计算出来的地址,通过最后的retn实现的.
其中一段的实际代码如下:
push    edi
mov   , 0B182DFA9h
push    36F05CB9h
push    eax
mov   eax, ds:dword_4081FE
add   eax, 0C224h
mov   , eax
pop   eax
retn    //进入第二层
我这里的第二层函数的地址是003AC224
(注意,刚刚进入第2层的时候,=上一层步骤1 push的立即数)
代码如下:
003AC224    55               push    ebp
003AC225    89E5               mov   ebp, esp
003AC227    50               push    eax
003AC228    53               push    ebx
003AC229    51               push    ecx
003AC22A    52               push    edx
003AC22B    56               push    esi
003AC22C    57               push    edi         //上面的操作相当pushad
003AC22D    8B45 04            mov   eax,
003AC230    50               push    eax         //第一层步骤1push的立即数
003AC231    E8 B2FFFFFF      call    003AC1E8   //进入第三层
003AC236    8945 04            mov   , eax
003AC239    5F               pop   edi      
003AC23A    5E               pop   esi
003AC23B    5A               pop   edx
003AC23C    59               pop   ecx
003AC23D    5B               pop   ebx
003AC23E    58               pop   eax      //相当popad
003AC23F    5D               pop   ebp
003AC240    C3               retn
进入第三层函数:
003AC1E8    55               push    ebp
003AC1E9    8BEC               mov   ebp, esp
003AC1EB    56               push    esi
003AC1EC    8B4D 08            mov   ecx,
003AC1EF    33F6               xor   esi, esi
003AC1F1    A1 58003B00      mov   eax,
003AC1F6    83C0 04            add   eax, 4
003AC1F9    8B10               mov   edx,
003AC1FB    83C0 04            add   eax, 4
003AC1FE    85D2               test    edx, edx
003AC200    76 18            jbe   short 003AC21A
003AC202    3B08               cmp   ecx,
003AC204    75 0E            jnz   short 003AC214
003AC206    83C0 04            add   eax, 4
003AC209    8B30               mov   esi,
003AC20B    A1 58003B00      mov   eax,
003AC210    3330               xor   esi,
003AC212    EB 06            jmp   short 003AC21A
003AC214    83C0 08            add   eax, 8
003AC217    4A               dec   edx
003AC218^ 75 E8            jnz   short 003AC202
003AC21A    8BC6               mov   eax, esi
003AC21C    5E               pop   esi
003AC21D    5D               pop   ebp
003AC21E    C2 0400            retn    4

通过分析上面的代码知:
API地址的解密方式如下:
在== 00BB0000(不同的程序,不同的机器地址不一样)有一个表,结构如下

表头是下列结构
struct tablehead
{
DWORD MagicNum;
DWORD count;   //API结构的个数
}
表身是一个由下列结构组成的数组
struct API
{
DWORD ID;
DWORD key;
}

在00BB0000存放的方式是表头+表身

IAT中的正确的API地址为:
在表中查找第一层步骤1中的立即数。也就是说用找struct API结构中的ID来和第一层步骤1中的那个立即数比较。
如果相等
那么
API Address = Keyxor MagicNum;
例如:
下面是我这个程序的表:
00BB00006A55116E
00BB00040000002D
00BB00084844D879
00BB000C1D83BD70
00BB0010865A2255
00BB00141D86D824
00BB0018D4C9B887
00BB001C1D84B9C3
00BB0020369744FB
00BB00241D87037F
00BB0028AC9E8550
00BB002C1D87024A
00BB0030509362AB
00BB00341D87E2F4
00BB0038BB32A0F6
00BB003C1D84DAEB
00BB00403B9BF46E
00BB00441D87733E
00BB00486CAACE09
00BB004C1D86A072
00BB0050BAFA03D7
00BB005416D5D7A1
00BB0058C1E6CFF5
00BB005C16D43D16
00BB006062F88496
00BB006416D5B5EE
00BB0068962C31C7
00BB006C16D69DD7
00BB00705752A351
00BB007416D5DFAA
00BB0078A3861600
00BB007C16D63F45
00BB008072F11E39
00BB008416D58DC3
00BB00883FC1BD8D
00BB008C16DD3EAA
00BB0090C97C1FFF
00BB009416D5BD46
00BB0098B1866570
00BB009C6A6FD19E
00BB00A0ADE2CB95
00BB00A416D50F80
00BB00A82D66B1C5
00BB00AC16D43DE3
00BB00B04CCF1A0F
00BB00B416D405C5
00BB00B8251097CC
00BB00BC6A6FD032
00BB00C0AB40BF8D
假如第一层中的立即数是 4844D879
那么API地址就为1D83BD70 xor 6A55116E=77D6AC1E

修复的方法见附件中的源代码
这个程序只能修复这个实例程序的IAT,因为那张解密表我是直接写到了程序里面。要修复其他程序,把那张表替换了就可以了。
发现有些函数 壳是自己实现的,解密出来的函数还是指向壳里,这部分我是手动修复的。正在研究自动修复的方法。

IAT修复程序使用方法:
先用OD,跑到OEP或者OEP附近。然后打开程序,填写要求的数据,点修复按钮就可以了。
源代码有点乱,下个版本改进。

已知的壳自己实现的API:
GetModuleHandleA
ExitProcess
GetModuleFileNameA

BTW:ETG和CMIX是什么东西啊?

hbqjxhw 发表于 2006-7-9 20:02:58

“He GetVersion       F9运行。第二次断下后。运行到返回。向上看看就是OEP.”

我这里怎么只能中断一次,第二次根本就不能中断,并且提示进程已终止,退出代码。

zsl01 发表于 2008-9-27 17:12:07

学习啊,多谢分享.
页: [1]
查看完整版本: Private exe Protector 1.8 IAT 加密分析