diff options
| author | Rusty Wagner <rusty@vector35.com> | 2016-07-06 22:58:22 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2016-07-06 22:58:22 -0400 |
| commit | 05b8dae707da62437abf262fe8d1dd2b74a5f98f (patch) | |
| tree | 7a2ed3fff81d9e77da8c5b9c75c0e635e32a36c0 | |
| parent | a7eaa72caa4a5e3e7cd7ea7c32236c93b06d1442 (diff) | |
Add API to get disassembly text for a basic block outside of a graph
| -rw-r--r-- | basicblock.cpp | 74 | ||||
| -rw-r--r-- | binaryninjaapi.h | 39 | ||||
| -rw-r--r-- | binaryninjacore.h | 34 | ||||
| -rw-r--r-- | functiongraph.cpp | 14 | ||||
| -rw-r--r-- | functiongraphblock.cpp | 10 | ||||
| -rw-r--r-- | python/__init__.py | 199 |
6 files changed, 314 insertions, 56 deletions
diff --git a/basicblock.cpp b/basicblock.cpp index 5acf41d7..67ee1983 100644 --- a/basicblock.cpp +++ b/basicblock.cpp @@ -24,6 +24,54 @@ using namespace BinaryNinja; using namespace std; +DisassemblySettings::DisassemblySettings() +{ + m_object = BNCreateDisassemblySettings(); +} + + +DisassemblySettings::DisassemblySettings(BNDisassemblySettings* settings) +{ + m_object = settings; +} + + +bool DisassemblySettings::IsOptionSet(BNDisassemblyOption option) const +{ + return BNIsDisassemblySettingsOptionSet(m_object, option); +} + + +void DisassemblySettings::SetOption(BNDisassemblyOption option, bool state) +{ + BNSetDisassemblySettingsOption(m_object, option, state); +} + + +size_t DisassemblySettings::GetWidth() const +{ + return BNGetDisassemblyWidth(m_object); +} + + +void DisassemblySettings::SetWidth(size_t width) +{ + BNSetDisassemblyWidth(m_object, width); +} + + +size_t DisassemblySettings::GetMaximumSymbolWidth() const +{ + return BNGetDisassemblyMaximumSymbolWidth(m_object); +} + + +void DisassemblySettings::SetMaximumSymbolWidth(size_t width) +{ + BNSetDisassemblyMaximumSymbolWidth(m_object, width); +} + + BasicBlock::BasicBlock(BNBasicBlock* block) { m_object = block; @@ -96,3 +144,29 @@ vector<vector<InstructionTextToken>> BasicBlock::GetAnnotations() { return GetFunction()->GetBlockAnnotations(GetArchitecture(), GetStart()); } + + +vector<DisassemblyTextLine> BasicBlock::GetDisassemblyText(DisassemblySettings* settings) +{ + size_t count; + BNDisassemblyTextLine* lines = BNGetBasicBlockDisassemblyText(m_object, settings->GetObject(), &count); + + vector<DisassemblyTextLine> result; + for (size_t i = 0; i < count; i++) + { + DisassemblyTextLine line; + line.addr = lines[i].addr; + for (size_t j = 0; j < lines[i].count; j++) + { + InstructionTextToken token; + token.type = lines[i].tokens[j].type; + token.text = lines[i].tokens[j].text; + token.value = lines[i].tokens[j].value; + line.tokens.push_back(token); + } + result.push_back(line); + } + + BNFreeDisassemblyTextLines(lines, count); + return result; +} diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 3f0b1f4b..9e8f516c 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1380,6 +1380,28 @@ namespace BinaryNinja void AddMemberWithValue(const std::string& name, uint64_t value); }; + class DisassemblySettings: public CoreRefCountObject<BNDisassemblySettings, + BNNewDisassemblySettingsReference, BNFreeDisassemblySettings> + { + public: + DisassemblySettings(); + DisassemblySettings(BNDisassemblySettings* settings); + + bool IsOptionSet(BNDisassemblyOption option) const; + void SetOption(BNDisassemblyOption option, bool state = true); + + size_t GetWidth() const; + void SetWidth(size_t width); + size_t GetMaximumSymbolWidth() const; + void SetMaximumSymbolWidth(size_t width); + }; + + struct DisassemblyTextLine + { + uint64_t addr; + std::vector<InstructionTextToken> tokens; + }; + class Function; struct BasicBlockEdge @@ -1407,6 +1429,8 @@ namespace BinaryNinja void MarkRecentUse(); std::vector<std::vector<InstructionTextToken>> GetAnnotations(); + + std::vector<DisassemblyTextLine> GetDisassemblyText(DisassemblySettings* settings); }; struct StackVariable @@ -1527,12 +1551,6 @@ namespace BinaryNinja std::vector<std::vector<InstructionTextToken>> GetBlockAnnotations(Architecture* arch, uint64_t addr); }; - struct FunctionGraphTextLine - { - uint64_t addr; - std::vector<InstructionTextToken> tokens; - }; - struct FunctionGraphEdge { BNBranchType type; @@ -1555,7 +1573,7 @@ namespace BinaryNinja int GetWidth() const; int GetHeight() const; - std::vector<FunctionGraphTextLine> GetLines() const; + std::vector<DisassemblyTextLine> GetLines() const; std::vector<FunctionGraphEdge> GetOutgoingEdges() const; }; @@ -1578,8 +1596,7 @@ namespace BinaryNinja int GetVerticalBlockMargin() const; void SetBlockMargins(int horiz, int vert); - size_t GetMaximumSymbolWidth() const; - void SetMaximumSymbolWidth(size_t width); + Ref<DisassemblySettings> GetSettings(); void StartLayout(BNFunctionGraphType = NormalFunctionGraph); bool IsLayoutComplete(); @@ -1592,8 +1609,8 @@ namespace BinaryNinja int GetHeight() const; std::vector<Ref<FunctionGraphBlock>> GetBlocksInRegion(int left, int top, int right, int bottom); - bool IsOptionSet(BNFunctionGraphOption option) const; - void SetOption(BNFunctionGraphOption option, bool state = true); + bool IsOptionSet(BNDisassemblyOption option) const; + void SetOption(BNDisassemblyOption option, bool state = true); }; struct LowLevelILLabel: public BNLowLevelILLabel diff --git a/binaryninjacore.h b/binaryninjacore.h index 048255b1..805ff090 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -96,6 +96,7 @@ extern "C" struct BNCallingConvention; struct BNPlatform; struct BNAnalysisCompletionEvent; + struct BNDisassemblySettings; //! Console log levels enum BNLogLevel @@ -294,7 +295,7 @@ extern "C" LiftedILFunctionGraph = 2 }; - enum BNFunctionGraphOption + enum BNDisassemblyOption { ShowAddress = 0, @@ -572,7 +573,7 @@ extern "C" size_t pointCount; }; - struct BNFunctionGraphTextLine + struct BNDisassemblyTextLine { uint64_t addr; BNInstructionTextToken* tokens; @@ -1180,6 +1181,10 @@ extern "C" BINARYNINJACOREAPI void BNFreeBasicBlockOutgoingEdgeList(BNBasicBlockEdge* edges); BINARYNINJACOREAPI bool BNBasicBlockHasUndeterminedOutgoingEdges(BNBasicBlock* block); + BINARYNINJACOREAPI BNDisassemblyTextLine* BNGetBasicBlockDisassemblyText(BNBasicBlock* block, + BNDisassemblySettings* settings, size_t* count); + BINARYNINJACOREAPI void BNFreeDisassemblyTextLines(BNDisassemblyTextLine* lines, size_t count); + BINARYNINJACOREAPI void BNMarkFunctionAsRecentlyUsed(BNFunction* func); BINARYNINJACOREAPI void BNMarkBasicBlockAsRecentlyUsed(BNBasicBlock* block); @@ -1226,6 +1231,21 @@ extern "C" BINARYNINJACOREAPI BNAnalysisProgress BNGetAnalysisProgress(BNBinaryView* view); + // Disassembly settings + BINARYNINJACOREAPI BNDisassemblySettings* BNCreateDisassemblySettings(void); + BINARYNINJACOREAPI BNDisassemblySettings* BNNewDisassemblySettingsReference(BNDisassemblySettings* settings); + BINARYNINJACOREAPI void BNFreeDisassemblySettings(BNDisassemblySettings* settings); + + BINARYNINJACOREAPI bool BNIsDisassemblySettingsOptionSet(BNDisassemblySettings* settings, + BNDisassemblyOption option); + BINARYNINJACOREAPI void BNSetDisassemblySettingsOption(BNDisassemblySettings* settings, + BNDisassemblyOption option, bool state); + + BINARYNINJACOREAPI size_t BNGetDisassemblyWidth(BNDisassemblySettings* settings); + BINARYNINJACOREAPI void BNSetDisassemblyWidth(BNDisassemblySettings* settings, size_t width); + BINARYNINJACOREAPI size_t BNGetDisassemblyMaximumSymbolWidth(BNDisassemblySettings* settings); + BINARYNINJACOREAPI void BNSetDisassemblyMaximumSymbolWidth(BNDisassemblySettings* settings, size_t width); + // Function graph BINARYNINJACOREAPI BNFunctionGraph* BNCreateFunctionGraph(BNFunction* func); BINARYNINJACOREAPI BNFunctionGraph* BNNewFunctionGraphReference(BNFunctionGraph* graph); @@ -1236,8 +1256,7 @@ extern "C" BINARYNINJACOREAPI int BNGetVerticalFunctionGraphBlockMargin(BNFunctionGraph* graph); BINARYNINJACOREAPI void BNSetFunctionGraphBlockMargins(BNFunctionGraph* graph, int horiz, int vert); - BINARYNINJACOREAPI size_t BNGetFunctionGraphMaximumSymbolWidth(BNFunctionGraph* graph); - BINARYNINJACOREAPI void BNSetFunctionGraphMaximumSymbolWidth(BNFunctionGraph* graph, size_t width); + BINARYNINJACOREAPI BNDisassemblySettings* BNGetFunctionGraphSettings(BNFunctionGraph* graph); BINARYNINJACOREAPI void BNStartFunctionGraphLayout(BNFunctionGraph* graph, BNFunctionGraphType type); BINARYNINJACOREAPI bool BNIsFunctionGraphLayoutComplete(BNFunctionGraph* graph); @@ -1253,8 +1272,8 @@ extern "C" BINARYNINJACOREAPI int BNGetFunctionGraphWidth(BNFunctionGraph* graph); BINARYNINJACOREAPI int BNGetFunctionGraphHeight(BNFunctionGraph* graph); - BINARYNINJACOREAPI bool BNIsFunctionGraphOptionSet(BNFunctionGraph* graph, BNFunctionGraphOption option); - BINARYNINJACOREAPI void BNSetFunctionGraphOption(BNFunctionGraph* graph, BNFunctionGraphOption option, bool state); + BINARYNINJACOREAPI bool BNIsFunctionGraphOptionSet(BNFunctionGraph* graph, BNDisassemblyOption option); + BINARYNINJACOREAPI void BNSetFunctionGraphOption(BNFunctionGraph* graph, BNDisassemblyOption option, bool state); BINARYNINJACOREAPI BNFunctionGraphBlock* BNNewFunctionGraphBlockReference(BNFunctionGraphBlock* block); BINARYNINJACOREAPI void BNFreeFunctionGraphBlock(BNFunctionGraphBlock* block); @@ -1267,8 +1286,7 @@ extern "C" BINARYNINJACOREAPI int BNGetFunctionGraphBlockWidth(BNFunctionGraphBlock* block); BINARYNINJACOREAPI int BNGetFunctionGraphBlockHeight(BNFunctionGraphBlock* block); - BINARYNINJACOREAPI BNFunctionGraphTextLine* BNGetFunctionGraphBlockLines(BNFunctionGraphBlock* block, size_t* count); - BINARYNINJACOREAPI void BNFreeFunctionGraphBlockLines(BNFunctionGraphTextLine* lines, size_t count); + BINARYNINJACOREAPI BNDisassemblyTextLine* BNGetFunctionGraphBlockLines(BNFunctionGraphBlock* block, size_t* count); BINARYNINJACOREAPI BNFunctionGraphEdge* BNGetFunctionGraphBlockOutgoingEdges(BNFunctionGraphBlock* block, size_t* count); BINARYNINJACOREAPI void BNFreeFunctionGraphBlockOutgoingEdgeList(BNFunctionGraphEdge* edges, size_t count); diff --git a/functiongraph.cpp b/functiongraph.cpp index 3d8d83da..93f60f63 100644 --- a/functiongraph.cpp +++ b/functiongraph.cpp @@ -70,15 +70,9 @@ void FunctionGraph::SetBlockMargins(int horiz, int vert) } -size_t FunctionGraph::GetMaximumSymbolWidth() const +Ref<DisassemblySettings> FunctionGraph::GetSettings() { - return BNGetFunctionGraphMaximumSymbolWidth(m_graph); -} - - -void FunctionGraph::SetMaximumSymbolWidth(size_t width) -{ - BNSetFunctionGraphMaximumSymbolWidth(m_graph, width); + return new DisassemblySettings(BNGetFunctionGraphSettings(m_graph)); } @@ -150,13 +144,13 @@ vector<Ref<FunctionGraphBlock>> FunctionGraph::GetBlocksInRegion(int left, int t } -bool FunctionGraph::IsOptionSet(BNFunctionGraphOption option) const +bool FunctionGraph::IsOptionSet(BNDisassemblyOption option) const { return BNIsFunctionGraphOptionSet(m_graph, option); } -void FunctionGraph::SetOption(BNFunctionGraphOption option, bool state) +void FunctionGraph::SetOption(BNDisassemblyOption option, bool state) { BNSetFunctionGraphOption(m_graph, option, state); } diff --git a/functiongraphblock.cpp b/functiongraphblock.cpp index 6ad86646..8d327cd0 100644 --- a/functiongraphblock.cpp +++ b/functiongraphblock.cpp @@ -72,15 +72,15 @@ int FunctionGraphBlock::GetHeight() const } -vector<FunctionGraphTextLine> FunctionGraphBlock::GetLines() const +vector<DisassemblyTextLine> FunctionGraphBlock::GetLines() const { size_t count; - BNFunctionGraphTextLine* lines = BNGetFunctionGraphBlockLines(m_object, &count); + BNDisassemblyTextLine* lines = BNGetFunctionGraphBlockLines(m_object, &count); - vector<FunctionGraphTextLine> result; + vector<DisassemblyTextLine> result; for (size_t i = 0; i < count; i++) { - FunctionGraphTextLine line; + DisassemblyTextLine line; line.addr = lines[i].addr; for (size_t j = 0; j < lines[i].count; j++) { @@ -93,7 +93,7 @@ vector<FunctionGraphTextLine> FunctionGraphBlock::GetLines() const result.push_back(line); } - BNFreeFunctionGraphBlockLines(lines, count); + BNFreeDisassemblyTextLines(lines, count); return result; } diff --git a/python/__init__.py b/python/__init__.py index e07bd7c5..0c983fe2 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -553,6 +553,16 @@ class _BinaryViewTypeMetaclass(type): core.BNFreeBinaryViewTypeList(types) return result + def __iter__(self): + _init_plugins() + count = ctypes.c_ulonglong() + types = core.BNGetBinaryViewTypes(count) + try: + for i in xrange(0, count.value): + yield BinaryViewType(types[i]) + finally: + core.BNFreeBinaryViewTypeList(types) + def __getitem__(self, value): _init_plugins() view_type = core.BNGetBinaryViewTypeByName(str(value)) @@ -787,6 +797,15 @@ class BinaryView(object): i._unregister() core.BNFreeBinaryView(self.handle) + def __iter__(self): + count = ctypes.c_ulonglong(0) + funcs = core.BNGetAnalysisFunctionList(self.handle, count) + try: + for i in xrange(0, count.value): + yield Function(self, core.BNNewFunctionReference(funcs[i])) + finally: + core.BNFreeFunctionList(funcs, count.value) + @property def modified(self): return self.file.modified @@ -2305,10 +2324,11 @@ class Function(object): def __iter__(self): count = ctypes.c_ulonglong() blocks = core.BNGetFunctionBasicBlockList(self.handle, count) - for i in xrange(0, count.value): - yield BasicBlock(self._view, core.BNNewBasicBlockReference(blocks[i])) - core.BNFreeBasicBlockList(blocks, count.value) - raise StopIteration + try: + for i in xrange(0, count.value): + yield BasicBlock(self._view, core.BNNewBasicBlockReference(blocks[i])) + finally: + core.BNFreeBasicBlockList(blocks, count.value) def __setattr__(self, name, value): try: @@ -2615,6 +2635,10 @@ class BasicBlock(object): """List of automatic annotations for the start of this block (read-only)""" return self.function.get_block_annotations(self.arch, self.start) + @property + def disassembly_text(self): + return self.get_disassembly_text() + def __setattr__(self, name, value): try: object.__setattr__(self,name,value) @@ -2643,11 +2667,30 @@ class BasicBlock(object): yield inst_text idx += inst_info.length - raise StopIteration - def mark_recent_use(): + def mark_recent_use(self): core.BNMarkBasicBlockAsRecentlyUsed(self.handle) + def get_disassembly_text(self, settings = None): + settings_obj = None + if settings: + settings_obj = settings.handle + + count = ctypes.c_ulonglong() + lines = core.BNGetBasicBlockDisassemblyText(self.handle, settings_obj, count) + result = [] + for i in xrange(0, count.value): + addr = lines[i].addr + tokens = [] + for j in xrange(0, lines[i].count): + token_type = core.BNInstructionTextTokenType_names[lines[i].tokens[j].type] + text = lines[i].tokens[j].text + value = lines[i].tokens[j].value + tokens.append(InstructionTextToken(token_type, text, value)) + result.append(DisassemblyTextLine(addr, tokens)) + core.BNFreeDisassemblyTextLines(lines, count.value) + return result + class LowLevelILBasicBlock(BasicBlock): def __init__(self, view, handle, owner): super(LowLevelILBasicBlock, self).__init__(view, handle) @@ -2656,9 +2699,8 @@ class LowLevelILBasicBlock(BasicBlock): def __iter__(self): for idx in xrange(self.start, self.end): yield self.il_function[idx] - raise StopIteration -class FunctionGraphTextLine: +class DisassemblyTextLine: def __init__(self, addr, tokens): self.address = addr self.tokens = tokens @@ -2743,8 +2785,8 @@ class FunctionGraphBlock(object): text = lines[i].tokens[j].text value = lines[i].tokens[j].value tokens.append(InstructionTextToken(token_type, text, value)) - result.append(FunctionGraphTextLine(addr, tokens)) - core.BNFreeFunctionGraphBlockLines(lines, count.value) + result.append(DisassemblyTextLine(addr, tokens)) + core.BNFreeDisassemblyTextLines(lines, count.value) return result @property @@ -2779,6 +2821,58 @@ class FunctionGraphBlock(object): else: return "<graph block: %#x-%#x>" % (self.start, self.end) + def __iter__(self): + count = ctypes.c_ulonglong() + lines = core.BNGetFunctionGraphBlockLines(self.handle, count) + try: + for i in xrange(0, count.value): + addr = lines[i].addr + tokens = [] + for j in xrange(0, lines[i].count): + token_type = core.BNInstructionTextTokenType_names[lines[i].tokens[j].type] + text = lines[i].tokens[j].text + value = lines[i].tokens[j].value + tokens.append(InstructionTextToken(token_type, text, value)) + yield DisassemblyTextLine(addr, tokens) + finally: + core.BNFreeDisassemblyTextLines(lines, count.value) + +class DisassemblySettings(object): + def __init__(self, handle = None): + if handle is None: + self.handle = core.BNCreateDisassemblySettings() + else: + self.handle = handle + + def __del__(self): + core.BNFreeDisassemblySettings(self.handle) + + @property + def width(self): + return core.BNGetDisassemblyWidth(self.handle) + + @width.setter + def width(self, value): + core.BNSetDisassemblyWidth(self.handle, value) + + @property + def max_symbol_width(self): + return core.BNGetDisassemblyMaximumSymbolWidth(self.handle) + + @max_symbol_width.setter + def max_symbol_width(self, value): + core.BNSetDisassemblyMaximumSymbolWidth(self.handle, value) + + def is_option_set(self, option): + if isinstance(option, str): + option = core.BNDisassemblyOption_by_name(option) + return core.BNIsDisassemblySettingsOptionSet(self.handle, option) + + def set_option(self, option, state = True): + if isinstance(option, str): + option = core.BNDisassemblyOption_by_name(option) + core.BNSetDisassemblySettingsOption(self.handle, option, state) + class FunctionGraph(object): def __init__(self, view, handle): self.view = view @@ -2846,12 +2940,8 @@ class FunctionGraph(object): core.BNSetFunctionGraphBlockMargins(self.handle, self.horizontal_block_margin, value) @property - def max_symbol_width(self): - return core.BNGetFunctionGraphMaximumSymbolWidth(self.handle) - - @max_symbol_width.setter - def max_symbol_width(self, value): - core.BNSetFunctionGraphMaximumSymbolWidth(self.handle, value) + def settings(self): + return DisassemblySettings(core.BNGetFunctionGraphSettings(self.handle)) def __setattr__(self, name, value): try: @@ -2862,6 +2952,15 @@ class FunctionGraph(object): def __repr__(self): return "<graph of %s>" % repr(self.function) + def __iter__(self): + count = ctypes.c_ulonglong() + blocks = core.BNGetFunctionGraphBlocks(self.handle, count) + try: + for i in xrange(0, count.value): + yield FunctionGraphBlock(core.BNNewFunctionGraphBlockReference(blocks[i])) + finally: + core.BNFreeFunctionGraphBlockList(blocks, count.value) + def _complete(self, ctxt): try: if self._on_complete is not None: @@ -2907,12 +3006,12 @@ class FunctionGraph(object): def is_option_set(self, option): if isinstance(option, str): - option = core.BNFunctionGraphOption_by_name(option) + option = core.BNDisassemblyOption_by_name(option) return core.BNIsFunctionGraphOptionSet(self.handle, option) def set_option(self, option, state = True): if isinstance(option, str): - option = core.BNFunctionGraphOption_by_name(option) + option = core.BNDisassemblyOption_by_name(option) core.BNSetFunctionGraphOption(self.handle, option, state) class RegisterInfo: @@ -2986,6 +3085,16 @@ class _ArchitectureMetaClass(type): core.BNFreeArchitectureList(archs) return result + def __iter__(self): + _init_plugins() + count = ctypes.c_ulonglong() + archs = core.BNGetArchitectureList(count) + try: + for i in xrange(0, count.value): + yield Architecture(archs[i]) + finally: + core.BNFreeArchitectureList(archs) + def __getitem__(cls, name): _init_plugins() arch = core.BNGetArchitectureByName(name) @@ -4218,10 +4327,11 @@ class LowLevelILFunction(object): view = None if self.source_function is not None: view = self.source_function.view - for i in xrange(0, count.value): - yield LowLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self) - core.BNFreeBasicBlockList(blocks, count.value) - raise StopIteration + try: + for i in xrange(0, count.value): + yield LowLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self) + finally: + core.BNFreeBasicBlockList(blocks, count.value) def clear_indirect_branches(self): core.BNLowLevelILClearIndirectBranches(self.handle) @@ -4509,6 +4619,16 @@ class _TransformMetaClass(type): core.BNFreeTransformTypeList(xforms) return result + def __iter__(self): + _init_plugins() + count = ctypes.c_ulonglong() + xforms = core.BNGetTransformTypeList(count) + try: + for i in xrange(0, count.value): + yield Transform(xforms[i]) + finally: + core.BNFreeTransformTypeList(xforms) + def __setattr__(self, name, value): try: type.__setattr__(self,name,value) @@ -4740,6 +4860,21 @@ class _UpdateChannelMetaClass(type): def active(self, value): return core.BNSetActiveUpdateChannel(value) + def __iter__(self): + _init_plugins() + count = ctypes.c_ulonglong() + errors = ctypes.c_char_p() + channels = core.BNGetUpdateChannels(count, errors) + if errors: + error_str = errors.value + core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) + raise IOError, error_str + try: + for i in xrange(0, count.value): + yield UpdateChannel(channels[i].name, channels[i].description, channels[i].latestVersion) + finally: + core.BNFreeUpdateChannelList(channels, count.value) + def __setattr__(self, name, value): try: type.__setattr__(self,name,value) @@ -4895,6 +5030,16 @@ class _PluginCommandMetaClass(type): core.BNFreePluginCommandList(commands) return result + def __iter__(self): + _init_plugins() + count = ctypes.c_ulonglong() + commands = core.BNGetAllPluginCommands(count) + try: + for i in xrange(0, count.value): + yield PluginCommand(commands[i]) + finally: + core.BNFreePluginCommandList(commands) + def __setattr__(self, name, value): try: type.__setattr__(self,name,value) @@ -5286,6 +5431,16 @@ class _PlatformMetaClass(type): core.BNFreePlatformOSList(platforms, count.value) return result + def __iter__(self): + _init_plugins() + count = ctypes.c_ulonglong() + platforms = core.BNGetPlatformList(count) + try: + for i in xrange(0, count.value): + yield Platform(None, core.BNNewPlatformReference(platforms[i])) + finally: + core.BNFreePlatformList(platforms, count.value) + def __setattr__(self, name, value): try: type.__setattr__(self,name,value) |
