aboutsummaryrefslogtreecommitdiff
path: root/subhook_x86.c
diff options
context:
space:
mode:
authorZeex <zeex@rocketmail.com>2014-11-27 19:46:18 +0600
committerZeex <zeex@rocketmail.com>2014-11-27 19:47:10 +0600
commit74721ebcc09523cd9d1c4e5bb142a6323bacb965 (patch)
treebf64e930fabfc9b71664fca1e0537cff8ccc4a91 /subhook_x86.c
parent51598ff1fa6837446c6b0200b51cc0603d7ba144 (diff)
downloadsubhook-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.c14
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 */
}