handle some masm vs some_other_msvc issues
authornotaz <notasas@gmail.com>
Tue, 11 Mar 2014 02:53:41 +0000 (04:53 +0200)
committernotaz <notasas@gmail.com>
Tue, 11 Mar 2014 02:53:41 +0000 (04:53 +0200)
plugin/saveasm.cpp
tools/cmpmrg_text.c

index 0732e09..48b21e4 100644 (file)
@@ -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)
index 0f8739a..49284be 100644 (file)
@@ -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;
                }