From 3567b1701aa55a6421aefa5f3de1ca5507cbdf79 Mon Sep 17 00:00:00 2001 From: "alkondratenko@gmail.com" Date: Tue, 7 May 2013 19:15:35 +0000 Subject: issue-511: recognise rex.w jmpq *(%rip) as iat jump Apparently Windows Server 2012 (and presumably windows 8) now has this form of iat jump. Which is quite useless (rex.w is according to my understanding is not needed at all) but because of rex.w our code to recognize jumps like that didn't work. Fix is just skip this prefix. git-svn-id: http://gperftools.googlecode.com/svn/trunk@214 6b5cf1ce-ec42-a296-1ba9-69fdba395a50 --- src/windows/preamble_patcher.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/windows/preamble_patcher.cc b/src/windows/preamble_patcher.cc index 4163691..51a5af7 100644 --- a/src/windows/preamble_patcher.cc +++ b/src/windows/preamble_patcher.cc @@ -103,6 +103,7 @@ void* PreamblePatcher::ResolveTargetImpl(unsigned char* target, new_target = target + 2 + relative_offset; } else if (target[0] == ASM_JMP32ABS_0 && target[1] == ASM_JMP32ABS_1) { + jmp32rel: // Visual studio seems to sometimes do it this way instead of the // previous way. Not sure what the rules are, but it was happening // with operator new in some binaries. @@ -118,6 +119,18 @@ void* PreamblePatcher::ResolveTargetImpl(unsigned char* target, memcpy(&new_target_v, reinterpret_cast(target + 2), 4); } new_target = reinterpret_cast(*new_target_v); + } else if (kIs64BitBinary && target[0] == ASM_REXW + && target[1] == ASM_JMP32ABS_0 + && target[2] == ASM_JMP32ABS_1) { + // in Visual Studio 2012 we're seeing jump like that: + // rex.W jmpq *0x11d019(%rip) + // + // according to docs I have, rex prefix is actually unneeded and + // can be ignored. I.e. docs say for jumps like that operand + // already defaults to 64-bit. But clearly it breaks abs. jump + // detection above and we just skip rex + target++; + goto jmp32rel; } else { break; } -- cgit v1.2.1