Skip to content

Commit 0f65203

Browse files
committed
Add constant renderer API
1 parent c7ff543 commit 0f65203

File tree

7 files changed

+473
-0
lines changed

7 files changed

+473
-0
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();
@@ -21277,6 +21278,54 @@ namespace BinaryNinja {
2127721278
std::vector<LinearDisassemblyLine>& lines
2127821279
) override;
2127921280
};
21281+
21282+
class ConstantRenderer : public StaticCoreRefCountObject<BNConstantRenderer>
21283+
{
21284+
std::string m_nameForRegister;
21285+
21286+
public:
21287+
ConstantRenderer(const std::string& name);
21288+
ConstantRenderer(BNConstantRenderer* renderer);
21289+
21290+
std::string GetName() const;
21291+
21292+
virtual bool IsValidForType(HighLevelILFunction* func, Type* type);
21293+
virtual bool RenderConstant(const HighLevelILInstruction& instr, Type* type, int64_t val,
21294+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNOperatorPrecedence precedence);
21295+
virtual bool RenderConstantPointer(const HighLevelILInstruction& instr, Type* type, int64_t val,
21296+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
21297+
BNOperatorPrecedence precedence);
21298+
21299+
/*! Registers the constant renderer.
21300+
21301+
\param renderer The constant renderer to register.
21302+
*/
21303+
static void Register(ConstantRenderer* renderer);
21304+
21305+
static Ref<ConstantRenderer> GetByName(const std::string& name);
21306+
static std::vector<Ref<ConstantRenderer>> GetRenderers();
21307+
21308+
private:
21309+
static bool IsValidForTypeCallback(void* ctxt, BNHighLevelILFunction* hlil, BNType* type);
21310+
static bool RenderConstantCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
21311+
int64_t val, BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings,
21312+
BNOperatorPrecedence precedence);
21313+
static bool RenderConstantPointerCallback(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type,
21314+
int64_t val, BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings,
21315+
BNSymbolDisplayType symbolDisplay, BNOperatorPrecedence precedence);
21316+
};
21317+
21318+
class CoreConstantRenderer : public ConstantRenderer
21319+
{
21320+
public:
21321+
CoreConstantRenderer(BNConstantRenderer* renderer);
21322+
bool IsValidForType(HighLevelILFunction* func, Type* type) override;
21323+
bool RenderConstant(const HighLevelILInstruction& instr, Type* type, int64_t val,
21324+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNOperatorPrecedence precedence) override;
21325+
bool RenderConstantPointer(const HighLevelILInstruction& instr, Type* type, int64_t val,
21326+
HighLevelILTokenEmitter& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
21327+
BNOperatorPrecedence precedence) override;
21328+
};
2128021329
} // namespace BinaryNinja
2128121330

2128221331

binaryninjacore.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 struct BNRemoteFileSearchMatch
316317
{
@@ -3814,6 +3815,17 @@ extern "C"
38143815
char* value;
38153816
} BNTypeAttribute;
38163817

3818+
typedef struct BNCustomConstantRenderer
3819+
{
3820+
void* context;
3821+
bool (*isValidForType)(void* ctxt, BNHighLevelILFunction* hlil, BNType* type);
3822+
bool (*renderConstant)(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val,
3823+
BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings, BNOperatorPrecedence precedence);
3824+
bool (*renderConstantPointer)(void* ctxt, BNHighLevelILFunction* hlil, size_t expr, BNType* type, int64_t val,
3825+
BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings, BNSymbolDisplayType symbolDisplay,
3826+
BNOperatorPrecedence precedence);
3827+
} BNCustomConstantRenderer;
3828+
38173829
BINARYNINJACOREAPI char* BNAllocString(const char* contents);
38183830
BINARYNINJACOREAPI char* BNAllocStringWithLength(const char* contents, size_t len);
38193831
BINARYNINJACOREAPI void BNFreeString(char* str);
@@ -8690,6 +8702,22 @@ extern "C"
86908702
BINARYNINJACOREAPI const char* BNGetStringRefContents(BNStringRef* ref);
86918703
BINARYNINJACOREAPI size_t BNGetStringRefSize(BNStringRef* ref);
86928704

8705+
// Constant Renderers
8706+
BINARYNINJACOREAPI BNConstantRenderer* BNRegisterConstantRenderer(
8707+
const char* name, BNCustomConstantRenderer* renderer);
8708+
BINARYNINJACOREAPI BNConstantRenderer* BNGetConstantRendererByName(const char* name);
8709+
BINARYNINJACOREAPI BNConstantRenderer** BNGetConstantRendererList(size_t* count);
8710+
BINARYNINJACOREAPI void BNFreeConstantRendererList(BNLanguageRepresentationFunctionType** renderers);
8711+
BINARYNINJACOREAPI char* BNGetConstantRendererName(BNConstantRenderer* renderer);
8712+
BINARYNINJACOREAPI bool BNIsConstantRendererValidForType(
8713+
BNConstantRenderer* renderer, BNHighLevelILFunction* il, BNType* type);
8714+
BINARYNINJACOREAPI bool BNConstantRendererRenderConstant(BNConstantRenderer* renderer, BNHighLevelILFunction* il,
8715+
size_t exprIndex, BNType* type, int64_t val, BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings,
8716+
BNOperatorPrecedence precedence);
8717+
BINARYNINJACOREAPI bool BNConstantRendererRenderConstantPointer(BNConstantRenderer* renderer,
8718+
BNHighLevelILFunction* il, size_t exprIndex, BNType* type, int64_t val, BNHighLevelILTokenEmitter* tokens,
8719+
BNDisassemblySettings* settings, BNSymbolDisplayType symbolDisplay, BNOperatorPrecedence precedence);
8720+
86938721
#ifdef __cplusplus
86948722
}
86958723
#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)