1 // Copyright (c) 2011 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_X86_H_
6 #define COURGETTE_DISASSEMBLER_WIN32_X86_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 DisassemblerWin32X86
: public Disassembler
{
23 explicit DisassemblerWin32X86(const void* start
, size_t length
);
25 virtual ExecutableType
kind() { return EXE_WIN_32_X86
; }
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 uint32
image_base() const { return static_cast<uint32
>(image_base_
); }
81 const ImageDataDirectory
& base_relocation_table() const {
82 return base_relocation_table_
;
85 // Returns description of the RVA, e.g. ".text+0x1243". For debugging only.
86 std::string
DescribeRVA(RVA rva
) const;
88 // Finds the first section at file_offset or above. Does not return sections
89 // that have no raw bytes in the file.
90 const Section
* FindNextSection(uint32 file_offset
) const;
92 // There are 2 'coordinate systems' for reasoning about executables.
93 // FileOffset - the the offset within a single .EXE or .DLL *file*.
94 // RVA - relative virtual address (offset within *loaded image*)
95 // FileOffsetToRVA and RVAToFileOffset convert between these representations.
97 RVA
FileOffsetToRVA(uint32 offset
) const;
102 bool ReadDataDirectory(int index
, ImageDataDirectory
* dir
);
104 bool incomplete_disassembly_
; // 'true' if can leave out 'uninteresting' bits
106 std::vector
<RVA
> abs32_locations_
;
107 std::vector
<RVA
> rel32_locations_
;
110 // Fields that are always valid.
114 // Information that is valid after successful ParseHeader.
116 bool is_PE32_plus_
; // PE32_plus is for 64 bit executables.
118 // Location and size of IMAGE_OPTIONAL_HEADER in the buffer.
119 const uint8
*optional_header_
;
120 uint16 size_of_optional_header_
;
121 uint16 offset_of_data_directories_
;
123 uint16 machine_type_
;
124 uint16 number_of_sections_
;
125 const Section
*sections_
;
126 bool has_text_section_
;
128 uint32 size_of_code_
;
129 uint32 size_of_initialized_data_
;
130 uint32 size_of_uninitialized_data_
;
134 uint64 image_base_
; // range limited to 32 bits for 32 bit executable
135 uint32 size_of_image_
;
136 int number_of_data_directories_
;
138 ImageDataDirectory export_table_
;
139 ImageDataDirectory import_table_
;
140 ImageDataDirectory resource_table_
;
141 ImageDataDirectory exception_table_
;
142 ImageDataDirectory base_relocation_table_
;
143 ImageDataDirectory bound_import_table_
;
144 ImageDataDirectory import_address_table_
;
145 ImageDataDirectory delay_import_descriptor_
;
146 ImageDataDirectory clr_runtime_header_
;
148 #if COURGETTE_HISTOGRAM_TARGETS
149 std::map
<RVA
, int> abs32_target_rvas_
;
150 std::map
<RVA
, int> rel32_target_rvas_
;
154 DISALLOW_COPY_AND_ASSIGN(DisassemblerWin32X86
);
157 } // namespace courgette
158 #endif // COURGETTE_DISASSEMBLER_WIN32_X86_H_