逆向基础概要

一,机器语言

加:0100 0000
减:0100 1000
乘:1111 0111 1110 0000
除:1111 0111 1111 0000

二,汇编语言

编译器作用:把汇编语言转为机器语言

img

三,C语言

img

四,C语言和C++的关系

  1. C与C++没有本质区别,只是编译器能做的事情越来越多,功能越来越强大了。
  2. C是学好C++的基础

五,为什么要学会汇编

img

六,学习环境

  1. VC6
  2. VS2010 VS2013 VS2016

选VC6的原因
越是新版的添加的代码越多,不利于学习

进制

前言

要想学好进制,首先忘记熟悉的十进制,和进制间的转换

进制的定义

  1. 八进制的定义:八个符号组成,0,1,2,3,4,5,6,7,逢八进一
  2. 十进制的定义:十个符号组成,0,1,2,3,4,5,6,7,8,9,逢十进一
  3. N进制的定义:N个符号组成,逢N进一

个人进制定义:关键是在逢N进一,符号是自己定义的

注意:进位是向左边进一位,左面是高位

进制的书写

比如说:七进制

img

注意

个人进制定义:关键是在逢N进一,符号是自己定义的

例如:1+1=3是否正确
答案可以是正确的,如果对于自定义进制的话

意义:
将这种进制方式用于进制加密,可以给解密者很大的困扰

进制运算

例如:八进制的运算

img

可以先把加法表和乘法表画出来

img

img

img

计算机为什么用二进制

计算机时用电的,电路只有两种状态:1 真(通电)0假(断电)
计算机中 存储的任何文件,接受的任何指令都是0和1组成的

题外:量子计算机:量子还有非真非假的状态,计算量大大提升

二进制的简写形式

十六进制在计算机中可以看作二进制的简写形式

img

数据宽度

在计算机中由于受硬件的限制,数据是有一定长度限制的(称为数据宽度),超过最多宽度的数据会被丢弃。
1. 常见的数据宽度

img

位:里面只能存放一个值(0或1),计算机中最小存储单位
字节:一个字节有8个位
字:有16位
双子:可以存储32位
2. 存储范围

img

例如:
char :计算机就知道要用容器是8位(1个字节)
int:计算机就知道你要用的容器是32位的(双字)

有无符号数

不同的编码不同的规则

1. 无符号数的编码规则

img

无符号数:这个数是多少就存多少
文件不同,解析方式也不同

2. 有符号数 正数编码规则

img

原码:最高位(最左面)为符号位,其余各位为数值本身绝对值
反码:
正数:反码与原码相同
负数:符号位为1,其余位对原码取反
补码:
正数:补码与原码相同
负数:符号位为1,其余位对原码取反加1(1是值)
正0和负0的补码相同
正数和负数的相加实质是:把正数和负数的补码相加,然后再补码,同位相加都为1的话进位。

3. 举例说明
正数编码:

img

负数编码:
符号为1

img

4. 假设数据宽度为1,Byte(8 bit)

img

  1. 假设数据宽度为 Doubleworld(32 bit)

img

位运算

前言:
计算机只认识和,计算机所做的运算归根结底是直接对0和1做运算,通常称:位运算。

为什么要学位运算:
1)必须要位运算来实现,比如说:调试器,判断CPU各种状态位
2)试题:比如2*8效率最高的实现方式

1. 与运算
两个数都为1结果才为1
比如:

img

2. 或运算

img

3. 异或运算

img

4. 非运算

img

5. 移位运算
左移

img

右移

img

而对于C语言来说,高位补零还是1看前面定义:比如说unsigned 意为无符号,没有定义unsigned默认就是有符号的,最高位就为符号位。

6. 总结
计算机的所有运算归根结底都会转换为位运算,计算机只会做位运算

7. 通过位运算实现四则运算
举例:加法

img

运算过程:

img

减法:

img

汇编以及环境搭建

1. 学习汇编不是为了写代码

img

2. 环境准备

Dbg 32位和64位

img

寄存器

寄存器就是CPU中用来存储数据的地方

img

64位的CPU是从32位的拓展来的,整体结构没有发生改变,只是在原来的基础上增加了寄存器,汇编指令都是一样的

img

使用32位的寄存器

1. 前言
mov指令是用来移动数据的,汇编的实质就是:寄存器与寄存器,或者寄存器与内存之间数据的来回流动

2. MOV指令

  1. 立即数存到寄存器里

    img

  2. 寄存器数存到寄存器里

    img

img

通用寄存器

不同位的MOV命令

img

不同位的寄存器,实际上32位的寄存器相当于4个字节的,选用16位的或者8位的,就相当于用了其中2个或者1个
例如:将eax存储-1,然后进行反汇编,用16位的mov命令

img

img

对于8位

img

H是高8位,L是低8位
补充
不同寄存器到寄存器的存储要相同位数。

内存地址和MOV指令

img

内存地址

  1. 内存太大没法起名字,只能用编号,当我们想向内存中存储数据时,或者从内存中读取数据时,必须用到这个编号,就像写信要写地址收件人一样。

  2. 这个编号又称内存地址(32位,前面0可以省略)

    img

MOV指令

必须告知内存具体宽度

  1. 立即数存到内存里
  2. 寄存器存到内存里
  3. 内存存到寄存器里
    img

img

img

内存地址的5种形式

  1. 形式一:立即数

    img

  2. 形式二:[reg],reg代表寄存器,可以是8个32位的通用寄存器中任意一个

    img

  3. 形式三:[reg+立即数] (地址是加过立即数后的编码地址)

    img

  4. 形式四:[reg+reg*{1,2,4,8}],(1或2或4或8)

    img

  5. 形式五:[reg+reg*{1,2,4,8}+立即数]

    img

归根结底,就是改变编码地址