The x86 Disassembler

Hopper Disassembler逆向实战:从Mach-O静态分析到动态调试 逆向工程是分析软件内部机制、理解程序逻辑的关键技术,其核心在于将二进制代码转化为可理解的信息。通过静态分析,可以解析程序结构、控制流和数据流;而动态调试则能实时监控程序运行状态,应对代码混淆和反调试等挑战。这些技术在软件安全分析、漏洞挖掘和恶意软件研究中具有重要价值。Hopper Disassembler作为一款强大的逆向工具,尤其擅长处理Mach-O文件格式,提供了直观的图形化界面和高效的伪代码生成能力。本文结合实战案例,深入探讨如何利用Hopper进行Mach-O文件格式解析、静态分析进阶技巧以及动态调 阅读详情

Wednesday, January 6, 2010

The x86 Disassembler

Disassemblers make binary analysis work. With a reliable disassembler, you can solve high-level problems like tracing back through a program’s call stack or analyzing sample-based profiles to low-level problems like figuring out how your compiler unrolled a tight floating-point loop or what advantages declaring a variable const actually had at the other end of the optimization chain. A reliable disassembler, which takes sequences of bytes and prints human-readable instruction mnemonics, is a crucial part of any development platform. You’re about to go on a whirlwind tour of the LLVM disassembler: why one should exist, what’s great about this one, and how you can use it.

The case for an LLVM-based disassembler

Disassemblers are all over the place. A disassembler you may well be familiar with is the disassembler from GNU gdb (source). In fact, any debugger needs one: Sun mdb has a disassembler too (source). Some specialized applications like Dtrace need disassemblers as well (source). So because this is well-traveled ground, there are several common properties you should expect from a disassembler:

  • A large library can contain hundreds of thousands of instructions, so disassembly must be fast.
  • A disassembler with a large memory footprint can steal memory and cache from analysis algorithms that need them more, so its code and data should be compact.
  • Because disassemblers are used in a variety of applications, they should provide information about instructions in a generic, preferably even architecture-independent form.
  • For the benefit of future code maintainers, disassemblers should be as table-driven as possible.

Enter the LLVM MC architecture. In MC, instructions are represented using the architecture-independent MCInst class (include/llvm/MC/MCInst.h). The translation between MC instructions and machine code is specified by pre-existing TableGen tables (lib/Target/X86/X86.td for x86 platforms). Writing a disassembler inside the MC framework makes sense because it solves the generality and table-driven problems naturally, but we still need to solve two problems: speed and compactness.

Quick Testdrive of the Disassembler

The llvm-mc tool provides a simple command line wrapper around the disassembler that we primarily use for testing (e.g. test/MC/Disassembler/simple-tests.txt

$ echo '1 2' | llvm-mc -disassemble -triple=x86_64-apple-darwin9
addl %eax, (%rdx)
$ echo '0x0f 0x1 0x9' | llvm-mc -disassemble -triple=x86_64-apple-darwin9
sidt (%rcx)
$ echo '0x0f 0xa2' | llvm-mc -disassemble -triple=x86_64-apple-darwin9
cpuid
$ echo '0xd9 0xff' | llvm-mc -disassemble -triple=i386-apple-darwin9
fcos

Design of the decode process

Fast disassemblers can be classified into two categories, depending on the instruction format. On platforms with fixed-length instructions, it is possible to pull out all bits of the instruction at once and filter based on arbitrary ranges of those bits. In contrast, platforms with variable-length instructions require that the instruction be parsed byte by byte. In this article, I will discuss the variable-length case, and in particular the case of x86, which includes the i386 and x86_64 targets.

The structure of an x86 instruction is determined by several important factors, each of which is of vital importance when decoding:

  • The context of the instruction determines the meaning of the instruction and the size of its operands. The context includes the address and operand sizes of the instruction, as well as the presence (and position!) of prefixes such as the REX.w prefix on x86_64 targets and the f3 prefix on architectures with SSE.
  • The opcode of the instruction is of varying size, and determines what operands are required. Opcodes come in four different types: one-byte opcodes of the form xx, two-byte opcodes of the form 0f xx, three-byte opcodes of the form 0f 38 xx, and three-byte opcodes of the form 0f``3a xx.
  • The addressing bytes of the instruction determine the addressing mode of the instruction’s memory operand (there is only one memory operand possible with a selectable mode). The addressing bytes include the ModR/M (Modifier - Register/Memory) byte and the SIB (Scale - Index - Base) byte.

| Other prefixes? | Mandatory prefix? | REX prefix? | 0f [38/3a]? | Opcode | ModR/M byte? | SIB byte? |

Table 1: Portions of an instruction relevant to decode
You can read more about the meaning of all of these bytes in Chapter 2 of the Intel instruction manual, volume 2A (large PDF). The x86 disassembler is structured around hierarchical tables that assume a 5-phase decode process. You can follow along with this discussion by looking at lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h, and the steps below are colored consistently with the data they access in Table 1.

  • Phase 1

    Record all prefixes but do not use them. Determine the type of the opcode, and obtain a ContextDecision on that basis: **ONEBYTE_SYM**, **TWOBYTE_SYM**, **THREEBYTE38_SYM**, and **THREEBYTE3A_SYM**.

  • Phase 2

    Develop a context mask based on the prefixes that are present and the machine architecture being decoded for. Look up this mask in a lookup table (**CONTEXTS_SYM**) to get a context ID. Consult the **ContextDecision** to find the **OpcodeDecision** that corresponds to the context. As the comments in the header point out, the many possible contexts are boiled down to **IC_max** distinct context IDs that actually matter when decoding. This saves a lot of space.

  • Phase 3

    Read the opcode and use it to consult the **OpcodeDecision** to find the right **ModRMDecision**.

  • Phase 4

    The ModR/M byte not only specifies the addressing mode, but also sometimes serves to identify the specific instruction intended. For example, extended opcodes and escape opcodes (often seen in SSE) use the Reg/Opcode field in the ModR/M byte as part of the opcode. You can see these oddities in Chapters A.4 and A.5 of the Intel instruction manual, volume 2B (large PDF). Given the value of the ModR/M byte, look up the LLVM opcode for the decoded instruction in the **ModRMDecision**.

  • Phase 5

    If the ModR/M byte indicates that an SIB byte is needed, read the SIB byte. This phase occurs as operands are read.

Once these five steps have been performed, the disassembler consumes the operands, whose forms are now completely specified.

Using the disassemblers in real code

If you want to use a disassembler in your own code, then tools/llvm-mc/Disassembler.cpp is a good example of how to use one. You can instantiate a disassembler given a Target using the following code:

llvm::OwningPtr<const llvm::MCDisassembler>
  disassembler(target.createMCDisassembler());

This disassembler works with **MemoryObject**s (include/llvm/Support/MemoryObject.h), and you will need to subclass **MemoryObject** to perform the proper reading functions. A very simple **MemoryObject** subclass might look like this:

class BufferMemoryObject : public llvm::MemoryObject {
private:
  const uint8_t *Bytes;
  uint64_t Length;
public:
    BufferMemoryObject(const uint8_t *bytes, uint64_t length) :
    Bytes(bytes), Length(length) {
    }

    uint64_t getBase() const { return 0; }
    uint64_t getExtent() const { return Length; }

	int readByte(uint64_t addr, uint8_t *byte) const {
        if (addr > getExtent())
            return -1;
        *byte = Bytes[addr];
        return 0;
    }
};

Given a BufferMemoryObject, all you have to do to extract MCInst objects is to call the getInstruction method of the disassembler you got earlier:

llvm::MCInst Inst;
uint64_t Size;
disassembler->getInstruction(Inst, Size, BufferMObj, 0, llvm::nulls()));

The last argument is an optional diagnostic stream, and the 0 indicates that the disassembler should start from address 0 in the buffer.

Where to look for more documentation

For general information on how the disassembler’s decode tables are generated from lib/Target/X86/X86.td, visit utils/TableGen/DisassemblerEmitter.cpp, which provides an overview of the TableGen side of the code. If you’re interested in the gory, bit-for-bit details of how the disassembler dissects the various instruction bytes, you can go straight to lib/Target/X86/Disassembler/X86Disassembler.h, which describes the decode process in more detail and gives a guide to the implementation files.

深度剖析反汇编工具Borg源码 本文还有配套的精品资源,点击获取 简介:Borg是一款静态反汇编工具,其源代码是理解编译原理和逆向工程的宝贵资源。文章将探讨Borg源代码中的编程理念和技术细节,涉及VC++开发、反汇编技术、编译原理以及错误处理等方面。源代码使用Visual C++ 6开发,展示了动态地址解析、符号表解析、PE文件格式解析、控制流分析等关键技术。通过研究Borg源代码,开发者可以提升逆向工... 阅读详情

相关推荐

反汇编工具(Hacker’s Disassembler) v1.06 汉化版软件.zip

Hackers Disassembler 1.06 汉化版是一个非常快速和舒适的免费反汇编工具,玩过破解的我相信Hacker’s Disassembler 会成为你收藏的工具之一。 软件功能特色:对于COM,MZ和PE可执行文件的支持 在JMP和CALL指令和给定的地址,存储地址的历史 认识到引用字符串,对话框和菜单 认识到导入函数的调用 有关导出函数的信息 自定义的热键和颜色,语法高亮 “跟踪模式” 程序和全局变量名称 注释 书签 使用拖放和拖放打开文件 保存文本片段 对话框中的“反汇编模式” 在正常模式下可以反汇编或者整个文件(二进制和MZ),部分路段(PE)或间隔(虚拟地址在相应的字段中指定)。 在跟踪模式下反汇编开始从虚拟地址在现场开始设置,到结束设置地址,或到最接近的指令JMP或沤。然后当控制被转移到块被分解。这种模式便于拆卸的代码的小片段,例如,在RTL函数调用一些辅助功能。请注意,该守则某些部分可以通过反汇编,如果控件使用间接寻址指令(例如,调用[ESI EAX*4])转让有被错过。默认情况下,现场开始包含入口点的地址。 当打开二进制文件,需要指定文件图像(物理地址)的偏移量,图像的大小,对应于图像(虚拟地址)的开头的虚拟地址,进入点的和是否该代码是32位的虚拟地址。     反汇编 最小的字符串长度:具有长度小于给定数量少的字符串是由反汇编忽略,并且不包括在字符串引用列表。此参数用于预防参考其他不属于字符串符号的短序列。

Disassembler反汇编工具

Disassembler是ArkTS反汇编工具。如果需要分析方舟字节码文件(*.abc)相关问题,开发者可以使用Disassembler将字节数据反编译为可读的汇编指令。

2302_77228054的博客 575

Zigbee开发环境搭建:从驱动安装到程序烧录全指南

本文提供了一份详尽的Zigbee开发环境搭建全指南,涵盖从驱动安装到程序烧录的完整流程。重点介绍了使用SmartRF Flash Programmer和仿真器进行程序下载的关键步骤,并详细说明了USB转串口驱动的配置方法,帮助开发者快速构建稳定的Zigbee开发基础。

weixin_29195217的博客 394

MC Instruction Decoder

MC Instruction Decoder属于MC层LLVM中反汇编模块,主要功能是将输入的二进制文件读写成Bytes形式,输出为对应Target 机器指令MCInst,是反汇编中不可或缺的模块: MCDisassembler类是MC Instruction Decoder中对外提高的接口类,属于所有target disassembler的superclass,该类位于:llvm\include\llvm\MC\MCDisassembler\MCDisassembler.h文件该类所接口比较少,其中最重要

weixin_42730667的博客 957

【OpenCV-Python】图像的载入、显示和输出(imread()、imshow()、waitKey()、namedWindow()、imwrite())

图像的载入:imread()函数 imread()函数可以用来非常便捷地读取文件中的图片到Opencv中。这个函数一般需要两个参数: (1)载入图片的路径名。如果图像文件在工程文件夹下,可以直接用文件名读取,如“cat.jpg”,否则需要输入完整的访问路径,如“D:\\test\\lena.png”。这里还有几个tips: imread函数中,一个点代表省略当前文件夹路径,两个点则代表回...

M&Q的博客 1397

海康工业相机SDK+OpenCV实战:图像采集与Mat格式转换优化指南

本文深入探讨了如何高效利用海康工业相机SDK与OpenCV进行图像采集与处理。重点解析了从相机RawData到OpenCV Mat格式转换的核心优化技巧,包括像素格式匹配、内存零拷贝管理以及彩色图像BGR/RGB转换,旨在解决工业应用中常见的性能瓶颈与内存问题,构建稳定高效的图像处理流程。

weixin_29192211的博客 108

CTF逆向工程入门_1

这篇文章写给众多参加东华网络安全大赛的小伙伴们~ 初次撰写,大佬们发现错误的地方可以指正出来哈~ Windows下CTF赛题的主要工具下载: PEID:http://down.52pojie.cn/Tools/PEtools/PEiD 0.95.zip(解压密码:www.52pojie.cn) IDA:   http://down.52pojie.cn/Tools/Disassembl

s1054436218的博客 2万+

IntelliJ IDEA 中git使用说明书

IntelliJ IDEA 中git使用说明书

junyang2012的博客 5390

OllyDbg 80x86 32-bit Disassembler and Assembler

80x86 32-bit Disassembler and Assembler Legal partIntroductionBrief description of functionsAssembleCheckconditionDecodeaddressDisasmDisassemblebackDisassembleforwardIsfillingPrintfloat* functions Download source Legal part This package includes source

子曰小玖的博客 519

第二十六届中国机器人及人工智能大赛CRAIC决赛小型桌面级-立体仓储代码分享

国二奖,精度还有不少问题,没有视觉模块,单线程,比起其他大佬写的确实还有欠缺,继续加油吧。

qq_68232259的博客 691

SAP 屏幕增强:客户商主数据屏幕增强(KNA1、KNB1、KNVV)

本文介绍了SAP系统中针对客户主数据(KNA1、KNB1、KNVV)进行屏幕增强的具体实现方法。主要内容包括:1)在SPRO配置中创建新条目;2)通过SE80创建函数组和程序(LZKNA1TOP等);3)设置子屏幕9001并添加自定义结构字段;4)利用BADI(CUSTOMER_ADD_DATA等)实现数据交互逻辑。文章分别详细说明了针对客户主数据的一般数据(KNA1)、公司代码数据(KNB1)和销售数据(KNVV)三类不同数据的增强配置步骤,包括函数模块创建、屏幕设置和BADI方法调用等关键技术点。

SAP ABAP开发技能记录分享 1617

Bytecode-Viewer与Hopper Disassembler对比:功能与效率分析

你是否在Java/Android逆向与原生代码分析之间频繁切换工具?是否因不同平台工具的操作逻辑差异而降低工作效率?本文将深入对比两款专业逆向工程工具——**Bytecode-Viewer(BCV)** 与**Hopper Disassembler**,从功能架构、性能表现、适用场景三个维度展开分析,助你精准选择最适合的逆向工具链。 读完本文你将获得: - 两款工具的核心功能对比表 - 逆向效率...

gitblog_00636的博客 524

D457深度相机调试记录(max96712+max9295A)

使用max96712解串器解4路D457相机。采集深度相机Depth和RGB流。

navy2015_163的博客 1268

macOS ARM/x86双架构支持:全平台QQ聊天数据库解密苹果版QQ教程

gh_mirrors/qq/qq-win-db-key项目提供了全平台QQ聊天数据库解密解决方案,本文将详细介绍如何在macOS系统(包括ARM和x86架构)上解密QQ数据库,帮助你轻松获取自己的聊天记录数据。 ## 📋 准备工作:解密前的必要准备 ### 支持架构与系统要求 - **ARM架构**:适用于搭载Apple Silicon芯片的Mac设备(M1/M2/M3系列) - **x86

gitblog_00013的博客 996

Autosar PWM模块的配置和使用

在上面的代码中,我们首先配置了PWM的初始化参数,包括频率和分辨率。GPIO Driver:由于PWM信号需要输出到特定的引脚上,因此我们还需要使用GPIO驱动程序来控制引脚的状态。通过合理配置和应用PWM模块,我们可以实现对汽车电子系统中各种功能的精确控制,从而提高汽车性能和用户体验。在实际应用中,我们可以根据需要进行更多的配置和调整,以实现灵活的PWM控制。PWM Driver:这是主要的PWM驱动程序,负责产生PWM信号并输出到相应的引脚上。接下来,我们需要配置PWM模块的参数。

TcData的博客 682

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Interactive Disassembler GUI:一款强大的浏览器端反汇编工具

Interactive Disassembler GUI:一款强大的浏览器端反汇编工具 项目介绍 Interactive Disassembler GUI(简称Disasm)是一款基于Flask框架开发的浏览器端应用程序,旨在将ELF文件反汇编为Intel x86汇编代码,并在浏览器中以交互式的方式展示反汇编结果。用户可以通过点击操作,深入分析汇编代码,获取详细的指令信息、寄存器内容、跳转表解析等...

gitblog_00697的博客 443

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Capstone disassembler framework for JavaScript 的常见问题解答

Capstone disassembler framework for JavaScript 的常见问题解答 项目介绍 Capstone 是一个多架构的反汇编框架,支持多种处理器架构,最初由 Nguyen Anh Quynh 开发,并在 BSD 许可证下发布。该项目的 JavaScript 版本(Capstone.js)利用 Emscripten 将 Capstone 的功能移植到了 JavaSc...

gitblog_00056的博客 904

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

2 assembler & 2 disassembler

文章目录反汇编引擎:BeaEngineCapstone汇编引擎:XEDParsekeystone 反汇编引擎: BeaEngine 把headers和库文件win32两个文件夹拷贝到项目目录下。 预定义宏、包含头文件和库文件 #include "stdafx.h" #include <windows.h> #define BEA_ENGINE_STATIC #define BEA_US...

Starr 985

仓颉 std.database.sql 表结构操作实战:用 DriverManager 与 Statement 删除、创建数据表

本篇技术指南基于仓颉标准库 `std.database.sql` 的官方示例,完整讲解"删除表、创建表"这一最基础的数据库结构操作流程:从 `DriverManager` 获取驱动、打开数据源、建立连接,到使用 `prepareStatement` 执行 `DROP TABLE` / `CREATE TABLE` 并解析 `UpdateResult` 返回值。读者学完后,将能独立写出可编译、可运行

gitblog_00918的博客 473

08 `.o`中的汇编信息 & hopper disassembler 调试 HelloWorld

前言 上周[2020.05.23]想要 直接使用 fastdebug 版本的 jdk 来进行调试, 可惜失败了 原来是 缺少 可执行文件关联的,object file, 里面记录了 关联的源码的一些信息 看来还是 免不了, 需要 手动 编译 open jdk, 哎 本文主要是两个东西 :1. 查看 object file 中的汇编信息, 2. 基于hopper disassembler 来调试 代码 测试用例 // // Created by Jerry.X.H...

970655147的专栏 954

distorm Powerful Disassembler Library For x86/AMD64

https://code.google.com/p/distorm/

LLC 632

Zydis:x86 反汇编与代码生成,零依赖免 malloc

Zydis 是纯 C11 实现的 x86/x86-64 反汇编与代码生成库:零第三方依赖,不需要 libc,也不做任何 malloc 调用,可把内存缓冲区中的字节解码为指令文本,也能从助记符、操作数等语义描述反向生成机器码。 ## 核心能力速览 - 覆盖全部 x86/x86-64 指令与指令集扩展 - 零第三方依赖,甚至不需要 libc - 无动态内存分配,设计上线程安全 - 解码与编码双向支

gitblog_00226的博客 963

Hacker Disassembler Engine (HDE) v 0.09

Description:This is small disassembler engine intended to x86-32 code analyse. HDE get length of command, prefixes, ModR/M and SIB bytes, opcode, immediate value, displacement, etc. For example, y

Linhanshi Blog 8603

HookLib²与Zydis disassembler集成:高性能指令解析的秘密

HookLib²是一个基于纯C语言编写的轻量级函数拦截库,它巧妙集成了Zydis disassembler来实现高性能的指令解析和重定位功能。这个开源项目支持用户模式和内核模式,为Windows平台提供了高效、可靠的函数钩子解决方案。🚀 ## 什么是HookLib²? HookLib²是一个专门为Windows平台设计的函数拦截库,它的核心优势在于极致的轻量化和高性能。与传统的钩子库不同,H

gitblog_00154的博客 465

如何 10 分钟跑通 x86 反汇编库 Zydis:快速上手指南

如果你曾盯着一串机器码不知道每条指令在做什么,这篇文章适合你。Zydis 是一个高速、轻量的 C 语言 x86/x86-64 反汇编与指令编码库,能把原始字节流翻译成可读指令,也能把指令反向写成机器码。它没有任何第三方依赖,连 libc 都不需要,x64dbg、Mozilla Firefox 等知名项目都在用它。 ## 🧩 一个不依赖 libc 的机器码"翻译器" Zydis 是用 C11

gitblog_00267的博客 840

ComfyUI 中文工作流指南:用 ComfyUI-Workflows-ZHO 覆盖 7 大创作场景

节点连了一堆跑起来却报红,或者导入一份工作流 JSON 后不知道从哪个参数下手,这是刚接触 ComfyUI 的人最常见的状态。ComfyUI-Workflows-ZHO 是一个面向中文用户的预配置 ComfyUI 中文工作流集合,包含 20 多份带中文注释的工作流,覆盖 FLUX.1、SD3、Stable Cascade 等主流模型。你不需要自己理解每个节点,导入即用,下面按场景带你把工作流挑出来

gitblog_00410的博客 1160
上一篇: The LLVM Foundation
下一篇: Using clang for Chrome production builds on Linux
「已注销」
博客等级 码龄11年 2粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值