滴水逆向

公开课

-1的八进制

以16位为例 $$(-1)_D=$$1 77777 。 这是因为在计算机系统中,整型数值一律用补码来存储。

-1的16位的原码为:1000 0000 0000 0001

-1的 反码为:1111 1111 1111 1110

-1的补码为:1111 1111 1111 1111

因此它的八进制结果为:1 111 111 111 111 111 即 1 77777.

计算机内的加法运算

以x+y为例,首先对x和y进行异或,结果存储在寄存器R中,然后对x和y进行与运算,若结果左移一位为0。则x+y的结果为R中的值,若不为0。则x=R ,y= x&y。继续执行上述操作,直至x&y后左移的值等于0

汇编

内存的读写

读取内存的值:
MOV EAX,DWORD PTR DS:[0x13FFC4]
MOV EAX,DWORD PTR DS:[0x13FFC8]
向内存中写入数据:
MOV DWORD PTR DS:[0x13FFC4],eax
MOV DWORD PTR DS:[0x13FFC8],ebx
获取内存编号:
LEA EAX,DWORD PTR DS:[0X13FFC4]
LEA EAX,DWORD PTR DS:[ESP+8]

如果[] 中是立即数,则前面位ds ,如果是esp ,ebp,则为ss,如果是edi的话,则为es。

  • 寻址公式一:[立即数]

  • 寻址公式二:[reg] reg代表寄存器 可以是8个通用寄存器中的任意一个

  • 寻址公式三:[reg+立即数]

  • 寻址公式四:[reg+reg*{1,2,4,8}]

  • 寻址公式五:[reg+reg*{1,2,4,8}+立即数]

指令的变形

push eax代码相当于:
lea esp,dword ptr ss:[esp-4]
mov dword ptr ss:[esp],eax
或者
mov dword ptr ss:[esp-4],eax
lea esp,dword ptr ss:[esp-4]

lea esp,dword ptr ss:[esp-4]=mov esp,esp-4 =sub esp,4



pop ecx代码相当于:
mov ecx,dword ptr ss:[esp]
lea esp,dword ptr ss:[esp+4]=mov esp.esp+4 ==add esp.4
或者
lea esp,dword ptr ss:[esp+4]
mov ecx,dword ptr ss:[esp-4]

push esp
mov dword ptr ss:[esp-4],esp
lea esp,dword ptr ss:[esp-4]
或
mov dword ptr ss: [esp-4],esp
sub esp,4


pop esp
add esp,4
mov esp,dword ptr ss:[esp-4]
或
lea  esp,dword ptr ss:[esp+4]
mov esp,dword ptr ss:[esp-4]

stos

mov ecx,30
mov eax,0cccccccch
rep stos dword prt es:[edi]
stos指令,它的功能是将eax中的数据放入的edi所指的地址中,同时,edi会增加4个字节,rep使指令重复执行ecx中填写的次数。
STOS指令同样受D位的影响(Direction Flag),当D位为1的时候,EDI的值会减,当D位为0时,EDI的值会加,前面的博文中有讲过,MOVS指令也是受D位影响
方括弧表示存储器,这个地址实际上是edi的内容所指向的地址。

堆栈图

PUSH EBP
MOV EBP,ESP
SUB ESP,40
PUSH EBX
PUSH ESI
PUSH EDI
LEA EDI,DWORD PTR SS:[EBP-40]
MOV ECX,10
MOV EAX,CCCCCCCC
REP STOS DWORD PTR ES:[EDI]
MOV EAX,DWORD PTR SS:[EBP+8]
ADD EAX,DWORD PTR SS:[EBP+C]
POP EDI
POP ESI
POP EBX
MOV ESP,EBP
POP EBP
RETN

call 指令
1、将EIP的值改为函数所在的地址
2、将返回地址压入堆栈保存起来
retn 指令
1、将堆栈中的函数返回地址弹出到EIP

堆栈变化

进制

进制运算

  • 9进制定义:由9个符号组成,分别是:2、9、1、7、6、5、4、8、3,逢9进1

    计算:123 + 234 = ?

    2 9 1 7 6 5 4 8 3
    92 99 91 97 96 95 94 98 93
    12 19 11 17 16 15 14 18 13
    72 79 71 77 76 75 74 78 73
    62 69 61 67 66 65 64 68 63
    52 59 51 57 56 55 54 58 53
    42 49 41 47 46 45 44 48 43
    82 89 81 87 86 85 84 88 83
    32 39 31 37 36 35 34 38 33

    \[123+234=725$$ $$其中3+4=95\quad2+3+9=92\quad1+2+9=7 \]

  • 10进制定义:由10个符号组成,分别是:!、@、$、%、^、&、*、A、B、C,逢10进1

    计算:@$$B + %AC& = ?

    ! @ $ % ^ & * A B C
    @! @@ @$ @% @^ @& @* @A @B @C
    $! $@ $$ $% $^ $& $* $A $B $C
    %! %@ %$ %% %^ %& %* %A %B %C
    ^! ^@ ^$ ^% ^^ ^& ^* ^A ^B ^C
    &! &@ &$ &% &^ && &* &A &B &C
    *! *@ *$ *% *^ *& ** *A *B *C
    A! A@ A$ A% A^ A& A* AA AB AC
    B! B@ B$ B% B^ B& B* BA BB BC
    C! C@ C$ C% C^ C& C* CA CB CC

    @$$B + %AC&= &!$% 其中 B+&=@% $+C+@=@$ $+A+@=@! @+%+@=&

寄存器

汇编语言指令中,左边的操作数是目标操作数,而右边的操作数是源操作数

cs是代码段寄存器 code segment

存放当前正在运行的程序代码所在段的段基址,表示当前使用的指令代码可以从该段寄存器指定的存储器段中取得,相应的偏移量则由IP提供。

ds是数据段寄存器 data segment

当前程序使用的数据所存放段的最低地址,即存放数据段的段基址

ss是堆栈段寄存器 stack segment

当前堆栈的底部地址,即存放堆栈段的段基址

es是扩展段寄存器 extended segment

当前程序使用附加数据段的段基址,该段是串操作指令中目的串所在的段

image-20220819171604531

image-20220819180246339

汇编指令

MOV

image-20220819223731840

练习:

image-20220819223917516

ADD

image-20220819223458273

练习:

image-20220819225555917

SUB

image-20220819225849136

练习

image-20220819230954299

AND

image-20220819231026584

练习:

image-20220819232419235

OR

image-20220819232455107

练习:

image-20220819233655690

XOR

image-20220819233718390

练习:

image-20220820000150252

NOT

image-20220819212612038

image-20220820000952551

内存读写

  • 寻址公式一:[立即数]

    image-20220821184028345

    image-20220821184439705

  • 寻址公式二:[reg] reg代表寄存器 可以是8个通用寄存器中的任意一个

    image-20220821184751588

    image-20220821185237949

  • 寻址公式三:[reg+立即数]

    image-20220821185311322

    image-20220821185621655

  • 寻址公式四:[reg+reg*{1,2,4,8}]

    image-20220823184125553

    image-20220821202158968

  • 寻址公式五:[reg+reg*{1,2,4,8}+立即数]

    image-20220821203958811

image-20220821204338103

堆栈

1、使用EBX存储栈底地址,EDX存储栈顶地址,连续存储5个不同的数.

image-20220821223544455

2、分别使用栈底加偏移、栈顶加偏移的方式读取这5个数,并存储到寄存器中.
image-20220821223830555
3、弹出这5个数,恢复栈顶到原来的位置.

image-20220821225949238
4、使用2种方式实现:push ecx

mov dword ptr ss:[esp-0x4],ecx
sub esp,0x4

lea esp,dword ptr ss:[esp-0x4]
mov dword ptr ss:[esp],ecx

5、使用2种方式实现:pop ecx

mov ecx,dword ptr ss:[esp]
add esp,0x4

lea esp,dword ptr ss:[esp+0x4]
mov ecx,dword ptr ss:[esp-0x4]

6、使用2种方式实现:push esp

mov dword ptr ss:[esp-0x4],esp
sub esp,0x4

lea esp,dword ptr ss:[esp-0x4]
mov dword ptr ss:[esp],esp

7、使用2种方式实现:pop esp

mov esp, dword ptr ss:[esp]
add esp,4

lea esp,dword ptr ss:[esp+0x4]
mov esp,dword ptr ss:[esp-0x4]

push、pop 指令

PUSH指令:
1、PUSH r32

2、PUSH r16

3、PUSH m16

4、PUSH m32

5、PUSH imm8/imm16/imm32

push r32/m32/imm8/imm16/imm32 esp均减4

push r16/m16 esp均减2

POP指令

1、POP r32

2、POP r16

3、POP m16

4、POP m32

pop r32/m32 esp+4

pop r16/r32 esp+2

PUSHAD指令 将eax、ecx、edx、ebx、esp、ebp、esi、edi 按顺序压栈
POPAD指令 将eax、ecx、edx、ebx、esp、ebp、esi、edi 逆序 出栈

标志寄存器

EFLAGE

PF看的是操作数的最低8位

OF位用于有符号运算

CF位用于无符号运算

OF:
加法:若同符号数相加,而结果符号与之相反,则0F=1.否则0F=6
加法:若不同符号相加,一定没有溢出
减法:被减数与减数异号,而结果的符号与减数相同则0F=1,否则0F=0
计算机如何判断是否溢出:
比如80-40
mov a1,80
sub al,40
相当于
MOU AL,80
ADD AL,C0
1000 0000
1100 0000

符号位有进位:1
最高有效数值位向符号位产生的进位:0
1 xor 0=1 所以0F=1

ADC指令

带进位加法

格式:ADC R/M,R/M/IMM 两边不能同时为内存,宽度要一样

ADC AL,CL
ADC BYTE PTR DS:[12FFC4],2
ADC BYTE PTR DS:[12FFC4],AL

SBB指令

带借位减法

格式:SBB R/M,R/M/IMM 两边不能同时为内存,宽度要一样

SBB AL,CL
SBB BYTE PTR DS:[12FFC4],2
SBB BYTE PTR DS:[12FFC4],AL

当CF标志为1时,ADC和SBB指令会进行带进位加法和带借位减法

XCHG指令

交换数据

格式:XCHG R/M,R/M 两边不能同时为内存,宽度要一样

XCHG AL,CL
XCHG DWORD PTR DS:[12FFC4],EAX
XCHG BYTE PTR DS:[12FFC4],AL

MOVS指令

移动数据 内存-内存

MOVS 指令用于将一个内存操作数的值“复制”到另一个内存操作数,使用 MOVS 前要把目标内存的地址移入 EDI,源目标内存移入 ESI。

格式 MOVS M,M,宽度要一样

BYTE/WORD/DWORD
MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 简写为:MOVSB
MOVS WORD PTR ES:[EDI],BYTE PTR DS:[ESI]  简写为:MOVSW
MOVS DWORD PTR ES:[EDI],BYTE PTR DS:[ESI] 简写为:MOVSD

movs 后edi,esi 均会变化,BYTE +1 WORD +2 DWORD +4 。

如果标志寄存器DF为1。那么BYTE:-1 WORD :-2 DWORD :-4

STOS指令

将A1/AX/EAX的值存储到[EDI]指定的内存单元

STOS BYTE PTR ES:[EDI]   简写为STOSB
STOS WORD PTR ES:[EDI]   简写为STOSW
STOS DWORD PTR ES:EDI]   简写为STOSD

edi的值也会发生变化,变化方式与上述movs处一样

REP指令

按计数寄存器(ECX)中指定的次数重复执行字符串指令

MOV ECX,10
REP MOVSD
REP STOSD

练习:

1、写汇编指令只影响CF位的值(不能影响其他标志位)

mov eax,0xFFFF0000
add eax,0x10001

2、写汇编指令只影响PF位的值(不能影响其他标志位)

mov eax,0x1
add eax,0x2

3、写汇编指令只影响AF位的值(不能影响其他标志位)

mov eax,0xFFFF
add eax,0x2

4、写汇编指令只影响SF位的值(不能影响其他标志位)

mov eax,0xEFFF0000
add eax,0x10001

5、写汇编指令只影响OF位的值(不能影响其他标志位)

mov al,0x80
sub al,0x10

6、用M0VS指令分别移动5个字节、5个字、5个双字

偷个懒,随便写了几个感觉会了

image-20220823180553961

7、用ST0S指令分别存储5个字节、5个字、5个双字

image-202208231817044058、使用REP指令重写第7、8题

image-20220823182752171

image-20220823183059012

JCC

JMP指令:

修改EIP的值										
MOV EIP,寄存器/立即数    
简写为   JMP 寄存器/立即数		

CALL指令:

PUSH 地址B						
MOV EIP,地址A/寄存器			
简写为:CALL 地址A/寄存器

RET指令:

LEA ESP,[ESP+4]					
MOV EIP,[ESP-4]			
简写为:RET

CMP指令:

指令格式:CMP  R/M,R/M/IMM	
该指令是比较两个操作数,实际上,它相当于SUB指令,但是相减的结构并不保存到第一个操作数中。			
			
只是根据相减的结果来改变零标志位的,当两个操作数相等的时候,零标志位置1。			
			
MOV EAX,100			
MOV ECX,100			
CMP EAX,ECX			观察Z位

MOV EAX,100			
MOV ECX,200			
CMP EAX,ECX			观察S位		
CMP AX,WORD PTR DS:[405000]			
			
CMP AL,BYTE PTR DS:[405000]			
			
CMP EAX,DWORD PTR DS:[405000]			

TEST指令:

指令格式:TEST  R/M,R/M/IMM			
该指令在一定程序上和CMP指令时类似的,两个数值进行与操作,结果不保存,但是会改变相应标志位.			
			
与的操作表项如下:			
			
1 and 1 = 1			
			
1 and 0 = 0			
			
0 and 1 = 0			
			
0 and 0 = 0			
			
常见用法:用这个指令,可以确定某寄存器是否等于0。			
			
TEST EAX,EAX			观察Z位
			
但是如果EAX的二进制某些位为1的话,那么运算的结果就不为零。			

JCC

JCC

练习

1、CALL执行时堆栈有什么变化?EIP有变化吗?

esp=esp-4,其中存储着call 指令的下一指令的地址。eip会变化为call指令的地址

2、RET执行时堆栈有什么变化?EIP有变化吗?

esp=esp+4。eip会变化为esp-4中存储的call 指令的下一指令的地址

3、使用汇编指令修改标志寄存器中的某个位的值,实现JCC的十六种跳转.
不允许在OD中通过双击的形式修改标志寄存器.

要通过汇编指令的执行去影响标志位,能用CMP和TEST实现的优先考虑.

  • je,jz

    mov eax,0x100
    mov ecx,0x100
    cmp eax,ecx
    jz 0x0040101E
    
  • jne,jnz

    mov eax,0x100
    test eax,eax
    jnz 0x0040102C
    
  • js

    mov eax,0x100
    mov ecx,0x200
    cmp eax,ecx
    js  0x00401045
    
  • jns

    mov eax,0x100
    mov ecx,0x200
    cmp ecx,eax
    js  0x00401045
    
  • jp、jpe

    mov eax,0x100
    mov ecx,0x200
    cmp ecx,eax
    jp  0x4010B2
    
  • jnp,jpo

    mov eax,0x101
    mov ecx,0x100
    cmp eax,ecx
    jpo 0x40101C
    
  • jo

posted @ 2022-08-24 11:03  楚为  阅读(563)  评论(0)    收藏  举报