Skip to content

Commit ffdd90a

Browse files
committed
Registering default function lifter with core
Start of migrating FunctionLifter::Lift to API. The default implementation can be overriden by architecture plugins to lift entire functions in a single call to Architecture::LiftFunction.
1 parent d9c58e9 commit ffdd90a

File tree

7 files changed

+726
-0
lines changed

7 files changed

+726
-0
lines changed

architecture.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,29 @@ void BasicBlockAnalysisContext::Finalize()
466466
}
467467

468468

469+
FunctionLifterContext::FunctionLifterContext(BNFunctionLifterContext* context)
470+
{
471+
m_context = context;
472+
m_blocks.reserve(m_context->basicBlockCount);
473+
for (size_t i = 0; i < m_context->basicBlockCount; i++)
474+
{
475+
m_blocks.emplace_back(new BasicBlock(m_context->basicBlocks[i]));
476+
}
477+
}
478+
479+
480+
void FunctionLifterContext::Finalize()
481+
{
482+
// TODO
483+
}
484+
485+
486+
vector<Ref<BasicBlock>> FunctionLifterContext::GetBasicBlocks()
487+
{
488+
return m_blocks;
489+
}
490+
491+
469492
Architecture::Architecture(BNArchitecture* arch)
470493
{
471494
m_object = arch;
@@ -600,6 +623,15 @@ void Architecture::AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function,
600623
}
601624

602625

626+
bool Architecture::LiftFunctionCallback(void *ctxt, BNLowLevelILFunction* function, BNFunctionLifterContext* context)
627+
{
628+
CallbackRef<Architecture> arch(ctxt);
629+
FunctionLifterContext flc(context);
630+
Ref func(new LowLevelILFunction(BNNewLowLevelILFunctionReference(function)));
631+
return arch->LiftFunction(func, flc);
632+
}
633+
634+
603635
char* Architecture::GetRegisterNameCallback(void* ctxt, uint32_t reg)
604636
{
605637
CallbackRef<Architecture> arch(ctxt);
@@ -1091,6 +1123,7 @@ void Architecture::Register(Architecture* arch)
10911123
callbacks.freeInstructionText = FreeInstructionTextCallback;
10921124
callbacks.getInstructionLowLevelIL = GetInstructionLowLevelILCallback;
10931125
callbacks.analyzeBasicBlocks = AnalyzeBasicBlocksCallback;
1126+
callbacks.liftFunction = LiftFunctionCallback;
10941127
callbacks.getRegisterName = GetRegisterNameCallback;
10951128
callbacks.getFlagName = GetFlagNameCallback;
10961129
callbacks.getFlagWriteTypeName = GetFlagWriteTypeNameCallback;
@@ -1225,6 +1258,12 @@ void Architecture::AnalyzeBasicBlocks(Function* function, BasicBlockAnalysisCont
12251258
}
12261259

12271260

1261+
bool Architecture::LiftFunction(LowLevelILFunction* function, FunctionLifterContext& context)
1262+
{
1263+
return DefaultLiftFunction(function, context);
1264+
}
1265+
1266+
12281267
string Architecture::GetRegisterName(uint32_t reg)
12291268
{
12301269
return fmt::format("r{}", reg);
@@ -1792,6 +1831,12 @@ void CoreArchitecture::AnalyzeBasicBlocks(Function* function, BasicBlockAnalysis
17921831
}
17931832

17941833

1834+
bool CoreArchitecture::LiftFunction(LowLevelILFunction* function, FunctionLifterContext& context)
1835+
{
1836+
return BNArchitectureLiftFunction(m_object, function->GetObject(), context.m_context);
1837+
}
1838+
1839+
17951840
string CoreArchitecture::GetRegisterName(uint32_t reg)
17961841
{
17971842
char* name = BNGetArchitectureRegisterName(m_object, reg);

binaryninjaapi.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9387,6 +9387,17 @@ namespace BinaryNinja {
93879387
void Finalize();
93889388
};
93899389

9390+
class FunctionLifterContext {
9391+
private:
9392+
std::vector<Ref<BasicBlock>> m_blocks;
9393+
9394+
public:
9395+
BNFunctionLifterContext* m_context;
9396+
FunctionLifterContext(BNFunctionLifterContext* context);
9397+
std::vector<Ref<BasicBlock>> GetBasicBlocks();
9398+
void Finalize();
9399+
};
9400+
93909401
/*! The Architecture class is the base class for all CPU architectures. This provides disassembly, assembly,
93919402
patching, and IL translation lifting for a given architecture.
93929403

@@ -9415,6 +9426,7 @@ namespace BinaryNinja {
94159426
static bool GetInstructionLowLevelILCallback(
94169427
void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNLowLevelILFunction* il);
94179428
static void AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function, BNBasicBlockAnalysisContext* context);
9429+
static bool LiftFunctionCallback(void* ctxt, BNLowLevelILFunction* function, BNFunctionLifterContext* context);
94189430
static char* GetRegisterNameCallback(void* ctxt, uint32_t reg);
94199431
static char* GetFlagNameCallback(void* ctxt, uint32_t flag);
94209432
static char* GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags);
@@ -9496,6 +9508,16 @@ namespace BinaryNinja {
94969508
*/
94979509
static void DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnalysisContext& context);
94989510

9511+
static bool DefaultLiftFunctionCallback(BNLowLevelILFunction* function, BNFunctionLifterContext* context);
9512+
9513+
/*! Default implementation of LiftFunction
9514+
9515+
\param function Function to analyze
9516+
\param context Context for the analysis
9517+
\return Whether lifting was successful
9518+
*/
9519+
static bool DefaultLiftFunction(LowLevelILFunction* function, FunctionLifterContext& context);
9520+
94999521
/*! Get an Architecture by name
95009522

95019523
\param name Name of the architecture
@@ -9600,6 +9622,14 @@ namespace BinaryNinja {
96009622
*/
96019623
virtual void AnalyzeBasicBlocks(Function* function, BasicBlockAnalysisContext& context);
96029624

9625+
/*! Lift function instructions to IL
9626+
9627+
\param function Function to analyze
9628+
\param context Context for the analysis
9629+
\return Whether lifting was successful
9630+
*/
9631+
virtual bool LiftFunction(LowLevelILFunction* function, FunctionLifterContext& context);
9632+
96039633
/*! Gets a register name from a register index.
96049634

96059635
\param reg Register index
@@ -9994,6 +10024,7 @@ namespace BinaryNinja {
999410024
virtual bool GetInstructionLowLevelIL(
999510025
const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override;
999610026
virtual void AnalyzeBasicBlocks(Function* function, BasicBlockAnalysisContext& context) override;
10027+
virtual bool LiftFunction(LowLevelILFunction* function, FunctionLifterContext& context) override;
999710028
virtual std::string GetRegisterName(uint32_t reg) override;
999810029
virtual std::string GetFlagName(uint32_t flag) override;
999910030
virtual std::string GetFlagWriteTypeName(uint32_t flags) override;

binaryninjacore.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,29 @@ extern "C"
20242024
BNArchitectureAndAddress* inlinedUnresolvedIndirectBranches;
20252025
} BNBasicBlockAnalysisContext;
20262026

2027+
typedef struct BNFunctionLifterContext {
2028+
// IN
2029+
size_t basicBlockCount;
2030+
BNBasicBlock** basicBlocks;
2031+
2032+
// TODO: inlinedRemapping
2033+
2034+
size_t indirectBranchesCount;
2035+
BNIndirectBranchInfo* indirectBranches;
2036+
2037+
size_t noReturnCallsCount;
2038+
BNArchitectureAndAddress* noReturnCalls;
2039+
2040+
size_t contextualFunctionReturnCount;
2041+
BNArchitectureAndAddress* contextualFunctionReturnLocations;
2042+
bool* contextualFunctionReturnValues;
2043+
2044+
// OUT
2045+
size_t indirectSourceCount;
2046+
BNArchitectureAndAddress* indirectSourcesFrom;
2047+
BNArchitectureAndAddress* indirectSourcesTo;
2048+
} BNFunctionLifterContext;
2049+
20272050
typedef struct BNCustomArchitecture
20282051
{
20292052
void* context;
@@ -2043,6 +2066,7 @@ extern "C"
20432066
bool (*getInstructionLowLevelIL)(
20442067
void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNLowLevelILFunction* il);
20452068
void (*analyzeBasicBlocks)(void* ctxt, BNFunction* function, BNBasicBlockAnalysisContext* context);
2069+
bool (*liftFunction)(void *ctext, BNLowLevelILFunction* function, BNFunctionLifterContext* context);
20462070
char* (*getRegisterName)(void* ctxt, uint32_t reg);
20472071
char* (*getFlagName)(void* ctxt, uint32_t flag);
20482072
char* (*getFlagWriteTypeName)(void* ctxt, uint32_t flags);
@@ -4878,6 +4902,10 @@ extern "C"
48784902
BINARYNINJACOREAPI void BNArchitectureDefaultAnalyzeBasicBlocks(BNFunction* function, BNBasicBlockAnalysisContext* context);
48794903
BINARYNINJACOREAPI void BNArchitectureAnalyzeBasicBlocks(BNArchitecture* arch, BNFunction* function,
48804904
BNBasicBlockAnalysisContext* context);
4905+
BINARYNINJACOREAPI bool BNArchitectureSetDefaultLiftFunctionCallback(void *callback);
4906+
BINARYNINJACOREAPI bool BNArchitectureDefaultLiftFunction(BNLowLevelILFunction* function, BNFunctionLifterContext* context);
4907+
BINARYNINJACOREAPI bool BNArchitectureLiftFunction(BNArchitecture* arch, BNLowLevelILFunction* function,
4908+
BNFunctionLifterContext* context);
48814909
BINARYNINJACOREAPI void BNFreeInstructionTextLines(BNInstructionTextLine* lines, size_t count);
48824910
BINARYNINJACOREAPI char* BNGetArchitectureRegisterName(BNArchitecture* arch, uint32_t reg);
48834911
BINARYNINJACOREAPI char* BNGetArchitectureFlagName(BNArchitecture* arch, uint32_t flag);

0 commit comments

Comments
 (0)