duanbin_109 发表于 2015-3-23 13:17

脱壳破解经常

汇编
数据类型
**************************************************************************************************
十进制                二进制                十六进制
0                0000                0
1                0001                1
2                0010                2               
3                0011                3       
4                0100                4
5                0101                5
6                0110                6
7                0111                7
8                1000                8
9                1001                9
10                1010                A
11                1011                B
12                1100                C
13                1101                D
14                1110                E
15                1111                F
16                1,0000                10
D               B               H
十进制的22D
二进制的20010B
十六进制22H
**************************************************************************************************
寄存器
**************************************************************************************************
1. 通用寄存器
  通用寄存器包括了8个16/32位的寄存器:AX/EAX、BX/EBX、CX/ECX、DX/EDX、SP/ESP、BP/EBP、DI/EDI及SI/ESI。其中AX/EAX、BX/EBX、CX/ECX、DX/EDX在一般情况下作为通用的数据寄存器,用来暂时存放计算过程中所用到的操作数、结果或其他信息。它们还可分为两个独立的8位寄存器使用,命名为AL、AH、BL、BH、CL、CH、DL和DH。这4个通用数据寄存器除通用功能外,还有如下专门用途:

  AX/EAX作为累加器用,所以它是算术运算的主要寄存器。在乘除指令中指定用来存放操作数。另外,所有的I/O指令都使用AX或AL与外部设备传送信息。

  BX/EBX在计算存储器地址时,可作为基址寄存器使用。

  CX/ECX常用来保存计数值,如在移位指令、循环指令和串处理指令中用作隐含的计数器。DX在作双字长运算时,可把DX和AX组合在一起存放一个双字长数,DX用来存放高16位数据。此外,对某些I/O操作,DX可用来存放I/O的端口地址。

  SP/ESP、BP/EBP、SI/ESI、DI/EDI四个16/32位寄存器可以象数据寄存器一样在运算过程中存放操作数,但它们只能以字(16/32位)为单位使用。此外,它们更经常的用途是在存储器寻址时,提供偏移地址。因此,它们可称为指针或变址寄存器。

  SP/ESP称为堆栈指针寄存器,用来指出栈顶的偏移地址。

  BP/EBP称为基址指针寄存器,在寻址时作为基地址寄存器使用,但它必须与堆栈段寄存器SS联用来确定堆栈段中的存储单元地址。


2、标志寄存器FLAG
条件码标志用来记录程序中运行结果的状态信息,它们是根据有关指令的运行结果由(CPU)自动设置的。由于这些状态信息往往作为后续条件转移指令的转移控制条件,所以称为条件码。
  ① 进位标志 CF,记录运算时最高有效位产生的进位值。
  ② 符号标志 SF,记录运算结果的符号。结果为负时置1,否则置0。
  ③ 零标志  ZF,运算结果为0时ZF位置1,否则置0。
  ④ 溢出标志 OF,在运算过程中,如操作数超出了机器可表示数的范围称为溢出。溢出时OF位置1,否则置0。
  ⑤ 辅助进位标志 AF,记录运算时第3位(半个字节)产生的进位值。
  ⑥ 奇偶标志 PF,用来为机器中传送信息时可能产生的代码出错情况提供检验条件。当结果操作数中1的个数为偶数时置1,否则置0。

数据传送指令
**************************************************************************************************
1、传送指令MOV(move)
**************************************************************************************************
传送指令是使用最频繁的指令,它相对于高级语言里的赋值语句。指令的格式如下:
MOVReg/Mem, Reg/Mem/Imm
其中:Reg—Register(寄存器),Mem—Memory(存储器),Imm—Immediate(立即数),它们可以是8位、16位或32位(特别指出其位数的除外)。
**************************************************************************************************
2、传送—填充指令
**************************************************************************************************
传送—填充指令是把位数短的源操作数传送给位数长的目的操作数。指令格式如下:
MOVSX/MOVZXReg/Mem, Reg/Mem/Imm     
其中:80386+表示80386及其之后的CPU,其它类似符号含义类同,不再说明。
指令的主要功能和限制与MOV指令类似,不同之处是:在传送时,对目的操作数的高位进行填充。根据其填充方式,又分为:符号填充和零填充。

符号填充指令MOVSX
MOVSX的填充方式是:用源操作数的符号位来填充目的操作数的高位数据位

零填充指令MOVZX
MOVZX的填充方式是:恒用0来填充目的操作数的高位数据位

例如,AL=87H,指令MOVSXCX, AL;MOVZXDX, AL执行后,问CX和DX的值是什么?

根据传送-填充指令的填充方式可知:
指令MOVSX CX, AL执行后,(CX)=0FF87H,指令MOVZX DX, AL执行后,(DX)=0087H。


从上例可看出,两条指令的源操作数完全一样,但因为它们的填充方式不同,所得到的结果而就不同。
**************************************************************************************************
3、交换指令XCHG
**************************************************************************************************
交换指令XCHG是两个寄存器,寄存器和内存变量之间内容的交换指令,两个操作数的数据类型要相同。其指令格式如下:
XCHGReg/Mem, Reg/Mem

例如,AX=5678H,BX=1234H,指令XCHGAX, BX执行后,AX和BX的值是什么?

这是两个寄存器内容进行交换,指令执行后,有:(AX)=1234H,(BX)=5678H。
**************************************************************************************************
4、取有效地址指令LEA(Load)
**************************************************************************************************
指令LEA是把一个内存变量的有效地址送给指定的寄存器。其指令格式如下:
LEA Reg, Mem
**************************************************************************************************
5、取段寄存器指令
该组指令的功能是把内存单元的一个“低字”传送给指令中指定的16位寄存器,把随后的一个“高字”传给相应的段寄存器(DS、ES、FS、GS和SS)。其指令格式如下:
LDS/LES/LFS/LGS/LSS Reg, Mem
**************************************************************************************************
6、堆栈操作指令
**************************************************************************************************
堆栈是一个重要的数据结构,它具有“先进后出”的特点,通常用来保存程序的返回地址。它主要有两大类操作:进/压栈操作和出/弹栈操作。

1)、进栈操作

、PUSH
指令格式:PUSH Reg/Mem
PUSH Imm          
一个字进栈,系统自动完成两步操作:SP←SP-2,(SP)←操作数;
一个双字进栈,系统自动完成两步操作:ESP←ESP-4,(ESP)←操作数。

、PUSHA
指令格式:PUSHA      
其功能是依次把寄存器AX、CX、DX、BX、SP、BP、SI和DI等压栈。

、PUSHAD
指令格式:PUSHAD      
其功能是把寄存器EAX、ECX、EDX、EBX、ESP、EBP、ESI和EDI等压栈。

2)、出栈操作
、POP
指令格式:POP Reg/Mem
弹出一个字,系统自动完成两步操作:操作数←(SP),SP←SP-2;
弹出一个双字,系统自动完成两步操作:操作数←(ESP),ESP←ESP-4。

、POPA
指令格式:POPA       
其功能是依次把寄存器DI、SI、BP、SP、BX、DX、CX和AX等弹出栈。其实,程序员不用记住它们的具体顺序,只要与指令PUSHA对称使用就可以了。

、POPAD
指令格式:POPAD    
其功能是依次把寄存器EDI、ESI、EBP、ESP、EBX、EDX、ECX和EAX等弹出栈,它与PUSHAD对称使用即可。
**************************************************************************************************


算术运算指令
算术运算指令是反映CPU计算能力的一组指令,也是编程时经常使用的一组指令。它包括:加、减、乘、除及其相关的辅助指令。

该组指令的操作数可以是8位、16位和32位(80386+)。当存储单元是该类指令的操作数时,该操作数的寻址方式可以是任意一种存储单元寻址方式。

1、加法指令

指令的格式:ADDReg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是把源操作数的值加到目的操作数中。

、带进位加指令ADC(见得较少)

指令的格式:ADCReg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是把源操作数和进位标志位CF的值(0/1)一起加到目的操作数中。

、加1指令INC

指令的格式:INCReg/Mem
受影响的标志位:AF、OF、PF、SF和ZF,不影响CF
指令的功能是把操作数的值加1。


、交换加指令XADD(见得较少)

指令的格式:XADDReg/Mem, Reg     
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是先交换两个操作数的值,再进行算术“加”法操作

2、减法指令

、减法指令SUB

指令的格式:SUBReg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是从目的操作数中减去源操作数。

、带借位减SBB(见得较少)

指令的格式:SBBReg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是把源操作数和标志位CF的值从目的操作数中一起减去。

、减1指令DEC

指令的格式:DECReg/Mem
受影响的标志位:AF、OF、PF、SF和ZF,不影响CF
指令的功能是把操作数的值减去1。

、求补指令NEG

指令的格式:NEGReg/Mem
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能:操作数=0-操作数,即改变操作数的正负号


3、乘法指令

计算机的乘法指令分为无符号乘法指令和有符号乘法指令,它们的唯一区别就在于:数据的最高位是作为“数值”参与运算,还是作为“符号位”参与运算。

乘法指令的被乘数都是隐含操作数,乘数在指令中显式地写出来。CPU会根据乘数是8位、16位,还是32位操作数,来自动选用被乘数:AL、AX或EAX。

指令的功能是把显式操作数和隐含操作数相乘,并把乘积存入相应的寄存器中。

、无符号数乘法指令MUL/FMUL

指令的格式:MULReg/Mem
受影响的标志位:CF和OF(AF、PF、SF和ZF无定义)
指令的功能是把显式操作数和隐含操作数(都作为无符号数)相乘

、有符号数乘法指令IMUL/FIMUL

指令的格式: IMUL Reg/Mem
IMUL Reg, Imm
IMUL Reg, Reg, Imm
IMUL Reg, Reg/Mem

4、除法指令

除法指令的被除数是隐含操作数,除数在指令中显式地写出来。CPU会根据除数是8位、16位,还是32位,来自动选用被除数AX、DX-AX,还是EDX-EAX。

除法指令功能是用显式操作数去除隐含操作数,可得到商和余数。当除数为0,或商超出数据类型所能表示的范围时,系统会自动产生0号中断。

、无符号数除法指令DIV/FDIV

指令的格式:DIVReg/Mem
指令的功能是用显式操作数去除隐含操作数(都作为无符号数)。指令对标志位的影响无定义。

、有符号数除法指令IDIV/FIDIV

指令的格式:IDIVReg/Mem
受影响的标志位:AF、CF、OF、PF、SF和ZF

逻辑运算指令

逻辑运算指令是另一组重要的指令,它包括:逻辑与(AND)、逻辑或(OR)、逻辑非(NOT)和异或指令(XOR),逻辑运算指令也是经常使用的指令。

1、逻辑与操作指令AND

指令的格式:AND Reg/Mem, Reg/Mem/Imm
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义)
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑“与操作”,操作结果存入目标操作数中。


2、逻辑或操作指令OR

指令的格式:OR Reg/Mem, Reg/Mem/Imm
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义)
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑"或操作",操作结果存入目标操作数中。


3、逻辑非操作指令NOT

指令的格式:NOT Reg/Mem
其功能是把操作数中的每位变反,即:1←0,0←1。指令的执行不影响任何标志位。


4、逻辑异或操作指令XOR

指令的格式:XOR Reg/Mem, Reg/Mem/Imm
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义)
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑"异或操作",操作结果存入目标操作数中。


mov....--->00402536
call...
....
....
xor eax,eax--->返回为0//or eax,eax
retn

je/jz..--->0040253C

检测位指令TEST

检测位指令是把二个操作数进行逻辑“与”操作,并根据运算结果设置相应的标志位,但并不保存该运算结果,所以,不会改变指令中的操作数。在该指令后,通常用JE、JNE、JZ和JNZ等条件转移指令。

指令的格式:TESTReg/Mem, Reg/Mem/Imm

受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义)

call XXXXXXXX
test al,al/eax,eax...
je/jne...
**************************************************************************************************
循环指令本身的执行不影响任何标志位。

1、循环指令

循环指令LOOP的一般格式:

LOOP 标号
LOOPW 标号      ;CX作为循环计数器
LOOPD 标号      ;ECX作为循环计数器

....
....
inc eax
dex ebx
cmp eax,ebx
jne/je XXXX ^


求1+2+…+1000之和,并把结果存入AX中。


方法1:因为计数器CX只能递减,所以,可把求和式子改变为:1000+999+…+2+1。

       XOR AX, AX
       MOV CX, 1000D
again: ADD AX, CX ;计算过程:1000+999+…+2+1
       DEC CX
       LOOP again

方法2:不用循环计数器进行累加,求和式子仍为:1+2+…+999+1000。

       XOR AX, AX
       MOV CX, 1000D
       MOV BX, 1
again: ADD AX, BX ;计算过程:1+2+…+999+1000
       INC BX
       LOOP again

从程序段的效果来看:方法1要比方法2好。为什么?^_^
**************************************************************************************************
转移指令
转移指令是汇编语言程序员经常使用的一组指令。在高级语言中,时常有“尽量不要使用转移语句”的劝告,但如果在汇编语言的程序中也尽量不用转移语句,那么该程序要么无法编写,要么没有多少功能,所以,在汇编语言中,不但要使用转移指令,而且还要灵活运用,因为指令系统中有大量的转移指令。

转移指令分无条件转移指令和有条件转移指令两大类。

1、无条件转移指令

无条件转移指令包括:JMP、子程序的调用和返回指令、中断的调用和返回指令等。

下面只介绍无条件转移指令JMP

JMP指令的一般形式:

JMP标号/Reg/Mem


2、条件转移指令

条件转移指令是一组极其重要的转移指令,它根据标志寄存器中的一个(或多个)标志位来决定是否需要转移,这就为实现多功能程序提供了必要的手段。微机的指令系统提供了丰富的条件转移指令来满足各种不同的转移需要,在编程序时,要对它们灵活运用。

条件转移指令又分三大类:基于无符号数的条件转移指令、基于有符号数的条件转移指令和基于特殊算术标志位的条件转移指令。

、无符号数的条件转移指令

指令的助忆符

JE/JZ
ZF=1 Jump Equal or Jump Zero

JNE/JNZ
ZF=0 Jump Not Equal or Jump Not Zero

JA/JNBE
CF=0 and ZF=0 Jump Above or Jump Not Below or Equal

JAE/JNB
CF=0 Jump Above or Equal or Jump Not Below

JB/JNAE
CF=1 Jump Below or Jump Not Above or Equal

JBE/JNA
CF=1 or AF=1 Jump Below or Equal or Jump Not Above

、有符号数的条件转移指令

指令的助忆符

JE/JZ
ZF=1 Jump Equal or Jump Zero

JNE/JNZ
ZF=0 Jump Not Equal or Jump Not Zero

JG/JNLE
ZF=0 and SF=OF Jump Greater or Jump Not Less or Equal

JGE/JNL
SF=OF Jump Greater or Equal or Jump Not Less

JL/JNGE
SF≠OF Jump Less or Jump Not Greater or Equal

JLE/JNG
ZF=1 or SF≠OF Jump Less or Equal or Jump Not Greater

、特殊算术标志位的条件转移指令

指令的助忆符
检测的转移条件 功能描述
JC
CF=1 Jump Carry

JNC
CF=0 Jump Not Carry

JO
OF=1 Jump Overflow

JNO
OF=0 Jump Not Overflow

JP/JPE
PF=1 Jump Parity or Jump Parity Even

JNP/JPO
PF=0 Jump Not Parity or Jump Parity Odd

JS
SF=1 Jump Sign (negative)

JNS
SF=0 Jump No Sign (positive)

例,已知一个字节变量char,试编写一程序段,把其所存的大写字母变成小写字母。

解:
next: …
char DB'F'   ;变量说明

MOV AL, char
CMP AL, 'A'
JB next      ;注意:字符是无符号数,不要使用指令JL
CMP AL, 'Z'
JA next
ADD char, 20               


1、子程序的调用和返回指令

子程序的调用和返回是一对互逆操作,也是一种特殊的转移操作。
一方面,之所以说是转移,是因为当调用一个子程序时,程序的执行顺序被改变,CPU将转而执行子程序中的指令序列,在这方面,调用子程序的操作含有转移指令的功能,子程序的返回指令的转移特性与此类似;
另一方面,转移指令是一种“一去不复返”的操作,而当子程序完后,还要求CPU能转而执行调用指令之下的指令,它是一种“有去有回”的操作。
为了满足子程序调用和返回操作的特殊性,在指令系统中设置了相应的特定指令。

1、1调用指令(CALL)
调用子程序指令的格式如下:

CALL 子程序名/Reg/Mem

子程序的调用指令分为近(near)调用和远(far)调用。如果被调用子程序的属性是近的,那么,CALL指令将产生一个近调用,它把该指令之后地址的偏移量(用一个字来表示的)压栈,把被调用子程序入口地址的偏移量送给指令指针寄存器IP即可实现执行程序的转移

如果被调用子程序的属性是远的,那么,CALL指令将产生一个远调用。这时,调用指令不仅要把该指令之后地址的偏移量压进栈,而且也要把段寄存器CS的值压进栈。在此之后,再把被调用子程序入口地址的偏移量和段值分别送给IP和CS,这样完成了子程序的远调用操作

00405600 call 00406895
00405604 ......

子程序调用指令本身的执行不影响任何标志位,但子程序体中指令的执行会改变标志位,所以,如果希望子程序的执行不能改变调用指令前后的标志位,那么,就要在子程序的开始处保护标志位,在子程序的返回前恢复标志位。

例如:

CALLDISPLAY
;DISPLAY是子程序名
CALLBX
;BX的内容是子程序的偏移量
CALLWORD1
;WORD1是内存字变量,其值是子程序的偏移量
CALLDWORD1
;DWORD1是双字变量,其值是子程序的偏移量和段值
CALLword ptr
;BX所指内存字单元的值是子程序的偏移量
CALLdword ptr
;BX所指内存双字单元的值是子程序的偏移量和段值

1、2返回指令(RET)
当子程序执行完时,需要返回到调用它的程序之中。为实现此功能,指令系统提供了一条专用的返回指令。其格式如下:

RET/RETN/RETF

子程序的返回在功能上是子程序调用的逆操作。为了与子程序的远、近调用相对应,子程序的返回也分:远返回和近返回。返回指令在堆栈操作方面是调用指令的逆过程



---------------------------------------------------------------------------------
【脱壳一般流程】

查壳(PEID、FI、PE-SCAN)--->寻找OEP(OD)--->脱壳/Dump(LordPE、PeDumper、OD自带的脱壳插件、PETools)--->修复(Import REConstructor)

【工具介绍】
1、查壳
   PEID--功能强大的侦壳工具,自带脱壳插件(但是,效果不怎么样)
   工作原理:核心是userdb.txt(大家看看就完全明白了)[通过壳的入口特征码进行辨认]
   使用方法:可以拖放、也可以把PEID添加到右键菜单里面去

   FI--功能强大的侦壳工具,DOS界面。
   使用方法:可以拖放、可以使用DOS命令行

2、寻找OEP

ollydbg的四个区域

左上角是cpu窗口,分别是地址,机器码,汇编代码,注释;注释添加方便,而且还能即时显示函数的调用结果,返回值.
右上角是寄存器窗口,但不仅仅反映寄存器的状况,还有好多东东;双击即可改变Eflag的值,对于寄存器,指令执行后发生改变的寄存器会用红色突出显示.
cpu窗口下面还有一个小窗口,显示当前操作改变的寄存器状态.
左下角是内存窗口.可以ascii或者unicode两种方式显示内存信息.
右下角的是当前堆栈情况,还有注释啊.

几个经常使用的快捷键

F2:在需要的地方下断点(INT3型断点)
F3:选择打开程序
F4:运行到所选择的那一行
F7:单步进入
F8:单步跟踪
F9:执行程序(运行程序)


其中要特别讲一下3个F9的区别和作用:

根据Ollydbg.hlp的中文翻译

Shift+F9 - 与F9相同,但是如果被调试程序发生异常而中止,调试器会首先尝试执行被调试程序指定的异常处理(请参考忽略Kernel32中的内存非法访问)。

Ctrl+F9 - 执行直到返回,跟踪程序直到遇到返回,在此期间不进入子函数也不更新CPU数据。因为程序是一条一条命令执行的,所以速度可能会慢一些。按Esc键,可以停止跟踪。

Alt+F9 - 执行直到返回到用户代码段,跟踪程序直到指令所属于的模块不在系统目录中,在此期间不进入子函数也不更新CPU数据。因为程序是一条一条执行的,所以速度可能会慢一些。按Esc键,可以停止跟踪。

看这些中文介绍大家可能还不是很明白,用我们通俗的语句来说就是:
Ctrl+F9    运行至retn (一般到了retn之后接上F7返回)
Alt+F9   运行至上层调用的下句
Shift+F9   忽略异常运行


文件:
    1.其中包括该菜单的下部有上次打开的纪录,该纪录保存有上次未清除的断点.
    2.附加.对付那些Anti-Debug程序.先运行程序,再运行od,文件-->附加.

查看:
    1.执行模块(Alt+E),查看程序使用的动态链接库
    2.查看断点.Alt+B

调试:
    1.运行(F9)加载程序后,运行!
    2.暂停(F12)
    3.单步进入(F7)遇见CALL进入!进入该子程序.
    4.单步跳过(F8)遇见CALL不进去!
    5.执行到返回(ALT+F9)就是执行到该子程的返回语句

查看-->文件

二进制文件编辑功能.查看-->文件,打开的文件是二进制显示.选中要改变的机器指令,空格,修改,右击-->保存.

具体的用途在后面的几壳脱壳课程当中将会用到,大家现在理解就行。在后面的操作中学会使用!

其他的一些具体的大家还是要看看OD的中文帮助的

3、Dump
OD自带的脱壳插件--到达OEP之后右键。。。
LordPE、PeDumper--选择所调试的进程--右键--完整脱壳

4、修复
Import REConstructor 1.6


---------------------------------------------------------------------------------
一、概论

壳出于程序作者想对程序资源压缩、注册保护的目的,把壳分为压缩壳和加密壳两种
UPX ASPCAK TELOCK PELITE NSPACK ...
ARMADILLO ASPROTECT ACPROTECT EPE SVKP ...
顾名思义,压缩壳只是为了减小程序体积对资源进行压缩,加密壳是程序输入表等等进行加密保护。当然加密壳的保护能力要强得多!

二、常见脱壳方法

预备知识

1.PUSHAD (压栈) 代表程序的入口点,
2.POPAD (出栈) 代表程序的出口点,与PUSHAD想对应,一般找到这个OEP就在附近
3.OEP:程序的入口点,软件加壳就是隐藏了OEP(或者用了假的OEP/FOEP),只要我们找到程序真正的OEP,就可以立刻脱壳。

方法一:单步跟踪法
1.用OD载入,点“不分析代码!”
2.单步向下跟踪F8,实现向下的跳。也就是说向上的跳不让其实现!(通过F4)
3.遇到程序往回跳的(包括循环),我们在下一句代码处按F4(或者右健单击代码,选择断点——>运行到所选)
4.绿色线条表示跳转没实现,不用理会,红色线条表示跳转已经实现!
5.如果刚载入程序,在附近就有一个CALL的,我们就F7跟进去,不然程序很容易跑飞,这样很快就能到程序的OEP
6.在跟踪的时候,如果运行到某个CALL程序就运行的,就在这个CALL中F7进入
7.一般有很大的跳转(大跨段),比如 jmp XXXXXX 或者 JE XXXXXX 或者有RETN的一般很快就会到程序的OEP。

Btw:在有些壳无法向下跟踪的时候,我们可以在附近找到没有实现的大跳转,右键-->“跟随”,然后F2下断,Shift+F9运行停在“跟随”的位置,再取消断点,继续F8单步跟踪。一般情况下可以轻松到达OEP!

方法二:ESP定律法
ESP定理脱壳(ESP在OD的寄存器中,我们只要在命令行下ESP的硬件访问断点,就会一下来到程序的OEP了!)
1.开始就点F8,注意观察OD右上角的寄存器中ESP有没突现(变成红色)。(这只是一般情况下,更确切的说我们选择的ESP值是关键句之后的第一个ESP值)
2.在命令行下:dd XXXXXXXX(指在当前代码中的ESP地址,或者是hr XXXXXXXX),按回车!
3.选中下断的地址,断点--->硬件访--->WORD断点。
4.按一下F9运行程序,直接来到了跳转处,按下F8,到达程序OEP。

方法三:内存镜像法
1:用OD打开软件!
2:点击选项——调试选项——异常,把里面的忽略全部√上!CTRL+F2重载下程序!
3:按ALT+M,打开内存镜象,找到程序的第一个.rsrc.按F2下断点,然后按SHIFT+F9运行到断点,接着再按ALT+M,打开内存镜象,找到程序的第一个.rsrc.上面的.CODE(也就是00401000处),按F2下断点!然后按SHIFT+F9(或者是在没异常情况下按F9),直接到达程序OEP!


方法四:一步到达OEP
1.开始按Ctrl+F,输入:popad(只适合少数壳,包括UPX,ASPACK壳),然后按下F2,F9运行到此处
2.来到大跳转处,点下F8,到达OEP!

方法五:最后一次异常法
1:用OD打开软件
2:点击选项——调试选项——异常,把里面的√全部去掉!CTRL+F2重载下程序
3:一开始程序就是一个跳转,在这里我们按SHIFT+F9,直到程序运行,记下从开始按SHIFT+F9到程序运行的次数m!
4:CTRL+F2重载程序,按SHIFT+F9(这次按的次数为程序运行的次数m-1次)
5:在OD的右下角我们看见有一个"SE 句柄",这时我们按CTRL+G,输入SE 句柄前的地址!
6:按F2下断点!然后按SHIFT+F9来到断点处!
7:去掉断点,按F8慢慢向下走!
8:到达程序的OEP!

方法六:模拟跟踪法
1:先试运行,跟踪一下程序,看有没有SEH暗桩之类
2:ALT+M打开内存镜像,找到(包含=SFX,imports,relocations)

内存镜像,项目 30
地址=0054B000
大小=00002000 (8192.)
Owner=check    00400000
区段=.aspack
包含=SFX,imports,relocations
类型=Imag 01001002
访问=R
初始访问=RWE

3:地址为0054B000,如是我们在命令行输入tc eip<0054B000,回车,正在跟踪ing。。

Btw:大家在使用这个方法的时候,要理解他是要在怎么样的情况下才可以使用

方法七:“SFX”法
1:设置OD,忽略所有异常,也就是说异常选项卡里面都打上勾
2:切换到SFX选项卡,选择“字节模式跟踪实际入口(速度非常慢)”,确定。
3:重载程序(如果跳出是否“压缩代码?”选择“否”,OD直接到达OEP)

Btw:这种方法不要滥用得好,锻炼能力为妙。






风恋残影 发表于 2015-3-23 13:49

duanbin_109 发表于 2015-3-23 13:18

路过的给点分

名叫呆呆 发表于 2015-3-23 14:19

我念书少真的

不愿醒来 发表于 2015-3-23 14:06

感谢分享   支持

万物皆为灰烬 发表于 2015-3-23 14:33

谢谢,收藏了

ccc1188ccc 发表于 2015-3-23 22:24

谢谢楼主
页: [1]
查看完整版本: 脱壳破解经常