diff options
| -rw-r--r-- | architecture.cpp | 115 | ||||
| -rw-r--r-- | binaryninjaapi.cpp | 18 | ||||
| -rw-r--r-- | binaryninjaapi.h | 144 | ||||
| -rw-r--r-- | binaryview.cpp | 34 | ||||
| -rw-r--r-- | binaryviewtype.cpp | 39 | ||||
| -rw-r--r-- | callingconvention.cpp | 238 | ||||
| -rw-r--r-- | function.cpp | 6 | ||||
| -rw-r--r-- | platform.cpp | 216 | ||||
| -rw-r--r-- | type.cpp | 12 |
9 files changed, 803 insertions, 19 deletions
diff --git a/architecture.cpp b/architecture.cpp index 98e53b5c..2420d69b 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -226,6 +226,13 @@ uint32_t Architecture::GetStackPointerRegisterCallback(void* ctxt) } +uint32_t Architecture::GetLinkRegisterCallback(void* ctxt) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->GetLinkRegister(); +} + + bool Architecture::AssembleCallback(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors) { Architecture* arch = (Architecture*)ctxt; @@ -324,6 +331,7 @@ void Architecture::Register(Architecture* arch) callbacks.freeRegisterList = FreeRegisterListCallback; callbacks.getRegisterInfo = GetRegisterInfoCallback; callbacks.getStackPointerRegister = GetStackPointerRegisterCallback; + callbacks.getLinkRegister = GetLinkRegisterCallback; callbacks.assemble = AssembleCallback; callbacks.isNeverBranchPatchAvailable = IsNeverBranchPatchAvailableCallback; callbacks.isAlwaysBranchPatchAvailable = IsAlwaysBranchPatchAvailableCallback; @@ -451,6 +459,12 @@ uint32_t Architecture::GetStackPointerRegister() } +uint32_t Architecture::GetLinkRegister() +{ + return BN_INVALID_REGISTER; +} + + vector<uint32_t> Architecture::GetModifiedRegistersOnWrite(uint32_t reg) { size_t count; @@ -623,6 +637,101 @@ bool Architecture::ParseTypesFromSourceFile(const string& fileName, map<string, } +void Architecture::RegisterCallingConvention(CallingConvention* cc) +{ + BNRegisterCallingConvention(m_arch, cc->GetCallingConventionObject()); +} + + +vector<Ref<CallingConvention>> Architecture::GetCallingConventions() +{ + size_t count; + BNCallingConvention** list = BNGetArchitectureCallingConventions(m_arch, &count); + + vector<Ref<CallingConvention>> result; + for (size_t i = 0; i < count; i++) + result.push_back(new CoreCallingConvention(BNNewCallingConventionReference(list[i]))); + + BNFreeCallingConventionList(list, count); + return result; +} + + +Ref<CallingConvention> Architecture::GetCallingConventionByName(const string& name) +{ + BNCallingConvention* cc = BNGetArchitectureCallingConventionByName(m_arch, name.c_str()); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +void Architecture::SetDefaultCallingConvention(CallingConvention* cc) +{ + BNSetArchitectureDefaultCallingConvention(m_arch, cc->GetCallingConventionObject()); +} + + +void Architecture::SetCdeclCallingConvention(CallingConvention* cc) +{ + BNSetArchitectureCdeclCallingConvention(m_arch, cc->GetCallingConventionObject()); +} + + +void Architecture::SetStdcallCallingConvention(CallingConvention* cc) +{ + BNSetArchitectureStdcallCallingConvention(m_arch, cc->GetCallingConventionObject()); +} + + +void Architecture::SetFastcallCallingConvention(CallingConvention* cc) +{ + BNSetArchitectureFastcallCallingConvention(m_arch, cc->GetCallingConventionObject()); +} + + +Ref<CallingConvention> Architecture::GetDefaultCallingConvention() +{ + BNCallingConvention* cc = BNGetArchitectureDefaultCallingConvention(m_arch); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +Ref<CallingConvention> Architecture::GetCdeclCallingConvention() +{ + BNCallingConvention* cc = BNGetArchitectureCdeclCallingConvention(m_arch); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +Ref<CallingConvention> Architecture::GetStdcallCallingConvention() +{ + BNCallingConvention* cc = BNGetArchitectureStdcallCallingConvention(m_arch); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +Ref<CallingConvention> Architecture::GetFastcallCallingConvention() +{ + BNCallingConvention* cc = BNGetArchitectureFastcallCallingConvention(m_arch); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +Ref<Platform> Architecture::GetStandalonePlatform() +{ + return new Platform(BNGetArchitectureStandalonePlatform(m_arch)); +} + + CoreArchitecture::CoreArchitecture(BNArchitecture* arch): Architecture(arch) { } @@ -768,6 +877,12 @@ uint32_t CoreArchitecture::GetStackPointerRegister() } +uint32_t CoreArchitecture::GetLinkRegister() +{ + return BNGetArchitectureLinkRegister(m_arch); +} + + bool CoreArchitecture::Assemble(const string& code, uint64_t addr, DataBuffer& result, string& errors) { char* errorStr = nullptr; diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp index bba96296..088d6423 100644 --- a/binaryninjaapi.cpp +++ b/binaryninjaapi.cpp @@ -100,3 +100,21 @@ uint32_t BinaryNinja::GetBuildId() { return BNGetBuildId(); } + + +void BinaryNinja::SetCurrentPluginLoadOrder(BNPluginLoadOrder order) +{ + BNSetCurrentPluginLoadOrder(order); +} + + +void BinaryNinja::AddRequiredPluginDependency(const string& name) +{ + BNAddRequiredPluginDependency(name.c_str()); +} + + +void BinaryNinja::AddOptionalPluginDependency(const string& name) +{ + BNAddOptionalPluginDependency(name.c_str()); +} diff --git a/binaryninjaapi.h b/binaryninjaapi.h index b20d1b22..d4176aa5 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -144,6 +144,7 @@ namespace BinaryNinja }; class Architecture; + class Platform; class Type; class DataBuffer; @@ -189,6 +190,10 @@ namespace BinaryNinja std::string GetActiveUpdateChannel(); void SetActiveUpdateChannel(const std::string& channel); + void SetCurrentPluginLoadOrder(BNPluginLoadOrder order); + void AddRequiredPluginDependency(const std::string& name); + void AddOptionalPluginDependency(const std::string& name); + class DataBuffer { BNDataBuffer* m_buffer; @@ -559,6 +564,8 @@ namespace BinaryNinja Ref<Architecture> GetDefaultArchitecture() const; void SetDefaultArchitecture(Architecture* arch); + Ref<Platform> GetDefaultPlatform() const; + void SetDefaultPlatform(Platform* platform); BNEndianness GetDefaultEndianness() const; size_t GetAddressSize() const; @@ -571,16 +578,16 @@ namespace BinaryNinja void RegisterNotification(BinaryDataNotification* notify); void UnregisterNotification(BinaryDataNotification* notify); - void AddFunctionForAnalysis(Architecture* arch, uint64_t addr); - void AddEntryPointForAnalysis(Architecture* arch, uint64_t start); + void AddFunctionForAnalysis(Platform* platform, uint64_t addr); + void AddEntryPointForAnalysis(Platform* platform, uint64_t start); void RemoveAnalysisFunction(Function* func); - void CreateUserFunction(Architecture* arch, uint64_t start); + void CreateUserFunction(Platform* platform, uint64_t start); void UpdateAnalysis(); void AbortAnalysis(); std::vector<Ref<Function>> GetAnalysisFunctionList(); bool HasFunctions() const; - Ref<Function> GetAnalysisFunction(Architecture* arch, uint64_t addr); + Ref<Function> GetAnalysisFunction(Platform* platform, uint64_t addr); Ref<Function> GetRecentAnalysisFunctionForAddress(uint64_t addr); std::vector<Ref<Function>> GetAnalysisFunctionsForAddress(uint64_t addr); Ref<Function> GetAnalysisEntryPoint(); @@ -632,6 +639,8 @@ namespace BinaryNinja BinaryData(FileMetadata* file, FileAccessor* accessor); }; + class Platform; + class BinaryViewType: public RefCountObject { protected: @@ -656,6 +665,12 @@ namespace BinaryNinja void RegisterArchitecture(uint32_t id, Architecture* arch); Ref<Architecture> GetArchitecture(uint32_t id); + static void RegisterPlatform(const std::string& name, uint32_t id, Architecture* arch, Platform* platform); + static void RegisterDefaultPlatform(const std::string& name, Architecture* arch, Platform* platform); + void RegisterPlatform(uint32_t id, Architecture* arch, Platform* platform); + void RegisterDefaultPlatform(Architecture* arch, Platform* platform); + Ref<Platform> GetPlatform(uint32_t id, Architecture* arch); + std::string GetName(); std::string GetLongName(); @@ -850,7 +865,8 @@ namespace BinaryNinja class LowLevelILFunction; class FunctionRecognizer; - + class CallingConvention; + typedef size_t ExprId; class Architecture: public RefCountObject @@ -882,6 +898,7 @@ namespace BinaryNinja static void FreeRegisterListCallback(void* ctxt, uint32_t* regs); static void GetRegisterInfoCallback(void* ctxt, uint32_t reg, BNRegisterInfo* result); static uint32_t GetStackPointerRegisterCallback(void* ctxt); + static uint32_t GetLinkRegisterCallback(void* ctxt); static bool AssembleCallback(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors); @@ -925,6 +942,7 @@ namespace BinaryNinja virtual std::vector<uint32_t> GetAllFlagWriteTypes(); virtual BNRegisterInfo GetRegisterInfo(uint32_t reg); virtual uint32_t GetStackPointerRegister(); + virtual uint32_t GetLinkRegister(); std::vector<uint32_t> GetModifiedRegistersOnWrite(uint32_t reg); uint32_t GetRegisterByName(const std::string& name); @@ -956,6 +974,20 @@ namespace BinaryNinja std::map<std::string, Ref<Type>>& variables, std::map<std::string, Ref<Type>>& functions, std::string& errors, const std::vector<std::string>& includeDirs = std::vector<std::string>()); + + void RegisterCallingConvention(CallingConvention* cc); + std::vector<Ref<CallingConvention>> GetCallingConventions(); + Ref<CallingConvention> GetCallingConventionByName(const std::string& name); + + void SetDefaultCallingConvention(CallingConvention* cc); + void SetCdeclCallingConvention(CallingConvention* cc); + void SetStdcallCallingConvention(CallingConvention* cc); + void SetFastcallCallingConvention(CallingConvention* cc); + Ref<CallingConvention> GetDefaultCallingConvention(); + Ref<CallingConvention> GetCdeclCallingConvention(); + Ref<CallingConvention> GetStdcallCallingConvention(); + Ref<CallingConvention> GetFastcallCallingConvention(); + Ref<Platform> GetStandalonePlatform(); }; class CoreArchitecture: public Architecture @@ -978,6 +1010,7 @@ namespace BinaryNinja virtual std::vector<uint32_t> GetAllFlagWriteTypes() override; virtual BNRegisterInfo GetRegisterInfo(uint32_t reg) override; virtual uint32_t GetStackPointerRegister() override; + virtual uint32_t GetLinkRegister() override; virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors) override; @@ -1019,7 +1052,7 @@ namespace BinaryNinja bool IsConst() const; bool IsFloat() const; Ref<Type> GetChildType() const; - BNCallingConvention GetCallingConvention() const; + Ref<CallingConvention> GetCallingConvention() const; std::vector<NameAndType> GetParameters() const; bool HasVariableArguments() const; bool CanReturn() const; @@ -1039,7 +1072,7 @@ namespace BinaryNinja static Ref<Type> EnumerationType(Architecture* arch, Enumeration* enm, size_t width = 0); static Ref<Type> PointerType(Architecture* arch, Type* type, bool cnst = false); static Ref<Type> ArrayType(Type* type, uint64_t elem); - static Ref<Type> FunctionType(Type* returnValue, BNCallingConvention callingConvention, + static Ref<Type> FunctionType(Type* returnValue, CallingConvention* callingConvention, const std::vector<NameAndType>& params, bool varArg = false); }; @@ -1144,6 +1177,7 @@ namespace BinaryNinja BNFunction* GetFunctionObject() const { return m_func; } Ref<Architecture> GetArchitecture() const; + Ref<Platform> GetPlatform() const; uint64_t GetStart() const; Ref<Symbol> GetSymbol() const; bool WasAutomaticallyDiscovered() const; @@ -1478,4 +1512,100 @@ namespace BinaryNinja bool IsValid(const PluginCommandContext& ctxt) const; void Execute(const PluginCommandContext& ctxt) const; }; + + class CallingConvention: public RefCountObject + { + protected: + BNCallingConvention* m_callingConvention; + + CallingConvention(BNCallingConvention* cc); + CallingConvention(Architecture* arch, const std::string& name); + + static uint32_t* GetCallerSavedRegistersCallback(void* ctxt, size_t* count); + static uint32_t* GetIntegerArgumentRegistersCallback(void* ctxt, size_t* count); + static uint32_t* GetFloatArgumentRegistersCallback(void* ctxt, size_t* count); + static void FreeRegisterListCallback(void* ctxt, uint32_t* regs); + + static bool AreArgumentRegistersSharedIndexCallback(void* ctxt); + static bool IsStackReservedForArgumentRegistersCallback(void* ctxt); + + static uint32_t GetIntegerReturnValueRegisterCallback(void* ctxt); + static uint32_t GetHighIntegerReturnValueRegisterCallback(void* ctxt); + static uint32_t GetFloatReturnValueRegisterCallback(void* ctxt); + + public: + virtual ~CallingConvention(); + + BNCallingConvention* GetCallingConventionObject() const { return m_callingConvention; } + Ref<Architecture> GetArchitecture() const; + std::string GetName() const; + + virtual std::vector<uint32_t> GetCallerSavedRegisters(); + + virtual std::vector<uint32_t> GetIntegerArgumentRegisters(); + virtual std::vector<uint32_t> GetFloatArgumentRegisters(); + virtual bool AreArgumentRegistersSharedIndex(); + virtual bool IsStackReservedForArgumentRegisters(); + + virtual uint32_t GetIntegerReturnValueRegister() = 0; + virtual uint32_t GetHighIntegerReturnValueRegister(); + virtual uint32_t GetFloatReturnValueRegister(); + }; + + class CoreCallingConvention: public CallingConvention + { + public: + CoreCallingConvention(BNCallingConvention* cc); + + virtual std::vector<uint32_t> GetCallerSavedRegisters() override; + + virtual std::vector<uint32_t> GetIntegerArgumentRegisters() override; + virtual std::vector<uint32_t> GetFloatArgumentRegisters() override; + virtual bool AreArgumentRegistersSharedIndex() override; + virtual bool IsStackReservedForArgumentRegisters() override; + + virtual uint32_t GetIntegerReturnValueRegister() override; + virtual uint32_t GetHighIntegerReturnValueRegister() override; + virtual uint32_t GetFloatReturnValueRegister() override; + }; + + class Platform: public RefCountObject + { + protected: + BNPlatform* m_platform; + + Platform(Architecture* arch, const std::string& name); + + public: + Platform(BNPlatform* platform); + virtual ~Platform(); + + BNPlatform* GetPlatformObject() const { return m_platform; } + + Ref<Architecture> GetArchitecture() const; + std::string GetName() const; + + static void Register(const std::string& os, Platform* platform); + static Ref<Platform> GetByName(const std::string& name); + static std::vector<Ref<Platform>> GetList(); + static std::vector<Ref<Platform>> GetList(Architecture* arch); + static std::vector<Ref<Platform>> GetList(const std::string& os); + static std::vector<Ref<Platform>> GetList(const std::string& os, Architecture* arch); + static std::vector<std::string> GetOSList(); + + Ref<CallingConvention> GetDefaultCallingConvention() const; + Ref<CallingConvention> GetCdeclCallingConvention() const; + Ref<CallingConvention> GetStdcallCallingConvention() const; + Ref<CallingConvention> GetFastcallCallingConvention() const; + std::vector<Ref<CallingConvention>> GetCallingConventions() const; + + void RegisterCallingConvention(CallingConvention* cc); + void RegisterDefaultCallingConvention(CallingConvention* cc); + void RegisterCdeclCallingConvention(CallingConvention* cc); + void RegisterStdcallCallingConvention(CallingConvention* cc); + void RegisterFastcallCallingConvention(CallingConvention* cc); + + Ref<Platform> GetRelatedPlatform(Architecture* arch); + void AddRelatedPlatform(Architecture* arch, Platform* platform); + }; } diff --git a/binaryview.cpp b/binaryview.cpp index 9cf61bdc..b62d0290 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -645,6 +645,24 @@ void BinaryView::SetDefaultArchitecture(Architecture* arch) } +Ref<Platform> BinaryView::GetDefaultPlatform() const +{ + BNPlatform* platform = BNGetDefaultPlatform(m_view); + if (!platform) + return nullptr; + return new Platform(platform); +} + + +void BinaryView::SetDefaultPlatform(Platform* platform) +{ + if (platform) + BNSetDefaultPlatform(m_view, platform->GetPlatformObject()); + else + BNSetDefaultPlatform(m_view, nullptr); +} + + BNEndianness BinaryView::GetDefaultEndianness() const { return BNGetDefaultEndianness(m_view); @@ -669,15 +687,15 @@ bool BinaryView::Save(FileAccessor* file) } -void BinaryView::AddFunctionForAnalysis(Architecture* arch, uint64_t addr) +void BinaryView::AddFunctionForAnalysis(Platform* platform, uint64_t addr) { - BNAddFunctionForAnalysis(m_view, arch->GetArchitectureObject(), addr); + BNAddFunctionForAnalysis(m_view, platform->GetPlatformObject(), addr); } -void BinaryView::AddEntryPointForAnalysis(Architecture* arch, uint64_t addr) +void BinaryView::AddEntryPointForAnalysis(Platform* platform, uint64_t addr) { - BNAddEntryPointForAnalysis(m_view, arch->GetArchitectureObject(), addr); + BNAddEntryPointForAnalysis(m_view, platform->GetPlatformObject(), addr); } @@ -687,9 +705,9 @@ void BinaryView::RemoveAnalysisFunction(Function* func) } -void BinaryView::CreateUserFunction(Architecture* arch, uint64_t start) +void BinaryView::CreateUserFunction(Platform* platform, uint64_t start) { - BNCreateUserFunction(m_view, arch->GetArchitectureObject(), start); + BNCreateUserFunction(m_view, platform->GetPlatformObject(), start); } @@ -725,9 +743,9 @@ bool BinaryView::HasFunctions() const } -Ref<Function> BinaryView::GetAnalysisFunction(Architecture* arch, uint64_t addr) +Ref<Function> BinaryView::GetAnalysisFunction(Platform* platform, uint64_t addr) { - BNFunction* func = BNGetAnalysisFunction(m_view, arch->GetArchitectureObject(), addr); + BNFunction* func = BNGetAnalysisFunction(m_view, platform->GetPlatformObject(), addr); if (!func) return nullptr; return new Function(func); diff --git a/binaryviewtype.cpp b/binaryviewtype.cpp index 86a35520..e231586b 100644 --- a/binaryviewtype.cpp +++ b/binaryviewtype.cpp @@ -107,6 +107,45 @@ Ref<Architecture> BinaryViewType::GetArchitecture(uint32_t id) } +void BinaryViewType::RegisterPlatform(const string& name, uint32_t id, Architecture* arch, Platform* platform) +{ + Ref<BinaryViewType> type = BinaryViewType::GetByName(name); + if (!type) + return; + type->RegisterPlatform(id, arch, platform); +} + + +void BinaryViewType::RegisterDefaultPlatform(const string& name, Architecture* arch, Platform* platform) +{ + Ref<BinaryViewType> type = BinaryViewType::GetByName(name); + if (!type) + return; + type->RegisterDefaultPlatform(arch, platform); +} + + +void BinaryViewType::RegisterPlatform(uint32_t id, Architecture* arch, Platform* platform) +{ + BNRegisterPlatformForViewType(m_type, id, arch->GetArchitectureObject(), platform->GetPlatformObject()); +} + + +void BinaryViewType::RegisterDefaultPlatform(Architecture* arch, Platform* platform) +{ + BNRegisterDefaultPlatformForViewType(m_type, arch->GetArchitectureObject(), platform->GetPlatformObject()); +} + + +Ref<Platform> BinaryViewType::GetPlatform(uint32_t id, Architecture* arch) +{ + BNPlatform* platform = BNGetPlatformForViewType(m_type, id, arch->GetArchitectureObject()); + if (!platform) + return nullptr; + return new Platform(platform); +} + + string BinaryViewType::GetName() { char* contents = BNGetBinaryViewTypeName(m_type); diff --git a/callingconvention.cpp b/callingconvention.cpp new file mode 100644 index 00000000..076536c9 --- /dev/null +++ b/callingconvention.cpp @@ -0,0 +1,238 @@ +#include "binaryninjaapi.h" + +using namespace std; +using namespace BinaryNinja; + + +CallingConvention::CallingConvention(BNCallingConvention* cc): m_callingConvention(cc) +{ +} + + +CallingConvention::CallingConvention(Architecture* arch, const string& name) +{ + BNCustomCallingConvention cc; + cc.context = this; + cc.getCallerSavedRegisters = GetCallerSavedRegistersCallback; + cc.getIntegerArgumentRegisters = GetIntegerArgumentRegistersCallback; + cc.getFloatArgumentRegisters = GetFloatArgumentRegistersCallback; + cc.freeRegisterList = FreeRegisterListCallback; + cc.areArgumentRegistersSharedIndex = AreArgumentRegistersSharedIndexCallback; + cc.isStackReservedForArgumentRegisters = IsStackReservedForArgumentRegistersCallback; + cc.getIntegerReturnValueRegister = GetIntegerReturnValueRegisterCallback; + cc.getHighIntegerReturnValueRegister = GetHighIntegerReturnValueRegisterCallback; + cc.getFloatReturnValueRegister = GetFloatReturnValueRegisterCallback; + + m_callingConvention = BNCreateCallingConvention(arch->GetArchitectureObject(), name.c_str(), &cc); +} + + +CallingConvention::~CallingConvention() +{ + BNFreeCallingConvention(m_callingConvention); +} + + +uint32_t* CallingConvention::GetCallerSavedRegistersCallback(void* ctxt, size_t* count) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + vector<uint32_t> regs = cc->GetCallerSavedRegisters(); + *count = regs.size(); + + uint32_t* result = new uint32_t[regs.size()]; + for (size_t i = 0; i < regs.size(); i++) + result[i] = regs[i]; + return result; +} + + +uint32_t* CallingConvention::GetIntegerArgumentRegistersCallback(void* ctxt, size_t* count) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + vector<uint32_t> regs = cc->GetIntegerArgumentRegisters(); + *count = regs.size(); + + uint32_t* result = new uint32_t[regs.size()]; + for (size_t i = 0; i < regs.size(); i++) + result[i] = regs[i]; + return result; +} + + +uint32_t* CallingConvention::GetFloatArgumentRegistersCallback(void* ctxt, size_t* count) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + vector<uint32_t> regs = cc->GetFloatArgumentRegisters(); + *count = regs.size(); + + uint32_t* result = new uint32_t[regs.size()]; + for (size_t i = 0; i < regs.size(); i++) + result[i] = regs[i]; + return result; +} + + +void CallingConvention::FreeRegisterListCallback(void*, uint32_t* regs) +{ + delete[] regs; +} + + +bool CallingConvention::AreArgumentRegistersSharedIndexCallback(void* ctxt) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + return cc->AreArgumentRegistersSharedIndex(); +} + + +bool CallingConvention::IsStackReservedForArgumentRegistersCallback(void* ctxt) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + return cc->IsStackReservedForArgumentRegisters(); +} + + +uint32_t CallingConvention::GetIntegerReturnValueRegisterCallback(void* ctxt) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + return cc->GetIntegerReturnValueRegister(); +} + + +uint32_t CallingConvention::GetHighIntegerReturnValueRegisterCallback(void* ctxt) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + return cc->GetHighIntegerReturnValueRegister(); +} + + +uint32_t CallingConvention::GetFloatReturnValueRegisterCallback(void* ctxt) +{ + CallingConvention* cc = (CallingConvention*)ctxt; + return cc->GetFloatReturnValueRegister(); +} + + +Ref<Architecture> CallingConvention::GetArchitecture() const +{ + return new CoreArchitecture(BNGetCallingConventionArchitecture(m_callingConvention)); +} + + +string CallingConvention::GetName() const +{ + char* str = BNGetCallingConventionName(m_callingConvention); + string result = str; + BNFreeString(str); + return result; +} + + +vector<uint32_t> CallingConvention::GetCallerSavedRegisters() +{ + return vector<uint32_t>(); +} + + +vector<uint32_t> CallingConvention::GetIntegerArgumentRegisters() +{ + return vector<uint32_t>(); +} + + +vector<uint32_t> CallingConvention::GetFloatArgumentRegisters() +{ + return vector<uint32_t>(); +} + + +bool CallingConvention::AreArgumentRegistersSharedIndex() +{ + return false; +} + + +bool CallingConvention::IsStackReservedForArgumentRegisters() +{ + return false; +} + + +uint32_t CallingConvention::GetHighIntegerReturnValueRegister() +{ + return BN_INVALID_REGISTER; +} + + +uint32_t CallingConvention::GetFloatReturnValueRegister() +{ + return BN_INVALID_REGISTER; +} + + +CoreCallingConvention::CoreCallingConvention(BNCallingConvention* cc): CallingConvention(cc) +{ +} + + +vector<uint32_t> CoreCallingConvention::GetCallerSavedRegisters() +{ + size_t count; + uint32_t* regs = BNGetCallerSavedRegisters(m_callingConvention, &count); + vector<uint32_t> result; + result.insert(result.end(), regs, ®s[count]); + BNFreeRegisterList(regs); + return result; +} + + +vector<uint32_t> CoreCallingConvention::GetIntegerArgumentRegisters() +{ + size_t count; + uint32_t* regs = BNGetIntegerArgumentRegisters(m_callingConvention, &count); + vector<uint32_t> result; + result.insert(result.end(), regs, ®s[count]); + BNFreeRegisterList(regs); + return result; +} + + +vector<uint32_t> CoreCallingConvention::GetFloatArgumentRegisters() +{ + size_t count; + uint32_t* regs = BNGetFloatArgumentRegisters(m_callingConvention, &count); + vector<uint32_t> result; + result.insert(result.end(), regs, ®s[count]); + BNFreeRegisterList(regs); + return result; +} + + +bool CoreCallingConvention::AreArgumentRegistersSharedIndex() +{ + return BNAreArgumentRegistersSharedIndex(m_callingConvention); +} + + +bool CoreCallingConvention::IsStackReservedForArgumentRegisters() +{ + return BNIsStackReservedForArgumentRegisters(m_callingConvention); +} + + +uint32_t CoreCallingConvention::GetIntegerReturnValueRegister() +{ + return BNGetIntegerReturnValueRegister(m_callingConvention); +} + + +uint32_t CoreCallingConvention::GetHighIntegerReturnValueRegister() +{ + return BNGetHighIntegerReturnValueRegister(m_callingConvention); +} + + +uint32_t CoreCallingConvention::GetFloatReturnValueRegister() +{ + return BNGetFloatReturnValueRegister(m_callingConvention); +} diff --git a/function.cpp b/function.cpp index c1367ad6..9c8968b7 100644 --- a/function.cpp +++ b/function.cpp @@ -15,6 +15,12 @@ Function::~Function() } +Ref<Platform> Function::GetPlatform() const +{ + return new Platform(BNGetFunctionPlatform(m_func)); +} + + Ref<Architecture> Function::GetArchitecture() const { return new CoreArchitecture(BNGetFunctionArchitecture(m_func)); diff --git a/platform.cpp b/platform.cpp new file mode 100644 index 00000000..26d3b945 --- /dev/null +++ b/platform.cpp @@ -0,0 +1,216 @@ +#include "binaryninjaapi.h" + +using namespace std; +using namespace BinaryNinja; + + +Platform::Platform(BNPlatform* platform): m_platform(platform) +{ +} + + +Platform::Platform(Architecture* arch, const string& name) +{ + m_platform = BNCreatePlatform(arch->GetArchitectureObject(), name.c_str()); +} + + +Platform::~Platform() +{ + BNFreePlatform(m_platform); +} + + +Ref<Architecture> Platform::GetArchitecture() const +{ + return new CoreArchitecture(BNGetPlatformArchitecture(m_platform)); +} + + +string Platform::GetName() const +{ + char* str = BNGetPlatformName(m_platform); + string result = str; + BNFreeString(str); + return result; +} + + +void Platform::Register(const string& os, Platform* platform) +{ + BNRegisterPlatform(os.c_str(), platform->GetPlatformObject()); +} + + +Ref<Platform> Platform::GetByName(const string& name) +{ + BNPlatform* platform = BNGetPlatformByName(name.c_str()); + if (!platform) + return nullptr; + return new Platform(platform); +} + + +vector<Ref<Platform>> Platform::GetList() +{ + size_t count; + BNPlatform** list = BNGetPlatformList(&count); + + vector<Ref<Platform>> result; + for (size_t i = 0; i < count; i++) + result.push_back(new Platform(BNNewPlatformReference(list[i]))); + + BNFreePlatformList(list, count); + return result; +} + + +vector<Ref<Platform>> Platform::GetList(Architecture* arch) +{ + size_t count; + BNPlatform** list = BNGetPlatformListByArchitecture(arch->GetArchitectureObject(), &count); + + vector<Ref<Platform>> result; + for (size_t i = 0; i < count; i++) + result.push_back(new Platform(BNNewPlatformReference(list[i]))); + + BNFreePlatformList(list, count); + return result; +} + + +vector<Ref<Platform>> Platform::GetList(const string& os) +{ + size_t count; + BNPlatform** list = BNGetPlatformListByOS(os.c_str(), &count); + + vector<Ref<Platform>> result; + for (size_t i = 0; i < count; i++) + result.push_back(new Platform(BNNewPlatformReference(list[i]))); + + BNFreePlatformList(list, count); + return result; +} + + +vector<Ref<Platform>> Platform::GetList(const string& os, Architecture* arch) +{ + size_t count; + BNPlatform** list = BNGetPlatformListByOSAndArchitecture(os.c_str(), arch->GetArchitectureObject(), &count); + + vector<Ref<Platform>> result; + for (size_t i = 0; i < count; i++) + result.push_back(new Platform(BNNewPlatformReference(list[i]))); + + BNFreePlatformList(list, count); + return result; +} + + +vector<std::string> Platform::GetOSList() +{ + size_t count; + char** list = BNGetPlatformOSList(&count); + + vector<string> result; + for (size_t i = 0; i < count; i++) + result.push_back(list[i]); + + BNFreePlatformOSList(list, count); + return result; +} + + +Ref<CallingConvention> Platform::GetDefaultCallingConvention() const +{ + BNCallingConvention* cc = BNGetPlatformDefaultCallingConvention(m_platform); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +Ref<CallingConvention> Platform::GetCdeclCallingConvention() const +{ + BNCallingConvention* cc = BNGetPlatformCdeclCallingConvention(m_platform); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +Ref<CallingConvention> Platform::GetStdcallCallingConvention() const +{ + BNCallingConvention* cc = BNGetPlatformStdcallCallingConvention(m_platform); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +Ref<CallingConvention> Platform::GetFastcallCallingConvention() const +{ + BNCallingConvention* cc = BNGetPlatformFastcallCallingConvention(m_platform); + if (!cc) + return nullptr; + return new CoreCallingConvention(cc); +} + + +vector<Ref<CallingConvention>> Platform::GetCallingConventions() const +{ + size_t count; + BNCallingConvention** list = BNGetPlatformCallingConventions(m_platform, &count); + + vector<Ref<CallingConvention>> result; + for (size_t i = 0; i < count; i++) + result.push_back(new CoreCallingConvention(BNNewCallingConventionReference(list[i]))); + + BNFreeCallingConventionList(list, count); + return result; +} + + +void Platform::RegisterCallingConvention(CallingConvention* cc) +{ + BNRegisterPlatformCallingConvention(m_platform, cc->GetCallingConventionObject()); +} + + +void Platform::RegisterDefaultCallingConvention(CallingConvention* cc) +{ + BNRegisterPlatformDefaultCallingConvention(m_platform, cc->GetCallingConventionObject()); +} + + +void Platform::RegisterCdeclCallingConvention(CallingConvention* cc) +{ + BNRegisterPlatformCdeclCallingConvention(m_platform, cc->GetCallingConventionObject()); +} + + +void Platform::RegisterStdcallCallingConvention(CallingConvention* cc) +{ + BNRegisterPlatformStdcallCallingConvention(m_platform, cc->GetCallingConventionObject()); +} + + +void Platform::RegisterFastcallCallingConvention(CallingConvention* cc) +{ + BNRegisterPlatformFastcallCallingConvention(m_platform, cc->GetCallingConventionObject()); +} + + +Ref<Platform> Platform::GetRelatedPlatform(Architecture* arch) +{ + BNPlatform* platform = BNGetRelatedPlatform(m_platform, arch->GetArchitectureObject()); + if (!platform) + return nullptr; + return new Platform(platform); +} + + +void Platform::AddRelatedPlatform(Architecture* arch, Platform* platform) +{ + BNAddRelatedPlatform(m_platform, arch->GetArchitectureObject(), platform->GetPlatformObject()); +} @@ -60,9 +60,12 @@ Ref<Type> Type::GetChildType() const } -BNCallingConvention Type::GetCallingConvention() const +Ref<CallingConvention> Type::GetCallingConvention() const { - return BNGetTypeCallingConvention(m_type); + BNCallingConvention* cc = BNGetTypeCallingConvention(m_type); + if (cc) + return new CoreCallingConvention(cc); + return nullptr; } @@ -196,7 +199,7 @@ Ref<Type> Type::ArrayType(Type* type, uint64_t elem) } -Ref<Type> Type::FunctionType(Type* returnValue, BNCallingConvention callingConvention, +Ref<Type> Type::FunctionType(Type* returnValue, CallingConvention* callingConvention, const std::vector<NameAndType>& params, bool varArg) { BNNameAndType* paramArray = new BNNameAndType[params.size()]; @@ -206,7 +209,8 @@ Ref<Type> Type::FunctionType(Type* returnValue, BNCallingConvention callingConve paramArray[i].type = params[i].type->GetTypeObject(); } - Type* type = new Type(BNCreateFunctionType(returnValue->GetTypeObject(), callingConvention, + Type* type = new Type(BNCreateFunctionType(returnValue->GetTypeObject(), + callingConvention ? callingConvention->GetCallingConventionObject() : nullptr, paramArray, params.size(), varArg)); delete[] paramArray; return type; |
