滴水逆向作业笔记
进制
n进制是由n个符号组成,逢n进一
进制的本质
进制的实质就是查表
- 以8进制为例,由0,1,2,3,4,5,6,7符号组成
一 | 二 | 三 | 四 | 五 | 六 | 七 | 八 |
---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 |
…
八进制加法表
1+1=2
1+2=3 2+2=4
1+3=4 2+3=5 3+3=6
1+4=5 2+4=6 3+4=7 4+4=10
1+5=6 2+5=7 3+5=10 4+5=11 5+5=12
1+6=7 2+6=10 3+6=11 4+6=12 5+6=13 6+6=14
1+7=10 2+7=11 3+7=12 4+7=13 5+7=14 6+7=15 7+7=16
八进制乘法表
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=11
1*4=4 2*4=10 3*4=14 4*4=20
1*5=5 2*5=12 3*5=17 4*5=24 5*5=31
1*6=6 2*6=14 3*6=22 4*6=30 5*6=36 6*6=44
1*7=7 2*7=16 3*7=25 4*7=34 5*7=43 6*7=52 7*7=61
示例一:5+3=10,就是从5后面数3个数就是10;
示例二:4*2=10,就是4+4,从4后面在数4个数;
进制的运算
- 以八进制为例。
原理:查表
加法 乘法 减法 除法
277 276 236 234
+ 333 * 54 - 54 / 4
-------- -------- ------- ------
632 1370 162 47
+ 1666
---------
20250
二进制与十六进制的映射
- 牢记
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
自定义进制
- 例:5进制定义:由5个符号组成,分别是:6、1、4、2、7,逢5进1
一 | 二 | 三 | 四 | 五 |
---|---|---|---|---|
6 | 1 | 4 | 2 | 7 |
66 | 61 | 64 | 62 | 67 |
16 | 11 | 14 | 12 | 17 |
46 | 41 | 44 | 42 | 47 |
26 | 21 | 24 | 22 | 27 |
76 | 71 | 74 | 72 | 77 |
166 | 161 | 164 | 162 | 167 |
数据宽度
- 假如一个计算机只能存储4位2进制数,即一个十六进制数。
则只能存16个数字。若是无符号数,能存0-15(F),若是有符号数可以存 -8 - -1,0-1这16个数。
有符号数
正数:0 1 2 3 4 5 6 7
负数:-8 -7 -6 -5 -4 -3 -2 -1
8 9 A B C D E F
数据类型 | 单位(bit) |
---|---|
byte 字节 | 8 |
word 字 | 16 |
dword 双字 | 32 |
qword 四字 | 64 |
内存只能存0和1,没有正负数之分,其是通过人为分开的
原码补码反码
1. 机器数
- 一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.
- 例:
十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。那么,这里的 00000011 和 10000011 就是机器数。
2. 真值
- 因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。
List item - 正数的原码,反码,补码都相同
[+1] = [00000001]原 = [00000001]反 = [00000001]补
- 负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
- 负数的补码是在其原码的基础上, 符号位不变,其余各位取反, 最后+1. (即在反码的基础上+1)
[-1] = [10000001]原 = [11111110]反 = [11111111]补
二进制的逻辑运算
- 与(and &)
- 或(or |)
- 异或(xor ^)
- 非(not !)
- 左移(shl <<)
- 右移(shr\sar >>)
CPU数据计算
例:4+5=9
- 我们知道在没有进位时,相加与xo运算r的结果相同(如4+1,即:0100 + 0001,xor结果0101)
- 而判断有无进位用and运算,可以判断在哪个地方需要进位(如1+1,即0001+0001,and结果为0001,最后一位需要进位)
4: 0100; 5: 0101
(1) (2)判断是否有进位(3)有进位,左移继续xor(4)判断是否有进位
0100 0100 0001 0001
xor 0101 and 0101 xor 1000 and 1000
--------- --------- --------- ---------
0001 0100 1001 0000
得到结果:1001
计算机底层只进行加法运算
减法运算
1.将减法转换为加法;A-B=A+(-B)
2.用补码表示的二进制数的相反数替换-B,得到A-B=A+(~B+1);(转换规则:按位取反,末位加1);
3.再加法器的基础上实现减法运算;
cpu乘除法运算
- 使用亦或进行加密解密
使用异或对 87AD6 进行加密后再进行解密,加解密秘钥:5
5–>0101;8–>1000;7–>0111;A–>1001;D–>1101;6–>0110
加密:
10000111101011010110
xor 01010101010101010101
11010010111110000011 #加密后的值为D2F83
解密:
11010010111110000011
xor 01010101010101010101
10000111101011010110 #解密后的值为87AD6
寄存器与常用汇编指令
32位通用寄存器
寄存器 | 主要用途 | 编号 | 存储的数据范围 |
---|---|---|---|
EAX | 累加器 | 0 | 0 - 0xFFFFFFFF |
ECX | 计数 | 1 | 0 - 0xFFFFFFFF |
EDX | I/O指针 | 2 | 0 - 0xFFFFFFFF |
EBX | DS段的数据指针 | 3 | 0 - 0xFFFFFFFF |
ESP | 堆栈指针 | 4 | 0 - 0xFFFFFFFF |
EBP | SS段的数据指针 | 5 | 0 - 0xFFFFFFFF |
ESI | 字符串操作的源指针;SS段的数据指针 | 6 | 0 - 0xFFFFFFFF |
EDI | 字符串操作的目标指针;ES段的数据指针 | 7 | 0 - 0xFFFFFFFF |
AX-累加器(Accumulator)
BX-基址寄存器(Base Register)
CX-计数寄存器(Count Register)
DX-数据寄存器(Data Register)
BP-基址指针寄存器(Base Pointer)
SP-堆栈指针寄存器(Stack Pointer):存放函数
SI-源变址寄存器(Source Index)
DI-目的变址寄存器(Destination Index)
汇编指令
r通用寄存器;
m代表内存;
imm代表立即数;
r8代表8位通用寄存器;
imm8代表8位立即数;
m8代表8位内存;
mov 目标操作数,源操作数
- 源操作数可以是立即数,通用寄存器,段寄存器,内存单元
- 目标操作数可以是通用寄存器,段寄存器,内存单元
- 源操作数和目标操作数不能同时为内存单元
- 操作数宽度必须一致
mov r/m8, r8
mov r/m16, r16
mov r/m32, r32
mov r8, r/m8
mov r16, r/m16
mov r32, r/m32
mov r8, imm8
mov r16, imm16
mov r32, imm32
add指令
替换掉mov指令成add指令,上述也是成立的
sub指令
同理,替换掉mov指令成sub指令,上述也是成立的
and指令
同理,替换掉mov指令成sub指令,上述也是成立的
or指令
同理,替换掉mov指令成sub指令,上述也是成立的
xor指令
同理,替换掉mov指令成sub指令,上述也是成立的
not指令
not r/m8
not r/m16
not r/m32
内存地址
- 内存的数量特别多,,无法为每个内存都起名字,所以用编号代替。每一块内存都有一个编号。
32位计算机的最大编号是32位,也就是32个1,换成16进制就是8个F,也就是32位计算机内存寻址的最大范围是内存的单位,就是字节,而内存中存储的信息最多为:FFFFFFFF+1.
FFFFFFFF+1=100000000(转为十进制=4294967296)而1024指的是十进制的,所以要转换为十进制。4294967296/1024=4194304K,4194304/1024=4096MB,4096/1024=4GB
计算机中几个常用计量单位: byte, word, dword, qword
byte 字节 = 8bit 1kb = 1024 byte
word 字 = 16bit 1m = 1024kb
dword 双字 = 32bit 1gb = 1024mb
qword 四字 = 64bit
内存地址的读写
ptr表示地址,DS:固定写法
内存读写要指定数据宽度,也就是word,dword指定
mov word ptr ds:[0x12345678],0xffff
mov dword ptr ds[0x12345678],0xffffffff
从高位往低写,比如写word,小端存储的话,是高位存高位,低位存低位
寻址公式
公式一
读取内存的值: mov eax,dword ptr DS:[0x——]
向内存写入数据: mov dword ptr DS:[0x——],eax
获取内存编号: lea eax,dword ptr DS:[0x——]<1>esp+4; <2>0x——
公式二[reg]8个通用寄存器之一
读取内存的值: mov eax,0x——; mov dword ptr DS:[edx]
向内存中写入数据: mov edx 0x——; mov dword ptr DS:[edx],0x87654321
获取内存编号: lea eax,dword ptr DS:[edx]; mov eax,dowrd ptr DS:[edx]
公式三[reg+立即数]
读取内存的值: mov ecx,0x——; mov eax,dword ptr DS:[ecx+4]
向内存中写入数据: mov edx,0x——; mov dword ptr DS:[edx+0x87654321],0x987654321
获取内存编号: lea eax,dword ptr DS:[edx+4]; mov eax,dword ptr DS:[edx+4]
公式四
[reg+reg*{1,2,4,8}]
mov eax,13ffc4
mov ecx,2
mov edx,dword ptr ds:[eax+ecx*4]
公式五
[reg+reg*{1,2,4,8}+立即数]
mov eax,13ffc4
mov ecx,2
mov edx,dword ptr ds:[eax+ecx*4+4]