OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "courgette/disassembler.h" | 5 #include "courgette/disassembler_win32_x86.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 | 13 |
14 #include "courgette/assembly_program.h" | 14 #include "courgette/assembly_program.h" |
15 #include "courgette/courgette.h" | 15 #include "courgette/courgette.h" |
16 #include "courgette/encoded_program.h" | 16 #include "courgette/encoded_program.h" |
17 #include "courgette/image_info.h" | 17 #include "courgette/image_info.h" |
18 | 18 |
19 // COURGETTE_HISTOGRAM_TARGETS prints out a histogram of how frequently | 19 // COURGETTE_HISTOGRAM_TARGETS prints out a histogram of how frequently |
20 // different target addresses are referenced. Purely for debugging. | 20 // different target addresses are referenced. Purely for debugging. |
21 #define COURGETTE_HISTOGRAM_TARGETS 0 | 21 #define COURGETTE_HISTOGRAM_TARGETS 0 |
22 | 22 |
23 namespace courgette { | 23 namespace courgette { |
24 | 24 |
25 class DisassemblerWin32X86 : public Disassembler { | 25 DisassemblerWin32X86::DisassemblerWin32X86(PEInfo* pe_info) |
26 public: | 26 : pe_info_(pe_info), |
27 explicit DisassemblerWin32X86(PEInfo* pe_info) | 27 incomplete_disassembly_(false) { |
28 : pe_info_(pe_info), | 28 } |
29 incomplete_disassembly_(false) { | |
30 } | |
31 | |
32 virtual bool Disassemble(AssemblyProgram* target); | |
33 | |
34 virtual void Destroy() { delete this; } | |
35 | |
36 protected: | |
37 PEInfo& pe_info() { return *pe_info_; } | |
38 | |
39 CheckBool ParseFile(AssemblyProgram* target) WARN_UNUSED_RESULT; | |
40 bool ParseAbs32Relocs(); | |
41 void ParseRel32RelocsFromSections(); | |
42 void ParseRel32RelocsFromSection(const Section* section); | |
43 | |
44 CheckBool ParseNonSectionFileRegion(uint32 start_file_offset, | |
45 uint32 end_file_offset, AssemblyProgram* program) WARN_UNUSED_RESULT; | |
46 CheckBool ParseFileRegion(const Section* section, | |
47 uint32 start_file_offset, uint32 end_file_offset, | |
48 AssemblyProgram* program) WARN_UNUSED_RESULT; | |
49 | |
50 #if COURGETTE_HISTOGRAM_TARGETS | |
51 void HistogramTargets(const char* kind, const std::map<RVA, int>& map); | |
52 #endif | |
53 | |
54 PEInfo* pe_info_; | |
55 bool incomplete_disassembly_; // 'true' if can leave out 'uninteresting' bits | |
56 | |
57 std::vector<RVA> abs32_locations_; | |
58 std::vector<RVA> rel32_locations_; | |
59 | |
60 #if COURGETTE_HISTOGRAM_TARGETS | |
61 std::map<RVA, int> abs32_target_rvas_; | |
62 std::map<RVA, int> rel32_target_rvas_; | |
63 #endif | |
64 }; | |
65 | 29 |
66 bool DisassemblerWin32X86::Disassemble(AssemblyProgram* target) { | 30 bool DisassemblerWin32X86::Disassemble(AssemblyProgram* target) { |
67 if (!pe_info().ok()) | 31 if (!pe_info().ok()) |
68 return false; | 32 return false; |
69 | 33 |
70 target->set_image_base(pe_info().image_base()); | 34 target->set_image_base(pe_info().image_base()); |
71 | 35 |
72 if (!ParseAbs32Relocs()) | 36 if (!ParseAbs32Relocs()) |
73 return false; | 37 return false; |
74 | 38 |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 } | 367 } |
404 std::cout << std::endl; | 368 std::cout << std::endl; |
405 someSkipped = false; | 369 someSkipped = false; |
406 } else { | 370 } else { |
407 someSkipped = true; | 371 someSkipped = true; |
408 } | 372 } |
409 } | 373 } |
410 } | 374 } |
411 #endif // COURGETTE_HISTOGRAM_TARGETS | 375 #endif // COURGETTE_HISTOGRAM_TARGETS |
412 | 376 |
413 Disassembler* Disassembler::MakeDisassemberWin32X86(PEInfo* pe_info) { | |
414 return new DisassemblerWin32X86(pe_info); | |
415 } | |
416 | |
417 //////////////////////////////////////////////////////////////////////////////// | |
418 | |
419 Status ParseWin32X86PE(const void* buffer, size_t length, | |
420 AssemblyProgram** output) { | |
421 *output = NULL; | |
422 | |
423 PEInfo* pe_info = new PEInfo(); | |
424 pe_info->Init(buffer, length); | |
425 | |
426 if (!pe_info->ParseHeader()) { | |
427 delete pe_info; | |
428 return C_INPUT_NOT_RECOGNIZED; | |
429 } | |
430 | |
431 Disassembler* disassembler = Disassembler::MakeDisassemberWin32X86(pe_info); | |
432 AssemblyProgram* program = new AssemblyProgram(); | |
433 | |
434 if (!disassembler->Disassemble(program)) { | |
435 delete program; | |
436 disassembler->Destroy(); | |
437 delete pe_info; | |
438 return C_DISASSEMBLY_FAILED; | |
439 } | |
440 | |
441 disassembler->Destroy(); | |
442 delete pe_info; | |
443 *output = program; | |
444 return C_OK; | |
445 } | |
446 | |
447 void DeleteAssemblyProgram(AssemblyProgram* program) { | |
448 delete program; | |
449 } | |
450 | |
451 } // namespace courgette | 377 } // namespace courgette |
OLD | NEW |