-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdisassemble.cpp
104 lines (95 loc) · 3.46 KB
/
disassemble.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
Copyright (C) 2015 Alin Mindroc
(mindroc dot alin at gmail dot com)
This is a sample program that shows how to use InstructionAPI in order to
print the assembly code and functions in a provided binary.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
*/
#include "CodeObject.h"
#include "InstructionDecoder.h"
#include <iostream>
#include <iomanip>
using namespace std;
using namespace Dyninst;
using namespace ParseAPI;
using namespace InstructionAPI;
// How many bytes of the instruction hex dump should be printed
// on the first line. The remaining will go to the second line
// on the assumption that an instruction is at most 15 bytes long.
static const int l1_width = 7;
int main(int argc, char** argv) {
if(argc != 2) {
printf("Usage: %s <binary path>\n", argv[0]);
return -1;
}
char* binaryPath = argv[1];
SymtabCodeSource* sts;
CodeObject* co;
Instruction instr;
SymtabAPI::Symtab* symTab;
std::string binaryPathStr(binaryPath);
bool isParsable = SymtabAPI::Symtab::openFile(symTab, binaryPathStr);
if(isParsable == false) {
const char* error = "error: file can not be parsed";
cout << error;
return -1;
}
sts = new SymtabCodeSource(binaryPath);
co = new CodeObject(sts);
// parse the binary given as a command line arg
co->parse();
// get list of all functions in the binary
const CodeObject::funclist& all = co->funcs();
if(all.size() == 0) {
const char* error = "error: no functions in file";
cout << error;
return -1;
}
// create an Instruction decoder which will convert the binary opcodes to strings
InstructionDecoder decoder((const void *)nullptr, 1, sts->getArch());
for(auto fit = all.begin(); fit != all.end(); ++fit) {
Function* f = *fit;
// get address of entry point for current function
Address crtAddr = f->addr();
int instr_count = 0;
auto fbl = f->blocks().end();
fbl--;
Block* b = *fbl;
Address lastAddr = b->end();
// if current function has zero instructions, d o n t output it
if(crtAddr == lastAddr)
continue;
cout << "\n\n" << hex << setfill('0') << setw(2 * sts->getAddressWidth()) << f->addr() << " <" << f->name() << ">:\n";
while(crtAddr < lastAddr) {
// decode current instruction
const unsigned char *instr_ptr = (const unsigned char *)f->isrc()->getPtrToInstruction(crtAddr);
instr = decoder.decode(instr_ptr);
// failed to decode the instruction
if (instr.size() == 0)
break;
// pretty print it
cout << hex << setfill(' ') << setw(8) << crtAddr << ": ";
for (size_t i = 0; i < instr.size() && i < l1_width; i++) {
cout << hex << setfill('0') << setw(2) << (unsigned)instr_ptr[i] << " ";
}
for (size_t i = min(instr.size(), (size_t)l1_width); i < 8; i++) {
cout << " ";
}
cout << instr.format() << "\n";
if (instr.size() > l1_width) {
cout << hex << setfill(' ') << setw(8) << crtAddr + l1_width << ": ";
for (size_t i = l1_width; i < instr.size(); i++) {
cout << hex << setfill('0') << setw(2) << (unsigned)instr_ptr[i] << " ";
}
cout << "\n";
}
// go to the address of the next instruction
crtAddr += instr.size();
instr_count++;
}
}
return 0;
}