Capstone cs_disasm只反汇编代码的一小部分

时间:2017-08-27 21:56:31

标签: c++ c reverse-engineering disassembly capstone

我在MacOS和MacOS x86_64二进制文件上试验http://www.capstone-engine.org。它或多或少都有效,但我确实有两个问题。

我正在加载测试dylib

[self custom_logging:[NSString stringWithFormat:@"Module Path:%@",clientPath]];
NSMutableData *ModuleNSDATA = [NSMutableData dataWithContentsOfFile:clientPath];
[self custom_logging:[NSString stringWithFormat:@"Client Module Size: %lu MB",(ModuleNSDATA.length/1024/1024)]];
[ModuleNSDATA replaceBytesInRange:NSMakeRange(0, 20752) withBytes:NULL length:0];
uint8_t *bytes = (uint8_t*)[ModuleNSDATA bytes];
long size = [ModuleNSDATA length]/sizeof(uint8_t);
[self custom_logging:[NSString stringWithFormat:@"UInt8_t array size: %lu",size]];
ModuleASM = [NSString stringWithCString:disassembly(bytes,size,0x5110).c_str() encoding:[NSString defaultCStringEncoding]];
  1. 到目前为止我的研究似乎我需要从二进制代码中修剪“第一”字节以删除标题和元数据,直到它遇到真正的指令。但是我不确定capstone是否为此提供任何api,或者我需要按字节模式扫描并找到第一个指令地址。
  2. 事实上我已经应用了简单的解决方法,我确实找到了安全地址,肯定会对我将加载的大多数模块都有说明,但是我想应用适当的解决方案。

    1. 我已经使用我所描述的解决方法成功加载和反汇编了部分模块代码。然而,遗憾的是, cs_disasm 返回的指令大多不超过5000-6000,这令人困惑,似乎它打破常规指令,它不应该打破。我不确定我做错了什么。模块超过15mb的代码,因此有超过5k的指令进行反汇编。
    2. 以下功能我基于Capstone Docs示例

      string disassembly(uint8_t *bytearray, long size, uint64_t startAddress){
          csh handle;
          cs_insn *insn;
          size_t count;
          string output;
          if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) == CS_ERR_OK){
          count = cs_disasm(handle, bytearray, size, startAddress, 0, &insn);
                 printf("\nCOUNT:%lu",count);
              if (count > 0) {
                  size_t j;
                  for (j = 0; j < count; j++) {
                      char buffer[512];
                      int i=0;
                      i = sprintf(buffer, "0x%" PRIx64":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic,insn[j].op_str);
                      output += buffer;
                  }
                  cs_free(insn, count);
              } else {
                  output = "ERROR: Failed to disassemble given code!\n";
              }
          }
          cs_close(&handle);
          return output;
      }
      

      我真的很感激你的帮助。
      热烈,
      大卫

1 个答案:

答案 0 :(得分:0)

Anwser只是简单地使用SKIPDATA模式。凯普斯很棒,但他们的文档很糟糕。

下面的工作示例。这种模式仍然存在很大问题,因此最好对数据扇区的检测应该是自定义代码。对我来说,它只适用于小块代码。但实际上它确实反汇编到文件末尾。

string disassembly(uint8_t *bytearray, long size, uint64_t startAddress){
    csh handle;
    cs_insn *insn;
    size_t count;
    string output;
    cs_opt_skipdata skipdata = {
       .mnemonic = "db",
    };
    if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) == CS_ERR_OK){
        cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
        cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
        cs_option(handle, CS_OPT_SKIPDATA_SETUP, (size_t)&skipdata);
        count = cs_disasm(handle, bytearray, size, startAddress, 0, &insn);
        if (count > 0) {
            size_t j;
            for (j = 0; j < count; j++) {
                char buffer[512];
                int i=0;
                i = sprintf(buffer, "0x%" PRIx64":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic,insn[j].op_str);
                output += buffer;
            }
            cs_free(insn, count);
        } else {
            output = "ERROR: Failed to disassemble given code!\n";
        }
    }
    cs_close(&handle);
    return output;
}

对那些投票支持这个问题的巨魔感到羞耻。

相关问题