我无法使用 capstone 库从二进制文件中读取文本部分

I couldn't read text section from binary using capstone library

我有一个只打印“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

我使用 online disassembler and it is able to disassemble it, but with this code using 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); 总是 returns 零,这表明它没有反汇编和东西,任何解决方案?

这绝对是(曾经)是 libcapstone 中的错误或缺失的功能。从 the official repository and compiling the library by myself each bisection step. It seems like the first commit where cs_disasm actually becomes able to disassemble your code is 5a99624074d56f8eea26699496f0e8dc41cbf3fb 克隆后,我能够使用 git bisect 追踪它,它位于版本 4.0.1.

之后的某处

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

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,这也是正确的),.