summaryrefslogtreecommitdiffstats
path: root/courgette
diff options
context:
space:
mode:
Diffstat (limited to 'courgette')
-rw-r--r--courgette/disassembler_win32_x64.cc2
-rw-r--r--courgette/disassembler_win32_x86.cc8
2 files changed, 10 insertions, 0 deletions
diff --git a/courgette/disassembler_win32_x64.cc b/courgette/disassembler_win32_x64.cc
index 667b4e1..6f35ca5 100644
--- a/courgette/disassembler_win32_x64.cc
+++ b/courgette/disassembler_win32_x64.cc
@@ -264,6 +264,8 @@ bool DisassemblerWin32X64::ParseRelocs(std::vector<RVA> *relocs) {
int offset = entry & 0xFFF;
RVA rva = page_rva + offset;
+ // TODO(sebmarchand): Skip the relocs that live outside of the image. See
+ // the version of this function in disassembler_win32_x86.cc.
if (type == 10) { // IMAGE_REL_BASED_DIR64
relocs->push_back(rva);
} else if (type == 0) { // IMAGE_REL_BASED_ABSOLUTE
diff --git a/courgette/disassembler_win32_x86.cc b/courgette/disassembler_win32_x86.cc
index bb300d9..8490fcb 100644
--- a/courgette/disassembler_win32_x86.cc
+++ b/courgette/disassembler_win32_x86.cc
@@ -263,6 +263,14 @@ bool DisassemblerWin32X86::ParseRelocs(std::vector<RVA> *relocs) {
int offset = entry & 0xFFF;
RVA rva = page_rva + offset;
+ // Skip the relocs that live outside of the image. It might be the case
+ // if a reloc is relative to a register, e.g.:
+ // mov ecx,dword ptr [eax+044D5888h]
+ uint32 target_address = Read32LittleEndian(RVAToPointer(rva));
+ if (target_address < image_base_ ||
+ target_address > (image_base_ + size_of_image_)) {
+ continue;
+ }
if (type == 3) { // IMAGE_REL_BASED_HIGHLOW
relocs->push_back(rva);
} else if (type == 0) { // IMAGE_REL_BASED_ABSOLUTE