0

我有一个只打印“hello”的小二进制文件,我使用 libbfd 和 readelf 的命令导出 .text 部分, readelf -x .text a.out它们都给了我这个输出

f3 0f 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 f0 50 54 4c 8d 05 66 01 00 00 48 8d 0d ef 00 00 00 48 8d 3d c1 00 00 00 ff 15 52 2f 00 00 f4 90 48 8d 3d 79 2f 00 00 48 8d 05 72 2f 00 00 48 39 f8 74 15 48 8b 05 2e 2f 00 00 48 85 c0 74 09 ff e0 0f 1f 80 00 00 00 00 c3 0f 1f 80 00 00 00 00 48 8d 3d 49 2f 00 00 48 8d 35 42 2f 00 00 48 29 fe 48 89 f0 48 c1 ee 3f 48 c1 f8 03 48 01 c6 48 d1 fe 74 14 48 8b 05 05 2f 00 00 48 85 c0 74 08 ff e0 66 0f 1f 44 00 00 c3 0f 1f 80 00 00 00 00 f3 0f 1e fa 80 3d 05 2f 00 00 00 75 2b 55 48 83 3d e2 2e 00 00 00 48 89 e5 74 0c 48 8b 3d e6 2e 00 00 e8 19 ff ff ff e8 64 ff ff ff c6 05 dd 2e 00 00 01 5d c3 0f 1f 00 c3 0f 1f 80 00 00 00 00 f3 0f 1e fa e9 77 ff ff ff f3 0f 1e fa 55 48 89 e5 48 8d 3d ac 0e 00 00 b8 00 00 00 00 e8 ee fe ff ff b8 00 00 00 00 5d c3 0f 1f 80 00 00 00 00 f3 0f 1e fa 41 57 4c 8d 3d 3b 2c 00 00 41 56 49 89 d6 41 55 49 89 f5 41 54 41 89 fc 55 48 8d 2d 2c 2c 00 00 53 4c 29 fd 48 83 ec 08 e8 5f fe ff ff 48 c1 fd 03 74 1f 31 db 0f 1f 80 00 00 00 00 4c 89 f2 4c 89 ee 44 89 e7 41 ff 14 df 48 83 c3 01 48 39 dd 75 ea 48 83 c4 08 5b 5d 41 5c 41 5d 41 5e 41 5f c3 66 66 2e 0f 1f 84 00 00 00 00 00 f3 0f 1e fa c3

我使用在线反汇编程序,它能够反汇编它,但是使用capstone使用此代码:

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <capstone/capstone.h>

int main(int argc, char *argv[]) {
    csh dis;
    cs_insn *insns;

    size_t n;

    if(cs_open(CS_ARCH_X86, CS_MODE_64, &dis) != CS_ERR_OK){
        fprintf(stderr, "Faild to open Capstone\n");
        return -1;
    }

    uint8_t code []= { 0xF3, 0x0F, 0x1E, 0xFA, 0x31, 0xED, 0x49, 0x89, 0xD1, 0x5E, 0x48, 0x89, 0xE2, 0x48, 0x83, 0xE4, 0xF0, 0x50, 0x54, 0x4C, 0x8D, 0x05, 0x66, 0x01, 0x00, 0x00, 0x48, 0x8D, 0x0D, 0xEF, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x3D, 0xC1, 0x00, 0x00, 0x00, 0xFF, 0x15, 0x52, 0x2F, 0x00, 0x00, 0xF4, 0x90, 0x48, 0x8D, 0x3D, 0x79, 0x2F, 0x00, 0x00, 0x48, 0x8D, 0x05, 0x72, 0x2F, 0x00, 0x00, 0x48, 0x39, 0xF8, 0x74, 0x15, 0x48, 0x8B, 0x05, 0x2E, 0x2F, 0x00, 0x00, 0x48, 0x85, 0xC0, 0x74, 0x09, 0xFF, 0xE0, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x3D, 0x49, 0x2F, 0x00, 0x00, 0x48, 0x8D, 0x35, 0x42, 0x2F, 0x00, 0x00, 0x48, 0x29, 0xFE, 0x48, 0x89, 0xF0, 0x48, 0xC1, 0xEE, 0x3F, 0x48, 0xC1, 0xF8, 0x03, 0x48, 0x01, 0xC6, 0x48, 0xD1, 0xFE, 0x74, 0x14, 0x48, 0x8B, 0x05, 0x05, 0x2F, 0x00, 0x00, 0x48, 0x85, 0xC0, 0x74, 0x08, 0xFF, 0xE0, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0xC3, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0F, 0x1E, 0xFA, 0x80, 0x3D, 0x05, 0x2F, 0x00, 0x00, 0x00, 0x75, 0x2B, 0x55, 0x48, 0x83, 0x3D, 0xE2, 0x2E, 0x00, 0x00, 0x00, 0x48, 0x89, 0xE5, 0x74, 0x0C, 0x48, 0x8B, 0x3D, 0xE6, 0x2E, 0x00, 0x00, 0xE8, 0x19, 0xFF, 0xFF, 0xFF, 0xE8, 0x64, 0xFF, 0xFF, 0xFF, 0xC6, 0x05, 0xDD, 0x2E, 0x00, 0x00, 0x01, 0x5D, 0xC3, 0x0F, 0x1F, 0x00, 0xC3, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0F, 0x1E, 0xFA, 0xE9, 0x77, 0xFF, 0xFF, 0xFF, 0xF3, 0x0F, 0x1E, 0xFA, 0x55, 0x48, 0x89, 0xE5, 0x48, 0x8D, 0x3D, 0xAC, 0x0E, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xEE, 0xFE, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xC3, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0F, 0x1E, 0xFA, 0x41, 0x57, 0x4C, 0x8D, 0x3D, 0x3B, 0x2C, 0x00, 0x00, 0x41, 0x56, 0x49, 0x89, 0xD6, 0x41, 0x55, 0x49, 0x89, 0xF5, 0x41, 0x54, 0x41, 0x89, 0xFC, 0x55, 0x48, 0x8D, 0x2D, 0x2C, 0x2C, 0x00, 0x00, 0x53, 0x4C, 0x29, 0xFD, 0x48, 0x83, 0xEC, 0x08, 0xE8, 0x5F, 0xFE, 0xFF, 0xFF, 0x48, 0xC1, 0xFD, 0x03, 0x74, 0x1F, 0x31, 0xDB, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x89, 0xF2, 0x4C, 0x89, 0xEE, 0x44, 0x89, 0xE7, 0x41, 0xFF, 0x14, 0xDF, 0x48, 0x83, 0xC3, 0x01, 0x48, 0x39, 0xDD, 0x75, 0xEA, 0x48, 0x83, 0xC4, 0x08, 0x5B, 0x5D, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41, 0x5F, 0xC3, 0x66, 0x66, 0x2E, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x0F, 0x1E, 0xFA, 0xC3 };

    n = cs_disasm(dis, code, sizeof(code), 0x2000, 0, &insns);
    if(n <= 0){
        fprintf(stderr, "Disassembly error: %s\n", cs_strerror(cs_errno(dis)));
        return -1;
        }


    for(size_t i =0 ; i < n ; i++){
        printf("0x%016jx: ", insns[i].address);
        for(size_t j = 0; j < 16; j++){
            if(j < insns[i].size) printf("%02x ", insns[i].bytes[j]);
            else printf("    ");
        }
       printf("%-12s %s\n", insns[i].mnemonic, insns[i].op_str);
    }
    cs_free(insns, n);
    cs_close(&dis);

    return 0;
    return 0;
}

然后我用 gcc 构建它gcc disas.c -lcapstone

运行此代码后,我将始终得到以下输出:

Disassembly error: OK (CS_ERR_OK) 从这一行开始fprintf(stderr, "Disassembly error: %s\n", cs_strerror(cs_errno(dis))); ,这个函数n = cs_disasm(dis, code, sizeof(code), 0x2000, 0, &insns);总是返回零,这表明它没有反汇编和东西,有什么解决方案吗?

4

1 回答 1

3

这(曾经)绝对是 libcapstone 中的一个错误或缺失功能。git bisect在从官方存储库克隆并在每个二等分步骤中自己编译库之后,我能够使用它来追踪它。似乎第一个cs_disasm真正能够反汇编代码的提交5a99624074d56f8eea26699496f0e8dc41cbf3fb是在版本 4.0.1 之后的某个地方。

实际上,使用直接从他们的分支构建的最新版本的 libcapstone,main您的代码可以正常工作并生成(填充少一点):

0x0000000000002000: f3 0f 1e fa     endbr64
0x0000000000002004: 31 ed           xor          ebp, ebp
0x0000000000002006: 49 89 d1        mov          r9, rdx
0x0000000000002009: 5e              pop          rsi
0x000000000000200a: 48 89 e2        mov          rdx, rsp
0x000000000000200d: 48 83 e4 f0     and          rsp, 0xfffffffffffffff0
...

未正确解码的犯罪指令首先是endbr64(您的链接在线汇编程序将其解码为nop,这也是正确的),请参阅this other question了解更多信息

于 2021-07-12T05:47:24.193 回答