-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add instructionAPI/printVisitor (#44)
- Loading branch information
Showing
4 changed files
with
168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
project(InstructionAPI LANGUAGES CXX) | ||
|
||
add_executable(stateless_visitor stateless_visitor.cpp) | ||
target_compile_options(stateless_visitor PRIVATE ${EXAMPLES_WARNING_FLAGS}) | ||
target_link_libraries(stateless_visitor PRIVATE Dyninst::instructionAPI) | ||
|
||
add_executable(statefull_visitor statefull_visitor.cpp) | ||
target_compile_options(statefull_visitor PRIVATE ${EXAMPLES_WARNING_FLAGS}) | ||
target_link_libraries(statefull_visitor PRIVATE Dyninst::instructionAPI) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#include "BinaryFunction.h" | ||
#include "Dereference.h" | ||
#include "Expression.h" | ||
#include "Immediate.h" | ||
#include "Instruction.h" | ||
#include "InstructionDecoder.h" | ||
#include "Operand.h" | ||
#include "Register.h" | ||
#include "Visitor.h" | ||
|
||
#include <array> | ||
#include <iomanip> | ||
#include <iostream> | ||
|
||
namespace di = Dyninst::InstructionAPI; | ||
|
||
/* | ||
* A stateful visitor | ||
* | ||
* This visitor remembers the AST type that was most-recently visited. | ||
*/ | ||
|
||
struct stateful_visitor : di::Visitor { | ||
bool foundReg{}; | ||
bool foundImm{}; | ||
bool foundBin{}; | ||
bool foundDer{}; | ||
|
||
void visit(di::BinaryFunction*) override { foundBin = true; } | ||
|
||
void visit(di::Immediate* imm) override { foundImm = true; } | ||
|
||
void visit(di::RegisterAST*) override { foundReg = true; } | ||
|
||
void visit(di::Dereference*) override { foundDer = true; } | ||
|
||
// clang-format off | ||
friend std::ostream& operator<<(std::ostream &os, stateful_visitor const& v) { | ||
std::cout << std::boolalpha | ||
<< " foundReg: " << v.foundReg << '\n' | ||
<< " foundImm: " << v.foundImm << '\n' | ||
<< " foundBin: " << v.foundBin << '\n' | ||
<< " foundDer: " << v.foundDer << '\n'; | ||
return os; | ||
} | ||
|
||
// clang-format on | ||
}; | ||
|
||
void print(di::Instruction const& insn) { | ||
stateful_visitor v; | ||
std::vector<di::Operand> operands; | ||
insn.getOperands(operands); | ||
|
||
std::cout << "instruction: " << insn.format() << '\n'; | ||
for(auto const& o : operands) { | ||
std::cout << "operand '" << o.format(insn.getArch()) << "'\n"; | ||
o.getValue()->apply(&v); | ||
std::cout << v << '\n'; | ||
} | ||
} | ||
|
||
int main() { | ||
// clang-format off | ||
std::array<const unsigned char, 15> buffer = { | ||
0x05, 0xef, 0xbe, 0xad, 0xde, // add eax, 0xDEADBEEF | ||
0x90, // 1-byte nop | ||
0x66, 0x0F, 0x1F, 0x84, 0x00, | ||
0x00, 0x00, 0x00, 0x00 // 9-byte nop (NOP DWORD ptr [rax + rax*1 + 0x00000000]) | ||
|
||
}; | ||
// clang-format on | ||
|
||
di::InstructionDecoder decoder(buffer.data(), buffer.size(), Dyninst::Architecture::Arch_x86_64); | ||
|
||
di::Instruction i; | ||
do { | ||
i = decoder.decode(); | ||
if(i.isValid()) { | ||
print(i); | ||
std::cout << '\n'; | ||
} | ||
} while(i.isValid()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#include "BinaryFunction.h" | ||
#include "Dereference.h" | ||
#include "Expression.h" | ||
#include "Immediate.h" | ||
#include "Instruction.h" | ||
#include "InstructionDecoder.h" | ||
#include "Operand.h" | ||
#include "Register.h" | ||
#include "Visitor.h" | ||
|
||
#include <array> | ||
#include <iomanip> | ||
#include <iostream> | ||
|
||
namespace di = Dyninst::InstructionAPI; | ||
|
||
/* | ||
* A stateless visitor | ||
* | ||
* This visitor simply accesses some property of the ASTs, but | ||
* does not store any information about them. | ||
*/ | ||
|
||
class printer : public di::Visitor { | ||
public: | ||
void visit(di::BinaryFunction* b) override { | ||
std::cout << " BinaryFunction '" << b->format(di::defaultStyle) << "'\n"; | ||
}; | ||
|
||
void visit(di::Immediate* i) override { | ||
std::cout << " Immediate '0x" << i->format(di::defaultStyle) << "'\n"; | ||
}; | ||
|
||
void visit(di::Dereference* d) override { | ||
std::cout << " Dereference '" << d->format(di::defaultStyle) << "'\n"; | ||
}; | ||
|
||
void visit(di::RegisterAST* r) override { | ||
std::cout << " Register '" << r->format(di::defaultStyle) << "'\n"; | ||
} | ||
}; | ||
|
||
void print(di::Instruction const& insn) { | ||
printer pv; | ||
std::vector<di::Operand> operands; | ||
insn.getOperands(operands); | ||
|
||
std::cout << "instruction: " << insn.format() << '\n'; | ||
int op_num = 1; | ||
for(auto const& o : operands) { | ||
std::cout << "operand" << op_num << " '" << o.format(insn.getArch()) << "'\n"; | ||
o.getValue()->apply(&pv); | ||
op_num++; | ||
} | ||
} | ||
|
||
int main() { | ||
std::array<const unsigned char, 8> buffer = { | ||
0x05, 0xef, 0xbe, 0xad, 0xde, // add eax, 0xDEADBEEF | ||
0x50, // push rax | ||
0x74, 0x10 // je 0x12 | ||
}; | ||
|
||
di::InstructionDecoder decoder(buffer.data(), buffer.size(), Dyninst::Architecture::Arch_x86_64); | ||
|
||
di::Instruction i; | ||
do { | ||
i = decoder.decode(); | ||
if(i.isValid()) { | ||
print(i); | ||
std::cout << '\n'; | ||
} | ||
} while(i.isValid()); | ||
} |