Skip to content

Commit 56115ae

Browse files
committed
platform: initial BNCustomPlatform support
1 parent 74920c1 commit 56115ae

12 files changed

+319
-24
lines changed

architecture.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,7 @@ Ref<CallingConvention> Architecture::GetFastcallCallingConvention()
13721372

13731373
Ref<Platform> Architecture::GetStandalonePlatform()
13741374
{
1375-
return new Platform(BNGetArchitectureStandalonePlatform(m_object));
1375+
return new CorePlatform(BNGetArchitectureStandalonePlatform(m_object));
13761376
}
13771377

13781378

binaryninjaapi.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14495,6 +14495,12 @@ namespace BinaryNinja {
1449514495
Platform(Architecture* arch, const std::string& name, const std::string& typeFile,
1449614496
const std::vector<std::string>& includeDirs = std::vector<std::string>());
1449714497

14498+
static void InitCallback(void *ctxt, BNPlatform*);
14499+
static void InitViewCallback(void* ctxt, BNBinaryView* view);
14500+
static uint32_t* GetGlobalRegistersCallback(void* ctxt, size_t* count);
14501+
static void FreeRegisterListCallback(void* ctxt, uint32_t* regs, size_t count);
14502+
static BNType* GetGlobalRegisterTypeCallback(void* ctxt, uint32_t reg);
14503+
1449814504
public:
1449914505
Platform(BNPlatform* platform);
1450014506

@@ -14630,6 +14636,30 @@ namespace BinaryNinja {
1463014636
*/
1463114637
void SetSystemCallConvention(CallingConvention* cc);
1463214638

14639+
/*! Callback that will be called when the platform of a binaryview
14640+
* is set. Allows for the Platform to to do platform-specific
14641+
* processing of views just after finalization.
14642+
*
14643+
* \param view BinaryView that was just set to this Platform
14644+
*/
14645+
virtual void BinaryViewInit(BinaryView* view);
14646+
14647+
/*! Get the global register list for this Platform
14648+
*
14649+
* Allows the Platform to override the global register list
14650+
* used by analysis.
14651+
*/
14652+
virtual std::vector<uint32_t> GetGlobalRegisters();
14653+
14654+
/*! Get the type of a global register
14655+
*
14656+
* Called by analysis when the incoming register value of a
14657+
* global register is observed.
14658+
*
14659+
* \param reg The register being queried for type information.
14660+
*/
14661+
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg);
14662+
1463314663
Ref<Platform> GetRelatedPlatform(Architecture* arch);
1463414664
void AddRelatedPlatform(Architecture* arch, Platform* platform);
1463514665
Ref<Platform> GetAssociatedPlatformByAddress(uint64_t& addr);
@@ -14720,6 +14750,16 @@ namespace BinaryNinja {
1472014750
const std::string& autoTypeSource = "");
1472114751
};
1472214752

14753+
14754+
class CorePlatform : public Platform
14755+
{
14756+
public:
14757+
CorePlatform(BNPlatform* plat);
14758+
14759+
virtual std::vector<uint32_t> GetGlobalRegisters() override;
14760+
virtual Ref<Type> GetGlobalRegisterType(uint32_t reg) override;
14761+
};
14762+
1472314763
/*!
1472414764
\ingroup typeparser
1472514765
*/

binaryninjacore.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,18 @@ extern "C"
18721872
bool (*skipAndReturnValue)(void* ctxt, uint8_t* data, uint64_t addr, size_t len, uint64_t value);
18731873
} BNCustomArchitecture;
18741874

1875+
typedef struct BNCustomPlatform
1876+
{
1877+
void* context;
1878+
void (*init)(void* ctxt, BNPlatform* obj);
1879+
void (*viewInit)(void* ctxt, BNBinaryView* view);
1880+
1881+
uint32_t* (*getGlobalRegisters)(void* ctxt, size_t* count);
1882+
void (*freeRegisterList)(void* ctxt, uint32_t* regs, size_t len);
1883+
1884+
BNType* (*getGlobalRegisterType)(void* ctxt, uint32_t reg);
1885+
} BNCustomPlatform;
1886+
18751887
typedef struct BNBasicBlockEdge
18761888
{
18771889
BNBranchType type;
@@ -6360,6 +6372,10 @@ extern "C"
63606372
BINARYNINJACOREAPI BNPlatform* BNCreatePlatform(BNArchitecture* arch, const char* name);
63616373
BINARYNINJACOREAPI BNPlatform* BNCreatePlatformWithTypes(
63626374
BNArchitecture* arch, const char* name, const char* typeFile, const char** includeDirs, size_t includeDirCount);
6375+
BINARYNINJACOREAPI BNPlatform* BNCreateCustomPlatform(BNArchitecture* arch, const char* name, BNCustomPlatform* impl);
6376+
BINARYNINJACOREAPI BNPlatform* BNCreateCustomPlatformWithTypes(
6377+
BNArchitecture* arch, const char* name, BNCustomPlatform* impl,
6378+
const char* typeFile, const char** includeDirs, size_t includeDirCount);
63636379
BINARYNINJACOREAPI void BNRegisterPlatform(const char* os, BNPlatform* platform);
63646380
BINARYNINJACOREAPI BNPlatform* BNNewPlatformReference(BNPlatform* platform);
63656381
BINARYNINJACOREAPI void BNFreePlatform(BNPlatform* platform);
@@ -6391,6 +6407,9 @@ extern "C"
63916407
BINARYNINJACOREAPI void BNRegisterPlatformFastcallCallingConvention(BNPlatform* platform, BNCallingConvention* cc);
63926408
BINARYNINJACOREAPI void BNSetPlatformSystemCallConvention(BNPlatform* platform, BNCallingConvention* cc);
63936409

6410+
BINARYNINJACOREAPI uint32_t* BNGetPlatformGlobalRegisters(BNPlatform* platform, size_t* count);
6411+
BINARYNINJACOREAPI BNType* BNGetPlatformGlobalRegisterType(BNPlatform* platform, uint32_t reg);
6412+
63946413
BINARYNINJACOREAPI BNPlatform* BNGetArchitectureStandalonePlatform(BNArchitecture* arch);
63956414

63966415
BINARYNINJACOREAPI BNPlatform* BNGetRelatedPlatform(BNPlatform* platform, BNArchitecture* arch);

binaryview.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,7 @@ Ref<Platform> BinaryView::GetDefaultPlatform() const
19201920
BNPlatform* platform = BNGetDefaultPlatform(m_object);
19211921
if (!platform)
19221922
return nullptr;
1923-
return new Platform(platform);
1923+
return new CorePlatform(platform);
19241924
}
19251925

19261926

@@ -4177,7 +4177,7 @@ std::optional<std::pair<Ref<Platform>, QualifiedName>> BinaryView::LookupImporte
41774177
return std::nullopt;
41784178
QualifiedName targetName = QualifiedName::FromAPIObject(&resultName);
41794179
BNFreeQualifiedName(&resultName);
4180-
return std::make_pair(new Platform(resultLib), targetName);
4180+
return std::make_pair(new CorePlatform(resultLib), targetName);
41814181
}
41824182

41834183

debuginfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ vector<DebugFunctionInfo> DebugInfo::GetFunctions(const string& parserName) cons
100100
functions[i].fullName ? functions[i].fullName : "", functions[i].rawName ? functions[i].rawName : "",
101101
functions[i].address,
102102
functions[i].type ? new Type(BNNewTypeReference(functions[i].type)) : nullptr,
103-
functions[i].platform ? new Platform(BNNewPlatformReference(functions[i].platform)) : nullptr, components);
103+
functions[i].platform ? new CorePlatform(BNNewPlatformReference(functions[i].platform)) : nullptr, components);
104104
}
105105

106106
BNFreeDebugFunctions(functions, count);

function.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ Ref<BinaryView> Function::GetView() const
192192

193193
Ref<Platform> Function::GetPlatform() const
194194
{
195-
return new Platform(BNGetFunctionPlatform(m_object));
195+
return new CorePlatform(BNGetFunctionPlatform(m_object));
196196
}
197197

198198

platform.cpp

Lines changed: 120 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,89 @@ Platform::Platform(BNPlatform* platform)
3030
}
3131

3232

33+
CorePlatform::CorePlatform(BNPlatform* platform) : Platform(platform) {}
34+
35+
3336
Platform::Platform(Architecture* arch, const string& name)
3437
{
35-
m_object = BNCreatePlatform(arch->GetObject(), name.c_str());
38+
BNCustomPlatform plat;
39+
plat.context = this;
40+
plat.init = InitCallback;
41+
plat.viewInit = InitViewCallback;
42+
plat.getGlobalRegisters = GetGlobalRegistersCallback;
43+
plat.freeRegisterList = FreeRegisterListCallback;
44+
plat.getGlobalRegisterType = GetGlobalRegisterTypeCallback;
45+
m_object = BNCreateCustomPlatform(arch->GetObject(), name.c_str(), &plat);
46+
AddRefForRegistration();
3647
}
3748

3849

3950
Platform::Platform(Architecture* arch, const string& name, const string& typeFile, const vector<string>& includeDirs)
4051
{
52+
BNCustomPlatform plat;
53+
plat.context = this;
54+
plat.init = InitCallback;
55+
plat.viewInit = InitViewCallback;
56+
plat.getGlobalRegisters = GetGlobalRegistersCallback;
57+
plat.freeRegisterList = FreeRegisterListCallback;
58+
plat.getGlobalRegisterType = GetGlobalRegisterTypeCallback;
4159
const char** includeDirList = new const char*[includeDirs.size()];
4260
for (size_t i = 0; i < includeDirs.size(); i++)
4361
includeDirList[i] = includeDirs[i].c_str();
44-
m_object = BNCreatePlatformWithTypes(
45-
arch->GetObject(), name.c_str(), typeFile.c_str(), includeDirList, includeDirs.size());
62+
m_object = BNCreateCustomPlatformWithTypes(
63+
arch->GetObject(), name.c_str(), &plat,
64+
typeFile.c_str(), includeDirList, includeDirs.size());
4665
delete[] includeDirList;
66+
AddRefForRegistration();
67+
}
68+
69+
70+
71+
72+
void Platform::InitCallback(void* ctxt, BNPlatform* plat)
73+
{
74+
}
75+
76+
77+
void Platform::InitViewCallback(void* ctxt, BNBinaryView* view)
78+
{
79+
CallbackRef<Platform> plat(ctxt);
80+
Ref<BinaryView> viewObj = new BinaryView(BNNewViewReference(view));
81+
plat->BinaryViewInit(viewObj);
82+
}
83+
84+
85+
uint32_t* Platform::GetGlobalRegistersCallback(void* ctxt, size_t* count)
86+
{
87+
CallbackRef<Platform> plat(ctxt);
88+
89+
std::vector<uint32_t> regs = plat->GetGlobalRegisters();
90+
*count = regs.size();
91+
92+
uint32_t* result = new uint32_t[regs.size()];
93+
for (size_t i = 0; i < regs.size(); i++)
94+
result[i] = regs[i];
95+
96+
return result;
97+
}
98+
99+
100+
void Platform::FreeRegisterListCallback(void*, uint32_t* regs, size_t)
101+
{
102+
delete[] regs;
103+
}
104+
105+
106+
BNType* Platform::GetGlobalRegisterTypeCallback(void* ctxt, uint32_t reg)
107+
{
108+
CallbackRef<Platform> plat(ctxt);
109+
110+
Ref<Type> result = plat->GetGlobalRegisterType(reg);
111+
112+
if (!result)
113+
return nullptr;
114+
115+
return BNNewTypeReference(result->GetObject());
47116
}
48117

49118

@@ -73,7 +142,7 @@ Ref<Platform> Platform::GetByName(const string& name)
73142
BNPlatform* platform = BNGetPlatformByName(name.c_str());
74143
if (!platform)
75144
return nullptr;
76-
return new Platform(platform);
145+
return new CorePlatform(platform);
77146
}
78147

79148

@@ -85,7 +154,7 @@ vector<Ref<Platform>> Platform::GetList()
85154
vector<Ref<Platform>> result;
86155
result.reserve(count);
87156
for (size_t i = 0; i < count; i++)
88-
result.push_back(new Platform(BNNewPlatformReference(list[i])));
157+
result.push_back(new CorePlatform(BNNewPlatformReference(list[i])));
89158

90159
BNFreePlatformList(list, count);
91160
return result;
@@ -100,7 +169,7 @@ vector<Ref<Platform>> Platform::GetList(Architecture* arch)
100169
vector<Ref<Platform>> result;
101170
result.reserve(count);
102171
for (size_t i = 0; i < count; i++)
103-
result.push_back(new Platform(BNNewPlatformReference(list[i])));
172+
result.push_back(new CorePlatform(BNNewPlatformReference(list[i])));
104173

105174
BNFreePlatformList(list, count);
106175
return result;
@@ -115,7 +184,7 @@ vector<Ref<Platform>> Platform::GetList(const string& os)
115184
vector<Ref<Platform>> result;
116185
result.reserve(count);
117186
for (size_t i = 0; i < count; i++)
118-
result.push_back(new Platform(BNNewPlatformReference(list[i])));
187+
result.push_back(new CorePlatform(BNNewPlatformReference(list[i])));
119188

120189
BNFreePlatformList(list, count);
121190
return result;
@@ -130,7 +199,7 @@ vector<Ref<Platform>> Platform::GetList(const string& os, Architecture* arch)
130199
vector<Ref<Platform>> result;
131200
result.reserve(count);
132201
for (size_t i = 0; i < count; i++)
133-
result.push_back(new Platform(BNNewPlatformReference(list[i])));
202+
result.push_back(new CorePlatform(BNNewPlatformReference(list[i])));
134203

135204
BNFreePlatformList(list, count);
136205
return result;
@@ -248,12 +317,53 @@ void Platform::SetSystemCallConvention(CallingConvention* cc)
248317
}
249318

250319

320+
void Platform::BinaryViewInit(BinaryView*)
321+
{
322+
}
323+
324+
325+
std::vector<uint32_t> Platform::GetGlobalRegisters()
326+
{
327+
return GetArchitecture()->GetGlobalRegisters();
328+
}
329+
330+
331+
Ref<Type> Platform::GetGlobalRegisterType(uint32_t reg)
332+
{
333+
return nullptr;
334+
}
335+
336+
337+
std::vector<uint32_t> CorePlatform::GetGlobalRegisters()
338+
{
339+
size_t count;
340+
uint32_t* regs = BNGetPlatformGlobalRegisters(m_object, &count);
341+
342+
std::vector<uint32_t> result;
343+
for (size_t i = 0; i < count; i++)
344+
result.push_back(regs[i]);
345+
346+
BNFreeRegisterList(regs);
347+
348+
return result;
349+
}
350+
351+
352+
Ref<Type> CorePlatform::GetGlobalRegisterType(uint32_t reg)
353+
{
354+
BNType* res = BNGetPlatformGlobalRegisterType(m_object, reg);
355+
if (!res)
356+
return nullptr;
357+
return new Type(res);
358+
}
359+
360+
251361
Ref<Platform> Platform::GetRelatedPlatform(Architecture* arch)
252362
{
253363
BNPlatform* platform = BNGetRelatedPlatform(m_object, arch->GetObject());
254364
if (!platform)
255365
return nullptr;
256-
return new Platform(platform);
366+
return new CorePlatform(platform);
257367
}
258368

259369

@@ -268,7 +378,7 @@ Ref<Platform> Platform::GetAssociatedPlatformByAddress(uint64_t& addr)
268378
BNPlatform* platform = BNGetAssociatedPlatformByAddress(m_object, &addr);
269379
if (!platform)
270380
return nullptr;
271-
return new Platform(platform);
381+
return new CorePlatform(platform);
272382
}
273383

274384

0 commit comments

Comments
 (0)