diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2026-07-09 00:58:20 +0200 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2026-07-09 00:58:20 +0200 |
| commit | 0379f7634200c35682adb53a6653d441849903ae (patch) | |
| tree | b927d39a662df77e0dc95dda109da1303d401e9b /src/disasm.c | |
| parent | 3c091fe6eacd542a506a3f8adf1a8bd91e2e34b0 (diff) | |
Fixed compilation
Add disasm to compiled files
Removed dependency to strsafe
Detect SIB and displacement bytes correctly
Diffstat (limited to 'src/disasm.c')
| -rw-r--r-- | src/disasm.c | 147 |
1 files changed, 93 insertions, 54 deletions
diff --git a/src/disasm.c b/src/disasm.c index 62f3fab..2f59dfe 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -1,3 +1,8 @@ +#include <Windows.h> + +#include "disasm.h" +#include "utils.h" + const u8 MAX_LEGACY_PREFIXES = 4U; const u8 legacy_prefixes[] = { // Operand-size override @@ -108,7 +113,7 @@ struct opcode { const struct opcode rep_f3_opcode_map[] = { { "PAUSE", { .src = None }, { .src = None }}, // 0x90 -} +}; const struct opcode primary_opcode_map[256U] = { { "ADD", { .src = TYPE_E, .type = TYPE_BYTE }, { .src = ModRM_Reg, .type = TYPE_BYTE }}, @@ -516,6 +521,13 @@ const struct opcode group_11[2U] = { { "MOV", { .src = TYPE_E, .type = TYPE_v }, { .src = Imm, .type = TYPE_z }}, }; +const u8 mod_to_disp_size[4U] = { + 4U, + 1U, + 4U, + 0U, +}; + u8 is_legacy_prefix(u8 byte) { for (u8 index = 0U; index < sizeof(legacy_prefixes); index++) { if (byte == legacy_prefixes[index]) { @@ -599,7 +611,7 @@ u64 get_immediate(u8** bytes, enum DATA_TYPE type, u8 operand_effective_size) { return imm; } -u8 get_immediate_size(enum OPERAND_TYPE type, u8 operand_effective_size) { +u8 get_immediate_size(enum DATA_TYPE type, u8 operand_effective_size) { if (type == TYPE_BYTE) { return 1U; } else if (type == TYPE_WORD) { @@ -617,16 +629,16 @@ u8 get_immediate_size(enum OPERAND_TYPE type, u8 operand_effective_size) { } #define MODRM_MOD(ModRM) (ModRM >> 6U) -#define MODRM_REG(ModRM) (ModRM & 0b00111000) >> 0x3 +#define MODRM_REG(ModRM) ((ModRM & 0b00111000) >> 0x3) #define MODRM_RM(ModRM) (ModRM & 0b00000111) #define SIB_SCALE(SIB) (SIB >> 6U) -#define SIB_INDEX(SIB) (SIB & 0b00111000) >> 0x3 +#define SIB_INDEX(SIB) ((SIB & 0b00111000) >> 0x3) #define SIB_BASE(SIB) (SIB & 0b00000111) -#define REXW(REX) (REX & 0b00001000) >> 3U -#define REXR(REX) (REX & 0b00000100) >> 2U -#define REXX(REX) (REX & 0b00000010) >> 1U +#define REXW(REX) ((REX & 0b00001000) >> 3U) +#define REXR(REX) ((REX & 0b00000100) >> 2U) +#define REXX(REX) ((REX & 0b00000010) >> 1U) #define REXB(REX) (REX & 0b00000001) // void unassemble(CONTEXT* ctx, u32 count) { @@ -679,24 +691,31 @@ void unassemble(u8* start, u64 size) { op = &primary_opcode_map[op_byte]; } - u8 has_displacement = FALSE; + u8 disp_bytes_count = 0U; u8 has_src_SIB = FALSE; u8 has_dst_SIB = FALSE; if (op->src_operand.src & (TYPE_E | ModRM_Reg) || op->dst_operand.src & (TYPE_E | ModRM_Reg)) { u8 Mod = MODRM_MOD(ModRM); u8 RM = MODRM_RM(ModRM); - if (Mod == 0b10 || Mod == 0b01) { - has_displacement = TRUE; + // Table 1-14 + // Displacement detection + if (Mod == 0b00 && RM == 0b101) { + disp_bytes_count = mod_to_disp_size[Mod]; + } else if (Mod != 0b11) { + disp_bytes_count = mod_to_disp_size[Mod]; } - if (Mod != 0b11 && RM == 0b100) { // This may not be the only way to has an SIB byte + // SIB detection + if (Mod != 0b11 && RM == 0b100) { // This may not be the only way to have an SIB byte if (op->src_operand.src & (TYPE_E | ModRM_Reg)) { has_src_SIB = TRUE; } if (op->dst_operand.src & (TYPE_E | ModRM_Reg)) { has_dst_SIB = TRUE; } + // NOTE: We probably can't have both operand needing an SIB byte + assert(!(has_src_SIB == has_dst_SIB == TRUE)); } current_byte++; @@ -704,14 +723,23 @@ void unassemble(u8* start, u64 size) { // SIB u8 SIB = *current_byte; - if (has_SIB) { + if (has_src_SIB || has_dst_SIB) { + u8 Mod = MODRM_MOD(ModRM); + if (SIB_BASE(SIB)) { + disp_bytes_count = mod_to_disp_size[Mod]; + } current_byte++; } // Displacement bits - if (has_displacement) { - // Read displacement bits - current_byte++; + u32 disp = 0U; + if (disp_bytes_count) { + if (disp_bytes_count == 1U) { + disp = *current_byte; + } else if (disp_bytes_count == 4U) { + disp = *((u32*)current_byte); + } + current_byte += disp_bytes_count; } u64 src_imm = 0U; @@ -728,56 +756,67 @@ void unassemble(u8* start, u64 size) { u8 inst_size = (u8)(current_byte - inst_start); - for (u8 index = 0U; index < inst_size; index++) { - print("%2xb ", inst_start[index]); - } - print("\t\t%s", op->name); - - if (op->src_operand.src == Imm) { - print(" %u", src_imm); - } else if (op->src_operand.src == ModRM_Reg) { - u8 Reg = MODRM_REG(ModRM); - print(" %s", ModRM_registers[Reg][3U]); - } else if (op->src_operand.src == TYPE_E) { - u8 Mod = MODRM_MOD(ModRM); - u8 RM = MODRM_RM(ModRM); - if (Mod == 0b11) { - print(" %s", ModRM_registers[RM][3U]); + for (u8 index = 0U; index < 6U; index++) { + if (index < inst_size) { + print("%.2x ", inst_start[index]); + } else { + print(" "); } } + print("%s", op->name); - if (has_src_SIB) { - // Read SIB - i32 scale_factors[4U] = { - 1, 2, 4, 8, + // Src operand + { + if (op->src_operand.src == Imm) { + print(" %u", src_imm); + } else if (op->src_operand.src == ModRM_Reg) { + u8 Reg = MODRM_REG(ModRM); + print(" %s", ModRM_registers[Reg][3U]); + } else if (op->src_operand.src == TYPE_E) { + u8 Mod = MODRM_MOD(ModRM); + u8 RM = MODRM_RM(ModRM); + if (Mod == 0b11) { + print(" %s", ModRM_registers[RM][3U]); + } } - effective_address = scale_factors[SIB_SCALE(SIB)] * SIB_INDEX(SIB) + SIB_BASE(SIB) + off; - } - if (op->dst_operand.src == Imm) { - print(" %xu", dst_imm); + if (has_src_SIB) { + // Read SIB + i32 scale_factors[4U] = { + 1, 2, 4, 8, + }; + i32 off = 0; // displacement bytes + effective_address = scale_factors[SIB_SCALE(SIB)] * SIB_INDEX(SIB) + SIB_BASE(SIB) + off; + } } - if (has_dst_SIB) { - // Read SIB - i32 scale_factors[4U] = { - 1, 2, 4, 8, + // Dst operand + { + if (op->dst_operand.src == Imm) { + print(" %x", dst_imm); } - u8 index = SIB_INDEX(SIB); - if (index != 0b100) { - print(" [%d * %s", scale_factors[SIB_SCALE(SIB)], SIB_index_registers[index]); - } + if (has_dst_SIB) { + // Read SIB + i32 scale_factors[4U] = { + 1, 2, 4, 8, + }; - u8 base = SIB_BASE(SIB); - if (base != 0b101 && MODRM_MOD(ModRM) != 0U) { - print(" + %s", SIB_base_registers[base]); - } + u8 index = SIB_INDEX(SIB); + if (index != 0b100) { + print(" [%d * %s", scale_factors[SIB_SCALE(SIB)], SIB_index_registers[index]); + } - if (has_displacement) { - print("+ %d]", ); - } else { - print("]"); + u8 base = SIB_BASE(SIB); + if (base != 0b101 && MODRM_MOD(ModRM) != 0U) { + print(" + %s", SIB_base_registers[base]); + } + + if (disp_bytes_count) { + print("+ %d]", disp); + } else { + print("]"); + } } } |
