WEB开发网
开发学院网络安全黑客技术 解密教学---第2章 基础知识 阅读

解密教学---第2章 基础知识

 2006-12-04 20:11:23 来源:WEB开发网   
核心提示:第一节 软件保护软件的破解技术与保护技术这两者之间本身就是矛与盾的关系,它们是在互相斗争中发展进化的,解密教学---第2章 基础知识,这种技术上的较量归根到底是一种利益的冲突,软件开发者为了维护自身的商业利益,上面的几点分析方法,只是提供了一种基本的分析方法,不断地寻找各种有效的技术来保护自身的软件版权,以增加其保护强

第一节 软件保护

软件的破解技术与保护技术这两者之间本身就是矛与盾的关系,它们是在互相斗争中发展进化的。这种技术上的较量归根到底是一种利益的冲突。软件开发者为了维护自身的商业利益,不断地寻找各种有效的技术来保护自身的软件版权,以增加其保护强度,推迟软件被破解的时间;而破解者则或受盗版所带来的高额利润的驱使,或出于纯粹的个人兴趣,而不断制作新的破解工具并针对新出现的保护方式进行跟踪分析以找到相应的破解方法。从理论上说,几乎没有破解不了的保护。对软件的保护仅仅靠技术是不够的,而这最终要靠人们的知识产权意识和法制观念的进步以及生活水平的提高。但是如果一种保护技术的强度强到足以让破解者在软件的生命周期内无法将其完全破解,这种保护技术就可以说是非常成功的。软件保护方式的设计应在一开始就作为软件开发的一部分来考虑,列入开发计划和开发成本中,并在保护强度、成本、易用性之间进行折衷考虑,选择一个合适的平衡点。

在桌面操作系统中,微软的产品自然是独霸天下,一般个人用户接触得最多,研究得自然也更多一些。在DOS时代之前就有些比较好的软件保护技术,而在DOS中使用得最多的恐怕要算软盘指纹防拷贝技术了。由于DOS操作系统的脆弱性,在其中运行的普通应用程序几乎可以访问系统中的任何资源,如直接访问任何物理内存、直接读写任何磁盘扇区、直接读写任何I/O端口等,这给软件保护者提供了极大的自由度,使其可以设计出一些至今仍为人称道的保护技术;自Windows 95开始(特别是WinNT和Windows 2000这样严格意义上的多用户操作系统),操作系统利用硬件特性增强了对自身的保护,将自己运行在Ring 0特权级中,而普通应用程序则运行在最低的特权级Ring 3中,限制了应用程序所能访问的资源,使得软件保护技术在一定程度上受到一些限制。开发者要想突破Ring 3的限制,一般需要编写驱动程序,如读写并口上的软件狗的驱动程序等,这增加了开发难度和周期,自然也增加了成本。同时由于Win32程序内存寻址使用的是相对来说比较简单的平坦寻址模式(相应地其采用的PE文件格式也比以前的16-bit的EXE程序的格式要容易处理一些),并且Win32程序大量调用系统提供的API,而Win32平台上的调试器如SoftICE等恰好有针对API设断点的强大功能,这些都给跟踪破解带来了一定的方便。

第二节 8088 汇编速查手册           

一、数据传输指令

───────────────────────────────────────

它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.

1. 通用数据传送指令.

MOV  传送字或字节.

MOVSX 先符号扩展,再传送.

MOVZX 先零扩展,再传送.

PUSH  把字压入堆栈.

POP  把字弹出堆栈.

PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.

POPA  把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.

PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.

POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.

BSWAP 交换32位寄存器里字节的顺序

XCHG  交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)

CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )

XADD  先交换再累加.( 结果在第一个操作数里 )

XLAT  字节查表转换.

── BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即

0-FFH); 返回 AL 为查表结果. ( [BX+AL]->AL )

2. 输入输出端口传送指令.

IN   I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )

OUT  I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )

输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,

其范围是 0-65535.

3. 目的地址传送指令.

LEA  装入有效地址.

例: LEA DX,string ;把偏移地址存到DX.

LDS  传送目标指针,把指针内容装入DS.

例: LDS SI,string ;把段地址:偏移地址存到DS:SI.

LES  传送目标指针,把指针内容装入ES.

例: LES DI,string ;把段地址:偏移地址存到ES:DI.

LFS  传送目标指针,把指针内容装入FS.

例: LFS DI,string ;把段地址:偏移地址存到FS:DI.

LGS  传送目标指针,把指针内容装入GS.

例: LGS DI,string ;把段地址:偏移地址存到GS:DI.

LSS  传送目标指针,把指针内容装入SS.

例: LSS DI,string ;把段地址:偏移地址存到SS:DI.

4. 标志传送指令.

LAHF  标志寄存器传送,把标志装入AH.

SAHF  标志寄存器传送,把AH内容装入标志寄存器.

PUSHF 标志入栈.

POPF  标志出栈.

PUSHD 32位标志入栈.

POPD  32位标志出栈.

二、算术运算指令

───────────────────────────────────────

ADD  加法.

ADC  带进位加法.

INC  加 1.

AAA  加法的ASCII码调整.

DAA  加法的十进制调整.

SUB  减法.

SBB  带借位减法.

DEC  减 1.

NEC  求反(以 0 减之).

CMP  比较.(两操作数作减法,仅修改标志位,不回送结果).

AAS  减法的ASCII码调整.

DAS  减法的十进制调整.

MUL  无符号乘法.

IMUL  整数乘法.

以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算),

AAM  乘法的ASCII码调整.

DIV  无符号除法.

IDIV  整数除法.

以上两条,结果回送:

商回送AL,余数回送AH, (字节运算);

或 商回送AX,余数回送DX, (字运算).

AAD  除法的ASCII码调整.

CBW  字节转换为字. (把AL中字节的符号扩展到AH中去)

CWD  字转换为双字. (把AX中的字的符号扩展到DX中去)

CWDE  字转换为双字. (把AX中的字符号扩展到EAX中去)

CDQ  双字扩展.  (把EAX中的字的符号扩展到EDX中去)

三、逻辑运算指令

───────────────────────────────────────

AND  与运算.

OR   或运算.

XOR  异或运算.

NOT  取反.

TEST  测试.(两操作数作与运算,仅修改标志位,不回送结果).

SHL  逻辑左移.

SAL  算术左移.(=SHL)

SHR  逻辑右移.

SAR  算术右移.(=SHR)

ROL  循环左移.

ROR  循环右移.

RCL  通过进位的循环左移.

RCR  通过进位的循环右移.

以上八种移位指令,其移位次数可达255次.

移位一次时, 可直接用操作码. 如 SHL AX,1.

移位>1次时, 则由寄存器CL给出移位次数.

如 MOV CL,04

SHL AX,CL

四、串指令

───────────────────────────────────────

DS:SI 源串段寄存器 :源串变址.

ES:DI 目标串段寄存器:目标串变址.

CX   重复次数计数器.

AL/AX 扫描值.

D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.

Z标志 用来控制扫描或比较操作的结束.

MOVS  串传送.

( MOVSB 传送字符.  MOVSW 传送字.  MOVSD 传送双字. )

CMPS  串比较.

( CMPSB 比较字符.  CMPSW 比较字. )

SCAS  串扫描.

把AL或AX的内容与目标串作比较,比较结果反映在标志位.

LODS  装入串.

把源串中的元素(字或字节)逐一装入AL或AX中.

( LODSB 传送字符.  LODSW 传送字.  LODSD 传送双字. )

STOS  保存串.

是LODS的逆过程.

REP      当CX/ECX<>0时重复.

REPE/REPZ   当ZF=1或比较结果相等,且CX/ECX<>0时重复.

REPNE/REPNZ  当ZF=0或比较结果不相等,且CX/ECX<>0时重复.

REPC     当CF=1且CX/ECX<>0时重复.

REPNC     当CF=0且CX/ECX<>0时重复.

五、程序转移指令

───────────────────────────────────────

1>无条件转移指令 (长转移)

JMP  无条件转移指令

CALL  过程调用

RET/RETF过程返回.

2>条件转移指令 (短转移,-128到+127的距离内)

( 当且仅当(SF XOR OF)=1时,OP1<OP2 )

JA/JNBE 不小于或不等于时转移.

JAE/JNB 大于或等于转移.

JB/JNAE 小于转移.

JBE/JNA 小于或等于转移.

以上四条,测试无符号整数运算的结果(标志C和Z).

JG/JNLE 大于转移.

JGE/JNL 大于或等于转移.

JL/JNGE 小于转移.

JLE/JNG 小于或等于转移.

以上四条,测试带符号整数运算的结果(标志S,O和Z).

JE/JZ 等于转移.

JNE/JNZ 不等于时转移.

JC   有进位时转移.

JNC  无进位时转移.

JNO  不溢出时转移.

JNP/JPO 奇偶性为奇数时转移.

JNS  符号位为 "0" 时转移.

JO   溢出转移.

JP/JPE 奇偶性为偶数时转移.

JS   符号位为 "1" 时转移.

3>循环控制指令(短转移)

LOOP      CX不为零时循环.

LOOPE/LOOPZ  CX不为零且标志Z=1时循环.

LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.

JCXZ      CX为零时转移.

JECXZ     ECX为零时转移.

4>中断指令

INT  中断指令

INTO  溢出中断

IRET  中断返回

5>处理器控制指令

HLT  处理器暂停, 直到出现中断或复位信号才继续.

WAIT  当芯片引线TEST为高电平时使CPU进入等待状态.

ESC  转换到外处理器.

LOCK  封锁总线.

NOP  空操作.

STC  置进位标志位.

CLC  清进位标志位.

CMC  进位标志取反.

STD  置方向标志位.

CLD  清方向标志位.

STI  置中断允许位.

CLI  清中断允许位.

六、伪指令

───────────────────────────────────────

DW   定义字(2字节).

PROC  定义过程.

ENDP  过程结束.

SEGMENT 定义段.

ASSUME 建立段寄存器寻址.

ENDS  段结束.

END  程序结束.

第三节 8088 汇编跳转

一、状态寄存器

PSW(Program Flag)程序状态字寄存器,是一个16位寄存器,由条件码标志(flag)和控制标志构成,如下所示:

1514131211109876543210
    OFDFIFTFSFZF AF PF CF

条件码:

①OF(Overflow Flag)溢出标志。溢出时为1,否则置0。

②SF(Sign Flag)符号标志。结果为负时置1,否则置0.

③ZF(Zero Flag)零标志,运算结果为0时ZF位置1,否则置0.

④CF(Carry Flag)进位标志,进位时置1,否则置0.

⑤AF(Auxiliary carry Flag)辅助进位标志,记录运算时第3位(半个字节)产生的进位置。有进位时1,否则置0.

⑥PF(Parity Flag)奇偶标志。结果操作数中1的个数为偶数时置1,否则置0.

控制标志位:

⑦DF(Direction Flag)方向标志,在串处理指令中控制信息的方向。

⑧IF(Interrupt Flag)中断标志。

⑨TF(Trap Flag)陷井标志。

二、 直接标志转移(8位寻址)

指令格式机器码测试条件如...则转移  指令格式机器码测试条件如...则转移
JC 72C=1有进位JNS79S=0正号
JNC 73C=0无进位JO70O=1有溢出
JZ/JE 74Z=1零/等于JNO71O=0无溢出
JNZ/JNE 75Z=0不为零/不等于JP/JPE7AP=1奇偶位为偶
JS78S=1负号JNP/IPO7BP=0奇偶位为奇

三、间接标志转移(8位寻址)

指令格式机器码测试格式如...则转移
JA/JNBE(比较无符号数)77C或Z=0>  高于/不低于或等于
JAE/JNB(比较无符号数)73C=0>=  高于或等于/不低于
JB/JNAE(比较无符号数)72C=1<  低于/不高于或等于
JBE/JNA(比较无符号数)76C或Z=1<=  低于或等于/不高于
JG/JNLE(比较带符号数)7F(S异或O)或Z=0>  大于/不小于或等于
JGE/JNL(比较带符号数)7DS异或O=0>=  大于或等于/不小于
JL/JNGE(比较带符号数)7CS异或O=1<  小于/不大于或等于
JLE/JNG(比较带符号数)7E(S异或O)或Z=1<=  小于或等于/不大于

四、无条件转移指令(fisheep译 fisheep@sohu.com)

操作码 伪码指令含义
EB  cbJMP rel8相对短跳转(8位),使rel8处的代码位下一条指令
E9  cwJMP rel16 相对跳转(16位),使rel16处的代码位下一条指令
FF  /4JMP r/m16绝对跳转(16位),下一指令地址在r/m16中给出
FF  /4JMP r/m32绝对跳转(32位),下一指令地址在r/m32中给出
EA  cbJMP ptr16:16远距离绝对跳转, 下一指令地址在操作数中
EA  cbJMP ptr16:32 远距离绝对跳转, 下一指令地址在操作数中
FF  /5JMP m16:16远距离绝对跳转, 下一指令地址在内存m16:16中
FF  /5JMP m16:32 远距离绝对跳转, 下一指令地址在内存m16:32中

五、16位/32位寻址方式(fisheep译 fisheep@sohu.com)

操作码伪码指令跳转含义 跳转类型跳转的条件(标志位)
0F 87  cw/cdJA rel16/32大于near(CF=0 and ZF=0)
0F 83  cw/cdJAE rel16/32大于等于near(CF=0)
0F 82  cw/cdJB rel16/32小于near(CF=1)
0F 86  cw/cdJBE rel16/32小于等于near(CF=1 or ZF=1)
0F 82  cw/cdJC rel16/32进位near(CF=1)
0F 84  cw/cdJE rel16/32等于near(ZF=1)
0F 84  cw/cdJZ rel16/32为0near(ZF=1)
0F 8F  cw/cdJG rel16/32大于near(ZF=0 and SF=OF)
0F 8D  cw/cdJGE rel16/32 大于等于near(SF=OF)
0F 8C  cw/cdJL rel16/32小于 near(SF<>OF)
0F 8E  cw/cdJLE rel16/32小于等于near(ZF=1 or SF<>OF)
0F 86  cw/cdJNA rel16/32 不大于near(CF=1 or ZF=1)
0F 82  cw/cdJNAE rel16/32不大于等于near(CF=1)
0F 83  cw/cdJNB rel16/32不小于near(CF=0)
0F 87  cw/cdJNBE rel16/32不小于等于near(CF=0 and ZF=0)
0F 83  cw/cdJNC rel16/32 不进位near(CF=0)
0F 85  cw/cdJNE rel16/32不等于near(ZF=0)
0F 8E  cw/cdJNG rel16/32不大于near(ZF=1 or SF<>OF)
0F 8C  cw/cdJNGE rel16/32 不大于等于near(SF<>OF)
0F 8D  cw/cdJNL rel16/32不小于near(SF=OF)
0F 8F  cw/cdJNLE rel16/32 不小于等于near(ZF=0 and SF=OF)
0F 81  cw/cdJNO rel16/32未溢出near(OF=0)
0F 8B  cw/cdJNP rel16/32 不是偶数near(PF=0)
0F 89  cw/cdJNS rel16/32 非负数near(SF=0)
0F 85  cw/cdJNZ rel16/32非零(不等于)near(ZF=0)
0F 80  cw/cdJO rel16/32 溢出near(OF=1)
0F 8A  cw/cdJP rel16/32 偶数near(PF=1)
0F 8A  cw/cdJPE rel16/32偶数near(PF=1)
0F 8B  cw/cdJPO rel16/32 奇数near(PF=0)
0F 88  cw/cdJS rel16/32负数near(SF=1)
0F 84  cw/cdJZ rel16/32 为零(等于)near(ZF=1)

注:一些指令操作数的含义说明:

rel8   表示 8 位相对地址

rel16  表示 16 位相对地址

rel16/32 表示 16或32 位相对地址

r/m16  表示16位寄存器

r/m32  表示32位寄存器

第四节 浮点指令

对下面的指令先做一些说明:

st(i):代表浮点寄存器,所说的出栈、入栈操作都是对st(i)的影响

src,dst,dest,op等都是指指令的操作数,src表示源操作数,dst/dest表示目的操作数

mem8,mem16,mem32,mem64,mem80等表示是内存操作数,后面的数值表示该操作数的内存位数(8位为一字节)

x <- y 表示将y的值放入x,例st(0) <- st(0) - st(1)表示将st(0)-st(1)的值放入浮点寄存器st(0)

1. 数据传递和对常量的操作指令

指令格式

指令含义

执行的操作

FLD src

装入实数到st(0)

st(0) <- src (mem32/mem64/mem80)

FILD src

装入整数到st(0)

st(0) <- src (mem16/mem32/mem64)

FBLD src 

装入BCD数到st(0)

st(0) <- src (mem80)

FLDZ

将0.0装入st(0)

st(0) <- 0.0

FLD1

将1.0装入st(0)

st(0) <- 1.0

FLDPI

将pi装入st(0)

st(0) <- ?(ie, pi)

FLDL2T

将log2(10)装入st(0)

st(0) <- log2(10)

FLDL2E

将log2(e)装入st(0)

st(0) <- log2(e)

FLDLG2

将log10(2)装入st(0)

st(0) <- log10(2)

FLDLN2

将loge(2)装入st(0)

st(0) <- loge(2)

FST dest

保存实数st(0)到dest

dest <- st(0) (mem32/mem64)

FSTP dest

dest <- st(0) (mem32/mem64/mem80);然后再执行一次出栈操作

FIST dest

将st(0)以整数保存到dest

dest <- st(0) (mem32/mem64)

FISTP dest

dest <- st(0) (mem16/mem32/mem64);然后再执行一次出栈操作

FBST dest

将st(0)以BCD保存到dest

dest <- st(0) (mem80)

FBSTP dest 

dest<- st(0) (mem80);然后再执行一次出栈操作

2.比较指令

指令格式

指令含义

执行的操作

FCOM

实数比较

将标志位设置为 st(0) - st(1) 的结果标志位

FCOM op

实数比较

将标志位设置为 st(0) - op (mem32/mem64)的结果标志位

FICOM op

和整数比较

将Flags值设置为st(0)-op 的结果op (mem16/mem32)

FICOMP op

和整数比较

将st(0)和op比较 op(mem16/mem32)后;再执行一次出栈操作

FTST 

零检测 

将st(0)和0.0比较

FUCOM st(i) 

比较st(0) 和st(i)         [486]

FUCOMP st(i)   

比较st(0) 和st(i),并且执行一次出栈操作

FUCOMPP st(i)  

比较st(0) 和st(i),并且执行两次出栈操作

FXAM 

Examine: Eyeball st(0) (set condition codes)

3.运算指令

指令格式

指令含义

执行的操作

加法

FADD

加实数

st(0) <-st(0) + st(1)

FADD src

st(0) <-st(0) + src (mem32/mem64)

FADD st(i),st

st(i) <- st(i) + st(0)

FADDP st(i),st 

st(i) <- st(i) + st(0);然后执行一次出栈操作

FIADD src 

加上一个整数

st(0) <-st(0) + src (mem16/mem32)

减法

FSUB

减去一个实数

st(0) <- st(0) - st(1)

FSUB src

st(0) <-st(0) - src (reg/mem)

FSUB st(i),st

st(i) <-st(i) - st(0)

FSUBP st(i),st

st(i) <-st(i) - st(0),然后执行一次出栈操作

FSUBR st(i),st

用一个实数来减

st(0) <- st(i) - st(0)

FSUBRP st(i),st

st(0) <- st(i) - st(0),然后执行一次出栈操作

FISUB src

减去一个整数

st(0) <- st(0) - src (mem16/mem32)

FISUBR src

用一个整数来减

st(0) <- src - st(0) (mem16/mem32)

乘法

FMUL

乘上一个实数

st(0) <- st(0) * st(1)

FMUL st(i)

st(0) <- st(0) * st(i)

FMUL st(i),st

st(i) <- st(0) * st(i)

FMULP st(i),st

st(i) <- st(0) * st(i),然后执行一次出栈操作

FIMUL src

乘上一个整数

st(0) <- st(0) * src (mem16/mem32)

除法

FDIV 

除以一个实数

st(0) <-st(0) /st(1)

FDIV st(i)

st(0) <- st(0) /t(i)

FDIV st(i),st

st(i) <-st(0) /st(i)

FDIVP st(i),st

st(i) <-st(0) /st(i),然后执行一次出栈操作

FIDIV src 

除以一个整数

st(0) <- st(0) /src (mem16/mem32)

FDIVR st(i),st

用实数除

st(0) <- st(i) /st(0)

FDIVRP st(i),st

FDIVRP st(i),st

FIDIVR src

用整数除

st(0) <- src /st(0) (mem16/mem32)

FSQRT

平方根

st(0) <- sqrt st(0)

FSCALE

2的st(0)次方

st(0) <- 2 ^ st(0)

FXTRACT

Extract exponent:

st(0) <-exponent of st(0); and gets pushed

st(0) <-significand of st(0)

FPREM 

取余数

st(0) <-st(0) MOD st(1)

FPREM1

取余数(IEEE),同FPREM,但是使用IEEE标准[486]

FRNDINT 

取整(四舍五入)

st(0) <- INT( st(0) ); depends on RC flag

FABS

求绝对值

st(0) <- ABS( st(0) ); removes sign

FCHS

改变符号位(求负数)

st(0) <-st(0)

F2XM1

计算(2 ^ x)-1

st(0) <- (2 ^ st(0)) - 1

FYL2X 

计算Y * log2(X)

st(0)为Y;st(1)为X;将st(0)和st(1)变为st(0) * log2( st(1) )的值

FCOS

余弦函数Cos

st(0) <- COS( st(0) )

FPTAN

正切函数tan

st(0) <- TAN( st(0) )

FPATAN

反正切函数arctan

st(0) <- ATAN( st(0) )

FSIN

正弦函数sin

st(0) <- SIN( st(0) )

FSINCOS

sincos函数

st(0) <-SIN( st(0) ),并且压入st(1)

st(0) <- COS( st(0) )

FYL2XP1 

计算Y * log2(X+1)

st(0)为Y; st(1)为X; 将st(0)和st(1)变为st(0) * log2( st(1)+1 )的值

处理器控制指令

FINIT

初始化FPU

FSTSW AX

保存状态字的值到AX

AX<- MSW

FSTSW dest

保存状态字的值到dest

dest<-MSW (mem16)

FLDCW src

从src装入FPU的控制字

FPU CW <-src (mem16)

FSTCW dest

将FPU的控制字保存到dest

dest<- FPU CW

FCLEX 

清除异常

FSTENV dest

保存环境到内存地址dest处 保存状态字、控制字、标志字和异常指针的值

FLDENV src

从内存地址src处装入保存的环境

FSAVE dest

保存FPU的状态到dest处 94字节

FRSTOR src

从src处装入由FSAVE保存的FPU状态

FINCSTP

增加FPU的栈指针值

st(6) <-st(5); st(5) <-st(4),...,st(0) <-?

FDECSTP

减少FPU的栈指针值

st(0) <-st(1); st(1) <-st(2),...,st(7) <-?

FFREE st(i)

标志寄存器st(i)未被使用

FNOP 

空操作,等同CPU的nop

st(0) <-st(0)

WAIT/FWAIT

同步FPU与CPU:停止CPU的运行,直到FPU完成当前操作码

FXCH

交换指令,交换st(0)和st(1)的值

st(0) <-st(1)

st(1) <- st(0)

第五节 分析技术

在进行软件的破解、解密以及计算机病毒分析工作中,一个首要的问题是对软件及病毒进行分析。这些软件都是机器代码程序,对于它们分析必须使用静态或动态调试工具,分析跟踪其汇编代码。

一、从软件使用说明和操作中分析软件

欲破解一软件,首先应该先用用这软件,了解一下功能是否有限制,最好阅读一下软件的说明或手册,特别是自己所关心的关键部分的使用说明,这样也许能够找点线索。

二、静态反汇编

所谓静态分析即从反汇编出来的程序清单上分析,从提示信息入手进行分析。目前,大多数软件在设计时,都采用了人机对话方式。所谓人机对话,即在软件运行过程中,需要由用户选择的地方,软件即显示相应的提示信息,并等待用户按键选择。而在执行完某一段程序之后,便显示一串提示信息,以反映该段程序运行后的状态,是正常运行,还是出现错误,或者提示用户进行下一步工作的帮助信息。为此,如果我们对静态反汇编出来的程序清单进行阅读,可了解软件的编程思路,以便顺利破解。 常用的静态分析工具是W32DASM、IDA和HIEW等。

三、动态跟踪分析

虽然从静态上可以了解程序的思路,但是并不可能真正了解地了解软件的细节,如静态分析找不出线索,就要动态分析程序,另外,碰到压缩程序,静态分析也无能为力了,只能动态分析了。所谓动态分析是利用SOFTICE或TRW2000一步一步地单步执行软件。为什么要对软件进行动态分析呢?这主要是因为:

1、许多软件在整体上完成的功能,一般要分解成若干模块来完成,而且后一模块在执行时,往往需要使用其前一模块处理的结果,这一结果我们把它叫中间结果。如果我们只对软件本身进行静态地分析,一般是很难分析出这些中间结果的。而只有通过跟踪执行前一模块,才能看到这些结果。另外,在程序的运行过程中,往往会在某一地方出现许多分支和转移,不同的分支和转移往往需要不同的条件,而这些条件一般是由运行该分支之前的程序来产生的。如果想知道程序运行到该分支的地方时,去底走向哪一分支,不进行动态地跟踪和分析是不得而知的。

2、有许多软件在运行时,其最初执行的一段程序往往需要对该软件的后面各个模块进行一些初始始化工作,而没有依赖系统的重定位。

3、有许多加密程序为了阻止非法跟踪和阅读,对执行代码的大部分内容进行了加密变换,而只有很短的一段程序是明文。加密程序运行时,采用了逐块解密,逐块执行和方法,首先运行最初的一段明文程序,该程序在运行过程中,不仅要完成阻止跟踪的任务,而且还要负责对下一块密码进行解密。显然仅对该软件的密码部分进行反汇编,不对该软件动态跟踪分析,是根本不可能进行解密的。

由于上述原因,在对软件静态分析不行的条件下,就要进行动态分析了。哪么如何有效地进行动态跟踪分析呢?一般来说有如下几点:

1、对软件进行粗跟踪

所谓粗跟踪,即在跟踪时要大块大块地跟踪,也就是说每次遇到调用CALL指令、重复操作指令REP.循环操作LOOP指令以及中断调用INT指令等,一般不要跟踪进去,而是根据执行结果分析该段程序的功能。

2、对关键部分进行细跟踪

对软件进行了一定程度的粗跟踪之后,便可以获取软件中我们所关心的模块或程序段,这样就可以针对性地对该模块进行具体而详细地跟踪分析。一般情况下,对关键代码的跟踪可能要反复进行若干次才能读懂该程序,每次要把比较关键的中间结果或指令地址记录下来,这样会对下一次分析有很大的帮助。软件分析是一种比较复杂和艰苦的工作,上面的几点分析方法,只是提供了一种基本的分析方法。要积累软件分析的经验需要在实践中不断地探索和总结。

Tags:解密 教学 基础知识

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接