逆向基础概要
一,机器语言
加:0100 0000
减:0100 1000
乘:1111 0111 1110 0000
除:1111 0111 1111 0000
二,汇编语言
编译器作用:把汇编语言转为机器语言
三,C语言
四,C语言和C++的关系
- C与C++没有本质区别,只是编译器能做的事情越来越多,功能越来越强大了。
- C是学好C++的基础
五,为什么要学会汇编
六,学习环境
- VC6
- VS2010 VS2013 VS2016
选VC6的原因
越是新版的添加的代码越多,不利于学习
进制
前言
要想学好进制,首先忘记熟悉的十进制,和进制间的转换
进制的定义
- 八进制的定义:八个符号组成,0,1,2,3,4,5,6,7,逢八进一
- 十进制的定义:十个符号组成,0,1,2,3,4,5,6,7,8,9,逢十进一
- N进制的定义:N个符号组成,逢N进一
个人进制定义:关键是在逢N进一,符号是自己定义的
注意:进位是向左边进一位,左面是高位
进制的书写
比如说:七进制
注意
个人进制定义:关键是在逢N进一,符号是自己定义的
例如:1+1=3是否正确
答案可以是正确的,如果对于自定义进制的话
意义:
将这种进制方式用于进制加密,可以给解密者很大的困扰
进制运算
例如:八进制的运算
可以先把加法表和乘法表画出来
计算机为什么用二进制
计算机时用电的,电路只有两种状态:1 真(通电)0假(断电)
计算机中 存储的任何文件,接受的任何指令都是0和1组成的
题外:量子计算机:量子还有非真非假的状态,计算量大大提升
二进制的简写形式
十六进制在计算机中可以看作二进制的简写形式
数据宽度
在计算机中由于受硬件的限制,数据是有一定长度限制的(称为数据宽度),超过最多宽度的数据会被丢弃。
1. 常见的数据宽度
位:里面只能存放一个值(0或1),计算机中最小存储单位
字节:一个字节有8个位
字:有16位
双子:可以存储32位
2. 存储范围
例如:
char :计算机就知道要用容器是8位(1个字节)
int:计算机就知道你要用的容器是32位的(双字)
有无符号数
不同的编码不同的规则
1. 无符号数的编码规则
无符号数:这个数是多少就存多少
文件不同,解析方式也不同
2. 有符号数 正数编码规则
原码:最高位(最左面)为符号位,其余各位为数值本身绝对值
反码:
正数:反码与原码相同
负数:符号位为1,其余位对原码取反
补码:
正数:补码与原码相同
负数:符号位为1,其余位对原码取反加1(1是值)
正0和负0的补码相同
正数和负数的相加实质是:把正数和负数的补码相加,然后再补码,同位相加都为1的话进位。
3. 举例说明
正数编码:
负数编码:
符号为1
4. 假设数据宽度为1,Byte(8 bit)
- 假设数据宽度为 Doubleworld(32 bit)
位运算
前言:
计算机只认识和,计算机所做的运算归根结底是直接对0和1做运算,通常称:位运算。
为什么要学位运算:
1)必须要位运算来实现,比如说:调试器,判断CPU各种状态位
2)试题:比如2*8效率最高的实现方式
1. 与运算
两个数都为1结果才为1
比如:
2. 或运算
3. 异或运算
4. 非运算
5. 移位运算
左移
右移
而对于C语言来说,高位补零还是1看前面定义:比如说unsigned 意为无符号,没有定义unsigned默认就是有符号的,最高位就为符号位。
6. 总结
计算机的所有运算归根结底都会转换为位运算,计算机只会做位运算
7. 通过位运算实现四则运算
举例:加法
运算过程:
减法:
汇编以及环境搭建
1. 学习汇编不是为了写代码
2. 环境准备
Dbg 32位和64位
寄存器
寄存器就是CPU中用来存储数据的地方
64位的CPU是从32位的拓展来的,整体结构没有发生改变,只是在原来的基础上增加了寄存器,汇编指令都是一样的
使用32位的寄存器
1. 前言
mov指令是用来移动数据的,汇编的实质就是:寄存器与寄存器,或者寄存器与内存之间数据的来回流动
2. MOV指令
立即数存到寄存器里
寄存器数存到寄存器里
通用寄存器
不同位的MOV命令
不同位的寄存器,实际上32位的寄存器相当于4个字节的,选用16位的或者8位的,就相当于用了其中2个或者1个
例如:将eax存储-1,然后进行反汇编,用16位的mov命令
对于8位
H是高8位,L是低8位
补充
不同寄存器到寄存器的存储要相同位数。
内存地址和MOV指令
内存地址
内存太大没法起名字,只能用编号,当我们想向内存中存储数据时,或者从内存中读取数据时,必须用到这个编号,就像写信要写地址收件人一样。
这个编号又称内存地址(32位,前面0可以省略)
MOV指令
必须告知内存具体宽度
- 立即数存到内存里
- 寄存器存到内存里
- 内存存到寄存器里
内存地址的5种形式
形式一:立即数
形式二:[reg],reg代表寄存器,可以是8个32位的通用寄存器中任意一个
形式三:[reg+立即数] (地址是加过立即数后的编码地址)
形式四:[reg+reg*{1,2,4,8}],(1或2或4或8)
形式五:[reg+reg*{1,2,4,8}+立即数]
归根结底,就是改变编码地址