Files

263 lines
8.2 KiB
C++

#include "ExeCommander.h"
#include <bearparser/core.h>
//------------------------------------------
char cmd_util::addrTypeToChar(Executable::addr_type type)
{
switch (type) {
case Executable::RAW: return 'r';
case Executable::RVA: return 'v';
case Executable::VA: return 'V';
default:
return '_';
}
return '_';
}
std::string cmd_util::addrTypeToStr(Executable::addr_type type)
{
switch (type) {
case Executable::RAW: return "raw";
case Executable::RVA: return "RVA";
case Executable::VA: return "VA";
default:
return "";
}
return "";
}
Executable* cmd_util::getExeFromContext(CmdContext *context)
{
ExeCmdContext *exeContext = dynamic_cast<ExeCmdContext*>(context);
if (exeContext == NULL) throw CustomException("Invalid command context!");
Executable *exe = exeContext->getExe();
if (exe == NULL) throw CustomException("Invalid command context: no Exe");
return exe;
}
offset_t cmd_util::readOffset(Executable::addr_type aType)
{
if (aType == Executable::NOT_ADDR) {
return INVALID_ADDR;
}
std::string prompt = addrTypeToStr(aType);
offset_t offset = 0;
std::cout << prompt.c_str() << ": ";
std::cin >> std::hex >> offset;
return offset;
}
size_t cmd_util::readNumber(const std::string& prompt, bool read_hex)
{
unsigned int num = 0;
std::cout << prompt.c_str() << ": ";
if (read_hex) {
std::cin >> std::hex >> num;
} else {
std::cin >> std::dec >> num;
}
return num;
}
void cmd_util::fetch(Executable *peExe, offset_t offset, Executable::addr_type aType, bool hex)
{
offset = peExe->toRaw(offset, aType);
if (offset == INVALID_ADDR) {
std::cerr << "ERROR: Invalid Address suplied" << std::endl;
return;
}
BufferView *sub = new BufferView(peExe, offset, 100);
if (sub->getContent() == NULL) {
std::cout << "[ERROR] Cannot fetch" << std::endl;
delete sub;
return;
}
AbstractFormatter *formatter = NULL;
std::string separator = " ";
if (hex) formatter = new HexFormatter(sub);
else {
formatter = new Formatter(sub);
separator = "";
}
std::cout << "Fetched:" << std::endl;
for (bufsize_t i = 0; i < sub->getContentSize(); i++) {
std::cout << (*formatter)[i].toStdString() << separator.c_str();
}
std::cout << std::endl;
delete formatter;
delete sub;
}
void cmd_util::printWrapperNames(MappedExe *exe)
{
size_t count = exe->wrappersCount();
for (size_t i = 0; i < count; i++) {
ExeElementWrapper *wr = exe->getWrapper(i);
if (wr == NULL || wr->getPtr() == NULL) {
continue;
}
std::cout << "[" << std::dec << i << "] "
<< exe->getWrapperName(i).toStdString()
<< std::endl;
}
}
void cmd_util::dumpEntryInfo(ExeElementWrapper *w)
{
if (w == NULL) return;
std::cout << "\n------\n";
size_t fields = w->getFieldsCount();
std::cout << "[" << w->getName().toStdString() << "] "
<< "size: 0x" << std::hex << w->getSize()
<< " "
<< "fieldsCount: " << std::dec << fields << "\n"
<< std::endl;
for (size_t i = 0; i < fields; i++) {
offset_t offset = w->getFieldOffset(i);
if (offset == INVALID_ADDR) {
continue;
}
OUT_PADDED_OFFSET(std::cout, offset);
std::cout << " " << w->getFieldName(i).toStdString() << "\t";
size_t subfields = w->getSubFieldsCount();
if (subfields == 0) subfields = 1; //it may not have a sublist, but a single value
for (size_t y = 0; y < subfields; y++) {
WrappedValue value = w->getWrappedValue(i, y);
if (!value.isValid()) break;
QString str = value.toQString();
Executable::addr_type aType = w->containsAddrType(i, y);
char c = addrTypeToChar(aType);
std::cout << "[" << str.toStdString() << " " << c << "]";
}
QString translated = w->translateFieldContent(i);
if (translated.size() > 0) {
std::cout << " " << translated.toStdString() << " ";
}
std::cout << "\n";
}
std::cout << "------" << std::endl;
}
void cmd_util::dumpNodeInfo(ExeNodeWrapper *w)
{
if (w == NULL) return;
std::cout << "------" << std::endl;
size_t entriesCnt = w->getEntriesCount();
std::cout << "\t [" << w->getName().toStdString() << "] "
<< "entriesCount: " << std::dec << entriesCnt
<< std::endl;
for (size_t i = 0; i < entriesCnt; i++) {
ExeNodeWrapper* entry = w->getEntryAt(i);
if (entry == NULL) break;
std::cout << "Entry #" << std::dec << i << "\n";
dumpEntryInfo(entry);
size_t subEntries = entry->getEntriesCount();
if (subEntries > 0) {
std::cout << "Have entries: "
<< std::dec << subEntries
<< " ( "
<< std::hex << "0x" << subEntries
<< " )";
}
std::cout << "\n";
}
}
void ExeCommander::initCommands()
{
this->addCommand("info", new ExeInfoCommand());
this->addCommand("r-v", new ConvertAddrCommand(Executable::RAW, Executable::RVA, "Convert: RAW -> RVA"));
this->addCommand("v-r", new ConvertAddrCommand(Executable::RVA, Executable::RAW, "Convert: RVA -> RAW"));
this->addCommand("printc", new FetchCommand(false, Executable::RAW, "Print content by Raw address"));
//this->addCommand("cV", new FetchCommand(false, Executable::RVA, "Fetch content by Virtual address"));
this->addCommand("printx", new FetchCommand(true, Executable::RAW, "Print content by Raw address - HEX"));
//this->addCommand("hV", new FetchCommand(true, Executable::RVA, "Fetch content by Virtual address - HEX"));
this->addCommand("cl", new ClearWrapperCommand("Clear chosen wrapper Content"));
this->addCommand("fdump", new DumpWrapperToFileCommand("Dump chosen wrapper Content into a file"));
this->addCommand("winfo", new DumpWrapperCommand("Dump chosen wrapper info"));
this->addCommand("einfo", new DumpWrapperEntriesCommand("Dump wrapper entries"));
this->addCommand("e_add", new AddEntryCommand("Add entry to a wrapper"));
this->addCommand("save", new SaveExeToFileCommand());
}
//---
void ConvertAddrCommand::execute(CmdParams *params, CmdContext *context)
{
Executable *exe = cmd_util::getExeFromContext(context);
offset_t offset = cmd_util::readOffset(addrFrom);
offset_t outOffset = exe->convertAddr(offset, addrFrom, addrTo);
if (outOffset == INVALID_ADDR) {
std::cout << "[WARNING] This address cannot be mapped" << std::endl;
return;
}
std::cout << "[" << cmd_util::addrTypeToStr(addrFrom) << "]"
<< "\t->\t"
<< "[" << cmd_util::addrTypeToStr(addrTo) << "]"
<< ":\n";
OUT_PADDED_OFFSET(std::cout, offset);
std::cout << "\t->\t";
OUT_PADDED_OFFSET(std::cout, outOffset);
std::cout << std::endl;
}
//---
void ExeInfoCommand::execute(CmdParams *params, CmdContext *context)
{
Executable *exe = cmd_util::getExeFromContext(context);
std::cout << "Bit mode: \t" << std::dec << exe->getBitMode() << "\n";
offset_t entryPoint = exe->getEntryPoint();
std::cout << "Entry point: \t";
std::cout << "[";
OUT_PADDED_HEX(std::cout, entryPoint, sizeof(entryPoint));
std::cout << " " << cmd_util::addrTypeToChar(Executable::RVA);
std::cout << "]\n";
//Raw:
std::cout << "Raw size: \t";
OUT_PADDED_OFFSET(std::cout, exe->getMappedSize(Executable::RAW));
std::cout << "\n";
std::cout << "Raw align. \t";
OUT_PADDED_OFFSET(std::cout, exe->getAlignment(Executable::RAW));
std::cout << "\n";
//Virtual:
std::cout << "Virtual size: \t";
OUT_PADDED_OFFSET(std::cout, exe->getMappedSize(Executable::RVA));
std::cout << "\n";
std::cout << "Virtual align. \t";
OUT_PADDED_OFFSET(std::cout, exe->getAlignment(Executable::RVA));
std::cout << "\n";
MappedExe *mappedExe = cmd_util::getMappedExeFromContext(context);
if (mappedExe) {
std::cout << "Contains:\n";
cmd_util::printWrapperNames(mappedExe);
}
std::cout << std::endl;
}