首页
社区
课程
招聘
怀旧篇dos仅有脱壳教程
发表于: 2005-7-8 23:18 5148

怀旧篇dos仅有脱壳教程

2005-7-8 23:18
5148
拨壳机 】     EXE 档进入点搜寻程式          v2.01 (旧版说明书)
==========================================================================
程式介绍∶

        EXESHAPE、EXEWRITE、EXEMAKE 这些软体都是将记忆体内的程式码
还原成执行档的工具 ,要使用这个工具的话 ,必需要先学会玩 DEBUG ,并追
踪执行档至进入点 ,才能回存程式码并还原成执行档 ,不过到底哪里是程式
进入点呢 ,相信大家都有所迷惑 ,而且万一要追踪的程式有坚强的防破能力
,那么根本就没有机会追踪到程式进入点。

        我想很多朋友都会使用 EXEWRITE 或是 EXESHAPE 这套程式 ,但是
先决条件是要会玩 DEBUG ,且有能力追踪程式至进入点 ;现在的保护程式防
破能力越来越强 ,强到使用失去相容性的保护手段 ,其目地就是要当掉十分
强悍的 S-ICE ,很不幸的为了当掉 S-ICE ,应用程式不断的 RESET 8259、
停止键盘控制权、干掉 BIOS 堆叠区 ,结果一些好用的长驻程式都无用武之
地(如电动克星、抓图程式) ,甚至会甘扰周边硬体的动作 (如PREXCM会甘扰
滑鼠)  ,所以将这个失去相容性的外壳去除 ,已经变成非常需要。

        笔者发展了这套『拨壳机』能搜寻程式进入点 ,并自动计算执行档
资料的正确长度 ,加以回存 ,让使用者可以将它还原 ,免除外壳的困扰。这
套程式使用了大量的80386特有命令 , 并以共生的方式追踪程式 ,因此不怕
像RESET 8259、干掉BIOS堆叠、干掉所有中断向量表、程式摆在 40:0 的地
方执行 ,只有那种会侦测是否载入长驻程式的外壳会造成当机 ,否则顶多是
找不到进入点 ,而不会当机。

        这个版本比上次的测试版增加了可设定拨壳层数 ,同时也增加了一
个侦测外壳层数的小工具 ,让那种经过压缩再压缩的程式 ,能够一次解决 ,
省掉不必要的时间。

        至於有朋友提到希望内建 EXEWRITE 功能 ,这点笔者蛮抱歉的 ,因
为『拨壳机』会占用主记忆体约8K ,如果再占用更大的记忆体 ,则可能造成
应用程式记忆体不足 ,同时为了避免本程式杀伤力太强 ,所以拿掉了部份人
工智慧 ,希望各位研究归研究 ,不要拿来当破解工具。

        为了不要耽误各位太多时间 ,本程式已经把 DELAY. 拿掉 ,让您用
起来比较顺手 ,如果您手痒的话 ,可以想办法破解 ,内有暗藏人工智慧旗标
开关 (Default=OFF) ,可以让程式闪过更多陷阱 ,如果此开关没有打开的话
,其功力等於 1.05 版 ,不过一般来说你是没有必要浪费时间去解它的 ,因
为它差不多可以应付 90% 的外壳了。

        本程式为 PD 版 ,亦即不论您觉得好用、难用、修改、拷贝都没有
关系 ,唯著作权仍归『软蛀』所有 ,非经作者同意 ,禁止贩卖图利。
--------------------------------------------------------------------------
程式需求∶

        本程式只可在 80386 以上的机器执行 ,且电脑不可挂入 EMM 系的
保护模式软体 ,不过 HIMEM.SYS 不在此限(因为它未进入保护模式)。 如果
您的电脑不是 80386 的 CPU  ,请勿强行执行本程式 ,以免发生不可预知的
後果。

        被外壳保护的程式必需以母片方式执行 ,且被保护的程式要有严重
的编码手序 ,才可以让本程式顺利判断出来。对於没有编码的程式 ,反而没
有办法找到进入点与拨壳。

注:请使用原版软体才能正确工作.
   底下两个范例是介绍一层外壳及多层外壳的使用方法。
--------------------------------------------------------------------------
RIPPER32 EXE       新版拨壳程式 2.00 正式版
TEST     EXE       测式壳有几层
WATCH    EXE       在指定的 CS:IP 处下断点、回写
--------------------------------------------------------------------------
简易说明∶
        键入 RIPPER32.EXE <要拨壳的档案> <参数>

        RIPPER32.EXE            是本拨壳程式主档
        <要拨壳的档案>          请记得档案後面要加上 .EXE 或 .COM
        <参数>                  被拨壳的档有参数要下就继续键入

        不管程式是否找到进入点 ,结果都会进入该程式 ,而找到关键点时 ,电
        脑会 Beep 一声 ,紧接著就开始分析进入点 ,如果这时候也成功执行 ,
        则会在硬碟产生 REG.DAT 与 BADY.DAT 两个档案。
        改变记忆体後再如法泡制 ,最後祭出 EXEWRITE 就可以了....

        其中 REG.DAT 是记录各暂存器的数值 ,内容如下

C>RIPPER32 XOE.EXE
  SAVE OK !

C>DEBUG REG.DAT (长度为 10 byte)
-d 100 l cx
15F3:0100  95 16 A5 16 00 00 A5 16 00 01
此例 DS=1695
     SS=16A5
     SP=0000
     CS=16A5
     IP=0100

而 BADY.DAT 则是供 EXEWRITE、EXESHAPE 使用的资料档 ,长度不一定。

==========================================================================
范例一.只有一层皮的拨法∶================================================
==========================================================================
本范例是 COPYLOCK 3.43 版 ,在未拨壳前的状态如下

A:\>dir

Volume in drive A has no label
Volume Serial Number is 3041-11CF
Directory of A:\

RIPPER32 EXE      6010 本拨壳程式
COPYLOCK EXE     41216 被COPYLOCK保护的程式
        5 file(s)      57722 bytes
                     1140224 bytes free
--------------------------------------------------------------------------
用本程式产生拨壳参考档∶

A:\>ripper32 copylock.exe
┌━━━━━━━━━━━━━━━━━━━━━━━━┐
┃ Ripper/32 for 80386+ Matchine    Version 1.07  ┃
┃ (C) Copyright Werong Ho           1995-01-28   ┃
└━━━━━━━━━━━━━━━━━━━━━━━━┘
?Search EXE Break point.
BREAK=00001 (Dex)               ━ 拨壳层数
....执行copylock.exe...
SAVE OK !

--------------------------------------------------------------------------
紧接著 DIR 看到多出两个档案
A:\>dir

Volume in drive A has no label
Volume Serial Number is 3041-11CF
Directory of A:\

RIPPER32 EXE      6010 01-01-96  10:07a
COPYLOCK EXE     41216 01-01-96  10:10a
REG      DAT        10 ┬ 暂存器值
BADY     DAT     34272 ┘ 程式记忆体存档
        5 file(s)      92004 bytes
                     1105408 bytes free

--------------------------------------------------------------------------
将此资料档改名 ,并载入一个长驻程式 ,用以改变记忆体量 ,然後再执行一
次拨壳手续.

C:\>REN *.DAT *.1
C:\>TSR (随便一个长驻程式)
A:\>ripper32 copylock.exe
--------------------------------------------------------------------------
於是你就有两组不同的暂存器 ,接著就准备玩 EXEWRITE 还原本程式罗.

Volume in drive A has no label
Volume Serial Number is 3041-11CF
Directory of A:\

RIPPER32 EXE      6010 01-01-96  10:07a
COPYLOCK EXE     41216 01-01-96  10:10a
REG      1          10 01-01-96  10:30a
BADY     1       34272 01-01-96  10:30a
REG      DAT        10 01-01-96  10:30a
BADY     DAT     34272 01-01-96  10:30a
        7 file(s)     126286 bytes
                     1070592 bytes free

--------------------------------------------------------------------------
在玩 EXEWRITE 前必需先记录各暂存器值 ,如下所示∶

A:\>debug reg.1
-d 100 l cx
15DD:0100  1F 08 2F 08 00 00 2F 08-00 00                    ../.../...
得到
DS=081F
SS=082F
SP=0000
CS=082F
IP=0000

A:\>debug reg.dat
-d 100 l cx
15DD:0100  52 0B 62 0B 00 00 62 0B-00 00                    R.b...b...
得到
DS=0B52
SS=0B62
SP=0000
CS=0B62
IP=0000

--------------------------------------------------------------------------
所有的暂存器值都有了 ,接著就是使用 EXEWRITE 还原主程式.

                        >>> EXE FILE WRITE PROGRAM <<<
                              Write by Gent Chen

The first file is Rewrite,you best have a back file
Please input first  exe file name :bady.1
Please input program DS(START PSP),SS,SP,CS,IP :
(dec)&h81f,&h82f,0,&h82f,0
Please input second exe file name :bady.dat
Please input program DS(START PSP),SS,SP,CS,IP :
(dec)&hb52,&hb62,0,&hb62,0
Please input NEW EXE file name :bady.exe

                        Make EXE file,please wait ....

                          EXE FILE MAKE SUCCESSFULL

--------------------------------------------------------------------------
比较还原後的主档 ,与原始档案的长度差异 ,虽增长了少许 ,但是仍然可以
正确执行。

Volume in drive C is XXXXXXXXX
Volume Serial Number is 145D-14D8
Directory of C:\

SOURCE   EXE     33513 未保护的主档
COPYLOCK EXE     41216 被COPYLOCK保护的程式
BADY     EXE     36674 还原後的主档

==========================================================================
范例二.有多层皮的拨法∶(如果不知道有几层 ,也可以用此法) =================
==========================================================================
【 测试外壳有几层 】

首先测试一下要被拨壳的主档有几层
C>test sample.exe
┌━━━━━━━━━━━━━━━━━━━━━━━━┐
┃ Ripper/32 for 80386+ Matchine    Version 1.07  ┃
┃ (C) Copyright Werong Ho           1995-01-28   ┃
└━━━━━━━━━━━━━━━━━━━━━━━━┘
?Search EXE Break point.
.....执行有保护的程式
BREAK=00013 (Dex)      ...... 有 13 层外衣

--------------------------------------------------------------------------
【 设定拨壳层数 】       (版本 v1.05 新增功能)

        知道外壳的层数以後 ,可以在 DOS  下键入 "SET BREAK=13" 用来
设定 DOS  的环境变数 ,让电脑记住拨壳参数 ,以後在执行 RIPPER32 时就
会自动被使用。(最小为 1 ,最大值为 65535)
--------------------------------------------------------------------------
【 产生档案回写用的参考档 】

C>ripper32 sample.exe
┌━━━━━━━━━━━━━━━━━━━━━━━━┐
┃ Ripper/32 for 80386+ Matchine    Version 1.07  ┃
┃ (C) Copyright Werong Ho           1995-01-28   ┃
└━━━━━━━━━━━━━━━━━━━━━━━━┘
?Search EXE Break point.
BREAK=00013 (Dex)                               拨 13 层外壳
................                                产生第一次参考档
SAVE OK !

C>ren *.dat *.1
C>tsr           (长驻程式)

C>ripper32 sample.exe
┌━━━━━━━━━━━━━━━━━━━━━━━━┐
┃ Ripper/32 for 80386+ Matchine    Version 1.07  ┃
┃ (C) Copyright Werong Ho           1995-01-28   ┃
└━━━━━━━━━━━━━━━━━━━━━━━━┘
?Search EXE Break point.
BREAK=00013 (Dex)
................                                产生第二次参考档
SAVE OK !
--------------------------------------------------------------------------
【 记录参考档各暂存器值 】

C>debug reg.1
-d 100 109
13EE:0100  E3 0B 90 19 90 01 40 17-12 00
C>debug reg.dat
-d 100 109
13EE:0100  ED 0C 9A 1A 90 01 4A 18-12 00
--------------------------------------------------------------------------
【 EXE 档回写、产生拨壳档 】

                        >>> EXE FILE WRITE PROGRAM <<<
                              Write by Gent Chen

The first file is Rewrite,you best have a back file
Please input first  exe file name :bady.1
Please input program DS(START PSP),SS,SP,CS,IP :
(dec)&hbe3,&h1990,&h190,&h1740,&h12
Please input second exe file name :bady.dat
Please input program DS(START PSP),SS,SP,CS,IP :
(dec)&hced,&h1a9a,&h190,&h184a,&h12
Please input NEW EXE file name : samp.exe

                        Make EXE file,please wait ....

                          EXE FILE MAKE SUCCESSFULL

--------------------------------------------------------------------------
【 RIPPER32.EXE 有几个地方开放给使用者修改的更人性化 】

1. 改预设拨壳层数: 就是在未下 "SET BREAK" 的命令时 ,会拨几层壳
   可用 PCTOOLS 搜寻 "COUNT=" 的字眼 , 将後面ASCII码改掉即可 ,
   预设值 01 表示拨掉一层 ,懂了吗 ?

File=RIPPER32.EXE    sector 0000003, Clust 01985
Displacement ━━━━━━━━  Hex codes  ━━━━━━━━━   ASCII value
0400(0190)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0416(01A0)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0432(01B0)  00 00 43 4F 55 4E 54 3D 01 00 42 52 45 41 4B 00   COUNT=
0448(01C0)  00 00 00 6F 02 00 00 5C 00 00 00 6C 00 00 00 00
0464(01D0)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0480(01E0)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0496(01F0)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

2. 修改存档的路径或档名: (范例为 1.05版、其它版本改法一样)

File=RIPPER32.EXE    sector 0000005, Clust 01986
Displacement ━━━━━━━━  Hex codes  ━━━━━━━━━   ASCII value
0096(0060)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0112(0070)  00 43 3A 5C 52 45 47 2E 44 41 54 00 00 00 00 00  C:\REG.DAT......
0128(0080)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ......可修改.....
0144(0090)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .................
0160(00A0)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0176(00B0)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0192(00C0)  00 00 00 00 00 00 00 00 00 00 00 00 43 3A 5C 42             C:\B
0208(00D0)  41 44 59 2E 44 41 54 00 00 00 00 00 00 00 00 00 ADY.DAT.........
0224(00E0)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .....可修改.....
0240(00F0)  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ............

--------------------------------------------------------------------------
TEST.EXE 新增警告讯息∶         (版本 v2.00 新增功能)

1.SoftICE Detect (INT 3)=00000 (Dex)
    表示应用程式在执行过程中 ,会透过 INT_3 来侦测 S-ICE 是否存在 ,
    本程式是拦截 INT_3 ,并监看 SI=4647 DI=4A4D ,若这些条件都符合的
    话 ,表示应用程式有去侦测 S-ICE  是否存在 ,我便会把此记录值加一
     ,当程式结束後 ,拨壳机便会把侦测的次数秀出 ;若您尝试要用 S-ICE
    对此软体侦错的话,务必要注意此陷阱。

2.80386 Engine Error !
    表示应用程式也使用到 80386. 的某些机能 ,为了相容性起见 ,本程式
    会永久关闭监看应用程式的动作 ,如果您手上拿到的是注册版 ,应该不
    会有此讯息出现。

3.INT 1 used=00000 (Dex)
    表示应用程式有使用 INT_01 来做解码动作 ,後面的数字是呼叫次数 ,
    正常的程式是不可能会去使用 INT_01 的 ,所以拨壳机也会监看此中断
    发生次数。
    (包含因为开启 'T' 旗标、插断01 所引起的中断)
    (注册版还包括应用程式使用硬体中断的次数)

4.INT 3 used=00000 (Dex)
    表示应用程式有使用 INT_03 来做解码动作 ,後面的数字是呼叫次数 ,
    正常的程式是不可能会去使用 INT_03 的 ,所以拨壳机也会监看此中断
    (包含呼叫 S-ICE 函式的次数)

5.INT 9 used=00000 (Dex)
    表示应用程式有使用 INT_09 来做解码动作 ,後面的数字是呼叫次数
    (除了来自键盘以外 ,所有产生 INT_09 的动作皆会被显示)

6.INT 7 Detect !
    (仅显示应用程式是否使用此插断程式 ,主要是让使用者知道用 S-ICE
     除错时 ,注意此插断会当掉旧版 S-ICE. )

RIPPER32.EXE 新增讯息∶         (版本 v2.00 新增功能)
      All Register List :
      DS:???? SS:???? SP:???? CS:???? IP:????

      若 RIPPER32 找到进入点 ,会秀出此讯息.
--------------------------------------------------------------------------
新增档案 WATCH.EXE              (版本 v2.01 新增功能)

        RIPPER32 找到进入点後 ,会将各暂存器值存回 REG.DAT ,自本版以後
增加 4 BYTE ,代表 BADY.DAT 的档案长度。

        因为在真实模式下 RIPPER32 会甘扰程式的部份动作 ,为了让甘扰减
到最低 ,笔者增加本程式 ,让存档的资料档更正确 ,甘扰减到最低。WATCH.EXE
会读取 C:\REG.DAT 档 ,根据此值直接监看 CS:IP ,当执行到此後 ,会将程式
码存档 ,因此你必需保持 RIPPER32 & WATCH 两程式执行时 ,电脑的记忆体剩
馀量与环境变数一致 ,以免抓不到中断点。

        最後将捕捉到的程式码再写回 BADY.DAT 内 ,此档的资料将最正确 ,
保护模式版的压缩档内无此档 ,因为保护模式监看 V86 的程式是不会甘扰程
式执行的。

--------------------------------------------------------------------------

结论∶

        本程式适用绝大多数的外壳 ,但也会有例外的情形 ,原因是本软体
并未真正进入保护模式 ,所以仍可能受到其它因素的影响造成当机 ,目前已
测试的外壳如下∶(还有一些不知名的未列出)

外壳名称        保护方式        状态    备注
---------       --------        ----    ----------------------------------
PKLITE          压缩             OK
PREXCM50        防TRACE          OK     只支援 EXE 档
XOE             防TRACE          OK
COPYLOCK 3.43   KeyDisk          OK
KPUTIL          KeyPro           OK
SBLOCK          KeyPro           OK     有些可以. 视档案有无被编码
DTKLOCK         KeyPro           OK
HASP            KeyPro           OK
SMARTLOCK       KeyPro           OK
PPIP            防TRACE          OK     不支援.

注∶有些可以是指被保护後 ,有的档可以解出、但是有的档却不行 ,原因是
    本版的人工智慧不足 ,还无法判断出谁才是进入点之故。

==========================================================================
小记:

发表日期   版本  名  目  功能
----------  ----  ------  ------------------------------------------------
1995/01/05  未定  测式版  可拨一层外加保护
1995/01/23  1.05  PD  版  支援多层外壳拨壳
1995/01/28  1.07  注册版  以翻译指令方式来取代追踪执行 (未发表)
1995/02/16  2.00  测试版  以1.05版为架构 ,加上更多的讯息 ,拿掉 DELAY (未发表)
1995/02/20  2.01  正式版  加上一个附属工具 WATCH.EXE ,修改 REG.DAT 档案格式
1996/09/29  3.00  正式版  加强拨壳能力 ,丢出所有程式 (含.ASM)

【 拨壳机 】     EXE 档进入点搜寻程式  (程式原理说明书)     - 软蛀 -
==========================================================================
信箱   Email:werongho@ms11.hinet.net      90网:Werong Ho    90:90/2
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌━━┐
┃前言┃
└━━┘

    拨壳机是笔者发展出的小程式 ,它能够自动追踪执行档 ,待程式执行完解压
缩、保护、病毒....等等外壳後 ,自动加以存档 ,并还原成执行档 ,使之成为无
压缩、保护、病毒的原始程式。在介绍这个软体之前 ,笔者必需介绍其所用的技
术 ,这样您的功力就会更上一层楼。

    有很多朋友都知道 PKLITE、LZEXE、SPACE MACKER .... 等等软体都能够将
执行档压缩 ,使得程式占用磁片或硬碟的空间大幅缩小 ,也可以增加载入电脑的
读取速度 ,这是因为压缩档执行後会在电脑内自我解压缩 ,并执行这个解压缩後
的程式 ;由於这些动作都是在记忆体内完成 ,使用者根本感觉不到 ,不过压缩後
的档案虽然可以节省磁片空间、加快载入速度 ,但是原来的程式码被压小了 ,程
式码变成另一个样子 ,使用者因此无法对此档做修改、扫毒 ,同时程式载入记忆
体时 ,解压程式会自动配置较大的记忆体供程式摆放压缩、解压缩的程式码 ,於
是在解压过程会占用近两倍的记忆体大小 ,直到解压完毕 ,於是稍微大一点的程
式经过压缩 ,可能就会因为记忆体不足而无法执行了 ,尤其是国外的公益软体 ,
经过压缩、电话线的资料传送来到台湾 ,国人想要将它中文化 ,第一道难题就是
将执行档解压缩。

        EXESHAPE、EXEWRITE、EXEMAKE 这些软体都是将记忆体内的程式码还原
成执行档的工具 ,要使用这个工具的话 ,必需要先学会玩 DEBUG ,并追踪执行档
至进入点 ,才能回存程式码并还原成执行档 ,不过到底哪里是程式进入点呢 ,相
信大家都有所迷惑 ,而且万一要追踪的程式有坚强的防破能力 ,那么根本就没有
机会追踪到程式进入点。

        我想很多朋友都会使用 EXEWRITE 或是 EXESHAPE 这套程式 ,但是先决
条件是要会玩 DEBUG ,且有能力追踪程式至进入点 ;现在的保护程式防破能力越
来越强 ,强到使用失去相容性的保护手段 ,其目地就是要当掉十分强悍的 S-ICE
除错程式 ,很不幸的为了当掉 S-ICE ,应用程式不断的 RESET 8259 、停止键盘
控制权、干掉 BIOS 堆叠区 ,结果一些好用的长驻程式都无用武之地 (如电动克
星、抓图程式) ,甚至会甘扰周边硬体的动作 (如PREXCM会甘扰滑鼠) ,所以将这
个失去相容性的外壳去除 ,已经变成非常需要。

        笔者发展了这套『拨壳机』能搜寻程式进入点 ,并自动计算执行档资料
的正确长度 ,加以回存 ,让使用者可以将它还原 ,免除外壳的困扰。这套程式使
用了大量的80386特有命令 , 并以共生的方式追踪程式 ,因此不怕像RESET 8259
、干掉BIOS堆叠、干掉所有中断向量表、程式摆在 40:0 的地方执行 ,只有那种
会侦测是否载入长驻程式的外壳会造成当机 ,否则顶多是找不到进入点 ,而不会
当机。

--------------------------------------------------------------------------
┌━━━━━━━━━┐
┃技术一、  档案回写┃
└━━━━━━━━━┘
※首先先要了解 EXE 档的档头的记录∶

(表格⒈)
位元组差距值
┌━━━┬━━━━━━━━━━━━━━━━━━━━━━━━━┐
┃0000H ┃EXE 档案记号的第一个部份 ( 4DH )                  ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0001H ┃EXE 档案记号的第二个部份 ( 5AH )                  ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0002H ┃档案大小除以512所得的馀数                         ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0004H ┃档案的大小,以页为单位,一页为512个BYTE             ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0006H ┃重新订位表格的项目数目                            ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0008H ┃以 PARA ( 16 BYTE) 为单位的表头大小               ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃000AH ┃程式载入之後所需的最小记忆体数                    ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃000CH ┃程式载入之後所需的最大记忆体数                    ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃000EH ┃堆叠的分段位移 ( SS ) ※⒈                        ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0010H ┃在程式开始时 SP 的初值                            ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0012H ┃查核字元                                          ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0014H ┃IP 的初值                                         ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0016H ┃程式码模组的分段位移量 ( CS ) ※⒉                ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃0018H ┃档案中第一个重定位项目的差距值                    ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃001AH ┃覆叠号码 ( 0 代表程式的常驻部份 )                 ┃
├━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
┃001BH ┃变数保留空间                                      ┃
└━━━┼━━━━━━━━━━━━━━━━━━━━━━━━━┤
        ┃重新订位表格 (每 2 Word一组)                      ┃
        ├━━━━━━━━━━━━━━━━━━━━━━━━━┤
        ┃变数保留空间                                      ┃
        ├━━━━━━━━━━━━━━━━━━━━━━━━━┤
        ┃程式与资料段                                      ┃
        ├━━━━━━━━━━━━━━━━━━━━━━━━━┤
        ┃堆叠段                                            ┃
        └━━━━━━━━━━━━━━━━━━━━━━━━━┘

    在这些资讯中 ,最难的就是重定位项目的建立 ;例如在组合语言中我们以
MOV AX,@DATA 或 CALL xxxx:xxxx ,这些会随著载入记忆体的位置而有所变动
的数值 ,就是我们要找的重定位表。底下是介绍程式载入後 ,移位表的变化。

00000   ┌━━━━━━━━━━┬━━━━━━━┐
        ┃中断向量表      ┃同左     ┃
00400   ├━━━━━━━━━━┼━━━━━━━┤
        ┃MS-DOS        ┃同左          ┃
        ├━━━━━━━━━━┼━━━━━━━┤
若前相  ┃    .               ┃       .      ┃
程,同  ┃    .               ┃       .      ┃
式环。  ┃    .               ┃       .      ┃
载境 |  ┃    .               ┃       .      ┃
入不 +->├━━━━━━━━━━┼━━━━━━━┤<-0600
        ┃mechine  assembly   ┃某一常驻程式  ┃
        ┃ code     code      ├━━━━━━━┤<-0700
        ┃                    ┃ .       .    ┃
程式本体┃  .        .        ┃ .       .    ┃
        ┃  .        .        ┃ .       .    ┃
        ┃  .        .        ┃ .       .    ┃
        ┃B83412   MOV AX,1234┃ B83413   MOV AX,1334
        ┃  .        .        ┃ .       .    ┃
        ┃  .        .        ┃ .       .    ┃
        ┃  .        .        └━━━┐      ┃
        ┃9A34000001   CALL 1000:0034 ┃  CALL 1100:0034
        ┃  .        .        ┌━━━┘ .    ┃
        ┃  .        .        ┃ .       .    ┃
10034   ├━━━━━━━━━━┤ .       .    ┃
其CS之  ┃  .        .        ┃ .       .    ┃
它节程  ┃  .        .        ├━━━━━━━┤10134
不区式->┃  .        .        ┃  .      .    ┃
在内    ┃  .        .        ┃  .      .    ┃
        ┃  .        .        ┃  .      .    ┃
12340   ├━━━━━━━━━━┤  .      .    ┃
        ┃DATA SEGMENT        ┃  .      .    ┃
        ┃  .                 ├━━━━━━━┤13340
        ┃  .                 ┃DATA SEGMENT  ┃
        ┃  .                 ┃     .        ┃  ^
        ┃  .                 ┃     .        ┃  |
        ┃DATA ENDS           ┃     .        ┃  皆
        ├━━━━━━━━━━┤     .        ┃  固
        ┃    .               ┃DATA ENDS     ┃  定
        ┃    .               ├━━━━━━━┤  差
        ┃    .               ┃     .        ┃  一
        ┃    .               ┃     .        ┃  个
        ┃    .               ┃     .        ┃  定
        ┃                    ┃     .        ┃  值

                <a>                  <b>

    EXE 档在载入记忆体时 ,DOS 会先把程式主体载入段落记忆体的偏移100H的
地方 ,然後根据档头的重定位表将指定的程式码加上段落值(DS) ,最後将控制权
交给应用程式 ,完成整个载入的动作 ;也就是说你可以在 DS:0100h 的地方找到
程式码的开头。

    从上面在的图我们可以发现有些程式码会随著载入记忆体段落不同 ,而有著
不同的变化 ,如果能在记忆体不同的时候将程式码存档 ,就可以根据这个变化制
作出档案重定位表了。所有的 EXE 档的档头资料都齐全了 ,你应该会还原执行
档了吧。
--------------------------------------------------------------------------
┌━━━━━━━━━━━┐
┃技术二、  'T' 旗标介绍┃
└━━━━━━━━━━━┘

    旗标暂存器可以用来显示 CPU 最近一次执行的结果 ,每一个位元都代表不同
的意思 ,其中 TF 是一个陷阱旗标 ,当此位元设定为 '1' 的时候 , CPU 每执行
一个指令就会产生 INT_01 中断 ,供应用程式拦截除错使用。

    ┌━┬━┬━┬━┬━┬━┬━┬━┬━┬━┬━┬━┬━┬━┬━┬━┐
    ┃xx┃xx┃xx┃xx┃OF┃DF┃IF┃TF┃SF┃ZF┃xx┃AF┃xx┃PF┃xx┃CF┃
    └━┴━┴━┴━┴━┴━┴━┴━┴━┴━┴━┴━┴━┴━┴━┴━┘

                             ┌━━━━━━━━━━━━━━━┐
   CF:进位旗标               ┃ 最简单的打开 'T' 旗标的程式: ┃
   PF:同位旗标               ┃                              ┃
   AF:辅助进位旗标           ┃         PUSHF                ┃
   ZF:零旗标                 ┃         POP     AX           ┃
   SF:正负旗标               ┃         OR      AX,0100h     ┃
   OF:溢位旗标               ┃         PUSH    AX           ┃
   TF:陷阱旗标               ┃         POPF                 ┃
   IF:中断旗标               └━━━━━━━━━━━━━━━┘
   DF:方向旗标

--------------------------------------------------------------------------
┌━━━━━━━━━━━━━━━━━━━┐
┃技术三、  硬体中断 - 除错暂存器的运用.┃
└━━━━━━━━━━━━━━━━━━━┘

    除错暂存器对於程式除错过程十分有用 ,它可以不必依靠 'T' 旗标 ,或是
变动程式码即可产生硬体中断 ,只要将记忆体的绝对位址告诉除错暂存器 ,并设
定发生硬体中断的条件 ,便可以产生 INT_01 的硬体中断。

    你可以设定电脑执行、读取、写入、读写某一位址 ,便产生 INT_01 的硬体
中断 ,如果善加利用的话 ,它确实是一个软体除错的最好方法 ,由於它是 80386
CPU 才提供的内建命令 ,所以设定此暂存器後 ,并不会因此降低电脑执行速度 ,
真是太帅了。

    80386、80486 都有 8 个除错暂存器 ,我们分别以 DR0~DR7 来表示它 ,每
个暂存器都是 32Bit ,以下是它的简易设定方式∶

DR0~DR3 提供应用程式设定发生中断的32位元绝对位址
DR4~DR5 保留
     DR6 表示发生中断(INT_1)的原因
             bit14 若为 '1' 表示这个中断的发生是因为 'T' 旗标
             bit0  若为 '1' 表示这个中断的发生原因为 DR0 发生的
             bit1  若为 '1' 表示这个中断的发生原因为 DR1 发生的
             bit2  若为 '1' 表示这个中断的发生原因为 DR2 发生的
             bit3  若为 '1' 表示这个中断的发生原因为 DR3 发生的
     DR7 表示发生中断(INT_1)的条件 ,每一个 bit 代表意义如下∶

   ┌31━━━━━━━━━━━━━━━━━━━━━━━━━━━━00┐
   ┃L┃R┃L┃R┃L┃R┃L┃R┃      ┃ ┃ ┃G┃L┃G┃L┃G┃L┃G┃L┃
   ┃E┃/┃E┃/┃E┃/┃E┃/┃001000┃1┃1┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
   ┃N┃W┃N┃W┃N┃W┃N┃W┃      ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
   ┃3┃3┃2┃2┃1┃1┃0┃0┃      ┃ ┃ ┃3┃3┃2┃2┃1┃1┃0┃0┃
   └━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┘

      LEN 表示发生中断的资料长度        R/W 表示发生中断的条件
          00 表示 BYTE                      00 执行
          01 表示 WORD                      01 写入
          10 保留                           10 未定义
          11 表示 DWORD                     11 读取与写入

        G 表示只要符合条件便会发生中断
        L 表示使用硬体中断 ,且可供其它程式使用

    例如: DR0=000A0000h (32位元绝对位址)
          DR7=00012303h
    表示当读取 A000:0000 的记忆体时 ,会发生 INT_01 的中断 ,且 DR6 的
    Bit0='1' ,记得使用者读完後 ,要自己把此 Bit 清为 '0' 唷。

--------------------------------------------------------------------------
┌━━━━━━━━━━━┐
┃技术四、  中断表大搬移┃
└━━━━━━━━━━━┘

    前面提到产生硬体中断时 ,其实就是产生 INT_01h ,我们可以靠拦截此中断
向量而得知是否产生硬体中断 ,不过万一你要除错的程式也要用到 INT_01h  的
时候 ,势必两者就会打架 ,最後只剩一个程式拥有INT_01 ,为了省掉不必要的控
制权争夺战 ,笔者便想到了此「乾坤大挪移」 ,将所有的中断表通通搬到别的地
方 ,将原先的中断表格 0000:0000 ~ 0000:03FF 的记忆体保留给应用程式 ,我
再另辟一块中断向量表 ,讲到这里 ,我相信有读者一定看不懂它是什么意思 ,原
来平常产生中断时 ,CPU 会去查最前端的1K记忆体 ,并将 CS、IP 指向它所代表
的位址继续执行 ,不过自 80386  以後的电脑就允许你把此表随意搬移到记忆体
的任何一个角落 ,例如 1000:0000 的地方 ,甚至是 1MB 以外的地方。

    原来 80386 多了一个 IDT 可以设定 ,用来告诉电脑中断表的位址 ,它的控
制很简单 ,例如 LIDT FWORD PTR CS:[IDTABLE]
            而 IDTABLE 内的值为 03FFh  ,  12345678h
                                ^^^^^长度 ^^^^^^^^^中断表所在位址

使用「乾坤大挪移」的方法很像一般 TSR 的处理方式

    未经过搬移前的中断处理方式:
         INT_X ━━━━━→ 根据 0000:0000 去查出所在中断服务程式位址

    经过搬移後的中断处理方式:
         INT_X ━━━━━→ 以 IDT 表指向的位址查出中断表服物程式位址

    如果您将所有的中断指向自己 ,那么你就可以决定是不是要带动原先的中
    断服务程式 ,如同下图:
         INT_X ━━→ 自己的中断 ━━→ 呼叫原先的旧中断

1. 笔者使用 LIDT 将中断表的 TABLE 搬到自己的程式内
━━━━━━━━━━━━━━━━━━━━━━━━━
        xor     eax,eax
        xor     edx,edx
        mov     ax,cs
        mov     cl,04h
        shl     eax,cl
        mov     dx,offset idttab
        add     eax,edx
        mov     bx,offset idtadds
        mov     cs:[bx+02h],eax         ;计算自己的中断表所在记忆体绝对位址
        mov     bx,offset idtadds
        lidt    fword ptr cs:idtadds    ;中断表大搬移「乾坤大挪移」
         .
         .
idtadds dw      03ffh,0000h,0000h
idttab  dw      offset new_00,code,offset new_01,code,offset new_02,code
        dw      offset new_03,code,offset new_04,code,offset new_05,code
                                       .
                                       . 省略 (共256个中断)
                                       .

    现在你已经把中断表给搬移了 ,於是中断发生时 ,电脑不会再去抓最前面1K
的中断表了 ,当发生中断时 ,电脑改成根据上面重设的位址去抓向量表。如果您
想要拦截什么中断就可以从这地方下手。

2. 将 256 个中断表指向自己 ,且服务程式都要去带动原始 INT
new_00 :
        push    0000h
        jmp     int_emu
new_01 :
        push    0001h
        jmp     int_emu
new_02 :
        push    0002h
        jmp     int_emu         ;限於篇幅本处未全刊出
int_emu :                       ;共要处理 255 个中断
        pushf                   ;
        push    ax
        push    bx
        push    bp
        push    ds
        cli
        mov     bp,sp
        xor     bx,bx
        mov     ds,bx
        mov     bx,ss:[bp+0ah]
        add     bx,bx
        add     bx,bx
        mov     ax,ds:[bx]              ;根据所产生的中断码 ,去 0:0 的相对
        mov     cs:int_stack,ax         ;应位址找出指向位址
        mov     ax,ds:[bx+02h]
        mov     cs:int_stack+02h,ax
        pop     ds
        pop     bp
        pop     bx
        pop     ax
        popf
        add     sp,02h
        jmp     dword ptr cs:oopstack   ;带动原始中断

    於是一场控制权争夺战终於避过了 ,应用程式拦截属於它的中断(最前面1K)
而您拦截属於自己的中断表 ,再去带动一下应用程式的中断表 ,於是大家都可以
和平共存了。

--------------------------------------------------------------------------
┌━━━━━━━━┐
┃技术整合实地应用┃
└━━━━━━━━┘

    1. 先将自己的中断表处理程式安装好
    2. 使用 AX=4B01h INT_21h 载入要拨壳的程式
    3. 打开 'T' 旗标并执行原始程式 ,应用程式每执行一个指令就会发生 INT_01
       然後就可以监看何时程式执行到进入点 ,并在适当时机打开除错暂存器 ,取
       代 'T' 旗标的执行 ,用以加快程式执行速度
    4. 若发现程式经过 RETF、JMP FAR....等等长程跳跃指令 ,便检查 DS=ES
       且 DS:[0000h] 的程式码为 CD20 ,这些条件都符合的话 ,那它应该就是
       程式进入点 ,把程式码加以存档 ,再用档案还原技术变回 .EXE 档

    举个最简单的例子来说 , .COM 格式的档案在载入记忆体後 ,一定是 DS=ES=CS
,且IP值一定等於 100h ,所以我们可以设定除错暂存器 ,当程式执行到 DS:100h 的
时候产生硬体中断 ,会发生此中断的原因只有两种可能 ,一种是程式刚载入时执行产
生的 ,另一种是经过解压、保护的手续後 ,又回到 DS:100 去执行解压後的主程式 ,
所以我们知道当中断下在 DS:100 的地方 ,产生硬体中断的条件为"执行" ,那么一共
会发生两次中断 ,当发生第二次中断的时後 ,档案加以回写 ,於是我们就完成了拨壳
的动作了。

    大多数写保护程式的人都习惯的先验证保护是否过关 ,然後才去将主程式解码 ,
执行 ,而拨壳机也是利用这个习惯去找到真正的程式进入点 ,我们只需要监视 DS:100
的地方被写入几次 ,就可以知道它有几层壳 ,就算不代表壳的层数 ,起码可以知道复
杂程度。就在最後一次写入 DS:100 的时候我们打开 'T' 旗标去追程式码 ,直到遇
到 RETF.IRET 这种长程跳越指令以後 ,就是它真正的程式进入点 ,屡试不爽。

    在本程式的 TEST.EXE 就是监视 DS:100 被写入的次数 ,并秀给使用者看。
    RIPPER32.EXE 才是根据壳数去拨它 ,笔者顺便把完整的原始程式秀给各位去改
良它。至於笔者提到保护模式版的拨壳机 ,那是因为很多保护程式会去读写除错暂
存器 ,使得拨壳机失效 ,所以笔者利用进入保护模式 ,并在最後一次读写除错暂存
器或产生 INT_1 的时候 ,偷偷下断点 ,这样就可以与别的应用程式并存 ,这点很
奸诈 ,至於应用程式读写除错暂存器的次数可以由笔者另一套软体 KPEMU310.ZIP
内可以找到 ,但是因为保护模式版拨壳机相容性太差劲 ,我不愿意流出来害人。

    或许各位会觉得本篇好像是在探讨程式进入点 ,其实当你找到程式进入点 ,便可
以透过档案回写技术 ,将资料档还原成执行档了 ,这样您是否懂了 ?

有关 EXEWRITE、RIPPER32(拨壳机) 程式都可以在笔者BBS站台找到 (02)5955461
--------------------------------------------------------------------------

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//