diff options
| author | Alexander Gavrilov | 2012-08-30 19:28:53 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-08-30 19:28:53 +0400 |
| commit | 750eefe48ad3250cc51682508cc30e78accff7e1 (patch) | |
| tree | 31c8696b98db360815131b9efa7f781a84f1e909 /library | |
| parent | c414aafc593acf7a4a2b6f38297667c6f06f7ede (diff) | |
| download | dfhack-750eefe48ad3250cc51682508cc30e78accff7e1.tar.gz dfhack-750eefe48ad3250cc51682508cc30e78accff7e1.tar.bz2 dfhack-750eefe48ad3250cc51682508cc30e78accff7e1.tar.xz | |
Follow unconditional JMP chains in MSVC vmethod ptr detection.
Diffstat (limited to 'library')
| -rw-r--r-- | library/VTableInterpose.cpp | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/library/VTableInterpose.cpp b/library/VTableInterpose.cpp index 04c436ba..079890fe 100644 --- a/library/VTableInterpose.cpp +++ b/library/VTableInterpose.cpp @@ -48,6 +48,26 @@ struct MSVC_MPTR { intptr_t this_shift; }; +static uint32_t *follow_jmp(void *ptr) +{ + uint8_t *p = (uint8_t*)ptr; + + for (;;) + { + switch (*p) + { + case 0xE9: + p += 5 + *(int32_t*)(p+1); + break; + case 0xEB: + p += 2 + *(int8_t*)(p+1); + break; + default: + return (uint32_t*)p; + } + } +} + bool DFHack::is_vmethod_pointer_(void *pptr) { auto pobj = (MSVC_MPTR*)pptr; @@ -55,7 +75,7 @@ bool DFHack::is_vmethod_pointer_(void *pptr) // MSVC implements pointers to vmethods via thunks. // This expects that they all follow a very specific pattern. - auto pval = (unsigned*)pobj->method; + auto pval = follow_jmp(pobj->method); switch (pval[0]) { case 0x20FF018BU: // mov eax, [ecx]; jmp [eax] case 0x60FF018BU: // mov eax, [ecx]; jmp [eax+0x??] @@ -71,7 +91,7 @@ int DFHack::vmethod_pointer_to_idx_(void *pptr) auto pobj = (MSVC_MPTR*)pptr; if (!pobj->method || pobj->this_shift != 0) return -1; - auto pval = (unsigned*)pobj->method; + auto pval = follow_jmp(pobj->method); switch (pval[0]) { case 0x20FF018BU: // mov eax, [ecx]; jmp [eax] return 0; |
