首页
社区
课程
招聘
[原创]学习从基础自学逆向
发表于: 2021-10-29 20:37 24292

[原创]学习从基础自学逆向

2021-10-29 20:37
24292

CPU指令集(CPU微处理器架构)分为x86以及ARM

ASM(assembly language):汇编语言

在运行 Microsoft Windows 的 x86 系统中,其他一些有名的汇编器包括:TASM(Turbo 汇编器),NASM(Netwide 汇编器)和 MASM32(MASM 的一种变体)。GAS(GNU 汇编器)和 NASM 是两种基于 Linux 的汇编器。在这些汇编器中,NASM 的语法与 MASM 的最相似。

32 位保护模式(32-Bit Protected Mode):32 位保护模式程序运行于所有的 32 位和 64 位版本的 Microsoft Windows 系统。它们通常比实模式程序更容易编写和理解。从现在开始,将其简称为 32 位模式。

64 位模式(64-Bit Mode):64 位程序运行于所有的 64 位版本 Microsoft Windows 系统。

16 位实地址模式(16-Bit Real-Address Mode):16 位程序运行于 32 位版本 Windows 和嵌入式系统。 64 位 Windows 不支持这类程序。

汇编语言与机器语言是一对一(one-to-one)的关系:每一条汇编语言指令对应一条机器语言指令。

x86可以再两种操作模式下运行:实模式保护模式

x86通过一种环级别(ring level)的抽象来支持特权隔离。处理器支持4种特权级别,编号为0到3(通常不使用ring1和ring2,所以不讨论)

因此现代操作系统通常将用户模式应用程序运行在ring3级别,内核运行在ring0级别,以此实现用户/内核特权隔离,ring级别编码于CS寄存器

x86独有的,支持INC或ADD指令,让内存地址中的某个数递增

Intel

mov ecx , AABBCCDDh
mov ecx , [eax]
mov ecx , eax

AT&T

movl $0xAABBCCDD , %ecx
movl (%eax) , %ecx
movl %eax , %ecx

x86使用[]标识内存地址,LEA指令也使用[],但不一定指内存LEA不访问内存

转化为C伪码

dword (double word)双字 就是四个字节
ptr pointer缩写 即指针
[]里的数据是一个地址值,这个地址指向一个双字型数据
比如mov eax, dword ptr [12345678] 把内存地址12345678中的双字型(32位)数据赋给eax

C语言实现strlen()

image-20211028140257199

image-20211028144511317

 
 
 
 
 
 
通用寄存器名 作用
EAX(双字)
EBX(双字)
ECX(双字) 循环计数
EDX
EDI 字符串/内存操作的目标
ESI 字符串/内存操作的源
EBP 帧基指针
ESP 栈指针
其他寄存器 作用
EIP 存储指令指针,存储CPU当前要运行的内存地址
EFLAGS 用于存储算术运算状态以及其他运行状态(比如陷阱标志位DF)
CR0 控制分页机制的开关
CR2 保存着导致缺页异常发生的线性地址
CR3 分页数据结构的基地址
CR4 控制硬件虚拟化设置
DR0~DR7 用于设置内存断电,其中系统只支持4个内存断电(DR0~DR3),其余寄存器用于保存状态
其他寄存器 作用
指令 作用
MOVSB/MOVSW/MOVSD 指令分别以1字节,2字节或4字节为单位,在两个内存地址之间移动数据
SCAS(B/W/D) SCAS指令隐式地把(当指令为SCASB/SCASW/SCASD时)AL/AX/EAX的数值与地址为EDI的内存数值比较。根据EFLAGS中DF标志位的不同,EDI自动递增或递减。
REP 重复执行目标指令n次,比如:rep movsd ;复制4n字节(重复n次movsd),找ECX,每循环一次,ECX值减一,满足条件ECX>0
LEA
repne(repeat no equal) 不相等时重复(零标志位)ZF=0且ECX>0进行重复
repe(repeat equal) 相等是时候重复(零标志位)ZF=1且ECX>0进行重复
MUL(无符号) 只允许后面有一个操作数,比如:mul ebx ;将ebx的值与eax的值相乘,若结果存不下,则扩展为EDX:EAX。乘法运算,寄存器值与AL、AX或EAX值相乘,结果存储于AX、DX:AX或EDX:EAX 例如:mul ecx ;EDX:EAX=EAX*ECX
DIV(无符号) 只允许后面有一个操作数,比如:div ebx ;将EAX / EBX 的商放入EAX,余数放入EDX。计算得到的商和余数存储在AL/AH、AX/DX或EAX/EDX中。
IMUL(有符号) 可有多个操作数。例如:imul ebx,ecx ;若溢出,结果高位部分存到ECX,低位部分存入EBX。
指令 作用
NOP 垃圾指令,不执行任何操作
PUSHFD 对标志位进行现场保护,对标志位寄存器的压入栈
POPFD 还原标志位寄存器,从栈中弹出标志位寄存器的值到标志位寄存器
MOVSX 有符号扩展( movsx eax,bx)(movsx eax , bh(或者bl))如果bx(对应2个字节),bh/bl(对应一个字节)的值大于它所对应字节的一半+1,则复制到的存储器的高位值要变负。
MOVZX 无符号扩展( movzx eax, bx)(movzx eax, bh(或者bl))如果bx(对应2个字节),bh/bl(对应一个字节)的值大于它所对应字节的一半+1,则复制到的存储器的高位值不用变。
XCHG 值交换,将两个值交换
ADC 比如:adc eax,ebx 相当于 eax=eax+ebx+CF(进位标志位)
SBB 比如:sbb eax,ebx 相当于 eax=eax-ebx-CF
INC 递增,就是寄存器自动加1
指令 作用
DEC 递减,就是寄存器自动减1
IDIV (有符号)
XADD 例如:xadd ebx,eax ; 设ebx为3,eax为2,则执行执行这条指令,交换双方的值,ebx为2,eax为3,然后相加返回给ebx,则ebx为5。
NEG 取反指令,neg ebx ;若ebx为100,则执行此指令,ebx为-100
CMP 比较指令,比较两个寄存器的值是否想等。例如:cmp edx,eax ;其实是两个值相减,sub edx,eax比较两个值是否相等,结果并不会存到edx寄存器,若比较出来结果相等,即相减为0,则运算结果为0,ZF标志位置为1
TEST 比较指令,比较两个寄存器的值是否相等。例如:test eax,ebx;其实是两个值进行与运算,and eax,ebx;运算结果是否为0,若为0,则置ZF为1,否则置0。结果不保存到EAX寄存器上。
JMP 无条件跳转指令,不根据标志位来改变程序运行逻辑
JE/JZ 根据ZF标志位来进行跳转,如果ZF标志位为1时则跳,为0时不跳
指令 作用
JNE/JNZ 根据ZF标志位来进行跳转,ZF标志位为0时则跳,为1时则不跳
JS 如果结果为负,SF为1,根据SF标志位来进行跳转,如果SF标志位为1时则跳,为0时则不跳
JNS 根据SF标志位来进行跳转,如果SF标志位为0时则跳,为1时则不跳
JP/JPE 如果结果的低十六位含1个数为偶数时,PF为1。根据PF标志位来进行跳转,如果PF标志位为1时则跳,为0时则不跳
JNP/JPO 根据PF标志位来进行跳转,如果PF标志位为0时则跳,为1时则不跳
JO 根据OF标志位来进行跳转,如果OF标志位为1时则跳,为0时则不跳
JNO 根据OF标志位来进行跳转,如果OF标志位为0时则跳,为1时则不跳
JB (判断无符号)根据CF标志位(根据无符号进行运算,只有进位或借位,不存在有无符号)来进行跳转,如果CF标志位为1时则跳,为0时则不跳
JNB 根据CF标志位来进行跳转,如果CF标志位为0时则跳,为1时则不跳
指令 作用
JBE 根据CF或ZF标志位来进行跳转,如果CF或者ZF标志为1时则跳,为0则不跳。例如:cmp eax,ebx;若运算结果为0,ZF为1,运算结果小于0,CF为1。所以就是看eax-ebx的结果是否<=0,就是判断eax<=ebx
JNBE/JA 根据CF和ZF标志位来进行跳转,如果CF和ZF标志都为0时则跳,有一个为1时则不跳。例如:cmp eax,ebx;若运算结果不为0,ZF为0,运算结果大于0,CF为0。所以就是看eax-ebx的结果是否>0,就是判断eax>ebx
JL (判断有符号)根据SF标志位(根据有符号进行运算)来进行跳转,若SF为1,则跳,为0则不跳
JNL (判断有符号)根据SF标志位(根据有符号进行运算)来进行跳转,若SF为0,则跳,为1则不跳
CALL 函数调用,例如:call 00007FFB59C4A838 ;跳到子程序的地址执行,主程序的下个地址存入栈中,当子程序执行完后,从栈顶弹出地址赋值给EIP,然后继续执行主程序后的部分。
RET call和ret配合使用,当运行到ret时,表示子程序返回到主程序。
LOOP 根据寄存器ECX值递减至1时,则不继续循环,且ECX减为0;常见有loopd,loopb和loop是一样的 loopd使用ECX 32位计数器。loopb使用ECX 8位计数器。
 
mov dword ptr [eax] , 1
;把1放入EAX内存地址
mov ecx, [eax]
;访问EAX寄存器存储的地址值,并把这个地址值当做内存地址值去访问内存,把值提取出来并放入ECX寄存器
mov [eax], ebx
;把EBX寄存器里的值放入EAX内存地址
mov [esi+34h], eax
;把EAX寄存器里的值放入内存地址为(ESI+0x34)的值
mov eax, [esi+34h]
;把内存地址为(ESI+0x34)的值放入EAX寄存器
mov edx, [ecx+eax]
;把内存地址为(ECX+EAX)的值放入EDX寄存器
mov dword ptr [eax] , 1
;把1放入EAX内存地址
mov ecx, [eax]
;访问EAX寄存器存储的地址值,并把这个地址值当做内存地址值去访问内存,把值提取出来并放入ECX寄存器
mov [eax], ebx
;把EBX寄存器里的值放入EAX内存地址
mov [esi+34h], eax
;把EAX寄存器里的值放入内存地址为(ESI+0x34)的值
mov eax, [esi+34h]
;把内存地址为(ESI+0x34)的值放入EAX寄存器
mov edx, [ecx+eax]
;把内存地址为(ECX+EAX)的值放入EDX寄存器

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

上传的附件:
收藏
免费 12
支持
分享
最新回复 (12)
雪    币: 132
活跃值: (543)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好文
2021-11-3 13:37
0
雪    币: 21
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
不错不错
2021-11-11 11:22
1
雪    币: 38
活跃值: (33)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
好文
2021-11-11 13:35
0
雪    币: 1166
活跃值: (307)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
内容基础值得学习
2021-11-11 16:05
0
雪    币: 220
活跃值: (493)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
会的人不需要 不会的人傻也看不懂
2021-11-13 15:33
1
雪    币: 1705
活跃值: (676)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
lolikon [em_19]会的人不需要 不会的人傻也看不懂
现在大部分都是这样的,教人入门门都不告诉在哪
2021-11-13 17:19
0
雪    币: 3785
活跃值: (3947)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
看到第一句“CPU指令集(CPU微处理器架构)分为x86以及ARM”就是错的。。。
2021-11-13 21:05
0
雪    币: 595
活跃值: (210)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
好文
2021-11-17 08:45
0
雪    币: 0
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
表里面少了LEA的说明
2021-11-17 16:59
0
雪    币: 138
活跃值: (351)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
文章不错呢!谢谢分享
2021-11-17 17:24
0
雪    币: 21
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
小白受益匪浅。谢谢。
2021-12-3 11:44
0
雪    币: 27
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
为什么底层代码非要用汇编呢,用Java不好吗
2021-12-9 18:34
0
游客
登录 | 注册 方可回帖
返回
//