10.4 认识Capstone反汇编引擎

这篇具有很好参考价值的文章主要介绍了10.4 认识Capstone反汇编引擎。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Capstone 是一款开源的反汇编框架,目前该引擎支持的CPU架构包括x86、x64、ARM、MIPS、POWERPC、SPARC等,Capstone 的特点是快速、轻量级、易于使用,它可以良好地处理各种类型的指令,支持将指令转换成AT&T汇编语法或Intel汇编语法等多种格式。Capstone的库可以集成到许多不同的应用程序和工具中,因此被广泛应用于反汇编、逆向工程、漏洞分析和入侵检测等领域,著名的比如IDA Pro、Ghidra、Hopper Disassembler等调试器都在使用该引擎。

10.4 认识Capstone反汇编引擎

  • 官方网站:http://www.capstone-engine.org/

读者可自行下载符合条件的版本,这里笔者选择的是capstone-4.0.2-win32版本,下载并解压这个版本,当读者解压后以后即可在项目中引用该引擎,Capstone引擎的配置非常容易,仅仅需要配置引用目录及库目录即可,配置完成如下图所示;

10.4 认识Capstone反汇编引擎

实现反汇编的第一步则是打开一个可执行文件,通常在引擎内可调用cs_open()函数实现打开,当打开成功时则该函数会返回一个句柄(handle)用来进行后续的反汇编操作,函数的原型通常如下:

cs_err cs_open
(
    cs_arch arch, 
    cs_mode mode, 
    csh *handle
)

其中,各参数的含义如下:

  • arch:指定要打开的CPU架构,例如CS_ARCH_X86表示x86架构,CS_ARCH_ARM表示ARM架构等。
  • mode:指定CPU的模式,例如CS_MODE_32表示32位模式,CS_MODE_64表示64位模式等。
  • handle:一个指针,用于返回打开成功后的句柄handle。

如上所示,函数返回值为cs_err类型,表示函数执行的状态或错误码,它是一个枚举类型,当函数执行成功时返回的数值为CS_ERR_OK,其次函数的第一个参数是指定CPU架构为x86,第二个参数是指定模式为32位模式,最后一个参数用来返回(handle)句柄。

当一个进程被打开后,则下一步可以通过调用cs_disasm()函数来实现对打开文件的反汇编,cs_disasm函数是Capstone反汇编框架中的一个函数,用于对指定的二进制数据进行反汇编,返回解码后的指令信息。函数原型通常如下:

size_t cs_disasm
(
    csh handle,
    const uint8_t *code,
    size_t code_size,
    uint64_t address,
    size_t count,
    cs_insn *insn
);

其中,各参数的含义如下:

  • handle:反汇编器句柄,表示使用哪一个Capstone实例来执行反汇编操作。
  • code:待反汇编的二进制数据的指针,可以是一个地址。
  • code_size:待反汇编的数据的长度,以字节为单位。
  • address:指定待反汇编数据的地址,通常为起始地址。
  • count:指定要反汇编的指令数,如果为0,则会一直反汇编至遇到code_size终止。
  • insn:指向用于保存反汇编结果的cs_insn结构体对象指针,在函数调用结束后存储反汇编结果。

函数返回值为size_t类型,代表解码的指令数量。在cs_disasm()函数中,我们通过将待反汇编的数据以及其它必要的参数传递给该函数,然后使用cs_insn结构体对象来存储反汇编结果。通过该函数,我们可以获取指令的指令助记符、指令操作数、寻址模式、使用的寄存器等信息。

当读者理解了这两个API接口后,那么反汇编实现将变得很容易实现,我们来看一下官方针对反汇编实现的一种方式,我们自行封装一个DisassembleCode()函数,该函数传入机器码字符串以及该字符串的长度则会输出该字符串的反汇编代码片段,这段代码的实现如下所示;

#include <stdio.h>
#include <inttypes.h>
#include <capstone/capstone.h>

#pragma comment(lib,"capstone32.lib")

// 反汇编字符串
void DisassembleCode(char *start_offset, int size)
{
    csh handle;
    cs_insn *insn;
    size_t count;

    char *buffer = "\x55\x8b\xec\x81\xec\x24\x03\x00\x00\x6a\x17\x90\x90\x90";

    // 打开句柄
    if (cs_open(CS_ARCH_X86, CS_MODE_32, &handle) != CS_ERR_OK)
    {
        return;
    }

    // 反汇编代码,地址从0x1000开始,返回总条数
    count = cs_disasm(handle, (unsigned char *)start_offset, size, 0x1000, 0, &insn);

    if (count > 0)
    {
        size_t index;
        for (index = 0; index < count; index++)
        {
            for (int x = 0; x < insn[index].size; x++)
            {
                printf("机器码: %d -> %02X \n", x, insn[index].bytes[x]);
            }

            printf("地址: 0x%"PRIx64" | 长度: %d 反汇编: %s %s \n", insn[index].address, insn[index].size, insn[index].mnemonic, insn[index].op_str);
        }

        cs_free(insn, count);
    }
    else
    {
        printf("反汇编返回长度为空 \n");
    }

    cs_close(&handle);
}

int main(int argc, char *argv[])
{
    char *buffer = "\x55\x8b\xec\x81\xec\x24\x03\x00\x00\x6a\x17\x90\x90\x90";
    DisassembleCode(buffer, 14);

    system("pause");
    return 0;
}

运行上述代码片段,则可看到如下图所示的输出效果;

10.4 认识Capstone反汇编引擎

上述代码虽然实现了反汇编但并无法保存结果,对于一个通用程序来说,我们当然是希望这写反汇编代码能够存储到一个特殊的容器内,当需要使用是可以随时调出来,此处我们通过定义一个MyStruct并将所需反汇编指令通过ptr.push_back(location)放入到一个全局容器内进行存储,当读者调用DisassembleCode(buffer, 14)函数是则会返回std::vector<MyStruct> ptr,并在主函数内通过循环输出这个容器,改进后的代码将会更加易于使用;

#include <iostream>
#include <vector>
#include <inttypes.h>
#include <capstone/capstone.h>

#pragma comment(lib,"capstone32.lib")

using namespace std;

typedef struct
{
    int OpCodeSize;
    int OpStringSize;
    unsigned long long Address;
    unsigned char OpCode[16];
    char OpString[256];
}MyStruct;

static void print_string_hex(unsigned char *str, size_t len)
{
    unsigned char *c;
    for (c = str; c < str + len; c++)
    {
        printf("0x%02x ", *c & 0xff);
    }
    printf("\n");
}

// 反汇编字符串
std::vector<MyStruct> DisassembleCode(char *start_offset, int size)
{
    std::vector<MyStruct> ptr = {};

    csh handle;
    cs_insn *insn;
    size_t count;

    // 打开句柄
    if (cs_open(CS_ARCH_X86, CS_MODE_32, &handle) != CS_ERR_OK)
    {
        return{};
    }

    // 反汇编代码,地址从0x1000开始,返回总条数
    count = cs_disasm(handle, (unsigned char *)start_offset, size, 0x0, 0, &insn);

    if (count > 0)
    {
        size_t index;

        // 循环反汇编代码
        for (index = 0; index < count; index++)
        {
            // 清空
            MyStruct location;
            memset(&location, 0, sizeof(MyStruct));

            // 循环拷贝机器码
            for (int x = 0; x < insn[index].size; x++)
            {
                location.OpCode[x] = insn[index].bytes[x];
            }

            // 拷贝地址长度
            location.Address = insn[index].address;
            location.OpCodeSize = insn[index].size;

            // 拷贝反汇编指令
            strcpy_s(location.OpString, insn[index].mnemonic);
            strcat_s(location.OpString, " ");
            strcat_s(location.OpString, insn[index].op_str);

            // 得到反汇编长度
            location.OpStringSize = strlen(location.OpString);

            ptr.push_back(location);
        }
        cs_free(insn, count);
    }
    else
    {
        return{};
    }
    cs_close(&handle);
    return ptr;
}

int main(int argc, char *argv[])
{
    char *buffer = "\x55\x8b\xec\x81\xec\x24\x03\x00\x00\x6a\x17\x90\x90\x90";

    // 反汇编并返回容器
    std::vector<MyStruct> ptr = DisassembleCode(buffer, 14);

    // 循环整个容器
    for (int x = 0; x < ptr.size(); x++)
    {
        // 输出地址
        printf("%08X | ", ptr[x].Address);
        printf("%03d | ", ptr[x].OpStringSize);

        // 输出反汇编
        for (int z = 0; z < ptr[x].OpStringSize; z++)
        {
            printf("%c", ptr[x].OpString[z]);
        }
        printf("\n");

        // 输出机器码
        for (int y = 0; y < ptr[x].OpCodeSize; y++)
        {
            printf("%02X ", ptr[x].OpCode[y]);
        }

        printf("\n");
        // print_string_hex(ptr[x].OpCode, ptr[x].OpCodeSize);
    }

    system("pause");
    return 0;
}

运行后输出效果图如下图所示;

10.4 认识Capstone反汇编引擎文章来源地址https://www.toymoban.com/news/detail-710428.html

到了这里,关于10.4 认识Capstone反汇编引擎的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FreeRTOS 全系列笔记——基于V10.4

    基于crotex-m处理器新建FreeRTOS工程 为什么使用嵌入式实时操作系统(RTOS) FreeRTOS——创建任务 FreeRTOS的任务调度和管理 FreeRTOS-内核链表数据结构 FreeRTOS-内核对时间的测量 FreeRTOS-内核中的钩子(Hook)函数 FreeRTOS-软件定时器的使用 FreeRTOS-软件定时器的实现原理 FreeRTOS-延后执行机制

    2024年02月04日
    浏览(30)
  • 【ARM 嵌入式 编译系列 10.4 -- 生成二进制文件】

    在嵌入的工作中,经常会使用到二进制文件,那么我们如何自己生成一个二进制文件呢?接下来介绍如何将一个只包含将32位数据的文件转化为二进制文件,原文件如下(数据一共 64bytes): 我们使用 gcc 对齐先进行编译然后再进行反汇编: 具体命令如下: 通过上面命令会生成

    2024年02月02日
    浏览(38)
  • dotnetcharting|||.netCHARTING 10.4 for .NET6-WEB

    .NET 6.0 Chart Support .netCHARTING 10.4 adds both a .NET 6.0 chart nuget package and .NET 6.0 chart sample bundle (requires Visual Studio 2022), .NET 5 was the successor of .NET Core 3.1 and .NET Framework 4.8, aims to provide .NET developers with a new cross-platform development experience. .NET 6.0 expands on this with simplified development, better perfo

    2024年02月08日
    浏览(21)
  • 文心一言 VS 讯飞星火 VS chatgpt (123)-- 算法导论10.4 4题

    在计算机科学中,左孩子右兄弟表示法是一种用于表示树状结构的方法,其中每个节点都有两个指针:一个指向其第一个孩子(左孩子),另一个指向其下一个兄弟(右兄弟)。对于一个有根树,我们可以使用一个数组来表示它,其中每个索引对应一个节点,每个节点包含两

    2024年02月08日
    浏览(32)
  • MATLAB机器人工具箱详解1—RTB 10.4版本简介及安装

    机器人学工具箱(Robotic Toolbook for Matlab) 是matlab中专门用于机器人仿真的工具箱,在机器人建模、轨迹规划、控制、可视化方面使用非常方便。本次安装环境为Windows 11+MATLAB 2023a,所安装的机器人工具箱的版本为RTB 10.4,后续将有详细的讲解不同的机器人工具箱的版本区别。

    2024年02月05日
    浏览(34)
  • Elastic stack8.10.4搭建、启用安全认证,启用https,TLS,SSL 安全配置详解

    ELK大家应该很了解了,废话不多说开始部署 kafka在其中作为消息队列解耦和让logstash高可用 kafka和zk 的安装可以参考这篇文章 深入理解Kafka3.6.0的核心概念,搭建与使用-CSDN博客 需要 elasticsearch-8.10.4 logstash-8.10.4 kibana-8.10.4 kafka_2.13-3.6.0 apache-zookeeper-3.9.1-bin.tar filebeat-8.10.4-linux-

    2024年02月04日
    浏览(32)
  • Blender 是一款免费开源的 3D 创作套件

            Blender是一个免费和开源的 3D 计算机图形软件工具集,用于创建动画电影、视觉效果、艺术、3D 打印模型、交互式 3D 应用、VR 和计算机游戏。随着 Blender 3.4 的发布,Blender 开发人员觉得这款开源 3D 建模软件能更好发挥其性能。           Blender 是一款免费开源的

    2024年02月16日
    浏览(38)
  • BSD-3-Clause是一种开源软件许可协议

    BSD-3-Clause是一种开源软件许可协议,也称为BSD三条款许可证。它是BSD许可证家族中的一种,是一种宽松的许可证,允许软件自由使用、修改和重新分发,同时也保留了一些版权和责任方面的规定。 BSD-3-Clause许可证的主要特点包括以下三个条款: 再分发条款 :允许在任何目的

    2024年04月23日
    浏览(51)
  • 思通舆情 是一款开源免费的舆情系统 介绍

    思通舆情 是一款开源免费的舆情系统。 支持本地化部署,支持在线体验。 支持对海量舆情数据分析和挖掘。 无论你是使用者还是共同完善的开发者,欢迎 pull request 或者 留言对我们提出建议。 您的支持和参与就是我们坚持开源的动力!请   star 或者 fork! 思通舆情 的功能

    2024年04月13日
    浏览(52)
  • 【AI 开源框架】BMTools 是一能让语言模型使用扩展工具的开源仓库

    BMTools 是一能让语言模型使用扩展工具的开源仓库,其也是开源社区构建和共享工具的一个平台。在这个仓库中,您可以: (1) 通过编写 Python 函数轻松构建插件, (2) 使用外部的 ChatGPT-Plugins。 本项目受到开源项目LangChain的启发,针对开源工具的使用(例如ChatGPT-Plugins)进行了

    2024年02月08日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包