获取x86-64指令的大小

时间:2017-05-28 14:18:57

标签: c assembly x86-64

我需要一个可以计算x86-64指令长度的函数。

例如,它可以这样使用:

char ret[] = { 0xc3 };
size_t length = instructionLength(ret);
在此示例中,

length将设置为1。

我不想包含整个反汇编库,因为我需要的唯一信息是指令的长度。

我正在寻找一种用C语言编写的极简主义方法,理想情况下尽可能小。

100%完整的x86-64指令集并不是绝对必要的(可以省略非常模糊的指令集,例如向量寄存器集指令)。

我正在寻找的类似答案(但对于错误的架构):

Get size of assembly instructions

2 个答案:

答案 0 :(得分:7)

英特尔的XED库可以使用x86 / x86_64指令:https://github.com/intelxed/xed,这是使用英特尔机器代码的唯一正确方法。

xed_decode函数将为您提供有关说明的所有信息:https://intelxed.github.io/ref-manual/group__DEC.html https://intelxed.github.io/ref-manual/group__DEC.html#ga9a27c2bb97caf98a6024567b261d0652

xed_ild_decode用于指令长度解码: https://intelxed.github.io/ref-manual/group__DEC.html#ga4bef6152f61997a47c4e0fe4327a3254

XED_DLL_EXPORT xed_error_enum_t xed_ild_decode    (   xed_decoded_inst_t *    xedd,
const xed_uint8_t *   itext,
const unsigned int    bytes 
)     
     

该函数只进行指令长度解码。

     

它不会返回完全解码的指令。

     

参数

     
      
  • xedd xed_decoded_inst_t类型的解码指令。通过xedd发送的模式/状态;请参阅xed_state_t。
  •   
  • 指向指令文本字节数组的指针
  •   
  • 字节迭代输入数组的长度。 1到15个字节,更多的东西被忽略。
  •   
     

返回:

     

xed_error_enum_t表示成功(XED_ERROR_NONE)或   失败。只有两个失败代码对此功能有效:   XED_ERROR_BUFFER_TOO_SHORT和XED_ERROR_GENERAL_ERROR。一般来说   此函数无法判断指令是否有效。对于   有效指令,XED可以判断是否提供了足够的字节   解码指令。如果提供的不够,则XED返回   XED_ERROR_BUFFER_TOO_SHORT。从这个功能,   XED_ERROR_GENERAL_ERROR表示XED无法解码   指令的长度,因为指令是无效的甚至是   它的长度可能会超出预期。

要获得xedd填充xed_ild_decode的长度,请使用xed_decoded_inst_get_lengthhttps://intelxed.github.io/ref-manual/group__DEC.html#gad1051f7b86c94d5670f684a6ea79fcdf

static XED_INLINE xed_uint_t xed_decoded_inst_get_length  (   const xed_decoded_inst_t *  p   )   
     

以字节为单位返回已解码指令的长度。

示例代码(“Intel License,Version 2.0”,作者:Intel 2016):https://github.com/intelxed/xed/blob/master/examples/xed-ex-ild.c

#include "xed/xed-interface.h"
#include <stdio.h>

int main()
{
    xed_bool_t long_mode = 1;
    xed_decoded_inst_t xedd;
    xed_state_t dstate;
    unsigned char itext[15] = { 0xf2, 0x2e, 0x4f, 0x0F, 0x85, 0x99,
                                0x00, 0x00, 0x00 };

    xed_tables_init(); // one time per process

    if (long_mode) 
        dstate.mmode=XED_MACHINE_MODE_LONG_64;
    else 
        dstate.mmode=XED_MACHINE_MODE_LEGACY_32;

    xed_decoded_inst_zero_set_mode(&xedd, &dstate);
    xed_ild_decode(&xedd, itext, XED_MAX_INSTRUCTION_BYTES);
    printf("length = %u\n",xed_decoded_inst_get_length(&xedd));

    return 0;
}

答案 1 :(得分:0)

如果您使用的是 Windows,则只需使用 dbgeng.dll 中的 IDebugControl::Disassemble(..., &end_address)。有关用法示例,请参阅 this question