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"
15 class AssemblyProgram
;
17 class DisassemblerWin32X86
: public Disassembler
{
19 explicit DisassemblerWin32X86(const void* start
, size_t length
);
21 virtual ExecutableType
kind() { return EXE_WIN_32_X86
; }
23 // Returns 'true' if the buffer appears to point to a Windows 32 bit
24 // executable, 'false' otherwise. If ParseHeader() succeeds, other member
25 // functions may be called.
26 virtual bool ParseHeader();
28 virtual bool Disassemble(AssemblyProgram
* target
);
31 // Exposed for test purposes
34 bool has_text_section() const { return has_text_section_
; }
35 uint32
size_of_code() const { return size_of_code_
; }
36 bool is_32bit() const { return !is_PE32_plus_
; }
38 // Returns 'true' if the base relocation table can be parsed.
39 // Output is a vector of the RVAs corresponding to locations within executable
40 // that are listed in the base relocation table.
41 bool ParseRelocs(std::vector
<RVA
> *addresses
);
43 // Returns Section containing the relative virtual address, or NULL if none.
44 const Section
* RVAToSection(RVA rva
) const;
46 static const int kNoOffset
= -1;
47 // Returns kNoOffset if there is no file offset corresponding to 'rva'.
48 int RVAToFileOffset(RVA rva
) const;
50 // Returns same as FileOffsetToPointer(RVAToFileOffset(rva)) except that NULL
51 // is returned if there is no file offset corresponding to 'rva'.
52 const uint8
* RVAToPointer(RVA rva
) const;
54 static std::string
SectionName(const Section
* section
);
57 CheckBool
ParseFile(AssemblyProgram
* target
) WARN_UNUSED_RESULT
;
58 bool ParseAbs32Relocs();
59 void ParseRel32RelocsFromSections();
60 void ParseRel32RelocsFromSection(const Section
* section
);
62 CheckBool
ParseNonSectionFileRegion(uint32 start_file_offset
,
63 uint32 end_file_offset
, AssemblyProgram
* program
) WARN_UNUSED_RESULT
;
64 CheckBool
ParseFileRegion(const Section
* section
,
65 uint32 start_file_offset
, uint32 end_file_offset
,
66 AssemblyProgram
* program
) WARN_UNUSED_RESULT
;
68 #if COURGETTE_HISTOGRAM_TARGETS
69 void HistogramTargets(const char* kind
, const std::map
<RVA
, int>& map
);
72 // Most addresses are represented as 32-bit RVAs. The one address we can't
73 // do this with is the image base address. 'image_base' is valid only for
74 // 32-bit executables. 'image_base_64' is valid for 32- and 64-bit executable.
75 uint32
image_base() const { return static_cast<uint32
>(image_base_
); }
77 const ImageDataDirectory
& base_relocation_table() const {
78 return base_relocation_table_
;
81 bool IsValidRVA(RVA rva
) const { return rva
< size_of_image_
; }
83 // Returns description of the RVA, e.g. ".text+0x1243". For debugging only.
84 std::string
DescribeRVA(RVA rva
) const;
86 // Finds the first section at file_offset or above. Does not return sections
87 // that have no raw bytes in the file.
88 const Section
* FindNextSection(uint32 file_offset
) const;
90 // There are 2 'coordinate systems' for reasoning about executables.
91 // FileOffset - the the offset within a single .EXE or .DLL *file*.
92 // RVA - relative virtual address (offset within *loaded image*)
93 // FileOffsetToRVA and RVAToFileOffset convert between these representations.
95 RVA
FileOffsetToRVA(uint32 offset
) const;
100 bool ReadDataDirectory(int index
, ImageDataDirectory
* dir
);
102 bool incomplete_disassembly_
; // 'true' if can leave out 'uninteresting' bits
104 std::vector
<RVA
> abs32_locations_
;
105 std::vector
<RVA
> rel32_locations_
;
108 // Fields that are always valid.
112 // Information that is valid after successful ParseHeader.
114 bool is_PE32_plus_
; // PE32_plus is for 64 bit executables.
116 // Location and size of IMAGE_OPTIONAL_HEADER in the buffer.
117 const uint8
*optional_header_
;
118 uint16 size_of_optional_header_
;
119 uint16 offset_of_data_directories_
;
121 uint16 machine_type_
;
122 uint16 number_of_sections_
;
123 const Section
*sections_
;
124 bool has_text_section_
;
126 uint32 size_of_code_
;
127 uint32 size_of_initialized_data_
;
128 uint32 size_of_uninitialized_data_
;
132 uint64 image_base_
; // range limited to 32 bits for 32 bit executable
133 uint32 size_of_image_
;
134 int number_of_data_directories_
;
136 ImageDataDirectory export_table_
;
137 ImageDataDirectory import_table_
;
138 ImageDataDirectory resource_table_
;
139 ImageDataDirectory exception_table_
;
140 ImageDataDirectory base_relocation_table_
;
141 ImageDataDirectory bound_import_table_
;
142 ImageDataDirectory import_address_table_
;
143 ImageDataDirectory delay_import_descriptor_
;
144 ImageDataDirectory clr_runtime_header_
;
146 #if COURGETTE_HISTOGRAM_TARGETS
147 std::map
<RVA
, int> abs32_target_rvas_
;
148 std::map
<RVA
, int> rel32_target_rvas_
;
152 DISALLOW_COPY_AND_ASSIGN(DisassemblerWin32X86
);
155 } // namespace courgette
156 #endif // COURGETTE_DISASSEMBLER_WIN32_X86_H_