• 标 题:ASProtect v0.94b保护
  • 作 者:kanxue
  • 时 间:2000年
  • 链 接:http://bbs.pediy.com

ASProtect v0.94b保护

英文原作:r!sc 《Almost Manual Unpacking (using Softice and Icedump)》
原作日期:6th febuary 2000
教程翻译: 看雪
翻译日期:2000年5月26日
声 明: 本文以r!sc的教程为基础,以自己的观点补充调整。

目标程序:aspack.exe . 231,424 . v 2.001
程序下载:AsPack
使用工具:Softice 4.05; ProcDump 1.6.2 Final; FrogsICE v0.43;Icedump 6.016

part1 . 理论知识

part2 . 分析原文件的PE头

part3 . 抓取import table

part4 . Dump整个程序并修正文件头


=part1===part1===part1===part1===part1===part1===part1===part1===part1===part1=
理论知识

这种被压缩或加密的PE文件,执行时,在内存中将会完全解压。其中import表在装载中也会被完全解压或解密(—攻击点)。其中抓取import表就很关键了,其具体位置,可用 Procdump分析文件头得到。然后,要跟踪程序完全解压后的跳到程序处的入口点,然后在内存里dump取程序的整个部分。将刚dump取的正确import表用十六进制工具粘贴到完全dump的程序,再 修正文件头,这样程序就可正常运行。


=part2===part2===part2===part2===part2===part2===part2===part2===part2===part2=
分析原文件的PE头

运行 Procdump,点击pe-editor按钮,选中ASPack.exe文件,我们想要得到程序解压后的尺寸,import表的地址和大小...幸运的是这个文件的每个块(section )都存在。

Size of image : 00079000 ; 这个PE文件执行时分配的内存空间。
image Base : 00400000 ; 基址

.idata ;.idata包含其他外来DLL的函数及数据信息
Virtual Size : 00002000 ; idata在内存的尺寸
Virtual Offset : 00046000 ; idata的地址(+imagebase == 00446000)

.rdata
Virtual Size : 00001000
Virtual Offset : 00049000

import表有可能在idata块或rdata块,到底在哪部分?看看它们的尺寸,我将马压在.idata ...


=part3===part3===part3===part3===part3===part3===part3===part3===part3===part3=
抓取import table

1、先装载Icedump
在这用Icedump 6.016版本,其命令操作形式完全和以前的版本不同。先在Icedump目录里运行相应SOFTICE版本的icedump.exe(我用的SOFTICE是4.05版,因此在win9x/405目录下运行icedump.exe),如Icedump装载成功,Icedump会返回如下信息:

icedump v6.0.1.6 for winice v4.05 loader
icedump unloaded
icedump loaded ←出现这句话表示Icedump装载成功

C:>

2、再装载FrogsICE
由于aspack能检测到SOFTICE的存在,因此装载Frogsice就可躲过。在我机子里:FrogsICE 1.00 Final和Icedump不能很好兼容工作,因此我将FrogsICE换成版本v0.43,hehe..它们配合的很好。双击FPloader.exe文件即可装载成功。
OK,到此你的SOFTICE的功能己大大加强里。
这时试试运行aspack,这时屏幕将蓝屏给你一菜单选项,告知aspack发现了SOFTICE,是否欺骗它,这时你按ESC按钮,程序即可正常运行。

3、 记住我们的第一步是抓取import table,它在内存的446000到449000处,因此程序运行时注意这段内存代码的解压情况。
由于SOFTICE不能LOAD aspack.exe,我们用:bpx loadlibrarya命令来拦断。

loadlibrarya命令解释:如果import表没在内存中就使用LoadLibraryA API调用装入该模块,因此我们可以拦截此函数来观察import表。

:bpx loadlibrarya 然后运行aspack将中断如下:
Break due to BPX KERNEL32!LoadLibraryA
:dd 446000 l 40 (下此命令观察内存446000到449000处的数据)

.
-------SPACK!.idata--------------------dword----------ROT--?(0)--
0030:00446000 ???????? ???????? ???????? ???????? ................ 
0030:00446010 ???????? ???????? ???????? ???????? ................ 
0030:00446020 ???????? ???????? ???????? ???????? ................ 
0030:00446030 ???????? ???????? ???????? ???????? ................

上图是SOFTICE的数据窗口,显示 ??...说明import表在内存中没解压。
再按F5一下,程序将中断如下:(记着:在这例中只能要按一下F5,否则将不能抓取正确的import表


0030:00446000 00000000 00000000 00000000 0004669C .............f..
0030:00446010 0004612C 00000000 00000000 00000000 ,a..............
0030:00446020 000468B6 000461AC 00000000 00000000 .h...a..........
0030:00446030 00000000 000468D0 000461B4 00000000 .....h...a......

这时446000处不是?? ?? ?? ??,意味着import表己被解压了。

.import表以一个IMAGE_IMPORT_DESCRIPTOR数组开始。 image_import_descriptors数据有5组dwords组成。

image_import_descriptors结构:
①dd offset original_first_thunk
②dd timedatestamp    时间及日期标志
③dd forwardchain    正向链结索引
④dd offset library name以NULL结尾的ASCII字符的RVA地址,该字符串包含输入的DLL名,
            比如"Kernel32.dll"或"USER32.DLL"。
⑤dd offset first_thunk 该字段是在image_thunk_data联合结构中的RVA偏移

其中timedatestamp和forwardchain通常设置为00000000, original first thunk 选项不是必须的.

:dd 446000 l 40
0030:00446000 00000000 00000000 00000000 0004669C .............f..
0030:00446010 0004612C 00000000 00000000 00000000 ,a..............

地址4669c 指向 LibraryName (RVA, 你需要加上基址imagebase+400000)

:db 44669c l 10
0030:0044669C 4B 45 52 4E 45 4C 33 32-2E 44 4C 4C 00 00 00 00 KERNEL32.DLL....

地址612c指向 first_thunk 库。

:dd 44612c l 10
0030:0044612C 000466AA 000466C2 000466DA 000466F2 .f...f...f...f..

这些是以NULL结尾的ASCII字符的RVA地址, . . 466aa 是第一个API函数的地址,466c2是第二个API函数地址...它们以以NULL结尾。

:db 0004466aa l 20
0030:004466AA 00 00 44 65 6C 65 74 65-43 72 69 74 69 63 61 6C ..DeleteCritical
0030:004466BA 53 65 63 74 69 6F 6E 00-00 00 4C 65 61 76 65 43 Section...LeaveC

通过上面的分析可知,这就是原始的.import表,快dump it!!(看看上文的image_import_descriptors地址)

:/dump 446000 2000 c:\aspack.idata.bin
(如你是用Icedump 6.016以前版本用此命令:pagein d 446000 2000 c:\aspack.idata.bin)

为了方便大家对比,特将dump正确的import表放在此下载


=part4===part4===part4===part4===part4===part4===part4===part4===part4===part4=
Dump整个程序并修正文件头

1、现在我们要找程序的入口点,下命令:bpx loadlibrarya ,然后按14下F5,然后按F10一步一步跟踪来到如下代码:

0137:00C1150E  8B4508              MOV      EAX,[EBP+08]                     
0137:00C11511  8B10                MOV      EDX,[EAX]  DS:004664FC=00400000 
0137:00C11513  8B4508              MOV      EAX,[EBP+08]                     
0137:00C11516  035018              ADD      EDX,[EAX+18]                     
0137:00C11519  8B4508              MOV      EAX,[EBP+08]                     
0137:00C1151C  8B401C              MOV      EAX,[EAX+1C]                     
0137:00C1151F  E874F9FFFF          CALL      00C10E98    ←在此按F8进入                     
0137:00C11524  5F                  POP      EDI                               
0137:00C11525  5E                  POP      ESI                               
0137:00C11526  5B                  POP      EBX                               
0137:00C11527  59                  POP      ECX                               
0137:00C11528  59                  POP      ECX                               
0137:00C11529  5D                  POP      EBP                               

0137:00C1152A  C20400              RET      0004 


F8进入后来到如下:

0137:00C10E96  8BC0                MOV      EAX,EAX                         
0137:00C10E98  89C4                MOV      ESP,EAX                         
0137:00C10E9A  89D0                MOV      EAX,EDX                           
0137:00C10E9C  8B1D6C66C100        MOV      EBX,[00C1666C]                   
0137:00C10EA2  89041C              MOV      [EBX+ESP],EAX                     
0137:00C10EA5  61                  POPAD                                       
0137:00C10EA6  50                  PUSH      EAX ;push 442b98 即为入口点                       
0137:00C10EA7  C3                  RET      ;返回到己完全解压的代码处,即入口点处。                                 
0137:00C10EA8  C3                  RET

来到入口点:

0167:00442B98 55 PUSH EBP ←此处为入口点
0167:00442B99 8BEC MOV EBP,ESP
0167:00442B9B 83C4F4 ADD ESP,-0C

0167:00442B98 处就可dump整个内存数据了,此时程序己完全解压准备运行了。记下程序入口点:00442B98
在dump前,清除所有的断点:bc *.

./dump 400000 79000 c:\aspack.dumped.exe
(如你是用Icedump 6.016以前版本用此命令:pagein d 400000 79000 c:\aspack.dumped.exe)

2、替换正确的import表

用Hexworkshop打开aspack.dumped.exe和aspack.idata.bin. Goto到exe文件的46000偏移处,Select Block大小为2000. 拷贝aspack.idata.bin文件的同样大小(2000)的Block,粘贴到exe文件中以替换掉不正确的.idata section,然后存盘。(注意:以上所有数据都是十六进制)

3、修正PE文件头

用 Procdump打开刚建好的 aspack.dumped.exe文件,点击pe-editor按钮,然后再点击SECTIONS按钮,在每个section点击右键,选中Edit section,把所有的 section 的PSize = VSize offset = RVA 。

如:CODE 的PSize=0001E000; VSize=00042000;offset =00000400;RVA=00001000;
改成:PSize = VSize= 00042000;offset = RVA =00001000;

在改完所有的sections后,按OK,存盘后,你在资源管理器中刷新一下,就会发现aspack.dumped.exe的图标回来了,但还不能运行,你还要修正入口点和import表

将入口点(Entry Point)改为:00042B98(记着:00442B98-imagebase=42B98

再点击Directory按钮,将Import Table改为 RVA (46000 );而其选项Size只要比0大就可;

然后点击OK,退出Procdump,再运行 aspack.dumped.exe ,程序运行的很甜美!

这时你用W32DASM不能反汇编,你可用 Procdump编辑第一个section characteristics:

将其 c0000060 (data, writable)改为: 60000040 (code, executable)或 e0000060 (code, data, etc etc)

注:大家抓取屏幕可在Icedump 6.016中,用:/Screendump抓取。
不加参数命令:/Screendump 选取模式,重复执行,会在0、1、2、3、4五种模式下转换。
模式1(默认)是以文本方式存盘,模式2是以HTML文件存盘。其它的请参考其readme.
模式选好后,就可用命令: /SCREENDUMP [路径]文件名 抓取整个SOFTICE的屏幕。