作业大纲
1.视频中linux的工具安装
2。汇编和栈堆概念基础知识和汇编指令整理
3。OD和IDA的使用参考
4。汇编作业,输出九九表
首先再linux上安装工具
有点linux有vim的安装包
sudo apt install vim
这样就可以使用vim了
然后安装gcc的32位库来让-m32可用
参考链接
我用第一个链接的方法失败,用了第二个链接成功安装32位库
$ sudo apt-get install build-essential module-assistant
$ sudo apt-get install gcc-multilib g++-multilib
然后是,简单学习linux的目录切换的教程
视频编译c程序和逆向命令(sudo的话就sudo)
vim hello.c
gcc hello.c -o hello -m32
objdump -d -M intel hello
因为大一的我还没学汇编,所以最近花了些时间简单啃了啃汇编的基础知识
当成作业内容写一下
CPU
和
内存,
硬件
对话
Cpu
可执行电脑的
所有运算
和
逻辑运算
和
基本IO
控制功能
寄存器:cpu
内部元件,寄存器之间传输数据特别快
用途:1.
将内存器的数据执行算数、逻辑运算
2.
存在寄存器的地址指向内存的某个地址
3.
读写电脑周边的设备
8086
有8
个8
位数据寄存器,
可分别组成16
位寄存器:
AH&AL=AX
:累加寄存器:常用于运算
BH&BL=BX
:基址寄存器,常用于地址索引;
CH&CL=CX
计数寄存器,常用于计数;
DH&DL=DX
数据寄存器,常用于数据传递。
为了运用所有的内存空间,8086
有四个段寄存器,专门用来保存段的地址:
CS
:代码段寄存器;
DS
:数据段寄存器;
SS
:堆栈段寄存器;
ES
:附加段寄存器;
一个程序要运行,就要决定程序代码,数据,堆栈各要用到的内存的哪些位置,通过设定段寄存器的cs
,ds
,ss
来指向这些起始位置。
通常ds
是固定的,根据需要修改cs
。
所以,程序可以在可寻址空间小于64K
的情况下被写成任意大小。
所以,程序和其数据组合起来的大小,限制在DS
所指的64K
内,这就是COM
文件不得大于64K
的原因。通常是将DS
固定,而根据需要修改CS
。8086
以内存做为战场,用寄存器做为军事基地,以加速工作。
内存是电脑运作中的关键部分,也是电脑在工作中储存信息的地方。
内存组织有许多可存放数值的储存位置,叫“地址”。
8086
地址总线有
20
位,所以
CPU
拥有达
1M
的寻址空间,这也是
DOS
的有效控制范围,而
8086
能做的运算仅限于处理
16
位数据,即只有
0
到
64K
,所以,必须用分段寻址才能控制整个内存地址。
完整的
20
位地址可分成两部份:
1.
段基址
(Segment)
:
16
位二进制数后面加上四个二进制0,即一个
16
进制0,变成
20
位二进制数,可设定
1M
中任何一个
64K
段,通常记做
16
位二进制数;
2.
偏移量
(Offset)
:直接使用
16
位二进制数,指向段基址中的任何一个地址。如:
2222
(段基址)
:3333
(偏移量),其实际的
20
位地址值为:
25553
。
除了上述营养要充分吸收外,你还要知道什么是
DOS
、
BIOS
功能调用。
EAX 函数执行结果return
ECX 计数器
EDX 存数据
ESP 栈指针寄存器
EBP 栈底部
ESI 源
EDI 目的
Stack栈局部变量
Heap堆动态分配的变量
Bss Section全局变量,静态变量,全局变量没有初始化的数据,
Data Section全局变量初始化过的数据
Mov
cmp比较
jmp无条件跳转
jxx跳转
jge大于等于跳转
jae不低于,或者高于等于,或者进位标志转移清零时转移
jnz结果不为零则转移
拿到逆向题的做题步骤
查壳 PEID
分析:静态OD
动态IDA pro
题目:破解类,算法分析类,绕过保护类
先查壳,再看关键代码。
重点:运算,循环
寻找关键代码:字符串搜索,下断点
视频示例:crackme2.exe
OD和IDA解析
OD的使用参考教程
IDA PRO参考教程
F5进入伪代码
,双击一个值或者地址可以查看当前值的情况
汇编语言输出99乘法表
汇编视屏我看了三遍,很遗憾目前只能是看懂一个逆向中汇编的指令和分配内存的动作。
能力目前只局限于看懂题。
c语言写个九九乘法表还是很简单的
然后IDA出来汇编语言的九九乘法表。。。
以下链接作为输出九九乘法表的作业吧
只能是作为我作业的主要参考了
DATAS SEGMENT CRLF db
13,
10,
'$' number dw ?,?,?,?
;存放乘数和被乘数 buf db ?,?,?,?
;缓存转换出来的数字 DATAS ENDSCODES SEGMENT ASSUME
CS:CODES,
DS:DATAS
START:
MOV AX,DATAS
MOV DS,AX
mov cx,
9
;外层循环9次
s1:
mov [number],cx ;
存放乘数
push cx
;保存外层计数
push cx
;乘数进栈
s2:
;内层循环,循环次数由外层循环来决定
;显示乘数
mov dx,[number]
add dx,30h
;转换到ASCII
mov ah,
2
int 21h
;显示x号
mov dl,78h
mov ah,
2
int 21h
;显示第二个乘数
mov [number+
1],cx
push cx
;第二个乘数进栈
mov dx,cx
add dx,30h
mov ah,
2
int 21h
;显示=号
mov dl,3dh
mov ah,
2
int 21h
;计算两数相乘的结果,并显示
pop dx
;取出第二个乘数
pop ax
;取出第一个乘数
push ax
;第一个乘数再次进栈,在下次内层循环中推出再次使用
;想直接用内存单元里面放的数据来相乘,但是结果不对
;所以最后用栈存放乘数再取出解决了问题
;调试发现第二个乘数[number+1]中的值是对的,但是[number]中的值不对
;很疑惑的是上面打印[number]的值显示结果正确
;那为什么在下面的指令中使用值就不对了呢?
;mov dx,[number]
;mov ax,[number+1]
mul dx
;相乘,结果在AX中
mov bx,
10
;准备除以10
mov si,
2
;循环2次,最大到十位 (乘法表最大为81,所以最大到十位)
toDec:
;把各个位转换为数值,如ax中的81,转换为 8,1存在内存中
mov dx,
0
div bx
;除10法得到各个位上的数值
mov [buf+si],dl
;余数为该位上的值,第一次循环为个位,第二次为十位...;存到内存中
dec si
cmp ax,
0
;商是否为0,为0算法结束
ja toDec
output:
;输出内存中存放的转换数值数
inc si
mov dl,[buf+si]
add dl,30h
;转为ascii
mov ah,
2
int 21h
cmp si,
2
jb output
mov dl,20h
mov ah,
2
int 21h loop s2
;内层循环结束
lea dx,crlf
;输出回车换行
mov ah,
9
int 21h
pop cx
pop cx
;还原外层计数 loop s1
mov ah,
1
;停留等待结束
int 21h
MOV AH,4CH
INT 21HCODES ENDS END START