Skip to content

Commit 8e91002

Browse files
committed
Add constant renderer API
1 parent 4c102c1 commit 8e91002

File tree

7 files changed

+474
-1
lines changed

7 files changed

+474
-1
lines changed

binaryninjaapi.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4811,6 +4811,7 @@ namespace BinaryNinja {
48114811
public:
48124812
StringRef();
48134813
explicit StringRef(BNStringRef* ref);
4814+
StringRef(const std::string& str);
48144815
StringRef(const StringRef& other);
48154816
StringRef(StringRef&& other);
48164817
~StringRef();
@@ -21271,6 +21272,54 @@ namespace BinaryNinja {
2127121272
std::vector<LinearDisassemblyLine>& lines
2127221273
) override;
2127321274
};
21275+
21276+
class ConstantRenderer : public StaticCoreRefCountObject<BNConstantRenderer>
21277+
{
21278+
std::string m_nameForRegister;
21279+
21280+
public:
21281+
ConstantRenderer(const std::string& name);
21282+
ConstantRenderer(BNConstantRenderer* renderer);
21283+
21284+
std::string GetName() const;
21285+
21286+
virtual bool IsValidForType(HighLevelILFunction* func, Type* type);
21287+
virtual bool RenderConstant(const HighLevelILInstruction& instr, Type* type, int64_t val,
21288+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNOperatorPrecedence precedence);
21289+
virtual bool RenderConstantPointer(const HighLevelILInstruction& instr, Type* type, int64_t val,
21290+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
21291+
BNOperatorPrecedence precedence);
21292+
21293+
/*! Registers the constant renderer.
21294+
21295+
\param renderer The constant renderer to register.
21296+
*/
21297+
static void Register(ConstantRenderer* renderer);
21298+
21299+
static Ref<ConstantRenderer> GetByName(const std::string& name);
21300+
static std::vector<Ref<ConstantRenderer>> GetRenderers();
21301+
21302+
private:
21303+
static bool IsValidForTypeCallback(void* ctxt, BNHighLevelILFunction* hlil, BNType* type);
21304+
static bool RenderConstantCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
21305+
int64_t val, BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings,
21306+
BNOperatorPrecedence precedence);
21307+
static bool RenderConstantPointerCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
21308+
int64_t val, BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings,
21309+
BNSymbolDisplayType symbolDisplay, BNOperatorPrecedence precedence);
21310+
};
21311+
21312+
class CoreConstantRenderer : public ConstantRenderer
21313+
{
21314+
public:
21315+
CoreConstantRenderer(BNConstantRenderer* renderer);
21316+
bool IsValidForType(HighLevelILFunction* func, Type* type) override;
21317+
bool RenderConstant(const HighLevelILInstruction& instr, Type* type, int64_t val,
21318+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNOperatorPrecedence precedence) override;
21319+
bool RenderConstantPointer(const HighLevelILInstruction& instr, Type* type, int64_t val,
21320+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
21321+
BNOperatorPrecedence precedence) override;
21322+
};
2127421323
} // namespace BinaryNinja
2127521324

2127621325

binaryninjacore.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 136
40+
#define BN_CURRENT_CORE_ABI_VERSION 137
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
@@ -311,6 +311,7 @@ extern "C"
311311
typedef struct BNStringRef BNStringRef;
312312
typedef struct BNIndirectBranchInfo BNIndirectBranchInfo;
313313
typedef struct BNArchitectureAndAddress BNArchitectureAndAddress;
314+
typedef struct BNConstantRenderer BNConstantRenderer;
314315

315316
typedef bool(*BNProgressFunction)(void*, size_t, size_t);
316317

@@ -3806,6 +3807,17 @@ extern "C"
38063807
char* value;
38073808
} BNTypeAttribute;
38083809

3810+
typedef struct BNCustomConstantRenderer
3811+
{
3812+
void* context;
3813+
bool (*isValidForType)(void* ctxt, BNHighLevelILFunction* hlil, BNType* type);
3814+
bool (*renderConstant)(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val,
3815+
BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings, BNOperatorPrecedence precedence);
3816+
bool (*renderConstantPointer)(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val,
3817+
BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
3818+
BNOperatorPrecedence precedence);
3819+
} BNCustomConstantRenderer;
3820+
38093821
BINARYNINJACOREAPI char* BNAllocString(const char* contents);
38103822
BINARYNINJACOREAPI char* BNAllocStringWithLength(const char* contents, size_t len);
38113823
BINARYNINJACOREAPI void BNFreeString(char* str);
@@ -8675,6 +8687,22 @@ extern "C"
86758687
BINARYNINJACOREAPI const char* BNGetStringRefContents(BNStringRef* ref);
86768688
BINARYNINJACOREAPI size_t BNGetStringRefSize(BNStringRef* ref);
86778689

8690+
// Constant Renderers
8691+
BINARYNINJACOREAPI BNConstantRenderer* BNRegisterConstantRenderer(
8692+
const char* name, BNCustomConstantRenderer* renderer);
8693+
BINARYNINJACOREAPI BNConstantRenderer* BNGetConstantRendererByName(const char* name);
8694+
BINARYNINJACOREAPI BNConstantRenderer** BNGetConstantRendererList(size_t* count);
8695+
BINARYNINJACOREAPI void BNFreeConstantRendererList(BNLanguageRepresentationFunctionType** renderers);
8696+
BINARYNINJACOREAPI char* BNGetConstantRendererName(BNConstantRenderer* renderer);
8697+
BINARYNINJACOREAPI bool BNIsConstantRendererValidForType(
8698+
BNConstantRenderer* renderer, BNHighLevelILFunction* il, BNType* type);
8699+
BINARYNINJACOREAPI bool BNConstantRendererRenderConstant(BNConstantRenderer* renderer, BNHighLevelILFunction* il,
8700+
size_t exprIndex, BNType* type, int64_t val, BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings,
8701+
BNOperatorPrecedence precedence);
8702+
BINARYNINJACOREAPI bool BNConstantRendererRenderConstantPointer(BNConstantRenderer* renderer,
8703+
BNHighLevelILFunction* il, size_t exprIndex, BNType* type, int64_t val, BNHighLevelILTokenEmitter* tokens,
8704+
BNDisassemblySettings* settings, BNSymbolDisplayType symbolDisplay, BNOperatorPrecedence precedence);
8705+
86788706
#ifdef __cplusplus
86798707
}
86808708
#endif

binaryview.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,12 @@ StringRef::StringRef(BNStringRef* ref)
662662
}
663663

664664

665+
StringRef::StringRef(const std::string& str)
666+
{
667+
m_ref = BNCreateStringRefOfLength(str.c_str(), str.size());
668+
}
669+
670+
665671
StringRef::StringRef(const StringRef& other)
666672
{
667673
m_ref = BNDuplicateStringRef(other.m_ref);

constantrenderer.cpp

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#include "binaryninjaapi.h"
2+
#include "ffi.h"
3+
#include "highlevelilinstruction.h"
4+
5+
using namespace BinaryNinja;
6+
using namespace std;
7+
8+
9+
ConstantRenderer::ConstantRenderer(const std::string& name): m_nameForRegister(name)
10+
{
11+
m_object = nullptr;
12+
}
13+
14+
15+
ConstantRenderer::ConstantRenderer(BNConstantRenderer* renderer)
16+
{
17+
m_object = renderer;
18+
}
19+
20+
21+
string ConstantRenderer::GetName() const
22+
{
23+
char* name = BNGetConstantRendererName(m_object);
24+
string result = name;
25+
BNFreeString(name);
26+
return result;
27+
}
28+
29+
30+
bool ConstantRenderer::IsValidForType(HighLevelILFunction*, Type*)
31+
{
32+
return true;
33+
}
34+
35+
36+
bool ConstantRenderer::RenderConstant(const HighLevelILInstruction&, Type*, int64_t,
37+
HighLevelILTokenEmitter&, DisassemblySettings*, BNOperatorPrecedence)
38+
{
39+
return false;
40+
}
41+
42+
43+
bool ConstantRenderer::RenderConstantPointer(const HighLevelILInstruction&, Type*, int64_t,
44+
HighLevelILTokenEmitter&, DisassemblySettings*, BNSymbolDisplayType, BNOperatorPrecedence)
45+
{
46+
return false;
47+
}
48+
49+
50+
void ConstantRenderer::Register(ConstantRenderer* renderer)
51+
{
52+
BNCustomConstantRenderer callbacks;
53+
callbacks.context = renderer;
54+
callbacks.isValidForType = IsValidForTypeCallback;
55+
callbacks.renderConstant = RenderConstantCallback;
56+
callbacks.renderConstantPointer = RenderConstantPointerCallback;
57+
58+
renderer->AddRefForRegistration();
59+
renderer->m_object = BNRegisterConstantRenderer(renderer->m_nameForRegister.c_str(), &callbacks);
60+
}
61+
62+
63+
bool ConstantRenderer::IsValidForTypeCallback(void* ctxt, BNHighLevelILFunction* hlil, BNType* type)
64+
{
65+
ConstantRenderer* renderer = (ConstantRenderer*)ctxt;
66+
Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil));
67+
Ref<Type> typeObj = new Type(BNNewTypeReference(type));
68+
return renderer->IsValidForType(hlilObj, typeObj);
69+
}
70+
71+
72+
bool ConstantRenderer::RenderConstantCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
73+
int64_t val, BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings,
74+
BNOperatorPrecedence precedence)
75+
{
76+
ConstantRenderer* renderer = (ConstantRenderer*)ctxt;
77+
Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil));
78+
HighLevelILInstruction instr = hlilObj->GetExpr(expr);
79+
Ref<Type> typeObj = new Type(BNNewTypeReference(type));
80+
Ref<HighLevelILTokenEmitter> tokenObj = new HighLevelILTokenEmitter(BNNewHighLevelILTokenEmitterReference(tokens));
81+
Ref<DisassemblySettings> settingsObj = settings ? new DisassemblySettings(BNNewDisassemblySettingsReference(settings)) : nullptr;
82+
return renderer->RenderConstant(instr, typeObj, val, *tokenObj, settingsObj, precedence);
83+
}
84+
85+
86+
bool ConstantRenderer::RenderConstantPointerCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
87+
int64_t val, BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
88+
BNOperatorPrecedence precedence)
89+
{
90+
ConstantRenderer* renderer = (ConstantRenderer*)ctxt;
91+
Ref<HighLevelILFunction> hlilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(hlil));
92+
HighLevelILInstruction instr = hlilObj->GetExpr(expr);
93+
Ref<Type> typeObj = new Type(BNNewTypeReference(type));
94+
Ref<HighLevelILTokenEmitter> tokenObj = new HighLevelILTokenEmitter(BNNewHighLevelILTokenEmitterReference(tokens));
95+
Ref<DisassemblySettings> settingsObj = settings ? new DisassemblySettings(BNNewDisassemblySettingsReference(settings)) : nullptr;
96+
return renderer->RenderConstantPointer(instr, typeObj, val, *tokenObj, settingsObj, symbolDisplay, precedence);
97+
}
98+
99+
100+
Ref<ConstantRenderer> ConstantRenderer::GetByName(const std::string& name)
101+
{
102+
BNConstantRenderer* renderer = BNGetConstantRendererByName(name.c_str());
103+
if (!renderer)
104+
return nullptr;
105+
return new CoreConstantRenderer(renderer);
106+
}
107+
108+
109+
vector<Ref<ConstantRenderer>> ConstantRenderer::GetRenderers()
110+
{
111+
size_t count = 0;
112+
BNConstantRenderer** renderers = BNGetConstantRendererList(&count);
113+
114+
vector<Ref<ConstantRenderer>> result;
115+
result.reserve(count);
116+
for (size_t i = 0; i < count; i++)
117+
result.push_back(new CoreConstantRenderer(renderers[i]));
118+
119+
BNFreeConstantRendererList(renderers);
120+
return result;
121+
}
122+
123+
124+
CoreConstantRenderer::CoreConstantRenderer(BNConstantRenderer* renderer):
125+
ConstantRenderer(renderer)
126+
{
127+
}
128+
129+
130+
bool CoreConstantRenderer::IsValidForType(HighLevelILFunction* func, Type* type)
131+
{
132+
return BNIsConstantRendererValidForType(m_object, func->GetObject(), type->GetObject());
133+
}
134+
135+
136+
bool CoreConstantRenderer::RenderConstant(const HighLevelILInstruction& instr, Type* type, int64_t val,
137+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNOperatorPrecedence precedence)
138+
{
139+
return BNConstantRendererRenderConstant(m_object, instr.function->GetObject(), instr.exprIndex,
140+
type->GetObject(), val, tokens.GetObject(), settings ? settings->GetObject() : nullptr, precedence);
141+
}
142+
143+
144+
bool CoreConstantRenderer::RenderConstantPointer(const HighLevelILInstruction& instr, Type* type, int64_t val,
145+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
146+
BNOperatorPrecedence precedence)
147+
{
148+
return BNConstantRendererRenderConstantPointer(m_object, instr.function->GetObject(), instr.exprIndex,
149+
type->GetObject(), val, tokens.GetObject(), settings ? settings->GetObject() : nullptr,
150+
symbolDisplay, precedence);
151+
}

python/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
from .languagerepresentation import *
8383
from .lineformatter import *
8484
from .renderlayer import *
85+
from .constantrenderer import *
8586
# We import each of these by name to prevent conflicts between
8687
# log.py and the function 'log' which we don't import below
8788
from .log import (

0 commit comments

Comments
 (0)