diff options
author | huangs <huangs@chromium.org> | 2015-09-18 11:52:56 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-18 18:53:28 +0000 |
commit | 6d2a30316defffdd77c473547063316ebb9c279b (patch) | |
tree | 6de1afe27ab096196c1c4e92587c19519691b443 /courgette/disassembler_win32_x86.cc | |
parent | 6d5ddf5cd94ed429df19496948062fe137e68116 (diff) | |
download | chromium_src-6d2a30316defffdd77c473547063316ebb9c279b.zip chromium_src-6d2a30316defffdd77c473547063316ebb9c279b.tar.gz chromium_src-6d2a30316defffdd77c473547063316ebb9c279b.tar.bz2 |
[Courgette] Refactor: Adding Rel32FinderWin32X86_Basic and Unittests
We're planning to improve heuristic to find Rel32 addresses for Win32 x86.
First refactor by by extraacting the feature into its own class. This also
lead to the extraction of RVA and various helpers from disassembler.h to
image_utils.h.
Also adding unittests for Rel32FinderWin32X86_Basic. The test is
data-driven by adding a simple parser for test data.
BUG=
Review URL: https://codereview.chromium.org/1344173003
Cr-Commit-Position: refs/heads/master@{#349727}
Diffstat (limited to 'courgette/disassembler_win32_x86.cc')
-rw-r--r-- | courgette/disassembler_win32_x86.cc | 76 |
1 files changed, 9 insertions, 67 deletions
diff --git a/courgette/disassembler_win32_x86.cc b/courgette/disassembler_win32_x86.cc index dd3dd5e..85d99f4 100644 --- a/courgette/disassembler_win32_x86.cc +++ b/courgette/disassembler_win32_x86.cc @@ -14,6 +14,7 @@ #include "courgette/assembly_program.h" #include "courgette/courgette.h" #include "courgette/encoded_program.h" +#include "courgette/rel32_finder_win32_x86.h" namespace courgette { @@ -434,7 +435,6 @@ void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) { uint32 start_file_offset = section->file_offset_of_raw_data; uint32 end_file_offset = start_file_offset + section->size_of_raw_data; - RVA relocs_start_rva = base_relocation_table().address_; const uint8* start_pointer = OffsetToPointer(start_file_offset); const uint8* end_pointer = OffsetToPointer(end_file_offset); @@ -442,75 +442,17 @@ void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) { RVA start_rva = FileOffsetToRVA(start_file_offset); RVA end_rva = start_rva + section->virtual_size; - // Quick way to convert from Pointer to RVA within a single Section is to - // subtract 'pointer_to_rva'. - const uint8* const adjust_pointer_to_rva = start_pointer - start_rva; - - std::vector<RVA>::iterator abs32_pos = abs32_locations_.begin(); - - // Find the rel32 relocations. - const uint8* p = start_pointer; - while (p < end_pointer) { - RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva); - if (current_rva == relocs_start_rva) { - uint32 relocs_size = base_relocation_table().size_; - if (relocs_size) { - p += relocs_size; - continue; - } - } - - //while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) - // ++abs32_pos; - - // Heuristic discovery of rel32 locations in instruction stream: are the - // next few bytes the start of an instruction containing a rel32 - // addressing mode? - const uint8* rel32 = NULL; - - if (p + 5 <= end_pointer) { - if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32 - rel32 = p + 1; - } - } - if (p + 6 <= end_pointer) { - if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form - if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely - rel32 = p + 2; - } - } - if (rel32) { - RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva); - - // Is there an abs32 reloc overlapping the candidate? - while (abs32_pos != abs32_locations_.end() && *abs32_pos < rel32_rva - 3) - ++abs32_pos; - // Now: (*abs32_pos > rel32_rva - 4) i.e. the lowest addressed 4-byte - // region that could overlap rel32_rva. - if (abs32_pos != abs32_locations_.end()) { - if (*abs32_pos < rel32_rva + 4) { - // Beginning of abs32 reloc is before end of rel32 reloc so they - // overlap. Skip four bytes past the abs32 reloc. - p += (*abs32_pos + 4) - current_rva; - continue; - } - } + Rel32FinderWin32X86_Basic finder( + base_relocation_table().address_, + base_relocation_table().address_ + base_relocation_table().size_, + size_of_image_); + finder.Find(start_pointer, end_pointer, start_rva, end_rva, abs32_locations_); + finder.SwapRel32Locations(&rel32_locations_); - RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32); - // To be valid, rel32 target must be within image, and within this - // section. - if (IsValidRVA(target_rva) && - start_rva <= target_rva && target_rva < end_rva) { - rel32_locations_.push_back(rel32_rva); #if COURGETTE_HISTOGRAM_TARGETS - ++rel32_target_rvas_[target_rva]; + DCHECK(rel32_target_rvas_.empty()); + finder.SwapRel32TargetRVAs(&rel32_target_rvas_); #endif - p = rel32 + 4; - continue; - } - } - p += 1; - } } CheckBool DisassemblerWin32X86::ParseNonSectionFileRegion( |