From: lace <> Date: Sun, 25 Dec 2005 06:23:09 +0000 (+0000) Subject: instruction_length(): Extended to support some new Microsoft binaries. X-Git-Tag: bp_HEAD~9 X-Git-Url: https://git.jankratochvil.net/?p=captive.git;a=commitdiff_plain;h=94d79a630294939ea84ce7d9cabc6c114b8d02e4 instruction_length(): Extended to support some new Microsoft binaries. instruction_length(): Improved error messages of unsupported opcodes. --- diff --git a/src/libcaptive/ldr/loader.c b/src/libcaptive/ldr/loader.c index 48fe811..51865ba 100644 --- a/src/libcaptive/ldr/loader.c +++ b/src/libcaptive/ldr/loader.c @@ -352,9 +352,23 @@ err_g_free_ModuleObject: g_return_val_if_reached(FALSE); } +static void instruction_fail(const guint8 *instr_base,gint offset_last,const gchar *location) +{ +char instr_buf[4*3+1],*s; + + g_return_if_fail(offset_last<=(gint)((sizeof(instr_buf)-1)/3)); + + s=instr_buf; + while (offset_last-->=0) + s+=sprintf(s," %02X",*instr_base++); + g_error("instruction_length(): Unhandled at %s:%s",location,instr_buf); + /* NOTREACHED */ +} static gsize instruction_length(const guint8 *instr) { +#define INSTRUCTION_FAIL(offset_last) instruction_fail(instr,(offset_last),G_STRLOC) + if ((instr[0] & 0xF8)==0x50) /* push %regular-register */ return 1; if ((instr[0] & 0xF8)==0x58) /* pop %regular-register */ @@ -378,7 +392,7 @@ static gsize instruction_length(const guint8 *instr) return 1+1+4+1; /* 80 3D immediate-quad-indirect byte */ case 0x7C: /* cmpb $byte,#immediate(%reg,1) */ return 1+1+1+1+1; /* 80 7C address-mode immediate byte */ - default: g_assert_not_reached(); + default: INSTRUCTION_FAIL(1); } case 0x83: switch (instr[1]) { @@ -388,7 +402,7 @@ static gsize instruction_length(const guint8 *instr) return 1+1+4+1; /* 83 3D immediate-quad-indirect byte */ case 0x7C: /* cmpl $byte,#immediate(%reg,1) */ return 1+1+1+1+1; /* 80 7C address-mode immediate byte */ - default: g_assert_not_reached(); + default: INSTRUCTION_FAIL(1); } case 0x8A: /* mov ??,?? */ case 0x8B: /* mov Gb,Eb */ @@ -401,13 +415,17 @@ static gsize instruction_length(const guint8 *instr) case 0x4C: /* mov #offset(%reg,#mult),%reg */ case 0x54: /* mov #offset(%reg,#mult),%reg */ return 1+1+1+1; /* 8B 44 address-mode offset */ - default: g_assert_not_reached(); + case 0xC0: /* mov %eax,%eax */ + return 2; + case 0xFF: /* mov %edi,%edi */ + return 2; + default: INSTRUCTION_FAIL(1); } case 0x8D: /* lea Gb,M */ switch (instr[1]) { case 0x44: /* mov #offset(%reg,%reg,#mult),%reg */ return 4; /* 8B 44 address-mode offset */ - default: g_assert_not_reached(); + default: INSTRUCTION_FAIL(1); } case 0x8F: /* lea Gb,M */ switch (instr[1]) { @@ -415,9 +433,9 @@ static gsize instruction_length(const guint8 *instr) switch (instr[2]) { case 0x24: /* popl (%esp,1) */ return 3; - default: g_assert_not_reached(); + default: INSTRUCTION_FAIL(2); } - default: g_assert_not_reached(); + default: INSTRUCTION_FAIL(1); } case 0x9C: /* pushf */ return 1; @@ -439,11 +457,13 @@ static gsize instruction_length(const guint8 *instr) return 1; case 0xFF: /* inc/dec Ev */ return 2; - default: g_assert_not_reached(); + default: INSTRUCTION_FAIL(0); } g_assert_not_reached(); /* TODO:fill the table */ /* NOTREACHED */ return 0; + +#undef INSTRUCTION_FAIL }