diff options
| -rw-r--r-- | binaryninjaapi.cpp | 18 | ||||
| -rw-r--r-- | binaryninjaapi.h | 83 | ||||
| -rw-r--r-- | binaryninjacore.h | 84 | ||||
| -rw-r--r-- | binaryview.cpp | 28 | ||||
| -rw-r--r-- | binaryviewtype.cpp | 2 | ||||
| -rw-r--r-- | docs/about/open-source.md | 6 | ||||
| -rw-r--r-- | docs/getting-started.md | 27 | ||||
| -rw-r--r-- | downloadprovider.cpp | 135 | ||||
| -rw-r--r-- | function.cpp | 6 | ||||
| -rw-r--r-- | python/__init__.py | 1 | ||||
| -rw-r--r-- | python/binaryview.py | 47 | ||||
| -rw-r--r-- | python/downloadprovider.py | 210 | ||||
| -rw-r--r-- | python/function.py | 7 | ||||
| -rw-r--r-- | python/lowlevelil.py | 5 | ||||
| -rw-r--r-- | python/pluginmanager.py | 3 | ||||
| -rw-r--r-- | themes/dark-blue.theme | 108 | ||||
| -rw-r--r-- | themes/high-contrast.theme | 107 | ||||
| -rw-r--r-- | themes/solarized-dark.theme | 104 | ||||
| -rw-r--r-- | themes/solarized-light.theme | 104 |
19 files changed, 1039 insertions, 46 deletions
diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp index f5eede03..b774cf2b 100644 --- a/binaryninjaapi.cpp +++ b/binaryninjaapi.cpp @@ -344,21 +344,3 @@ string BinaryNinja::GetUniqueIdentifierString() BNFreeString(str); return result; } - - -string BinaryNinja::GetLinuxCADirectory() -{ - char* str = BNGetLinuxCADirectory(); - string result = str; - BNFreeString(str); - return result; -} - - -string BinaryNinja::GetLinuxCABundlePath() -{ - char* str = BNGetLinuxCABundlePath(); - string result = str; - BNFreeString(str); - return result; -} diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 7a13118f..f2c15fde 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1022,6 +1022,25 @@ namespace BinaryNinja void Cancel(); }; + struct ActiveAnalysisInfo + { + Ref<Function> func; + uint64_t analysisTime; + size_t updateCount; + size_t submitCount; + + ActiveAnalysisInfo(Ref<Function> f, uint64_t t, size_t uc, size_t sc) : func(f), analysisTime(t), updateCount(uc), submitCount(sc) + { + } + }; + + struct AnalysisInfo + { + BNAnalysisState state; + uint64_t analysisTime; + std::vector<ActiveAnalysisInfo> activeInfo; + }; + struct DataVariable { DataVariable() { } @@ -1271,6 +1290,7 @@ namespace BinaryNinja Ref<AnalysisCompletionEvent> AddAnalysisCompletionEvent(const std::function<void()>& callback); + AnalysisInfo GetAnalysisInfo(); BNAnalysisProgress GetAnalysisProgress(); Ref<BackgroundTask> GetBackgroundAnalysisTask(); @@ -1350,6 +1370,8 @@ namespace BinaryNinja std::vector<uint8_t> GetRawMetadata(const std::string& key); uint64_t GetUIntMetadata(const std::string& key); + BNAnalysisParameters GetParametersForAnalysis(); + void SetParametersForAnalysis(BNAnalysisParameters params); uint64_t GetMaxFunctionSizeForAnalysis(); void SetMaxFunctionSizeForAnalysis(uint64_t size); }; @@ -2493,6 +2515,7 @@ namespace BinaryNinja bool IsFunctionTooLarge(); bool IsAnalysisSkipped(); + BNAnalysisSkipReason GetAnalysisSkipReason(); BNFunctionAnalysisSkipOverride GetAnalysisSkipOverride(); void SetAnalysisSkipOverride(BNFunctionAnalysisSkipOverride skip); }; @@ -3636,6 +3659,63 @@ namespace BinaryNinja const std::string& autoTypeSource = ""); }; + // DownloadProvider + class DownloadProvider; + + class DownloadInstance: public CoreRefCountObject<BNDownloadInstance, BNNewDownloadInstanceReference, BNFreeDownloadInstance> + { + protected: + DownloadInstance(DownloadProvider* provider); + DownloadInstance(BNDownloadInstance* instance); + + static void DestroyInstanceCallback(void* ctxt); + static int PerformRequestCallback(void* ctxt, const char* url); + + virtual void DestroyInstance(); + + public: + virtual int PerformRequest(const std::string& url) = 0; + + int PerformRequest(const std::string& url, BNDownloadInstanceOutputCallbacks* callbacks); + + std::string GetError() const; + void SetError(const std::string& error); + }; + + class CoreDownloadInstance: public DownloadInstance + { + public: + CoreDownloadInstance(BNDownloadInstance* instance); + + virtual int PerformRequest(const std::string& url) override; + }; + + class DownloadProvider: public StaticCoreRefCountObject<BNDownloadProvider> + { + std::string m_nameForRegister; + + protected: + DownloadProvider(const std::string& name); + DownloadProvider(BNDownloadProvider* provider); + + static BNDownloadInstance* CreateInstanceCallback(void* ctxt); + + public: + virtual Ref<DownloadInstance> CreateNewInstance() = 0; + + static std::vector<Ref<DownloadProvider>> GetList(); + static Ref<DownloadProvider> GetByName(const std::string& name); + static void Register(DownloadProvider* provider); + }; + + class CoreDownloadProvider: public DownloadProvider + { + public: + CoreDownloadProvider(BNDownloadProvider* provider); + virtual Ref<DownloadInstance> CreateNewInstance() override; + }; + + // Scripting Provider class ScriptingOutputListener { BNScriptingOutputListener m_callbacks; @@ -3994,7 +4074,4 @@ namespace BinaryNinja bool IsArray() const; bool IsKeyValueStore() const; }; - - std::string GetLinuxCADirectory(); - std::string GetLinuxCABundlePath(); } diff --git a/binaryninjacore.h b/binaryninjacore.h index e4d3a919..fda26d47 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -120,6 +120,8 @@ extern "C" struct BNArchitecture; struct BNFunction; struct BNBasicBlock; + struct BNDownloadProvider; + struct BNDownloadInstance; struct BNFunctionGraph; struct BNFunctionGraphBlock; struct BNSymbol; @@ -1474,7 +1476,24 @@ extern "C" { IdleState, DisassembleState, - AnalyzeState + AnalyzeState, + ExtendedAnalyzeState + }; + + struct BNActiveAnalysisInfo + { + BNFunction* func; + uint64_t analysisTime; + size_t updateCount; + size_t submitCount; + }; + + struct BNAnalysisInfo + { + BNAnalysisState state; + uint64_t analysisTime; + BNActiveAnalysisInfo* activeInfo; + size_t count; }; struct BNAnalysisProgress @@ -1483,6 +1502,36 @@ extern "C" size_t count, total; }; + struct BNAnalysisParameters + { + uint64_t maxAnalysisTime; + uint64_t maxFunctionSize; + uint64_t maxFunctionAnalysisTime; + size_t maxFunctionUpdateCount; + size_t maxFunctionSubmitCount; + }; + + struct BNDownloadInstanceOutputCallbacks + { + uint64_t (*writeCallback)(uint8_t* data, uint64_t len, void* ctxt); + void* writeContext; + bool (*progressCallback)(void* ctxt, uint64_t progress, uint64_t total); + void* progressContext; + }; + + struct BNDownloadInstanceCallbacks + { + void* context; + void (*destroyInstance)(void* ctxt); + int (*performRequest)(void* ctxt, const char* url); + }; + + struct BNDownloadProviderCallbacks + { + void* context; + BNDownloadInstance* (*createInstance)(void* ctxt); + }; + enum BNFindFlag { NoFindFlags = 0, @@ -1766,6 +1815,14 @@ extern "C" AlwaysSkipFunctionAnalysis }; + enum BNAnalysisSkipReason + { + NoSkipReason, + AlwaysSkipReason, + ExceedFunctionSizeSkipReason, + ExceedFunctionAnalysisTimeSkipReason + }; + BINARYNINJACOREAPI char* BNAllocString(const char* contents); BINARYNINJACOREAPI void BNFreeString(char* str); BINARYNINJACOREAPI char** BNAllocStringList(const char** contents, size_t size); @@ -2455,9 +2512,12 @@ extern "C" BINARYNINJACOREAPI bool BNIsFunctionTooLarge(BNFunction* func); BINARYNINJACOREAPI bool BNIsFunctionAnalysisSkipped(BNFunction* func); + BINARYNINJACOREAPI BNAnalysisSkipReason BNGetAnalysisSkipReason(BNFunction* func); BINARYNINJACOREAPI BNFunctionAnalysisSkipOverride BNGetFunctionAnalysisSkipOverride(BNFunction* func); BINARYNINJACOREAPI void BNSetFunctionAnalysisSkipOverride(BNFunction* func, BNFunctionAnalysisSkipOverride skip); + BINARYNINJACOREAPI BNAnalysisParameters BNGetParametersForAnalysis(BNBinaryView* view); + BINARYNINJACOREAPI void BNSetParametersForAnalysis(BNBinaryView* view, BNAnalysisParameters params); BINARYNINJACOREAPI uint64_t BNGetMaxFunctionSizeForAnalysis(BNBinaryView* view); BINARYNINJACOREAPI void BNSetMaxFunctionSizeForAnalysis(BNBinaryView* view, uint64_t size); @@ -2467,6 +2527,8 @@ extern "C" BINARYNINJACOREAPI void BNFreeAnalysisCompletionEvent(BNAnalysisCompletionEvent* event); BINARYNINJACOREAPI void BNCancelAnalysisCompletionEvent(BNAnalysisCompletionEvent* event); + BINARYNINJACOREAPI BNAnalysisInfo* BNGetAnalysisInfo(BNBinaryView* view); + BINARYNINJACOREAPI void BNFreeAnalysisInfo(BNAnalysisInfo* info); BINARYNINJACOREAPI BNAnalysisProgress BNGetAnalysisProgress(BNBinaryView* view); BINARYNINJACOREAPI BNBackgroundTask* BNGetBackgroundAnalysisTask(BNBinaryView* view); @@ -3195,6 +3257,24 @@ extern "C" char*** outVarName, size_t* outVarNameElements); + // Download providers + BINARYNINJACOREAPI BNDownloadProvider* BNRegisterDownloadProvider(const char* name, BNDownloadProviderCallbacks* callbacks); + BINARYNINJACOREAPI BNDownloadProvider** BNGetDownloadProviderList(size_t* count); + BINARYNINJACOREAPI void BNFreeDownloadProviderList(BNDownloadProvider** providers); + BINARYNINJACOREAPI BNDownloadProvider* BNGetDownloadProviderByName(const char* name); + + BINARYNINJACOREAPI char* BNGetDownloadProviderName(BNDownloadProvider* provider); + BINARYNINJACOREAPI BNDownloadInstance* BNCreateDownloadProviderInstance(BNDownloadProvider* provider); + + BINARYNINJACOREAPI BNDownloadInstance* BNInitDownloadInstance(BNDownloadProvider* provider, BNDownloadInstanceCallbacks* callbacks); + BINARYNINJACOREAPI BNDownloadInstance* BNNewDownloadInstanceReference(BNDownloadInstance* instance); + BINARYNINJACOREAPI void BNFreeDownloadInstance(BNDownloadInstance* instance); + BINARYNINJACOREAPI int BNPerformDownloadRequest(BNDownloadInstance* instance, const char* url, BNDownloadInstanceOutputCallbacks* callbacks); + BINARYNINJACOREAPI uint64_t BNWriteDataForDownloadInstance(BNDownloadInstance* instance, uint8_t* data, uint64_t len); + BINARYNINJACOREAPI bool BNNotifyProgressForDownloadInstance(BNDownloadInstance* instance, uint64_t progress, uint64_t total); + BINARYNINJACOREAPI char* BNGetErrorForDownloadInstance(BNDownloadInstance* instance); + BINARYNINJACOREAPI void BNSetErrorForDownloadInstance(BNDownloadInstance* instance, const char* error); + // Scripting providers BINARYNINJACOREAPI BNScriptingProvider* BNRegisterScriptingProvider(const char* name, BNScriptingProviderCallbacks* callbacks); @@ -3460,8 +3540,6 @@ extern "C" BINARYNINJACOREAPI BNMetadata* BNBinaryViewQueryMetadata(BNBinaryView* view, const char* key); BINARYNINJACOREAPI void BNBinaryViewRemoveMetadata(BNBinaryView* view, const char* key); - BINARYNINJACOREAPI char* BNGetLinuxCADirectory(); - BINARYNINJACOREAPI char* BNGetLinuxCABundlePath(); #ifdef __cplusplus } #endif diff --git a/binaryview.cpp b/binaryview.cpp index 0a9a7118..bebfb801 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -1014,6 +1014,21 @@ vector<Ref<Function>> BinaryView::GetAnalysisFunctionList() } +AnalysisInfo BinaryView::GetAnalysisInfo() +{ + AnalysisInfo result; + BNAnalysisInfo* info = BNGetAnalysisInfo(m_object); + result.state = info->state; + result.analysisTime = info->analysisTime; + result.activeInfo.reserve(info->count); + for (size_t i = 0; i < info->count; i++) + result.activeInfo.emplace_back(new Function(BNNewFunctionReference(info->activeInfo[i].func)), + info->activeInfo[i].analysisTime, info->activeInfo[i].submitCount, info->activeInfo[i].updateCount); + BNFreeAnalysisInfo(info); + return result; +} + + bool BinaryView::HasFunctions() const { return BNHasFunctions(m_object); @@ -1776,6 +1791,7 @@ bool BinaryView::GetSegmentAt(uint64_t addr, Segment& result) result.dataOffset = segment.dataOffset; result.dataLength = segment.dataLength; result.flags = segment.flags; + result.autoDefined = segment.autoDefined; return true; } @@ -1968,6 +1984,18 @@ uint64_t BinaryView::GetUIntMetadata(const string& key) } +BNAnalysisParameters BinaryView::GetParametersForAnalysis() +{ + return BNGetParametersForAnalysis(m_object); +} + + +void BinaryView::SetParametersForAnalysis(BNAnalysisParameters params) +{ + BNSetParametersForAnalysis(m_object, params); +} + + uint64_t BinaryView::GetMaxFunctionSizeForAnalysis() { return BNGetMaxFunctionSizeForAnalysis(m_object); diff --git a/binaryviewtype.cpp b/binaryviewtype.cpp index e8ef4f53..762b2de7 100644 --- a/binaryviewtype.cpp +++ b/binaryviewtype.cpp @@ -29,6 +29,8 @@ BNBinaryView* BinaryViewType::CreateCallback(void* ctxt, BNBinaryView* data) BinaryViewType* type = (BinaryViewType*)ctxt; Ref<BinaryView> view = new BinaryView(BNNewViewReference(data)); Ref<BinaryView> result = type->Create(view); + if (!result) + return nullptr; return BNNewViewReference(result->GetObject()); } diff --git a/docs/about/open-source.md b/docs/about/open-source.md index b0a35f37..be9725d0 100644 --- a/docs/about/open-source.md +++ b/docs/about/open-source.md @@ -22,13 +22,11 @@ The previous tools are used in the generation of our documentation, but are not * Core - [discount] ([discount license] - BSD) - - [libcurl] ([libcurl license] - MIT/X derivative) - [libgit2] ([libgit2 license] - GPLv2 with linking exception) - [libmspack] ([libmspack license] - LGPL, v2) - [llvm] ([llvm license] - BSD-style) - [lzf] ([lzf license] - BSD) - [jemalloc] ([jemalloc license] - BSD) - - [openssl] ([openssl license] - openssl license) - [sqlite] ([sqlite license] - public domain) - [zlib] ([zlib license] - zlib license) @@ -69,8 +67,6 @@ Please note that we offer no support for running Binary Ninja with modified Qt l [discount]: http://www.pell.portland.or.us/~orc/Code/discount/ [doxygen license]: https://github.com/doxygen/doxygen/blob/master/LICENSE [doxygen]: http://www.stack.nl/~dimitri/doxygen/ -[libcurl]: https://curl.haxx.se/ -[libcurl license]: https://curl.haxx.se/docs/copyright.html [libgit2]: https://libgit2.github.com/ [libgit2 license]: https://github.com/libgit2/libgit2/blob/master/COPYING [libmspack]: https://www.cabextract.org.uk/libmspack/ @@ -87,8 +83,6 @@ Please note that we offer no support for running Binary Ninja with modified Qt l [mkdocs]: http://www.mkdocs.org/ [opensans license]: http://www.apache.org/licenses/LICENSE-2.0.html [opensans]: https://www.google.com/fonts/specimen/Open+Sans -[openssl license]: https://www.openssl.org/source/license.html -[openssl]: https://www.openssl.org/ [qt license]: https://www.qt.io/qt-licensing-terms/ [qt]: https://www.qt.io/download/ [sourcecodepro license]: https://github.com/adobe-fonts/source-code-pro/blob/master/LICENSE.txt diff --git a/docs/getting-started.md b/docs/getting-started.md index e30a07fa..7e7e4acb 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -257,19 +257,20 @@ On windows, this is achieved through a separate launcher that loads first and re Settings are stored in the _user_ directory in the file `settings.json`. Each top level object in this file is represents a different plugin. As of build 860 the following settings are available: -|Plugin | Setting | Type | Default | Description | -|-------:|-------------------------:|-------------:|-----------------------------------------------:|:----------------------------------------------------------------------------------------------| -| core | linux\_ca\_bundle | string | "" | Certificate authority (.pem or .crt) file to be used for secure downloads | -| core | linux\_ca\_dir | string | "" | Certificate authority directory (for distributions without a CA bundle) | -| ui | activeContent | boolean | True | Allow Binary Ninja to connect to the web to check for updates | -| ui | colorblind | boolean | True | Choose colors that are visible to those with red/green colorblind | -| ui | debug | boolean | False | Enable developer debugging features (Additional views: Lifted IL, and SSA forms) | -| ui | recent-file-limit | integer | 10 | Specify limit for number of recent files | -| pdb | local-store-absolute | string | "" | Absolute path specifying where the pdb symbol store exists on this machine, overrides relative path | -| pdb | local-store-relative | string | "symbols" | Path *relative* to the binaryninja _user_ directory, sepcifying the pdb symbol store | -| pdb | auto-download-pdb | boolean | True | Automatically download pdb files from specified symbol servers | -| pdb | symbol-server-list | list(string) | ["http://msdl.microsoft.com/download/symbols"] | List of servers to query for pdb symbols. | -| python | interpreter | string | "python27.{dylib,dll,so.1}" | Python interpreter to load if one is not already present when plugins are loaded | +|Plugin | Setting | Type | Default | Description | +|----------:|-------------------------:|-------------:|-----------------------------------------------:|:----------------------------------------------------------------------------------------------| +| analysis | max-function-size | integer | 65536 | Any functions over this size will not be automatically analyzed and require manual override | +| core | linux\_ca\_bundle | string | "" | Certificate authority (.pem or .crt) file to be used for secure downloads | +| core | linux\_ca\_dir | string | "" | Certificate authority directory (for distributions without a CA bundle) | +| ui | activeContent | boolean | True | Allow Binary Ninja to connect to the web to check for updates | +| ui | colorblind | boolean | True | Choose colors that are visible to those with red/green colorblind | +| ui | debug | boolean | False | Enable developer debugging features (Additional views: Lifted IL, and SSA forms) | +| ui | recent-file-limit | integer | 10 | Specify limit for number of recent files | +| pdb | local-store-absolute | string | "" | Absolute path specifying where the pdb symbol store exists on this machine, overrides relative path | +| pdb | local-store-relative | string | "symbols" | Path *relative* to the binaryninja _user_ directory, sepcifying the pdb symbol store | +| pdb | auto-download-pdb | boolean | True | Automatically download pdb files from specified symbol servers | +| pdb | symbol-server-list | list(string) | ["http://msdl.microsoft.com/download/symbols"] | List of servers to query for pdb symbols. | +| python | interpreter | string | "python27.{dylib,dll,so.1}" | Python interpreter to load if one is not already present when plugins are loaded | Below is an example `settings.json` setting various options: ``` diff --git a/downloadprovider.cpp b/downloadprovider.cpp new file mode 100644 index 00000000..0e3483df --- /dev/null +++ b/downloadprovider.cpp @@ -0,0 +1,135 @@ +#include "binaryninjaapi.h" + +using namespace BinaryNinja; +using namespace std; + + +DownloadInstance::DownloadInstance(DownloadProvider* provider) +{ + BNDownloadInstanceCallbacks cb; + cb.context = this; + cb.destroyInstance = DestroyInstanceCallback; + cb.performRequest = PerformRequestCallback; + m_object = BNInitDownloadInstance(provider->GetObject(), &cb); +} + + +DownloadInstance::DownloadInstance(BNDownloadInstance* instance) +{ + m_object = instance; +} + + +void DownloadInstance::DestroyInstanceCallback(void* ctxt) +{ + DownloadInstance* instance = (DownloadInstance*)ctxt; + instance->DestroyInstance(); +} + + +int DownloadInstance::PerformRequestCallback(void* ctxt, const char* url) +{ + DownloadInstance* instance = (DownloadInstance*)ctxt; + return instance->PerformRequest(url); +} + + +string DownloadInstance::GetError() const +{ + char* str = BNGetErrorForDownloadInstance(m_object); + string result = str; + BNFreeString(str); + return result; +} + + +void DownloadInstance::SetError(const string& error) +{ + BNSetErrorForDownloadInstance(m_object, error.c_str()); +} + + +int DownloadInstance::PerformRequest(const string& url, BNDownloadInstanceOutputCallbacks* callbacks) +{ + return BNPerformDownloadRequest(m_object, url.c_str(), callbacks); +} + + +void DownloadInstance::DestroyInstance() +{ +} + + +CoreDownloadInstance::CoreDownloadInstance(BNDownloadInstance* instance): DownloadInstance(instance) +{ +} + + +int CoreDownloadInstance::PerformRequest(const std::string& url) +{ + (void)url; + return -1; +} + + +DownloadProvider::DownloadProvider(const string& name): m_nameForRegister(name) +{ +} + + +DownloadProvider::DownloadProvider(BNDownloadProvider* provider) +{ + m_object = provider; +} + + +BNDownloadInstance* DownloadProvider::CreateInstanceCallback(void* ctxt) +{ + DownloadProvider* provider = (DownloadProvider*)ctxt; + Ref<DownloadInstance> instance = provider->CreateNewInstance(); + return instance ? BNNewDownloadInstanceReference(instance->GetObject()) : nullptr; +} + + +vector<Ref<DownloadProvider>> DownloadProvider::GetList() +{ + size_t count; + BNDownloadProvider** list = BNGetDownloadProviderList(&count); + vector<Ref<DownloadProvider>> result; + for (size_t i = 0; i < count; i++) + result.push_back(new CoreDownloadProvider(list[i])); + BNFreeDownloadProviderList(list); + return result; +} + + +Ref<DownloadProvider> DownloadProvider::GetByName(const string& name) +{ + BNDownloadProvider* result = BNGetDownloadProviderByName(name.c_str()); + if (!result) + return nullptr; + return new CoreDownloadProvider(result); +} + + +void DownloadProvider::Register(DownloadProvider* provider) +{ + BNDownloadProviderCallbacks cb; + cb.context = provider; + cb.createInstance = CreateInstanceCallback; + provider->m_object = BNRegisterDownloadProvider(provider->m_nameForRegister.c_str(), &cb); +} + + +CoreDownloadProvider::CoreDownloadProvider(BNDownloadProvider* provider): DownloadProvider(provider) +{ +} + + +Ref<DownloadInstance> CoreDownloadProvider::CreateNewInstance() +{ + BNDownloadInstance* result = BNCreateDownloadProviderInstance(m_object); + if (!result) + return nullptr; + return new CoreDownloadInstance(result); +} diff --git a/function.cpp b/function.cpp index 835ab144..9c56c644 100644 --- a/function.cpp +++ b/function.cpp @@ -1372,6 +1372,12 @@ bool Function::IsAnalysisSkipped() } +BNAnalysisSkipReason Function::GetAnalysisSkipReason() +{ + return BNGetAnalysisSkipReason(m_object); +} + + BNFunctionAnalysisSkipOverride Function::GetAnalysisSkipOverride() { return BNGetFunctionAnalysisSkipOverride(m_object); diff --git a/python/__init__.py b/python/__init__.py index 729e4f8a..fda5f297 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -50,6 +50,7 @@ from .lineardisassembly import * from .undoaction import * from .highlight import * from .scriptingprovider import * +from .downloadprovider import * from .pluginmanager import * from .setting import * from .metadata import * diff --git a/python/binaryview.py b/python/binaryview.py index 81851c1f..1e078523 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -145,6 +145,27 @@ class AnalysisCompletionEvent(object): core.BNCancelAnalysisCompletionEvent(self.handle) +class ActiveAnalysisInfo(object): + def __init__(self, func, analysis_time, update_count, submit_count): + self.func = func + self.analysis_time = analysis_time + self.update_count = update_count + self.submit_count = submit_count + + def __repr__(self): + return "<ActiveAnalysisInfo %s, analysis_time %d, update_count %d, submit_count %d>" % (self.func, self.analysis_time, self.update_count, self.submit_count) + + +class AnalysisInfo(object): + def __init__(self, state, analysis_time, active_info): + self.state = AnalysisState(state) + self.analysis_time = analysis_time + self.active_info = active_info + + def __repr__(self): + return "<AnalysisInfo %s, analysis_time %d, active_info %s>" % (self.state, self.analysis_time, self.active_info) + + class AnalysisProgress(object): def __init__(self, state, count, total): self.state = state @@ -156,6 +177,8 @@ class AnalysisProgress(object): return "Disassembling (%d/%d)" % (self.count, self.total) if self.state == AnalysisState.AnalyzeState: return "Analyzing (%d/%d)" % (self.count, self.total) + if self.state == AnalysisState.ExtendedAnalyzeState: + return "Extended Analysis" return "Idle" def __repr__(self): @@ -939,6 +962,20 @@ class BinaryView(object): self.file.saved = value @property + def analysis_info(self): + """Relevant analysis information with list of functions under active analysis (read-only)""" + info_ref = core.BNGetAnalysisInfo(self.handle) + info = info_ref[0] + active_info_list = [] + for i in xrange(0, info.count): + func = function.Function(self, core.BNNewFunctionReference(info.activeInfo[i].func)) + active_info = ActiveAnalysisInfo(func, info.activeInfo[i].analysisTime, info.activeInfo[i].updateCount, info.activeInfo[i].submitCount) + active_info_list.append(active_info) + result = AnalysisInfo(info.state, info.analysisTime, active_info_list) + core.BNFreeAnalysisInfo(info_ref) + return result + + @property def analysis_progress(self): """Status of current analysis (read-only)""" result = core.BNGetAnalysisProgress(self.handle) @@ -1030,6 +1067,14 @@ class BinaryView(object): return function.RegisterValue(self.arch, result.value, confidence = result.confidence) @property + def parameters_for_analysis(self): + return core.BNGetParametersForAnalysis(self.handle) + + @parameters_for_analysis.setter + def parameters_for_analysis(self, params): + core.BNSetParametersForAnalysis(self.handle, params) + + @property def max_function_size_for_analysis(self): """Maximum size of function (sum of basic block sizes in bytes) for auto analysis""" return core.BNGetMaxFunctionSizeForAnalysis(self.handle) @@ -2725,6 +2770,8 @@ class BinaryView(object): if start is None: strings = core.BNGetStrings(self.handle, count) else: + if length is None: + length = self.end - start strings = core.BNGetStringsInRange(self.handle, start, length, count) result = [] for i in xrange(0, count.value): diff --git a/python/downloadprovider.py b/python/downloadprovider.py new file mode 100644 index 00000000..4756fd90 --- /dev/null +++ b/python/downloadprovider.py @@ -0,0 +1,210 @@ +# Copyright (c) 2015-2018 Vector 35 LLC +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + + +import abc +import code +import ctypes +import sys +import traceback + +try: + from urllib.parse import urlparse, urlencode + from urllib.request import urlopen, Request, build_opener, install_opener, ProxyHandler + from urllib.error import HTTPError, URLError +except ImportError: + from urlparse import urlparse + from urllib import urlencode + from urllib2 import urlopen, Request, build_opener, install_opener, ProxyHandler, HTTPError, URLError + +# Binary Ninja Components +import _binaryninjacore as core +from binaryninja.setting import Setting +import startup +import log + + +class DownloadInstance(object): + def __init__(self, provider, handle = None): + if handle is None: + self._cb = core.BNDownloadInstanceCallbacks() + self._cb.context = 0 + self._cb.destroyInstance = self._cb.destroyInstance.__class__(self._destroy_instance) + self._cb.performRequest = self._cb.performRequest.__class__(self._perform_request) + self.handle = core.BNInitDownloadInstance(provider.handle, self._cb) + else: + self.handle = core.handle_of_type(handle, core.BNDownloadInstance) + self._outputCallbacks = None + + def __del__(self): + core.BNFreeDownloadInstance(self.handle) + + def _destroy_instance(self, ctxt): + try: + self.perform_destroy_instance() + except: + log.log_error(traceback.format_exc()) + + def _perform_request(self, ctxt, url): + try: + return self.perform_request(ctxt, url) + except: + log.log_error(traceback.format_exc()) + return -1 + + @abc.abstractmethod + def perform_destroy_instance(self): + raise NotImplementedError + + @abc.abstractmethod + def perform_request(self, ctxt, url): + raise NotImplementedError + + def perform_request(self, url, callbacks): + return core.BNPerformDownloadRequest(self.handle, url, callbacks) + + +class _DownloadProviderMetaclass(type): + @property + def list(self): + """List all DownloadProvider types (read-only)""" + startup._init_plugins() + count = ctypes.c_ulonglong() + types = core.BNGetDownloadProviderList(count) + result = [] + for i in xrange(0, count.value): + result.append(DownloadProvider(types[i])) + core.BNFreeDownloadProviderList(types) + return result + + def __iter__(self): + startup._init_plugins() + count = ctypes.c_ulonglong() + types = core.BNGetDownloadProviderList(count) + try: + for i in xrange(0, count.value): + yield DownloadProvider(types[i]) + finally: + core.BNFreeDownloadProviderList(types) + + def __getitem__(self, value): + startup._init_plugins() + provider = core.BNGetDownloadProviderByName(str(value)) + if provider is None: + raise KeyError("'%s' is not a valid download provider" % str(value)) + return DownloadProvider(provider) + + def __setattr__(self, name, value): + try: + type.__setattr__(self, name, value) + except AttributeError: + raise AttributeError("attribute '%s' is read only" % name) + + +class DownloadProvider(object): + __metaclass__ = _DownloadProviderMetaclass + name = None + instance_class = None + _registered_providers = [] + + def __init__(self, handle = None): + if handle is not None: + self.handle = core.handle_of_type(handle, core.BNDownloadProvider) + self.__dict__["name"] = core.BNGetDownloadProviderName(handle) + + def register(self): + self._cb = core.BNDownloadProviderCallbacks() + self._cb.context = 0 + self._cb.createInstance = self._cb.createInstance.__class__(self._create_instance) + self.handle = core.BNRegisterDownloadProvider(self.__class__.name, self._cb) + self.__class__._registered_providers.append(self) + + def _create_instance(self, ctxt): + try: + result = self.__class__.instance_class(self) + if result is None: + return None + return ctypes.cast(core.BNNewDownloadInstanceReference(result.handle), ctypes.c_void_p).value + except: + log.log_error(traceback.format_exc()) + return None + + def create_instance(self): + result = core.BNCreateDownloadProviderInstance(self.handle) + if result is None: + return None + return DownloadInstance(self, handle = result) + + +class PythonDownloadInstance(DownloadInstance): + def __init__(self, provider): + super(PythonDownloadInstance, self).__init__(provider) + + @abc.abstractmethod + def perform_destroy_instance(self): + pass + + @abc.abstractmethod + def perform_request(self, ctxt, url): + try: + proxy_setting = Setting('download-client').get_string('https-proxy') + if proxy_setting: + opener = build_opener(ProxyHandler({'https': proxy_setting})) + install_opener(opener) + + r = urlopen(url) + total_size = int(r.headers.get('content-length', 0)) + bytes_sent = 0 + while True: + data = r.read(4096) + if not data: + break + raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data) + bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes)) + if bytes_wrote != len(raw_bytes): + core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!") + return -1 + bytes_sent = bytes_sent + bytes_wrote + continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_sent, total_size) + if continue_download is False: + core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!") + return -1 + + if not bytes_sent: + core.BNSetErrorForDownloadInstance(self.handle, "Received no data!") + return -1 + + except URLError as e: + core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) + return -1 + except: + core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") + log.log_error(traceback.format_exc()) + return -1 + + return 0 + + +class PythonDownloadProvider(DownloadProvider): + name = "DefaultDownloadProvider" + instance_class = PythonDownloadInstance + + +PythonDownloadProvider().register() diff --git a/python/function.py b/python/function.py index 6db44e6d..2f794f47 100644 --- a/python/function.py +++ b/python/function.py @@ -24,7 +24,7 @@ import ctypes # Binary Ninja components import _binaryninjacore as core -from enums import (FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType, +from enums import (AnalysisSkipReason, FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType, HighlightStandardColor, HighlightColorStyle, RegisterValueType, ImplicitRegisterExtend, DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext, VariableSourceType, FunctionAnalysisSkipOverride) @@ -828,6 +828,11 @@ class Function(object): """Whether automatic analysis was skipped for this function""" return core.BNIsFunctionAnalysisSkipped(self.handle) + @property + def analysis_skip_reason(self): + """Function analysis skip reason""" + return AnalysisSkipReason(core.BNGetAnalysisSkipReason(self.handle)) + @analysis_skipped.setter def analysis_skipped(self, skip): if skip: diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 34048704..bd1e9349 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -1809,8 +1809,9 @@ class LowLevelILFunction(object): param_list = [] for param in params: param_list.append(param.index) - return self.expr(LowLevelILOperation.LLIL_INTRINSIC, len(outputs), self.add_operand_list(output_list), - self.arch.get_intrinsic_index(intrinsic), len(params), self.add_operand_list(param_list), flags = flags) + call_param = self.expr(LowLevelILOperation.LLIL_CALL_PARAM, len(params), self.add_operand_list(param_list).index) + return self.expr(LowLevelILOperation.LLIL_INTRINSIC, len(outputs), self.add_operand_list(output_list).index, + self.arch.get_intrinsic_index(intrinsic), call_param.index, flags = flags) def breakpoint(self): """ diff --git a/python/pluginmanager.py b/python/pluginmanager.py index 2f293577..0cc43aca 100644 --- a/python/pluginmanager.py +++ b/python/pluginmanager.py @@ -32,6 +32,7 @@ class RepoPlugin(object): created by parsing the plugins.json in a plugin repository. """ def __init__(self, handle): + raise Exception("RepoPlugin temporarily disabled!") self.handle = core.handle_of_type(handle, core.BNRepoPlugin) def __del__(self): @@ -136,6 +137,7 @@ class Repository(object): ``Repository`` is a read-only class. Use RepositoryManager to Enable/Disable/Install/Uninstall plugins. """ def __init__(self, handle): + raise Exception("Repository temporarily disabled!") self.handle = core.handle_of_type(handle, core.BNRepository) def __del__(self): @@ -199,6 +201,7 @@ class RepositoryManager(object): the plugins that are installed/unstalled enabled/disabled """ def __init__(self, handle=None): + raise Exception("RepositoryManager temporarily disabled!") self.handle = core.BNGetRepositoryManager() def __getitem__(self, repo_path): diff --git a/themes/dark-blue.theme b/themes/dark-blue.theme new file mode 100644 index 00000000..b0f83598 --- /dev/null +++ b/themes/dark-blue.theme @@ -0,0 +1,108 @@ +{ + "name": "Dark Blue", + "style": "Fusion", + + "//": " Colors are specified as [Red, Green, Blue] values. Colors can be aliased in the 'colors' ", + "//": " section. Colors can also be averaged and mixed together using an RPN like notation: ", + "//": " '+' indicates 'average' - average the next two colors.", + "//": " '~' indicates 'mix' - mix the next two colors with the weight 0->255", + "//": " e.g.", + "//": " ['+', 'red', 'blue'] - average red and blue", + "//": " ['~', 'red', 'blue', 20] - mix a small amount of blue with red", + "//": " ['~', 'red', 'blue', 200] - mix a large amount of blue with red", + "//": " ['+', '~', 'red', 'blue', 20, 'green'] - mix red and blue with weight 20 then average with green", + "//": " The 'palette' section is to specify colors for the QPalette::ColorRole", + + "colors": { + "background": [0, 0, 42], + "backgroundDark": [0, 0, 30], + "backgroundWindow": [0, 0, 80], + "backgroundHighlight": [0, 0, 128], + "content": [224, 224, 224], + "disabled": [144, 144, 144], + "selection": [96, 96, 96], + "selectionLight": [128, 128, 128], + "green": [0, 255, 0], + "red": [222, 143, 151], + "blue": [128, 198, 233], + "cyan": [142, 230, 237], + "lightCyan": [176, 221, 228], + "orange": [237, 189, 129], + "yellow": [237, 223, 179], + "magenta": [218, 196, 209] + }, + + "palette": { + "Window": "backgroundWindow", + "WindowText": "content", + "Base": "backgroundDark", + "AlternateBase": "background", + "ToolTipBase": "backgroundHighlight", + "ToolTipText": "content", + "Text": "content", + "Button": "backgroundHighlight", + "ButtonText": "content", + "BrightText": "yellow", + "Link": "blue", + "Highlight": "blue", + "HighlightedText": "backgroundDark", + "Light": ["+", "backgroundDark", "content"] + }, + + "theme-colors": { + "addressColor": "green", + "modifiedColor": "red", + "insertedColor": "blue", + "notPresentColor": "disabled", + "selectionColor": "selection", + "outlineColor": "content", + "backgroundHighlightDarkColor": "backgroundDark", + "backgroundHighlightLightColor": "backgroundWindow", + "boldBackgroundHighlightDarkColor": "backgroundDark", + "boldBackgroundHighlightLightColor": "selection", + "alphanumericHighlightColor": "blue", + "printableHighlightColor": "lightCyan", + "graphBackgroundDarkColor": "background", + "graphBackgroundLightColor": "background", + "graphNodeDarkColor": "backgroundHighlight", + "graphNodeLightColor": "backgroundHighlight", + "graphNodeOutlineColor": "disabled", + "trueBranchColor": "green", + "falseBranchColor": "red", + "unconditionalBranchColor": "blue", + "altTrueBranchColor": "blue", + "altFalseBranchColor": "orange", + "altUnconditionalBranchColor": "content", + "registerColor": "yellow", + "numberColor": "green", + "codeSymbolColor": "blue", + "dataSymbolColor": "cyan", + "stackVariableColor": ["+", "green", "content"], + "importColor": "orange", + "instructionHighlightColor": "selectionLight", + "tokenHighlightColor": "red", + "annotationColor": "magenta", + "opcodeColor": "disabled", + "linearDisassemblyFunctionHeaderColor": "backgroundHighlight", + "linearDisassemblyBlockColor": "background", + "linearDisassemblyNoteColor": ["~", "+", "backgroundDark", "background", "green", 48], + "linearDisassemblySeparatorColor": "disabled", + "stringColor": "magenta", + "typeNameColor": "orange", + "fieldNameColor": "lightCyan", + "keywordColor": "yellow", + "uncertainColor": "disabled", + "scriptConsoleOutputColor": "content", + "scriptConsoleErrorColor": "red", + "scriptConsoleEchoColor": "disabled", + "blueStandardHighlightColor": "blue", + "greenStandardHighlightColor": "green", + "cyanStandardHighlightColor": "cyan", + "redStandardHighlightColor": "red", + "magentaStandardHighlightColor": "magenta", + "yellowStandardHighlightColor": "yellow", + "orangeStandardHighlightColor": "orange", + "whiteStandardHighlightColor": "content", + "blackStandardHighlightColor": [0,0,0] + } +}
\ No newline at end of file diff --git a/themes/high-contrast.theme b/themes/high-contrast.theme new file mode 100644 index 00000000..ecaf7c7c --- /dev/null +++ b/themes/high-contrast.theme @@ -0,0 +1,107 @@ +{ + "name": "High Contrast 2", + "style": "Fusion", + + "//": "Colors are specified as [Red, Green, Blue] values. Colors can be aliased in the", + "//": "'colors' section. Colors can also be averaged and mixed together using an RPN like notation.", + "//": "'+' indicates 'average' directs the parser to average the next two colors.", + "//": "'~' indicates 'mix' directs the parser to mix the next two colors with the specified weight 0->255", + "//": "e.g.", + "//": " ['+', 'red', 'blue'] - average red and blue", + "//": " ['~', 'red', 'blue', 20] - mix a small amount of blue into red", + "//": " ['+', '~', 'red', 'blue', 20, 'green'] - mix red and blue with weight 20 then average with green", + "//": "The 'palette' section is to specify colors for the QPalette::ColorRole", + + "colors": { + "background": [220, 220, 220], + "backgroundDark": [255, 255, 255], + "backgroundWindow": [240, 240, 240], + "backgroundHighlight": [255, 255, 255], + "content": [31, 31, 31], + "disabled": [122, 122, 122], + "selection": [159, 159, 159], + "selectionLight": [128, 128, 128], + "green": [48, 130, 13], + "red": [191, 38, 36], + "blue": [0, 164, 199], + "cyan": [39, 140, 173], + "lightCyan": [53, 218, 224], + "orange": [224, 124, 53], + "yellow": [141, 141, 45], + "magenta": [32, 54, 53] + }, + + "palette": { + "Window": "backgroundWindow", + "WindowText": "content", + "Base": "backgroundDark", + "AlternateBase": "background", + "ToolTipBase": "backgroundHighlight", + "ToolTipText": "content", + "Text": "content", + "Button": "backgroundHighlight", + "ButtonText": "content", + "BrightText": "magenta", + "Link": "blue", + "Highlight": "blue", + "HighlightedText": "backgroundDark", + "Light": ["+", "backgroundDark", "content"] + }, + + "theme-colors": { + "addressColor": "green", + "modifiedColor": "red", + "insertedColor": "blue", + "notPresentColor": "disabled", + "selectionColor": "selection", + "outlineColor": "content", + "backgroundHighlightDarkColor": "backgroundDark", + "backgroundHighlightLightColor": "backgroundWindow", + "boldBackgroundHighlightDarkColor": "backgroundDark", + "boldBackgroundHighlightLightColor": "selection", + "alphanumericHighlightColor": "blue", + "printableHighlightColor": "lightCyan", + "graphBackgroundDarkColor": "background", + "graphBackgroundLightColor": "background", + "graphNodeDarkColor": "backgroundHighlight", + "graphNodeLightColor": "backgroundHighlight", + "graphNodeOutlineColor": "disabled", + "trueBranchColor": "green", + "falseBranchColor": "red", + "unconditionalBranchColor": "blue", + "altTrueBranchColor": "blue", + "altFalseBranchColor": "orange", + "altUnconditionalBranchColor": "content", + "registerColor": "magenta", + "numberColor": "green", + "codeSymbolColor": "blue", + "dataSymbolColor": "cyan", + "stackVariableColor": ["+", "green", "content"], + "importColor": "orange", + "instructionHighlightColor": "selectionLight", + "tokenHighlightColor": "red", + "annotationColor": "red", + "opcodeColor": "disabled", + "linearDisassemblyFunctionHeaderColor": "backgroundHighlight", + "linearDisassemblyBlockColor": "background", + "linearDisassemblyNoteColor": ["~", "+", "backgroundDark", "background", "green", 48], + "linearDisassemblySeparatorColor": "disabled", + "stringColor": "magenta", + "typeNameColor": "orange", + "fieldNameColor": "lightCyan", + "keywordColor": "yellow", + "uncertainColor": "disabled", + "scriptConsoleOutputColor": "content", + "scriptConsoleErrorColor": "red", + "scriptConsoleEchoColor": "disabled", + "blueStandardHighlightColor": "blue", + "greenStandardHighlightColor": "green", + "cyanStandardHighlightColor": "cyan", + "redStandardHighlightColor": "red", + "magentaStandardHighlightColor": "magenta", + "yellowStandardHighlightColor": "yellow", + "orangeStandardHighlightColor": "orange", + "whiteStandardHighlightColor": "content", + "blackStandardHighlightColor": [0, 0, 0] + } +}
\ No newline at end of file diff --git a/themes/solarized-dark.theme b/themes/solarized-dark.theme new file mode 100644 index 00000000..5d1860f3 --- /dev/null +++ b/themes/solarized-dark.theme @@ -0,0 +1,104 @@ +{ + "name": "Solarized Dark 2", + "style": "Fusion", + + "//": "Colors are specified as [Red, Green, Blue] values. Colors can be aliased in the", + "//": "'colors' section. Colors can also be averaged and mixed together using an RPN like notation.", + "//": "'+' indicates 'average' directs the parser to average the next two colors.", + "//": "'~' indicates 'mix' directs the parser to mix the next two colors with the specified weight 0->255", + "//": "e.g.", + "//": " ['+', 'red', 'blue'] - average red and blue", + "//": " ['~', 'red', 'blue', 20] - mix a small amount of blue into red", + "//": " ['+', '~', 'red', 'blue', 20, 'green'] - mix red and blue with weight 20 then average with green", + "//": "The 'palette' section is to specify colors for the QPalette::ColorRole", + + "colors": { + "background": [0, 43, 54], + "backgroundHighlight": [7, 54, 66], + "content": [131, 148, 150], + "secondary": [88, 110, 117], + "emphasis": [147, 161, 161], + "yellow": [181, 137, 0], + "orange": [203, 75, 22], + "red": [220, 50, 47], + "magenta": [211, 54, 130], + "violet": [108, 113, 196], + "blue": [38, 139, 210], + "cyan": [42, 161, 152], + "green": [133, 153, 0] + }, + + "palette": { + "Window": "background", + "WindowText": "content", + "Base": "background", + "AlternateBase": "backgroundHighlight", + "ToolTipBase": "backgroundHighlight", + "ToolTipText": "content", + "Text": "content", + "Button": "backgroundHighlight", + "ButtonText": "content", + "BrightText": "emphasis", + "Link": "emphasis", + "Highlight": "backgroundHighlight", + "HighlightedText": "content", + "Light": ["+", "background", "content"] + }, + + "theme-colors": { + "addressColor": "secondary", + "modifiedColor": "red", + "insertedColor": "blue", + "notPresentColor": "secondary", + "selectionColor": ["+", "backgroundHighlight", "secondary"], + "outlineColor": "content", + "backgroundHighlightDarkColor": "background", + "backgroundHighlightLightColor": "backgroundHighlight", + "boldBackgroundHighlightDarkColor": "background", + "boldBackgroundHighlightLightColor": ["+", "background", "secondary"], + "alphanumericHighlightColor": "yellow", + "printableHighlightColor": "orange", + "graphBackgroundDarkColor": "background", + "graphBackgroundLightColor": "background", + "graphNodeDarkColor": "backgroundHighlight", + "graphNodeLightColor": "backgroundHighlight", + "graphNodeOutlineColor": "content", + "trueBranchColor": "green", + "falseBranchColor": "red", + "unconditionalBranchColor": "content", + "altTrueBranchColor": "blue", + "altFalseBranchColor": "yellow", + "altUnconditionalBranchColor": "content", + "registerColor": "green", + "numberColor": "cyan", + "codeSymbolColor": "blue", + "dataSymbolColor": "cyan", + "stackVariableColor": "violet", + "importColor": "orange", + "instructionHighlightColor": "secondary", + "tokenHighlightColor": ["+", "secondary", "orange"], + "annotationColor": "magenta", + "opcodeColor": "secondary", + "linearDisassemblyFunctionHeaderColor": "backgroundHighlight", + "linearDisassemblyBlockColor": ["+", "background", "backgroundHighlight"], + "linearDisassemblyNoteColor": ["~", "background", "green", 24], + "linearDisassemblySeparatorColor": [0, 0, 0], + "stringColor": "magenta", + "typeNameColor": "orange", + "fieldNameColor": "cyan", + "keywordColor": "green", + "uncertainColor": "secondary", + "scriptConsoleOutputColor": "content", + "scriptConsoleErrorColor": "red", + "scriptConsoleEchoColor": "secondary", + "blueStandardHighlightColor": "blue", + "greenStandardHighlightColor": "green", + "cyanStandardHighlightColor": "cyan", + "redStandardHighlightColor": "red", + "magentaStandardHighlightColor": "magenta", + "yellowStandardHighlightColor": "yellow", + "orangeStandardHighlightColor": "orange", + "whiteStandardHighlightColor": ["+", "background", [255, 255, 255]], + "blackStandardHighlightColor": "content" + } +}
\ No newline at end of file diff --git a/themes/solarized-light.theme b/themes/solarized-light.theme new file mode 100644 index 00000000..2799892b --- /dev/null +++ b/themes/solarized-light.theme @@ -0,0 +1,104 @@ +{ + "name": "Solarized Light 2", + "style": "Fusion", + + "//": "Colors are specified as [Red, Green, Blue] values. Colors can be aliased in the", + "//": "'colors' section. Colors can also be averaged and mixed together using an RPN like notation.", + "//": "'+' indicates 'average' directs the parser to average the next two colors.", + "//": "'~' indicates 'mix' directs the parser to mix the next two colors with the specified weight 0->255", + "//": "e.g.", + "//": " ['+', 'red', 'blue'] - average red and blue", + "//": " ['~', 'red', 'blue', 20] - mix a small amount of blue into red", + "//": " ['+', '~', 'red', 'blue', 20, 'green'] - mix red and blue with weight 20 then average with green", + "//": "The 'palette' section is to specify colors for the QPalette::ColorRole", + + "colors": { + "background": [253, 246, 227], + "backgroundHighlight": [238, 232, 213], + "content": [101, 123, 131], + "secondary": [147, 161, 161], + "emphasis": [88, 110, 117], + "yellow": [181, 137, 0], + "orange": [203, 75, 22], + "red": [220, 50, 47], + "magenta": [211, 54, 130], + "violet": [108, 113, 196], + "blue": [38, 139, 210], + "cyan": [42, 161, 152], + "green": [133, 153, 0] + }, + + "palette": { + "Window": "background", + "WindowText": "content", + "Base": "background", + "AlternateBase": "backgroundHighlight", + "ToolTipBase": "backgroundHighlight", + "ToolTipText": "content", + "Text": "content", + "Button": "backgroundHighlight", + "ButtonText": "content", + "BrightText": "emphasis", + "Link": "emphasis", + "Highlight": "backgroundHighlight", + "HighlightedText": "content", + "Light": ["+", "background", "content"] + }, + + "theme-colors": { + "addressColor": "secondary", + "modifiedColor": "red", + "insertedColor": "blue", + "notPresentColor": "secondary", + "selectionColor": ["+", "backgroundHighlight", "secondary"], + "outlineColor": "content", + "backgroundHighlightDarkColor": "background", + "backgroundHighlightLightColor": "backgroundHighlight", + "boldBackgroundHighlightDarkColor": "background", + "boldBackgroundHighlightLightColor": ["+", "background", "secondary"], + "alphanumericHighlightColor": "yellow", + "printableHighlightColor": "orange", + "graphBackgroundDarkColor": "background", + "graphBackgroundLightColor": "background", + "graphNodeDarkColor": "backgroundHighlight", + "graphNodeLightColor": "backgroundHighlight", + "graphNodeOutlineColor": "content", + "trueBranchColor": "green", + "falseBranchColor": "red", + "unconditionalBranchColor": "content", + "altTrueBranchColor": "blue", + "altFalseBranchColor": "yellow", + "altUnconditionalBranchColor": "content", + "registerColor": "green", + "numberColor": "cyan", + "codeSymbolColor": "blue", + "dataSymbolColor": "cyan", + "stackVariableColor": "violet", + "importColor": "orange", + "instructionHighlightColor": "secondary", + "tokenHighlightColor": ["+", "secondary", "orange"], + "annotationColor": "magenta", + "opcodeColor": "secondary", + "linearDisassemblyFunctionHeaderColor": "backgroundHighlight", + "linearDisassemblyBlockColor": ["+", "background", "backgroundHighlight"], + "linearDisassemblyNoteColor": ["~", "background", "green", 24], + "linearDisassemblySeparatorColor": [0, 0, 0], + "stringColor": "magenta", + "typeNameColor": "orange", + "fieldNameColor": "cyan", + "keywordColor": "green", + "uncertainColor": "secondary", + "scriptConsoleOutputColor": "content", + "scriptConsoleErrorColor": "red", + "scriptConsoleEchoColor": "secondary", + "blueStandardHighlightColor": "blue", + "greenStandardHighlightColor": "green", + "cyanStandardHighlightColor": "cyan", + "redStandardHighlightColor": "red", + "magentaStandardHighlightColor": "magenta", + "yellowStandardHighlightColor": "yellow", + "orangeStandardHighlightColor": "orange", + "whiteStandardHighlightColor": "content", + "blackStandardHighlightColor": ["+", "background", [0, 0, 0]] + } +}
\ No newline at end of file |
