Skip to content

Commit

Permalink
RDIL: Make pattern matching and value extraction developer friendly
Browse files Browse the repository at this point in the history
  • Loading branch information
Dax89 committed Apr 2, 2022
1 parent 92c821b commit f799571
Show file tree
Hide file tree
Showing 10 changed files with 341 additions and 244 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_definitions(-DSHARED_OBJECT_EXT="${CMAKE_SHARED_LIBRARY_SUFFIX}" -DMINIZ_NO_
# set(CPM_USE_LOCAL_PACKAGES ON)
include(cmake/CPM.cmake) # https://github.com/TheLartians/CPM.cmake
CPMAddPackage("gh:gabime/spdlog@1.9.2")
CPMAddPackage("gh:nlohmann/json@3.10.5")

if(ENABLE_TESTS)
add_subdirectory(tests)
Expand Down Expand Up @@ -66,8 +67,7 @@ set(SOURCES ${LIBS_SOURCES} ${RDCORE_SOURCES} ${RDAPI_SOURCES})
add_subdirectory(rdcore/libs/taojson EXCLUDE_FROM_ALL)
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})

target_link_libraries(${PROJECT_NAME} PRIVATE taocpp::json spdlog)
target_include_directories(${PROJECT_NAME} PRIVATE spdlog)
target_link_libraries(${PROJECT_NAME} PRIVATE taocpp::json spdlog nlohmann_json::nlohmann_json)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)

set_target_properties(${PROJECT_NAME} PROPERTIES
Expand Down
13 changes: 10 additions & 3 deletions rdapi/rdil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ RDGraph* RDILGraph_Create(RDContext* ctx, rd_address address)

RDILExpression* RDILExpression_Create(RDContext* ctx, rd_address address) { return CPTR(RDILExpression, ILFunction::generateOne(CPTR(Context, ctx), address)); }
rd_type RDILExpression_Type(const RDILExpression* e) { return e ? CPTR(const ILExpression, e)->type : RDIL_Unknown; }
bool RDILExpression_Match(const RDILExpression* e, const char* m) { return e ? RDIL::match(CPTR(const ILExpression, e), m) : false; }
const RDILExpression* RDILExpression_Extract(const RDILExpression* e, const char* q) { return (e && q) ? CPTR(const RDILExpression, RDIL::extract(CPTR(const ILExpression, e), q)) : nullptr; }
bool RDILExpression_Match(const RDILExpression* e, const char* m) { return e && m ? RDIL::match(CPTR(const ILExpression, e), m) : false; }
size_t RDILExpression_ExtractNew(const RDILExpression* e, const RDILValue** values) { return e && values ? RDIL::extract(CPTR(const ILExpression, e), values) : 0; }

bool RDILExpression_GetValue(const RDILExpression* e, RDILValue* value)
{
const ILExpression* expr = CPTR(const ILExpression, e);
if(!expr || !RDIL::hasValue(expr)) return false;

if(value) value->value = expr->value;
if(value)
{
value->type = expr->type;
value->value = expr->value;
}
return true;
}

Expand Down Expand Up @@ -49,6 +53,9 @@ const RDILExpression* RDILFunction_GetExpression(const RDILFunction* rdilfunctio
const RDILExpression* RDILFunction_GetFirstExpression(const RDILFunction* rdilfunction) { return CPTR(const RDILExpression, CPTR(const ILFunction, rdilfunction)->first()); }
const RDILExpression* RDILFunction_GetLastExpression(const RDILFunction* rdilfunction) { return CPTR(const RDILExpression, CPTR(const ILFunction, rdilfunction)->last()); }
size_t RDILFunction_Size(const RDILFunction* rdilfunction) { return CPTR(const ILFunction, rdilfunction)->size(); }
size_t RDILFunction_Extract(const RDILFunction* rdilfunction, const RDILValue** values) { return rdilfunction ? RDIL::extract(CPTR(const ILFunction, rdilfunction), values) : 0; }
bool RDILFunction_Match(const RDILFunction* rdilfunction, const char* m) { return rdilfunction && m ? RDIL::match(CPTR(const ILFunction, rdilfunction), m) : false; }
bool RDILFunction_Extract(const RDILFunction* rdilfunction, const char* m) { (void)rdilfunction; (void)m; return false; } //return rdilfunction && m ? RDIL::match(CPTR(const ILFunction, rdilfunction), m) : false; }
bool RDILFunction_GetAddress(const RDILFunction* rdilfunction, const RDILExpression* e, rd_address* address) { return CPTR(const ILFunction, rdilfunction)->getAddress(CPTR(const ILExpression, e), address); }
void RDILFunction_Insert(RDILFunction* rdilfunction, size_t idx, RDILExpression* expression) { CPTR(ILFunction, rdilfunction)->insert(idx, CPTR(ILExpression, expression)); }
void RDILFunction_Append(RDILFunction* rdilfunction, RDILExpression* expression) { CPTR(ILFunction, rdilfunction)->append(CPTR(ILExpression, expression)); }
Expand Down
12 changes: 9 additions & 3 deletions rdapi/rdil.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,13 @@ enum RDILTypes
u64 u_value; \
s64 s_value; \
const char* reg; \
const char* var; \
const char* var;

typedef union RDILValue { PRIVATE_RDIL_VALUE_FIELDS } RDILValue;
typedef struct RDILValue
{
rd_type type;
union { PRIVATE_RDIL_VALUE_FIELDS };
} RDILValue;

RD_HANDLE(RDILFunction);
RD_HANDLE(RDILExpression);
Expand All @@ -108,12 +112,14 @@ RD_API_EXPORT bool RDILExpression_Match(const RDILExpression* e, const char* m);
RD_API_EXPORT bool RDILExpression_GetValue(const RDILExpression* e, RDILValue* value);
RD_API_EXPORT const char* RDILExpression_GetText(const RDILExpression* e);
RD_API_EXPORT const char* RDILExpression_GetFormat(const RDILExpression* e);
RD_API_EXPORT const RDILExpression* RDILExpression_Extract(const RDILExpression* e, const char* q);
RD_API_EXPORT size_t RDILExpression_ExtractNew(const RDILExpression* e, const RDILValue** values);

RD_API_EXPORT RDILFunction* RDILFunction_Create(RDContext* context, rd_address address);
RD_API_EXPORT const RDILExpression* RDILFunction_GetExpression(const RDILFunction* rdilfunction, size_t idx);
RD_API_EXPORT const RDILExpression* RDILFunction_GetFirstExpression(const RDILFunction* rdilfunction);
RD_API_EXPORT const RDILExpression* RDILFunction_GetLastExpression(const RDILFunction* rdilfunction);
RD_API_EXPORT size_t RDILFunction_Extract(const RDILFunction* rdilfunction, const RDILValue** values);
RD_API_EXPORT bool RDILFunction_Match(const RDILFunction* rdilfunction, const char* m);
RD_API_EXPORT bool RDILFunction_GetAddress(const RDILFunction* rdilfunction, const RDILExpression* e, rd_address* address);
RD_API_EXPORT void RDILFunction_Insert(RDILFunction* rdilfunction, size_t idx, RDILExpression* expression);
RD_API_EXPORT void RDILFunction_Append(RDILFunction* rdilfunction, RDILExpression* expression);
Expand Down
17 changes: 7 additions & 10 deletions rdcore/builtin/analyzer/functionanalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ bool FunctionAnalyzer::findNullSubs(Context* ctx, const ILExpression* expr, rd_a
{
if((expr->type == RDIL_Ret) || ((expr->type == RDIL_Nop) && (ctx->document()->getFunctionInstrCount(address)) == 1))
{
ctx->document()->setLabel(address, AddressFlags_None, "nullsub_" + Utils::hex(address));
ctx->document()->updateLabel(address, "nullsub_" + Utils::hex(address));
return true;
}

Expand All @@ -49,18 +49,15 @@ bool FunctionAnalyzer::findNullSubs(Context* ctx, const ILExpression* expr, rd_a

std::string FunctionAnalyzer::findThunk(Context* ctx, const ILExpression* expr, rd_address address, int level)
{
std::string label;
const RDILValue* values = nullptr;
if(!RDIL::match(expr, "goto [cnst]") && RDIL::match(expr, "goto cnst")) return std::string();

rd_address raddress = 0;
std::string label;

if(RDIL::match(expr, "goto [cnst]"))
{
raddress = RDIL::extract(expr, "u:mem/u:cnst")->address;
auto dlabel = ctx->document()->getLabel(raddress);
if(dlabel) label = *dlabel;
}
else if(RDIL::match(expr, "goto cnst"))
if(size_t n = RDIL::extract(expr, &values); n == 1)
{
raddress = RDIL::extract(expr, "u:cnst")->address;
raddress = values->address;
auto dlabel = ctx->document()->getLabel(raddress);
if(dlabel) label = *dlabel;
}
Expand Down
94 changes: 94 additions & 0 deletions rdcore/rdil/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,97 @@ ILExpression* ILExpression::clone(const ILExpression* e)

return ne;
}

ILExpressionTree::ILExpressionTree(): Object() { }
ILExpressionTree::ILExpressionTree(Context* ctx): Object(ctx) { }
ILExpression* ILExpressionTree::exprUNKNOWN() const { return this->expr(RDIL_Unknown); }
ILExpression* ILExpressionTree::exprNOP() const { return this->expr(RDIL_Nop); }
ILExpression* ILExpressionTree::exprPOP(ILExpression* e) const { return this->exprU(RDIL_Pop, 0, e); }
ILExpression* ILExpressionTree::exprPUSH(ILExpression* e) const { return this->exprU(RDIL_Push, 0, e); }
ILExpression* ILExpressionTree::exprVAR(size_t size, const char* name) const { return this->exprVALUE_P(RDIL_Var, size, reinterpret_cast<uintptr_t>(name)); }
ILExpression* ILExpressionTree::exprREG(size_t size, const char* reg) const { return this->exprVALUE_P(RDIL_Reg, size, reinterpret_cast<uintptr_t>(reg)); }
ILExpression* ILExpressionTree::exprCNST(size_t size, u64 value) const { return this->exprVALUE(RDIL_Cnst, size, value); }
ILExpression* ILExpressionTree::exprJUMP(ILExpression* e) const { return this->exprU(RDIL_Goto, 0, e); }
ILExpression* ILExpressionTree::exprCALL(ILExpression* e) const { return this->exprU(RDIL_Call, 0, e); }
ILExpression* ILExpressionTree::exprRET(ILExpression* e) const { return this->exprU(RDIL_Ret, 0, e); }
ILExpression* ILExpressionTree::exprMEM(ILExpression* e) const { return this->exprU(RDIL_Mem, 0, e); }
ILExpression* ILExpressionTree::exprNOT(ILExpression* e) const { return this->exprU(RDIL_Not, 0, e); }
ILExpression* ILExpressionTree::exprADD(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Add, 0, l, r); }
ILExpression* ILExpressionTree::exprSUB(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Sub, 0, l, r); }
ILExpression* ILExpressionTree::exprMUL(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Mul, 0, l, r); }
ILExpression* ILExpressionTree::exprDIV(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Div, 0, l, r); }
ILExpression* ILExpressionTree::exprMOD(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Mod, 0, l, r); }
ILExpression* ILExpressionTree::exprAND(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Div, 0, l, r); }
ILExpression* ILExpressionTree::exprOR(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Or, 0, l, r); }
ILExpression* ILExpressionTree::exprXOR(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Xor, 0, l, r); }
ILExpression* ILExpressionTree::exprLSL(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Lsl, 0, l, r); }
ILExpression* ILExpressionTree::exprLSR(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Lsr, 0, l, r); }
ILExpression* ILExpressionTree::exprASL(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Asl, 0, l, r); }
ILExpression* ILExpressionTree::exprASR(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Asr, 0, l, r); }
ILExpression* ILExpressionTree::exprROL(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Rol, 0, l, r); }
ILExpression* ILExpressionTree::exprROR(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Ror, 0, l, r); }
ILExpression* ILExpressionTree::exprCOPY(ILExpression* dst, ILExpression* src) const { return this->exprDS(RDIL_Copy, 0, dst, src); }
ILExpression* ILExpressionTree::exprEQ(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Eq, 0, l, r); }
ILExpression* ILExpressionTree::exprNE(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Ne, 0, l, r); }
ILExpression* ILExpressionTree::exprLT(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Lt, 0, l, r); }
ILExpression* ILExpressionTree::exprLE(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Le, 0, l, r); }
ILExpression* ILExpressionTree::exprGT(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Gt, 0, l, r); }
ILExpression* ILExpressionTree::exprGE(ILExpression* l, ILExpression* r) const { return this->exprLR(RDIL_Ge, 0, l, r); }
ILExpression* ILExpressionTree::check(ILExpression* e) const { return e ? e : this->exprUNKNOWN(); }

ILExpression* ILExpressionTree::exprIF(ILExpression* cond, ILExpression* t, ILExpression* f) const
{
auto* expr = this->expr(RDIL_If, 0);
expr->cond = cond;
expr->t = this->check(t);
expr->f = this->check(f);
return expr;
}

ILExpression* ILExpressionTree::exprVALUE_P(rd_type rdil, size_t size, uintptr_t value) const
{
auto* expr = this->expr(rdil, size);
expr->value = value;
return expr;
}

ILExpression* ILExpressionTree::exprVALUE(rd_type rdil, size_t size, u64 value) const
{
auto* expr = this->expr(rdil, size);
expr->u_value = value;
return expr;
}

ILExpression* ILExpressionTree::exprLR(rd_type rdil, size_t size, ILExpression* l, ILExpression* r) const
{
auto* expr = this->expr(rdil, size);
expr->left = this->check(l);
expr->right = this->check(r);
return expr;
}

ILExpression* ILExpressionTree::exprDS(rd_type rdil, size_t size, ILExpression* dst, ILExpression* src) const
{
auto* expr = this->expr(rdil, size);
expr->dst = this->check(dst);
expr->src = this->check(src);
return expr;
}

ILExpression* ILExpressionTree::exprU(rd_type rdil, size_t size, ILExpression* e) const
{
auto* expr = this->expr(rdil, size);
expr->u = this->check(e);
return expr;
}

ILExpression* ILExpressionTree::expr(rd_type rdil, size_t size) const
{
auto& expr = m_pool.emplace_front(new ILExpression());
expr->type = rdil;
expr->size = size;
expr->value = 0;
return expr.get();
}

ILExpression* ILExpressionTree::expr(rd_type rdil) const { return this->expr(rdil, 0); }
59 changes: 58 additions & 1 deletion rdcore/rdil/expression.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#pragma once

#include <rdapi/rdil.h>
#include <memory>
#include <unordered_set>
#include <memory>
#include <list>
#include "../object.h"

class ILExpression;
Expand All @@ -27,3 +28,59 @@ class ILExpression : public Object

friend class ILFunction;
};

class ILExpressionTree: public Object
{
public:
ILExpressionTree();
ILExpressionTree(Context* ctx);
ILExpression* exprUNKNOWN() const;
ILExpression* exprNOP() const;
ILExpression* exprPOP(ILExpression* e) const;
ILExpression* exprPUSH(ILExpression* e) const;
ILExpression* exprREG(size_t size, const char* reg) const;
ILExpression* exprCNST(size_t size, u64 value) const;
ILExpression* exprVAR(size_t size, const char* name) const;
ILExpression* exprJUMP(ILExpression* e) const;
ILExpression* exprCALL(ILExpression* e) const;
ILExpression* exprRET(ILExpression* e) const;
ILExpression* exprMEM(ILExpression* e) const;
ILExpression* exprNOT(ILExpression* e) const;
ILExpression* exprADD(ILExpression* l, ILExpression* r) const;
ILExpression* exprSUB(ILExpression* l, ILExpression* r) const;
ILExpression* exprMUL(ILExpression* l, ILExpression* r) const;
ILExpression* exprDIV(ILExpression* l, ILExpression* r) const;
ILExpression* exprMOD(ILExpression* l, ILExpression* r) const;
ILExpression* exprAND(ILExpression* l, ILExpression* r) const;
ILExpression* exprOR(ILExpression* l, ILExpression* r) const;
ILExpression* exprXOR(ILExpression* l, ILExpression* r) const;
ILExpression* exprLSL(ILExpression* l, ILExpression* r) const;
ILExpression* exprLSR(ILExpression* l, ILExpression* r) const;
ILExpression* exprASL(ILExpression* l, ILExpression* r) const;
ILExpression* exprASR(ILExpression* l, ILExpression* r) const;
ILExpression* exprROL(ILExpression* l, ILExpression* r) const;
ILExpression* exprROR(ILExpression* l, ILExpression* r) const;
ILExpression* exprCOPY(ILExpression* dst, ILExpression* src) const;
ILExpression* exprIF(ILExpression* cond, ILExpression* t, ILExpression* f) const;
ILExpression* exprEQ(ILExpression* l, ILExpression* r) const;
ILExpression* exprNE(ILExpression* l, ILExpression* r) const;
ILExpression* exprLT(ILExpression* l, ILExpression* r) const;
ILExpression* exprLE(ILExpression* l, ILExpression* r) const;
ILExpression* exprGT(ILExpression* l, ILExpression* r) const;
ILExpression* exprGE(ILExpression* l, ILExpression* r) const;

protected:
ILExpression* check(ILExpression* e) const;

private:
ILExpression* exprVALUE_P(rd_type rdil, size_t size, uintptr_t value) const;
ILExpression* exprVALUE(rd_type rdil, size_t size, u64 value) const;
ILExpression* exprLR(rd_type rdil, size_t size, ILExpression* l, ILExpression* r) const;
ILExpression* exprDS(rd_type rdil, size_t size, ILExpression* dst, ILExpression* src) const;
ILExpression* exprU(rd_type rdil, size_t size, ILExpression* e) const;
ILExpression* expr(rd_type rdil, size_t size) const;
ILExpression* expr(rd_type rdil) const;

private:
mutable std::list<ILExpressionPtr> m_pool;
};
Loading

0 comments on commit f799571

Please sign in to comment.