From ed6ebb48ae7035389905f6176f2f77b0a3a5ef98 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 11 Mar 2014 04:53:41 +0200 Subject: [PATCH] handle some masm vs some_other_msvc issues --- plugin/saveasm.cpp | 11 +++++++++- tools/cmpmrg_text.c | 53 ++++++++++++++++++++++++++++++++------------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/plugin/saveasm.cpp b/plugin/saveasm.cpp index 0732e09..48b21e4 100644 --- a/plugin/saveasm.cpp +++ b/plugin/saveasm.cpp @@ -439,7 +439,7 @@ static void idaapi run(int /*arg*/) for (;;) { int drop_large = 0, do_rva = 0, set_scale = 0, jmp_near = 0; - int word_imm = 0, dword_imm = 0, do_pushf = 0; + int word_imm = 0, dword_imm = 0, do_pushf = 0, do_nops = 0; if ((ea >> 14) != ui_ea_block) { ui_ea_block = ea >> 14; @@ -497,6 +497,12 @@ static void idaapi run(int /*arg*/) if (get_word(ea + opr.offb) == (ushort)opr.value) word_imm = 1; } + else if (opr.type == o_displ && opr.addr == 0 + && opr.offb != 0 && opr.hasSIB && opr.sib == 0x24) + { + // uses [esp+0] with 0 encoded into op + do_nops++; + } } } else { // not code @@ -593,6 +599,9 @@ pass: qfprintf(fout, "%s\n", buf); } + while (do_nops-- > 0) + qfprintf(fout, " nop ; adj\n"); + // note: next_head skips some undefined stuff ea = next_not_tail(ea); // correct? if (ea == BADADDR) diff --git a/tools/cmpmrg_text.c b/tools/cmpmrg_text.c index 0f8739a..49284be 100644 --- a/tools/cmpmrg_text.c +++ b/tools/cmpmrg_text.c @@ -343,54 +343,73 @@ static int handle_pad(uint8_t *d_obj, uint8_t *d_exe, int maxlen) struct equiv_opcode { signed char len; signed char ofs; - short cmp_rm; + unsigned short cmp_rm:1; + unsigned short simple:1; uint8_t v_masm[8]; uint8_t v_masm_mask[8]; uint8_t v_msvc[8]; uint8_t v_msvc_mask[8]; } equiv_ops[] = { // cmp $0x11,%ax - { 4, -1, 0, + { 4, -1, 0, 0, { 0x66,0x83,0xf8,0x03 }, { 0xff,0xff,0xff,0x00 }, { 0x66,0x3d,0x03,0x00 }, { 0xff,0xff,0x00,0xff }, }, // lea -0x1(%ebx,%eax,1),%esi // op mod/rm sib offs // mov, test, imm grp 1 - { 3, -2, 1, + { 3, -2, 1, 0, { 0x8d,0x74,0x03 }, { 0xf0,0x07,0xc0 }, { 0x8d,0x74,0x18 }, { 0xf0,0x07,0xc0 }, }, // movzbl 0x58f24a(%eax,%ecx,1),%eax - { 4, -3, 1, + { 4, -3, 1, 0, { 0x0f,0xb6,0x84,0x08 }, { 0xff,0xff,0x07,0xc0 }, { 0x0f,0xb6,0x84,0x01 }, { 0xff,0xff,0x07,0xc0 }, }, // inc/dec - { 3, -2, 1, + { 3, -2, 1, 0, { 0xfe,0x4c,0x03 }, { 0xfe,0xff,0xc0 }, { 0xfe,0x4c,0x18 }, { 0xfe,0xff,0xc0 }, }, // cmp - { 3, -2, 1, + { 3, -2, 1, 0, { 0x38,0x0c,0x0c }, { 0xff,0xff,0xc0 }, { 0x38,0x0c,0x30 }, { 0xff,0xff,0xc0 }, }, // test %dl,%bl - { 2, -1, 1, + { 2, -1, 1, 0, { 0x84,0xd3 }, { 0xfe,0xc0 }, { 0x84,0xda }, { 0xfe,0xc0 }, }, // cmp r,r/m vs rm/r - { 2, 0, 1, + { 2, 0, 1, 0, { 0x3a,0xca }, { 0xff,0xc0 }, { 0x38,0xd1 }, { 0xff,0xc0 }, }, // rep + 66 prefix - { 2, 0, 0, + { 2, 0, 0, 0, { 0xf3,0x66 }, { 0xfe,0xff }, { 0x66,0xf3 }, { 0xff,0xfe }, }, // fadd st, st(0) vs st(0), st - { 2, 0, 0, + { 2, 0, 0, 0, { 0xd8,0xc0 }, { 0xff,0xf7 }, { 0xdc,0xc0 }, { 0xff,0xf7 }, }, + // [esp] vs [esp+0] + { 4, -1, 0, 0, + { 0x00,0x04,0x24,0x90 }, { 0x00,0xc7,0xff,0xff }, + { 0x00,0x44,0x24,0x00 }, { 0x00,0xc7,0xff,0xff }, }, + { 5, -1, 0, 0, + { 0x00,0x04,0x24,0x00,0x90 }, { 0x00,0xc7,0xff,0x00,0xff }, + { 0x00,0x44,0x24,0x00,0x00 }, { 0x00,0xc7,0xff,0xff,0x00 }, }, + + // various align insns/fillups + { 2, -1, 0, 0, + { 0x8b,0xff }, { 0xff,0xff }, + { 0x8b,0xc0 }, { 0xff,0xff }, }, + { 2, 0, 0, 1, + { 0x00,0x00 }, { 0x00,0x00 }, + { 0x8b,0xc0 }, { 0xff,0xff }, }, + { 3, 0, 0, 1, + { 0x00,0x00,0x00 }, { 0x50,0x00,0x00 }, + { 0x2e,0x8b,0xc0 }, { 0xff,0xff,0xff }, }, // broad filters (may take too much..) // testb $0x4,0x1d(%esi,%eax,1) // movb, push, .. - { 3, -2, 1, + { 3, -2, 1, 0, { 0xf6,0x44,0x06 }, { 0x00,0x07,0xc0 }, { 0xf6,0x44,0x30 }, { 0x00,0x07,0xc0 }, }, }; @@ -428,6 +447,9 @@ static int check_equiv(uint8_t *d_obj, uint8_t *d_exe, int maxlen) op->v_msvc_mask, len)) continue; + if (op->simple) + return len + ofs; + jo = je = 0; d_obj += ofs; d_exe += ofs; @@ -441,11 +463,11 @@ static int check_equiv(uint8_t *d_obj, uint8_t *d_exe, int maxlen) break; if ((jo == len && je != len) || (jo != len && je == len)) { - printf("invalid equiv_ops\n"); + printf("invalid equiv_op #%ld\n", op - equiv_ops); return -1; } if (jo == len) - return len + ofs - 1; // matched + return len + ofs; // matched // var byte vo = d_obj[jo] & ~op->v_masm_mask[jo]; @@ -564,7 +586,8 @@ int main(int argc, char *argv[]) left = sztext_cmn - i; - if (s_text_exe.data[i] == 0xcc) { // padding + if (s_text_exe.data[i] == 0xcc || s_text_exe.data[i] == 0x90) { + // padding if (handle_pad(s_text_obj.data + i, s_text_exe.data + i, left)) continue; @@ -572,7 +595,7 @@ int main(int argc, char *argv[]) ret = check_equiv(s_text_obj.data + i, s_text_exe.data + i, left); if (ret >= 0) { - i += ret; + i += ret - 1; continue; } -- 2.39.2