汇编与逆向(二)-汇编基础

一、汇编入门

(一)x86体系的CPU的工作模式

有两种基本的工作模式:实模式和保护模式。

实模式:也称为实地址模式,该模式最早被DOS,win9x所支持。可访问1M内存,可直接访问硬件,如对端口、中断等进行操作。目前CPU任然支持实模式,一是与早期CPU架构保持兼容,二是x86处理器都是从实模式引导。

保护模式:是处理器主要的工作模式,linux与windowsNT内核的系统都工作在x86的保护模式下。在保护模式下每个CPU可访问4GB的内存地址,且进程间是间隔的。

(二)寄存器

任何程序的执行,归根结底,都是存放在存储器中的指令序列执行的结果。

寄存器用来存放程序运行中的各种信息,包括操作数地址、操作数、运算的中间结果等。

寄存器(Register)是CPU内部的存储数据的存储单元。

x86寄存器中与逆向有关的寄存器有:基本寄存器、调试寄存器、控制寄存器。

基本寄存器分4类:8个通用寄存器(4个数据寄存器:EAX,EBX,ECX,EDX;4个指针变址寄存器:EDP,ESP,ESI,EDI),6个段寄存器(CS代码段,DS数据段,SS堆栈段,ES附加数据段,32位CPU中还有两个附加的段寄存器FS,GS)1个指令指针寄存器(EIP)1个标志寄存器(EFLAGS)。

注意:在32位CPU保护模式下段寄存器使用与概念完全不同于16位CPU段寄存器。在逆向工程中经常使用FS用于存储SEH、TEB、PEB等重要的操作系统数据结构。

(三)汇编指令

汇编指令由两部分组成分别为操作码与操作数,操作数可以有1,2或没有。

1.数据传递指令:MOV,XCHG(交换数据),LEA(装入有效地址指令)

2.逻辑运算指令:AND,OR,XOR,NOT

3.算术运算指令:ADD,SUB,ADC(带进位的加法指令=ADD+标志寄存器CF位的值),SBB(带借位的减法指令=SUB-标志寄存器CF位的值),INC(加1指令),DEC(减1指令)

注意:在进行算术运算时,需要注意各个指令影响标志寄存器的位。

4.堆栈操作指令

入栈与出栈指令:PUSH,POP。

ESP和EBP是两个32位的通用寄存器,分别存储栈顶与栈底的内存地址。堆栈分配的地址是由高到低。

保存/恢复指通用寄存器指令:PUSH AD,即在堆栈上压入所有的32位寄存器,顺序依次为EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI。POP AD指令以相反顺序弹出所有通用寄存器的数据

保存/恢复标志寄存器指令:PUSHFD、POPFD。在堆栈上压入或弹出32位EFLAGS标志寄存器的值。在某些特定情况下可以手动修改标准寄存器的某个标志位。比如让程序单步执行时可以设置EFLAGS的第八位TF标志位等,代码如下:

PUSHFD
POP EAX
OR EAX,100h
PUSH EAX
POPFD

通常将程序开始执行的地址称为入口点,简称EP。进行脱壳的首要任务就是找到程序的入口点。

指令指针EIP总是指向要执行的那条指令并在执行后自动执行下一条指令的地址。

5.转移指令:JMP(无条件转移),JCC指令集(JZ,JNZ,JE,JNE)等

测试指令TEST,比较指令(CMP),循环指令(LOOP),调用过程(CALL),返回指令(RET)

6.串操作指令:主要操作内存中连续区域的数据。MOVS,STOS,REP指令。

串传递指令MOVS:借助ESI寄存器与EDI寄存器,将内存源地址(ESI指向源地址)的数据送入内存的目标地址(EDI指向的目的地址)。共三个(MOVSB、MOVSW、MOVSD)默认MOVS为MOVSD。MOVS指令执行后,EDI和ESI寄存器指向的地址自动增加或减少1个单位(1字节、2字节或4字节),增加或减少受EFLAGS标志寄存器的DF标志位影响,DF位为0时增加,为1时减少。

串存储指令:STOS将AL/AX/EAX的值存储到EDI寄存器的指向的内存单元中。STOS指令执行后,EDI指向的内存地址根据DF标志位自动增加或减少1个单位。

重复前缀指令:REP根据ECX寄存器重复执行MOVS、STOS指令,每执行1次REP,ECX自动减1,直到为0结束。

(四)寻址方式

寻址即CPU要寻找最终操作数的过程,通常有以下方式:

1、立即数寻址:操作数直接放在指令中,作为指令的一部分放在代码中。

MOV ESI,00403000

MOV EDI,00403020

2、寄存器寻址:操作数放在寄存器中,在指令中指定寄存器名即可

MOV EAX,00403000

MOV ESI,EAX

3、内存中寻址:存储在内存中的数据,可以用多种方式给出,直接寻址、寄存器间接寻址、其他寻址方式

直接寻址:在指令中直接给出操作数所在的内存地址的方式。

MOV DWORD PTR [00403000],12345678

MOV EAX,DWORD PTR [00403000]

寄存器间接寻址:操作数的地址由寄存器给出,这里的地址为内存地址

MOV DWORD PTR [00403000],12345678

MOV EAX,00403000

MOV EDX,[EAX]

其他寻址方式:操作数据存储在内存中,寄存器相对寻址、变址寻址、基址变址寻址、比例因子寻址等。

[寄存器+立即数]

[寄存器+寄存器+数据宽度(1/2/4/8)]

......

二、汇编语言

汇编语言程序的语句指令外,还可以由伪操作宏指令组成。

伪操作又称伪指令,他不像机器指令那样在程序运行期间由计算机来执行,而是在汇编程序对源程序汇编期间由汇编程序处理的操作,它们可以完成如数据定义、分配存储区、指示程序结束等功能。

(一)数据定义及存储器分配伪操作

格式:[Variable] Mnemonic  Operand,...Operand  [;Comments]

1、其中变量(Variable)可有可无,它用符号地址表示,其作用与指令语句前的标号相同,但是后面不跟冒号。如果语句中有变量则汇编程序使其记以第一个字节的偏移量。

注释(Comments)可有可无

2、助记符(Mnemonic)说明所用伪操作的助记符,常用的有以下几种:

DB:定义字节,其后每个操作数都占1个字节

DW:定义字,占2字节

DD:定义双字,占4字节

DQ:定义四个字,占8字节

DT:定义十个字节,占10个字节

这些伪操作可以把其后跟的数据存入制定的存储单元,或者只分配存储空间并不存入确定的值。DW和DD伪操作可以存储偏移地址或完整的地址。

3、操作数(Operand)可以是常数,也可以是表达式(根据表达式可以求得一个常数),如下例4.1,图4.2

DATA_BYTE   DB   10,4,10H

DATA_WORD   DW   100,100H,-5

DATA_DW   DD   3*20,0FFFDH 

操作数也可以是字符串,如下例4.3

MESSAGE   DB  'HELLO'

 存储器中存储情况分别如下图4.2,图4.3,

操作数?可以保留存储空间,但不存入数据,如例4.3,图4.4

ABC   DB   0,?,?,?,0

DFF   DW  ?,52,?

操作数还可以使用复制操作符(DUP)复制某个或某些操作数

格式:repeat_count   DUP(operand,...,operand)

repeat_count指复制的次数或个数 。如例4.4,图4.5

ARRAY1   DB   2   DUP(0,1,2,?)

ARRAY2   DB   100   DUP(?)

             

(二)表达式赋值伪操作EQU

格式:Expression_name    EQU   Expression

例如:

CONSTANT    EQU   256   ;将数赋以符号名

DATA     EQU   HEIGHT+12   ;地址表达式赋以符号名

B   EQU   [BP+8]    ;变址引用赋以符号名B

P8    EQU    DS:[BP+8]    ;加段前缀的编制引用赋以符号名P8

注意:EQU语句的表达式中如果有变量或标号的表达式,则在该语句前应该先给出它们的定义!

与EQU类似=的伪操作也可以赋值,它们的区别:EQU中的表达式名是不允许重复定义的,而=伪操作则允许重复定义。如:EMP=7  ...   EMP=EMP+7

(三)段定义伪操作

存储器的物理地址是由段地址和偏移地址组合而成,汇编程勋再把源程序转换为目标文件时,必须确定标号和变量的偏移地址,并且需要把有关信息通过目标模块传递给连接程序,以便连接程序把不同的段和模块连接在一起形成一个可执行程序。

段定义伪操作格式:

segment   name    SEGMENT

      DS

      ES

      SS

(存储单元的定义、分配)

      CS

(指令)

      :

segment    name    SEGMENT

其中删节号部分,对于数据段、附加段和堆栈段来说,一般是存储单元的定义、分配等伪操作;对于代码段则是指令及伪操作。

 ASSUME只是将段分配给段寄存器,并不将段地址装入段寄存器中,故在代码段中要将段地址装入相应段寄存器,其中代码段并不需要装入地址,它由程序初始化时完成。

;title
;data_SEGMENT-->code_SEGMENT-->ASSUME-->start--->end
data_seg SEGMENToper1 dw 10oper2 dw 100result dw ?
data_seg ENDScode_seg SEGMENTASSUME ds:data_seg,cs:code_seg ;分配段与段寄存器start:mov ax,data_segmov ds,ax   ;向寄存器装入地址mov ax,oper1add ax,oper2mov result,ax
code_seg ENDSEND start

 上述代码需用16位编译器 (emu8086),32位编译器(MASM32)无法编译:

(四)程序开始和结束伪操作

格式:NAME   module_name

          END  [label]

其中标号指示程序开始执行的的起始地址。若果多个程序模块相连接,则只有主程序要使用标号,其它子程序模块则只使用END而不必指定标号。汇编程序将在遇到END时结束汇编,而程序则将从START开始执行。

汇编源码基本结构

code         segment                                          ;定义code段

main         proc     far                                        ;main程序

                assume        cs:code,ds:data,es:extra        ;明确段和段寄存器

start:

        push        ds

        sub        ax,ax        ;AX寄存器值0

        ....

main        endp

code        ends

        end        start        

三、编译过程

源文件:ASM文件 ----->  目标文件:OBJ文件 ----> 执行文件:EXE文件

两个汇编程序:小汇编ASM和宏汇编MASM

MASM源代码文件通常由以下几个基本部分组成:指令(包括汇编指令和伪指令)、数据定义、宏定义、模块声明以及程序入口点。

(一)建立ASM文件

使用文本编辑器或RadASM编写asm文件

(二)生成obj文件

汇编程序的输入文件是ASM文件,输出可以有三个:OBJ文件、LST文件、CRF文件

(三)生成exe文件

LINK程序有两个输入文件OBJ和LIB,输出EXE文件

参考:1、《逆向分析实战(第2版)》冀云 杜林美著 人民邮电出版社 

          2、《IBM-PC汇编语言程序设计》沈美明 温冬婵著 清华大学出版社

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/5709.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【游戏设计原理】77 - 沙盒与导轨

沙盒式体验和导轨式体验是游戏设计中两种截然不同的理念和手法,它们各自的特性和目标受众决定了其适用场景和设计思路。以下是对这两种体验的理解: 一、沙盒式体验 核心特点 自由度高:沙盒游戏给予玩家极大的自由,让他们自己决定…

【STM32】-TTP223B触摸开关

前言 本文章旨在记录博主STM32的学习经验,我自身也在不断的学习当中,如果文章有写的不对的地方,欢迎各位大佬批评指正。 准备工作 今天这篇文章介绍的是触摸开关这一外围硬件。 ST-link调试器STM32最小系统板单路TTP223B触摸传感器模块LE…

Python的进程和线程

ref 接受几个设定: 进程是一家almost密不透风的公司,缅甸KK园区 线程里面工作的…人 进程**[园区]**内公共资源对于进程来说,可以共享. 别的园区[进程],一般不能和自己的园区共享人员资源,除非… 好的,现在再接受设定: 单个CPU在任一时刻只能执行单个线程,只有…

消息队列篇--原理篇--Pulsar和Kafka对比分析

Pulsar和Kafka都是高性能、分布式的消息队列系统,广泛应用于大规模数据流处理和实时分析场景。然而,它们的设计哲学、架构特点和适用场景存在显著差异。以下是Pulsar和Kafka的详细对比,帮助你根据具体需求选择最合适的技术。 1、架构设计 P…

Git实用指南:忽略文件、命令别名、版本控制、撤销修改与标签管理

目录 1.忽略特殊文件 1.1.那如何配置我们需要忽略的文件的呢? 1.2.如何检验效果? 2.给命令配置别名 3.基本操作之版本回退 3.1.使用场景: 3.2.使用方法: 4.撤销修改 情况一:对于工作区的代码,还没…

Saas Paas Iaas服务区别

Saas、Paas和Iaas是云计算中常见的服务模式,它们分别代表软件即服务(Software as a Service)、平台即服务(Platform as a Service)和基础设施即服务(Infrastructure as a Service)。仅供大家参考…

nslookup在内网渗透的使用

1. 什么是 nslookup? nslookup(Name Server Lookup)是一个用于查询 DNS(域名系统)记录的命令行工具。通过该工具,用户可以查询域名的解析结果,例如获取某个域名对应的 IP 地址或查找域名的相关记…

博客搭建 — GitHub Pages 部署

关于 GitHub Pages GitHub Pages 是一项静态站点托管服务&#xff0c;它直接从 GitHub 上的仓库获取 HTML、CSS 和 JavaScript 文件&#xff0c;通过构建过程运行文件&#xff0c;然后发布网站。 本文最终效果是搭建出一个域名为 https://<user>.github.io 的网站 创建…

pikachu靶场-敏感信息泄露概述

敏感信息泄露概述 由于后台人员的疏忽或者不当的设计&#xff0c;导致不应该被前端用户看到的数据被轻易的访问到。 比如&#xff1a; ---通过访问url下的目录&#xff0c;可以直接列出目录下的文件列表; ---输入错误的url参数后报错信息里面包含操作系统、中间件、开发语言的版…

阿九的python 爬虫进阶课18.3 学习笔记

文章目录 前言1. 爬取大标题2. 爬取小标题3. 证券栏下的标题4. 某篇文章里的具体内容 前言 网课链接&#xff1a;https://www.bilibili.com/video/BV1kV4y1576b/新浪财经网址&#xff1a;https://finance.sina.com.cn/需先下载库&#xff1a; conda install lxml布置爬取的一…

客户案例:电商平台对帐-账单管理(亚马逊amazon)

账单管理&#xff1a; 功能定义&#xff1a; 账单管理用于上传亚马逊&#xff08;amazon&#xff09;平台下载的原始账单数据&#xff0c;美国站、日本站、墨西哥站等账单模板直接进行数据上传&#xff0c;做到0调整&#xff0c;下载下来的账单数据无缝上传至对账平台-账单管…

web端ActiveMq测试工具

如何用vue3创建简单的web端ActiveMq测试工具&#xff1f; 1、复用vue3模板框架 创建main.js,引入APP文件&#xff0c;createApp创建文件&#xff0c;并加载element插件&#xff0c;然后挂载dom节点 2、配置vue.config.js脚本配置 mport { defineConfig } from "vite&qu…

linux-ubuntu学习笔记碎记

~指/home/user_name这个目录 查看软件安装目录&#xff1a;whereis vim 查看当前路径&#xff1a;pwd 终端中键入ctrls会挂起终端&#xff0c;即终端不响应键鼠&#xff1b;ctrlq可以恢复。 和虚拟机开启共享文件夹互传文件 点击桌面&#xff0c;按ctrlaltt&#xff0c;开…

QT调用OpenSceneGraph

OSG和osgQt编译教程&#xff0c;实测通过 一、下载OpenSceneGraph OpenSceneGraphhttps://github.com/openscenegraph/OpenSceneGraph 二、使用CMAKE编译OpenSceneGraph 1.打开cmake&#xff0c;配置源代码目录 2. CMAKE_INSTALL_PREFIX设置为install文件夹&#xff0c;生…

ES6 简单练习笔记--变量申明

一、ES5 变量定义 1.在全局作用域中 this 其实就是window对象 <script>console.log(window this) </script>输出结果: true 2.在全局作用域中用var定义一个变量其实就相当于在window上定义了一个属性 例如: var name "孙悟空" 其实就相当于执行了 win…

Java 8 实战 书籍知识点散记

一、Lambda表达式 1.1 Lambda表达式的一些基本概念 1.2 Lambda表达式的三个部分 // 简化前Comparator<Apple> byWeightnew Comparator<Apple>() {public int compare(Apple a1, Apple a2){return a1.getWeight().compareTo(a2.getWeight());}};//Lambda表达式Comp…

XCP 协议基础

文章目录 一、XCP 简介二、XCP的主要功能三、什么是标定四、什么时候进行标定五、标定的意义六、标定的三层架构XCP协议 和 CCP协议的区别参考 一、XCP 简介 XCP 协议的全称为 eXtended Calibration Protocol&#xff0c;即扩展标定协议。 另有其他定义&#xff0c;XCP 协议全…

医学图像分析工具09.1:Brainstorm安装教程

1. 安装前准备 **官方安装包和数据&#xff1a;**https://neuroimage.usc.edu/bst/download.php **官方安装教程&#xff1a;**https://neuroimage.usc.edu/brainstorm/Installation Matlab 版本要求&#xff1a; 有 Matlab&#xff1a; R2009b (7.9) 或更高版本没有 Matlab&…

python创建一个httpServer网页上传文件到httpServer

一、代码 1.server.py import os from http.server import SimpleHTTPRequestHandler, HTTPServer import cgi # 自定义请求处理类 class MyRequestHandler(SimpleHTTPRequestHandler):# 处理GET请求def do_GET(self):if self.path /:# 响应200状态码self.send_response(2…

vue3搭建实战项目笔记

vue3搭建实战项目笔记 搭建项目笔记1.1.创建Vue项目1.2.划分目录结构assets -> 资源&#xff08;css/font/img&#xff09;components -> 抽取出来的公共组件hooks -> 组件对应的公共逻辑抽取到hooks文件夹下router -> 路由mock -> 模拟数据的一些配置service -…