说明
逆向工程是安全领域的基本技能之一。具有编程经验的任何人都应该熟悉从编译,链接到执行的高级语言源代码的过程。逆转就是逆转这个过程。防病毒人员捕获了一个样本,需要对其进行反转以分析该样本的行为。开发有效的特殊查杀工具。
在开始真正参与逆向工程之前,您必须首先具有一些汇编的基本知识。之所以说汇编的基本知识,是因为不需要精通汇编来进行逆向工程,因为它不需要我们成为汇编程序员。学习组装的方法晦涩难懂,最好的方法是在学习逆向裂纹的过程中根据实际需要学习。然后本文主要介绍有关逆向工程的寄存器和内存的信息。首先是要介绍逆向工程的主要作用。其次,我对编程和机器架构进行了介绍,最后详细介绍了逆向工程的寄存器和存储器。

逆向工程做什么?
1、对所编译的软件进行反向分析,然后以高级语言进行复制,从而可以模仿现有更好的软件供自雇使用。
2、用于分析病毒并提取特征代码以促进反病毒程序的开发。
3、高级代码审核,在汇编级别调试程序,编写的代码更安全。
4、插件,游戏插件是用这种方式制作的,具体细节将不作详细介绍,毕竟这不是光荣的事情。
5、分析嵌入式设备中的漏洞。
6、开发用于嵌入式设备的软件。

汇编语言的位置
我为什么要学习汇编语言?就像学习美国文化一样,您必须首先了解英语。如果您不懂计算机语言,该如何谈论了解计算机?众所周知,计算机执行的语言或称为命令序列或数据的语言是“ 1和0”的二进制语言,它在物理上由高电平和低电平的电信号表示。尽管我们现在拥有一系列强大的高级语言,例如C / C ++,Java,Python等,但仍需要将它们编译或解释为计算机能够在计算机上实际实现时理解的机器语言。在最早的计算机编程中,在纸带上打孔以指示1或0。作为编程指令,它不仅难以操作,而且难以检查错误,并且难以记住。因此人们发明了机器语言的“人性化”表示形式:汇编语言,每个汇编指令都对应一个机器二进制字符串,但是更容易理解和记住:

尽管我们现在有许多可用于编程的高级语言,但是如果我们想真正了解代码执行的实际过程,我们仍然需要了解一些汇编语言并从本质上了解机器的行为。因此,对于当今的IT童鞋来说,学习汇编语言仍然非常重要,更不用说相反了。
机器架构
计算机的核心是CPU,它负责各种运算,包括算术单元和寄存器。寄存器还用于存储数据,但是它们通常很小,并且读写速度很快。它们是由运算单元直接操作的对象。设备(例如图形卡,网卡等)通过主板上的总线连接到CPU,CPU通过总线连接到内存和各种设备。外设中的芯片(然后是外设中的内存)进行数据通信。
根据字节大小将存储器分为存储单元,例如,字节是存储单元。 CPU访问内存时,它必须完成三个任务:1.存储单元的地址(地址信息); 2.设备选择,读取或写入命令(控制信息); 3.读取或写入数据(数据信息));因此,CPU与各种内存之间自然存在三种总线:地址总线,控制总线和数据总线。
控制总线确定命令的类型,数据总线确定一次处理的最大数据位数。 8位数据总线以两种方式处理16位数据,而16位数据总线可以一次解决该问题。地址总线决定了CPU的寻址能力,即存储器的大小。例如,一个8位地址总线最多具有256个单位,即256个字节,而一个32位地址总线则最多具有2位至第32次幂的4GB。 ,这就是x86支持多达4G内存的原因。


由于我们讨论了4G内存的起源,因此我们可以在熨烫时讨论内存地址空间。默认情况下,CPU识别的每个内存单元为1字节,因此可以定位的所有内存单元的最大数量为N的2的幂。N是地址总线的长度,因此该内存地址也构成了计算机的存储器地址空间,即所有可读和可写的存储器单元必须在其中,否则CPU无法定位和检索它。总体结构是这样的:

在这里,0x9ffff是655539,0xbffff是786431,而0xfffff是1048575,因此您会更加清楚地知道(由于Python的计算机功能,很方便)。主内存地址空间是内存。如果直接在此地址空间中操作数据,则效果是直接读取和写入内存数据。视频内存地址空间是指视频内存的RAM部分。
反向基本寄存器和存储器
CPU中的主要结构是算术单元,控制器和寄存器。这些设备通过CPU的内部总线连接。运算单元负责信息处理,寄存器负责信息存储,控制器控制各种设备工作,并连接内部总线。各种设备在它们之间传输数据。对于汇编程序员,主要组成部分是寄存器,因为只有寄存器可以直接编程和操作。不同的CPU体系结构是不同的。 8086CPU共有14个寄存器,分别是AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW,今天我们将学习基本的通用寄存器,其余的使用寄存器时将进行解释。
一、通用寄存器
AX,BX,CX和DX是四个通用寄存器,通常用于存储通用数据。随后的分析在8086CPU中执行。每个通用寄存器为16位,即一次可以处理一个字(2个字节)的数据,但是为了与8086CPU之前的CPU兼容,它还支持一个字节的寄存器,即AH和AL以及类似的BH和BL等,CPU会在操作时将AH和AL减少为独立寄存器,而在执行操作时会直接丢弃,因为CPU认为只有一个8位寄存器:

二、物理地址
CPU对内存的访问需要知道存储单元的地址。因为8086CPU地址总线为20位,但是寄存器只有16位,即一次处理的地址只有2到16的幂,远远少于2到20的幂。为了解决这个问题,8086CPU使用一种特殊的方式通过16位寄存器来构造20位访问地址,简单来说就是:段地址* 16 +偏移地址。就计算的位数而言,段地址和偏移地址存储在CPU寄存器中,二者均为16位。段地址* 16,即整体向右加4个二进制数字成为20位; 20位和16位相加得到20位的实际存储器地址。尽管这是8086CPU中的方法,但实际上它实际上是现在所有CPU中的实际寻址算法,即基址加偏移量以获得实际地址。从中我们可以得到分段的概念,内存本身不是分段的,但是由于CPU的特殊寻址方式,我们可以将内存视为最大为64KB的分段(16位的最大值恰好是64KB) ),因此我们可以人为地在装配中指定段的开始和结束。当然,这里的段地址和偏移量实际上存储在CPU的寄存器中,例如获取指令的CS:IP,其中CS是代码段寄存器,用于存储代码段的基地址,而IP寄存器存储了当前执行的指令。该指令的指针是一个偏移量,因此CS:IP指定下一个要由CPU执行的指令的位置。这里需要说明的是,存储器中的数据都是CPU的所有二进制位。区分数据和指令的唯一标准是CS:IP已经或正在指定指令。每次执行一条指令,IP都会累积一条指令。的长度,因此指向向下的调整指令。

我们可以修改控件CS:IP的值吗?答案是肯定的,但是我们不能使用诸如mov之类的传输指令,而应该使用诸如jmp之类的传输指令。基本用法是:

-1.修改CS:IP:jmp 2AE3:3执行后:CS = 2AE3H,IP = 0003H;
-2.仅修改IP:jmp ax(即move ip,ax)将使用寄存器中的值修改IP;
三、内存访问
CPU除了获取指令外还访问内存,还获取数据,那么如何定位数据部分?与命令CS:IP相同,8086CPU使用DS:[。 。 。 ]为了获得内存数据地址,段寄存器存储内存数据段的基地址和[。 。 。 ]表示由内存偏移量指向的内存单元,例如[0]表示偏移量为0的内存单元。在此处使用它时,请注意8086CPU不支持将值直接传输到DS,因此mov ds和1000H是非法的。正确的实现是通过寄存器实现的,即:mov ax,1000H; mov ds,ax;
在这一部分中,我们需要学习基本的汇编指令,例如mov,sub,add等,它们都可以操纵寄存器。操作后,将数据放入第一个参数指示的寄存器中。 CPU中存储数据的特殊结果是堆栈,该堆栈只能从一端读取和写入数据。基本指令是推斧;将寄存器ax的值压入堆栈;并弹出斧头;从堆栈中移除顶部元素将其放入寄存器ax中;这是mov \ add \ sub命令的简单示例:

然后让我们看一下PUSH命令的执行过程:

然后使用POP命令:

可以看出,堆栈操作的关键是确定堆栈顶部的位置,因此CPU仅使用SS:SP来获取堆栈顶部在当前内存中的位置。值得一提的是,CPU本身不检查堆栈的大小,因此实际上堆栈顶部会出现问题(上限超过-PUSH;下限超过-POP),这需要我们手动检查,否则程序中将存在漏洞。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-363222-1.html
老美武器强大了用脑少了
你这不是自己在打自己的脸吗