1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COURGETTE_DISASSEMBLER_WIN32_X64_H_
6 #define COURGETTE_DISASSEMBLER_WIN32_X64_H_
8 #include "base/basictypes.h"
9 #include "courgette/disassembler.h"
10 #include "courgette/memory_allocator.h"
11 #include "courgette/types_win_pe.h"
13 #ifdef COURGETTE_HISTOGRAM_TARGETS
19 class AssemblyProgram
;
21 class DisassemblerWin32X64
: public Disassembler
{
23 explicit DisassemblerWin32X64(const void* start
, size_t length
);
25 virtual ExecutableType
kind() { return EXE_WIN_32_X64
; }
27 // Returns 'true' if the buffer appears to point to a Windows 32 bit
28 // executable, 'false' otherwise. If ParseHeader() succeeds, other member
29 // functions may be called.
30 virtual bool ParseHeader();
32 virtual bool Disassemble(AssemblyProgram
* target
);
35 // Exposed for test purposes
38 bool has_text_section() const { return has_text_section_
; }
39 uint32
size_of_code() const { return size_of_code_
; }
40 bool is_32bit() const { return !is_PE32_plus_
; }
42 // Returns 'true' if the base relocation table can be parsed.
43 // Output is a vector of the RVAs corresponding to locations within executable
44 // that are listed in the base relocation table.
45 bool ParseRelocs(std::vector
<RVA
> *addresses
);
47 // Returns Section containing the relative virtual address, or NULL if none.
48 const Section
* RVAToSection(RVA rva
) const;
50 static const int kNoOffset
= -1;
51 // Returns kNoOffset if there is no file offset corresponding to 'rva'.
52 int RVAToFileOffset(RVA rva
) const;
54 // Returns same as FileOffsetToPointer(RVAToFileOffset(rva)) except that NULL
55 // is returned if there is no file offset corresponding to 'rva'.
56 const uint8
* RVAToPointer(RVA rva
) const;
58 static std::string
SectionName(const Section
* section
);
61 CheckBool
ParseFile(AssemblyProgram
* target
) WARN_UNUSED_RESULT
;
62 bool ParseAbs32Relocs();
63 void ParseRel32RelocsFromSections();
64 void ParseRel32RelocsFromSection(const Section
* section
);
66 CheckBool
ParseNonSectionFileRegion(uint32 start_file_offset
,
67 uint32 end_file_offset
, AssemblyProgram
* program
) WARN_UNUSED_RESULT
;
68 CheckBool
ParseFileRegion(const Section
* section
,
69 uint32 start_file_offset
, uint32 end_file_offset
,
70 AssemblyProgram
* program
) WARN_UNUSED_RESULT
;
72 #if COURGETTE_HISTOGRAM_TARGETS
73 void HistogramTargets(const char* kind
, const std::map
<RVA
, int>& map
);
76 // Most addresses are represented as 32-bit RVAs. The one address we can't
77 // do this with is the image base address. 'image_base' is valid only for
78 // 32-bit executables. 'image_base_64' is valid for 32- and 64-bit executable.
79 uint64
image_base() const { return image_base_
; }
81 const ImageDataDirectory
& base_relocation_table() const {
82 return base_relocation_table_
;
85 bool IsValidRVA(RVA rva
) const { return rva
< size_of_image_
; }
87 // Returns description of the RVA, e.g. ".text+0x1243". For debugging only.
88 std::string
DescribeRVA(RVA rva
) const;
90 // Finds the first section at file_offset or above. Does not return sections
91 // that have no raw bytes in the file.
92 const Section
* FindNextSection(uint32 file_offset
) const;
94 // There are 2 'coordinate systems' for reasoning about executables.
95 // FileOffset - the the offset within a single .EXE or .DLL *file*.
96 // RVA - relative virtual address (offset within *loaded image*)
97 // FileOffsetToRVA and RVAToFileOffset convert between these representations.
99 RVA
FileOffsetToRVA(uint32 offset
) const;
104 bool ReadDataDirectory(int index
, ImageDataDirectory
* dir
);
106 bool incomplete_disassembly_
; // 'true' if can leave out 'uninteresting' bits
108 std::vector
<RVA
> abs32_locations_
;
109 std::vector
<RVA
> rel32_locations_
;
112 // Fields that are always valid.
116 // Information that is valid after successful ParseHeader.
118 bool is_PE32_plus_
; // PE32_plus is for 64 bit executables.
120 // Location and size of IMAGE_OPTIONAL_HEADER in the buffer.
121 const uint8
*optional_header_
;
122 uint16 size_of_optional_header_
;
123 uint16 offset_of_data_directories_
;
125 uint16 machine_type_
;
126 uint16 number_of_sections_
;
127 const Section
*sections_
;
128 bool has_text_section_
;
130 uint32 size_of_code_
;
131 uint32 size_of_initialized_data_
;
132 uint32 size_of_uninitialized_data_
;
137 uint32 size_of_image_
;
138 int number_of_data_directories_
;
140 ImageDataDirectory export_table_
;
141 ImageDataDirectory import_table_
;
142 ImageDataDirectory resource_table_
;
143 ImageDataDirectory exception_table_
;
144 ImageDataDirectory base_relocation_table_
;
145 ImageDataDirectory bound_import_table_
;
146 ImageDataDirectory import_address_table_
;
147 ImageDataDirectory delay_import_descriptor_
;
148 ImageDataDirectory clr_runtime_header_
;
150 #if COURGETTE_HISTOGRAM_TARGETS
151 std::map
<RVA
, int> abs32_target_rvas_
;
152 std::map
<RVA
, int> rel32_target_rvas_
;
156 DISALLOW_COPY_AND_ASSIGN(DisassemblerWin32X64
);
159 } // namespace courgette
160 #endif // COURGETTE_DISASSEMBLER_WIN32_X64_H_