11import ctypes
22import dataclasses
3+ from typing import Optional
34
45import binaryninja
56from binaryninja import BinaryView
@@ -22,7 +23,7 @@ def __str__(self):
2223 return repr (self )
2324
2425 def __repr__ (self ):
25- return f"<CacheRegion '{ self .name } ': { self .start :x} + { self .size :x} >"
26+ return f"<CacheRegion '{ self .name } ': 0x { self .start :x} + { self .size :x} >"
2627
2728@dataclasses .dataclass
2829class CacheImage :
@@ -34,7 +35,19 @@ def __str__(self):
3435 return repr (self )
3536
3637 def __repr__ (self ):
37- return f"<CacheImage '{ self .name } ': { self .header_address :x} >"
38+ return f"<CacheImage '{ self .name } ': 0x{ self .header_address :x} >"
39+
40+ @dataclasses .dataclass
41+ class CacheSymbol :
42+ symbol_type : sccore .SymbolTypeEnum
43+ address : int
44+ name : str
45+
46+ def __str__ (self ):
47+ return repr (self )
48+
49+ def __repr__ (self ):
50+ return f"<CacheSymbol '{ self .name } ': 0x{ self .address :x} >"
3851
3952def region_from_api (region : sccore .BNSharedCacheRegion ) -> CacheRegion :
4053 return CacheRegion (
@@ -57,21 +70,39 @@ def region_to_api(region: CacheRegion) -> sccore.BNSharedCacheRegion:
5770 )
5871
5972def image_from_api (image : sccore .BNSharedCacheImage ) -> CacheImage :
73+ region_starts = []
74+ for i in range (image .regionStartCount ):
75+ region_starts .append (image .regionStarts [i ])
6076 return CacheImage (
61- image .name ,
62- image .headerAddress ,
63- image . regionStarts
77+ name = image .name ,
78+ header_address = image .headerAddress ,
79+ region_starts = region_starts
6480 )
6581
6682def image_to_api (image : CacheImage ) -> sccore .BNSharedCacheImage :
67- region_start_array = (ctypes .POINTER ( ctypes . c_ulonglong ) * len (image .region_starts ))()
83+ region_start_array = (ctypes .c_ulonglong * len (image .region_starts ))()
6884 for i , region_start in enumerate (image .region_starts ):
69- region_start_array [i ] = ctypes .c_ulonglong (region_start )
85+ region_start_array [i ] = region_start
86+ core_region_starts = sccore .BNSharedCacheAllocRegionList (region_start_array , len (region_start_array ))
7087 return sccore .BNSharedCacheImage (
7188 _name = BNAllocString (image .name ),
7289 headerAddress = image .header_address ,
7390 regionStartCount = len (region_start_array ),
74- regionStarts = region_start_array
91+ regionStarts = core_region_starts
92+ )
93+
94+ def symbol_from_api (symbol : sccore .BNSharedCacheSymbol ) -> CacheSymbol :
95+ return CacheSymbol (
96+ symbol_type = symbol .symbolType ,
97+ address = symbol .address ,
98+ name = symbol .name
99+ )
100+
101+ def symbol_to_api (symbol : CacheSymbol ) -> sccore .BNSharedCacheSymbol :
102+ return sccore .BNSharedCacheSymbol (
103+ symbolType = symbol .symbol_type ,
104+ address = symbol .address ,
105+ _name = BNAllocString (symbol .name )
75106 )
76107
77108class SharedCacheController :
@@ -90,6 +121,74 @@ def load_image(self, view: BinaryView, image: CacheImage) -> bool:
90121 sccore .BNSharedCacheFreeImage (api_image )
91122 return result
92123
124+ def is_region_loaded (self , region : CacheRegion ) -> bool :
125+ api_region : sccore .BNSharedCacheRegion = region_to_api (region )
126+ result = sccore .BNSharedCacheControllerIsRegionLoaded (self .handle , api_region )
127+ sccore .BNSharedCacheFreeRegion (api_region )
128+ return result
129+
130+ def is_image_loaded (self , image : CacheImage ) -> bool :
131+ api_image : sccore .BNSharedCacheImage = image_to_api (image )
132+ result = sccore .BNSharedCacheControllerIsImageLoaded (self .handle , api_image )
133+ sccore .BNSharedCacheFreeImage (api_image )
134+ return result
135+
136+ def get_region_at (self , address : int ) -> Optional [CacheRegion ]:
137+ api_region = sccore .BNSharedCacheRegion ()
138+ if not sccore .BNSharedCacheControllerGetRegionAt (self .handle , address , api_region ):
139+ return None
140+ region = region_from_api (api_region )
141+ sccore .BNSharedCacheFreeRegion (api_region )
142+ return region
143+
144+ def get_region_containing (self , address : int ) -> Optional [CacheRegion ]:
145+ api_region = sccore .BNSharedCacheRegion ()
146+ if not sccore .BNSharedCacheControllerGetRegionContaining (self .handle , address , api_region ):
147+ return None
148+ region = region_from_api (api_region )
149+ sccore .BNSharedCacheFreeRegion (api_region )
150+ return region
151+
152+ def get_image_at (self , address : int ) -> Optional [CacheImage ]:
153+ api_image = sccore .BNSharedCacheImage ()
154+ if not sccore .BNSharedCacheControllerGetImageAt (self .handle , address , api_image ):
155+ return None
156+ image = image_from_api (api_image )
157+ sccore .BNSharedCacheFreeImage (api_image )
158+ return image
159+
160+ def get_image_containing (self , address : int ) -> Optional [CacheImage ]:
161+ api_image = sccore .BNSharedCacheImage ()
162+ if not sccore .BNSharedCacheControllerGetImageContaining (self .handle , address , api_image ):
163+ return None
164+ image = image_from_api (api_image )
165+ sccore .BNSharedCacheFreeImage (api_image )
166+ return image
167+
168+ def get_image_with_name (self , name : str ) -> Optional [CacheImage ]:
169+ api_image = sccore .BNSharedCacheImage ()
170+ if not sccore .BNSharedCacheControllerGetImageWithName (self .handle , name , api_image ):
171+ return None
172+ image = image_from_api (api_image )
173+ sccore .BNSharedCacheFreeImage (api_image )
174+ return image
175+
176+ def get_image_dependencies (self , image : CacheImage ) -> [str ]:
177+ """
178+ Returns a list of image names that this image depends on.
179+ """
180+ count = ctypes .c_ulonglong ()
181+ api_image : sccore .BNSharedCacheImage = image_to_api (image )
182+ value = sccore .BNSharedCacheControllerGetImageDependencies (self .handle , api_image , count )
183+ sccore .BNSharedCacheFreeImage (api_image )
184+ if value is None :
185+ return []
186+ result = []
187+ for i in range (count .value ):
188+ result .append (value [i ].decode ("utf-8" ))
189+ BNFreeStringList (value , count )
190+ return result
191+
93192 @property
94193 def regions (self ) -> [CacheRegion ]:
95194 count = ctypes .c_ulonglong ()
@@ -102,6 +201,21 @@ def regions(self) -> [CacheRegion]:
102201 sccore .BNSharedCacheFreeRegionList (value , count )
103202 return result
104203
204+ @property
205+ def loaded_regions (self ) -> [CacheRegion ]:
206+ """
207+ Get a list of regions that are currently loaded in the view.
208+ """
209+ count = ctypes .c_ulonglong ()
210+ value = sccore .BNSharedCacheControllerGetLoadedRegions (self .handle , count )
211+ if value is None :
212+ return []
213+ result = []
214+ for i in range (count .value ):
215+ result .append (region_from_api (value [i ]))
216+ sccore .BNSharedCacheFreeRegionList (value , count )
217+ return result
218+
105219 @property
106220 def images (self ) -> [CacheImage ]:
107221 count = ctypes .c_ulonglong ()
@@ -113,5 +227,32 @@ def images(self) -> [CacheImage]:
113227 result .append (image_from_api (value [i ]))
114228 sccore .BNSharedCacheFreeImageList (value , count )
115229 return result
230+
231+ @property
232+ def loaded_images (self ) -> [CacheImage ]:
233+ """
234+ Get a list of images that are currently loaded in the view.
235+ """
236+ count = ctypes .c_ulonglong ()
237+ value = sccore .BNSharedCacheControllerGetLoadedImages (self .handle , count )
238+ if value is None :
239+ return []
240+ result = []
241+ for i in range (count .value ):
242+ result .append (image_from_api (value [i ]))
243+ sccore .BNSharedCacheFreeImageList (value , count )
244+ return result
245+
246+ @property
247+ def symbols (self ) -> [CacheSymbol ]:
248+ count = ctypes .c_ulonglong ()
249+ value = sccore .BNSharedCacheControllerGetSymbols (self .handle , count )
250+ if value is None :
251+ return []
252+ result = []
253+ for i in range (count .value ):
254+ result .append (symbol_from_api (value [i ]))
255+ sccore .BNSharedCacheFreeSymbolList (value , count )
256+ return result
116257
117258
0 commit comments