diff options
author | Zeex <zeex@rocketmail.com> | 2014-11-27 19:46:18 +0600 |
---|---|---|
committer | Zeex <zeex@rocketmail.com> | 2014-11-27 19:47:10 +0600 |
commit | 74721ebcc09523cd9d1c4e5bb142a6323bacb965 (patch) | |
tree | bf64e930fabfc9b71664fca1e0537cff8ccc4a91 /subhook_x86.c | |
parent | 51598ff1fa6837446c6b0200b51cc0603d7ba144 (diff) | |
download | subhook-74721ebcc09523cd9d1c4e5bb142a6323bacb965.zip subhook-74721ebcc09523cd9d1c4e5bb142a6323bacb965.tar.gz subhook-74721ebcc09523cd9d1c4e5bb142a6323bacb965.tar.bz2 |
Fix decoding of [disp32] decoding
The [disp32] form requires mod == 0.
Diffstat (limited to 'subhook_x86.c')
-rw-r--r-- | subhook_x86.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/subhook_x86.c b/subhook_x86.c index 86d8ae7..606ff4c 100644 --- a/subhook_x86.c +++ b/subhook_x86.c @@ -148,22 +148,24 @@ static size_t subhook_disasm(uint8_t *code, int *reloc) { return 0; if (reloc != NULL && opcodes[i].flags & RELOC) - *reloc = len; + *reloc = len; /* relative call or jump */ if (opcodes[i].flags & MODRM) { int modrm = code[len++]; + int mod = modrm >> 6; + int rm = modrm & 7; - if ((modrm & 0xC0) != 0xC0 && (modrm & 0x07) == 0x04) + if (mod != 3 && rm == 4) len++; /* for SIB */ #ifdef SUBHOOK_X86_64 - if (reloc != NULL && (modrm & 0x07) == 0x05) - *reloc = len; + if (reloc != NULL && rm == 5) + *reloc = len; /* RIP-relative addressing */ #endif - if ((modrm & 0xC0) == 0x40) + if (mod == 1) len += 1; /* for disp8 */ - if ((modrm & 0xC0) == 0x80 || (modrm & 0x07) == 0x05) + if (mod == 2 || (mod == 0 && rm == 5)) len += 4; /* for disp32 */ } |