99from . import _sharedcachecore as sccore
1010from .sharedcache_enums import *
1111
12-
13- @dataclasses .dataclass
14- class DSCMemoryMapping :
15- name : str
16- vmAddress : int
17- size : int
18-
19- def __str__ (self ):
20- return repr (self )
21-
22- def __repr__ (self ):
23- return f"<DSCMemoryMapping '{ self .name } ': { self .vmAddress :x} +{ self .size :x} >"
24-
25-
26- @dataclasses .dataclass
27- class LoadedRegion :
28- name : str
29- headerAddress : int
30- mappings : list [DSCMemoryMapping ]
31-
32- def __str__ (self ):
33- return repr (self )
34-
35- def __repr__ (self ):
36- return f"<LoadedRegion { self .name } @ { self .headerAddress :x} >"
37-
38-
39- @dataclasses .dataclass
40- class DSCBackingCacheMapping :
41- vmAddress : int
42- size : int
43- fileOffset : int
44-
45- def __str__ (self ):
46- return repr (self )
47-
48- def __repr__ (self ):
49- return f"<DSCBackingCacheMapping { self .vmAddress :x} +{ self .size :x} @ { self .fileOffset :x} "
50-
51-
52- @dataclasses .dataclass
53- class DSCBackingCache :
54- path : str
55- cacheType : BackingCacheType
56- mappings : list [DSCBackingCacheMapping ]
57-
58- def __str__ (self ):
59- return repr (self )
60-
61- def __repr__ (self ):
62- match self .cacheType :
63- case BackingCacheType .BackingCacheTypePrimary :
64- cacheTypeStr = 'Primary'
65- case BackingCacheType .BackingCacheTypeSecondary :
66- cacheTypeStr = 'Secondary'
67- case BackingCacheType .BackingCacheTypeSymbols :
68- cacheTypeStr = 'Symbols'
69- return f"<DSCBackingCache { self .path } { cacheTypeStr } | { len (self .mappings )} mappings>"
70-
71-
7212@dataclasses .dataclass
73- class DSCImageMemoryMapping :
74- filePath : str
75- name : str
76- vmAddress : int
77- size : int
78- loaded : bool
79- rawViewOffset : int
13+ class CacheRegion :
14+ regionType : SharedCacheRegionType
15+ name : str
16+ start : int
17+ size : int
18+ imageStart : int
19+ flags : binaryninja . enums . SegmentFlag
8020
81- def __str__ (self ):
82- return repr (self )
83-
84- def __repr__ (self ):
85- return f"<DSCImageMemoryMapping '{ self .name } ' { os .path .basename (self .filePath )} raw<{ self .rawViewOffset :x} >: { self .vmAddress :x} +{ self .size :x} >"
21+ def __str__ (self ):
22+ return repr (self )
8623
24+ def __repr__ (self ):
25+ return f"<CacheRegion '{ self .name } ': { self .start :x} +{ self .size :x} >"
8726
8827@dataclasses .dataclass
89- class DSCImage :
90- name : str
91- headerAddress : int
92- mappings : list [DSCImageMemoryMapping ]
93-
94- def __str__ (self ):
95- return repr (self )
96-
97- def __repr__ (self ):
98- return f"<DSCImage { self .name } @ { self .headerAddress :x} >"
99-
100-
101- @dataclasses .dataclass
102- class DSCSymbol :
103- name : str
104- image : str
105- address : int
106-
107- def __str__ (self ):
108- return repr (self )
109-
110- def __repr__ (self ):
111- return f"<DSCSymbol { self .name } @ { self .address :x} ({ self .image } >"
112-
113-
114- class SharedCache :
115- def __init__ (self , view ):
116- self .handle = sccore .BNGetSharedCache (view .handle )
117-
118- def load_image_with_install_name (self , installName , skipObjC = False ):
119- return sccore .BNDSCViewLoadImageWithInstallName (self .handle , installName , skipObjC )
120-
121- def load_section_at_address (self , addr ):
122- return sccore .BNDSCViewLoadSectionAtAddress (self .handle , addr )
123-
124- def load_image_containing_address (self , addr , skipObjC = False ):
125- return sccore .BNDSCViewLoadImageContainingAddress (self .handle , addr , skipObjC )
126-
127- def process_objc_sections_for_image_with_install_name (self , installName ):
128- return sccore .BNDSCViewProcessObjCSectionsForImageWithInstallName (self .handle , installName )
129-
130- def process_all_objc_sections (self ):
131- return sccore .BNDSCViewProcessAllObjCSections (self .handle )
132-
133- @property
134- def caches (self ):
135- count = ctypes .c_ulonglong ()
136- value = sccore .BNDSCViewGetBackingCaches (self .handle , count )
137- if value is None :
138- return []
139-
140- result = []
141- for i in range (count .value ):
142- mappings = []
143- for j in range (value [i ].mappingCount ):
144- mapping = DSCBackingCacheMapping (
145- value [i ].mappings [j ].vmAddress ,
146- value [i ].mappings [j ].size ,
147- value [i ].mappings [j ].fileOffset
148- )
149- mappings .append (mapping )
150- result .append (DSCBackingCache (
151- value [i ].path ,
152- value [i ].cacheType ,
153- mappings
154- ))
155-
156- sccore .BNDSCViewFreeBackingCaches (value , count )
157- return result
158-
159- @property
160- def images (self ):
161- count = ctypes .c_ulonglong ()
162- value = sccore .BNDSCViewGetAllImages (self .handle , count )
163- if value is None :
164- return []
165-
166- result = []
167- for i in range (count .value ):
168- mappings = []
169- for j in range (value [i ].mappingCount ):
170- mapping = DSCImageMemoryMapping (
171- value [i ].mappings [j ].filePath ,
172- value [i ].mappings [j ].name ,
173- value [i ].mappings [j ].vmAddress ,
174- value [i ].mappings [j ].size ,
175- value [i ].mappings [j ].loaded ,
176- value [i ].mappings [j ].rawViewOffset
177- )
178- mappings .append (mapping )
179- result .append (DSCImage (
180- value [i ].name ,
181- value [i ].headerAddress ,
182- mappings
183- ))
184-
185- sccore .BNDSCViewFreeAllImages (value , count )
186- return result
187-
188- @property
189- def loaded_regions (self ):
190- """
191- Get all loaded regions in the shared cache
192-
193- The internal logic for loading images treats a region as 'loaded' whenever
194- that region has been mapped into memory, and, if it's located within an image, header information has been applied to that region.
195-
196- Individual segments within an image can be loaded independently of the image itself.
197-
198- Only once all regions of an image are loaded will the header processor refuse to run on that region.
199- :return:
200- """
201- count = ctypes .c_ulonglong ()
202- value = sccore .BNDSCViewGetLoadedRegions (self .handle , count )
203- if value is None :
204- return []
205-
206- result = []
207- for i in range (count .value ):
208- mapping = DSCMemoryMapping (
209- value [i ].name ,
210- value [i ].vmAddress ,
211- value [i ].size ,
212- )
213- result .append (mapping )
214- sccore .BNDSCViewFreeLoadedRegions (value , count )
215- return result
216-
217- def load_all_symbols_and_wait (self ):
218- count = ctypes .c_ulonglong ()
219- value = sccore .BNDSCViewLoadAllSymbolsAndWait (self .handle , count )
220- if value is None :
221- return []
222- result = []
223- for i in range (count .value ):
224- sym = DSCSymbol (
225- value [i ].name ,
226- value [i ].image ,
227- value [i ].address
228- )
229- result .append (sym )
230-
231- sccore .BNDSCViewFreeSymbols (value , count )
232- return result
233-
234- @property
235- def image_names (self ):
236- count = ctypes .c_ulonglong ()
237- value = sccore .BNDSCViewGetInstallNames (self .handle , count )
238- if value is None :
239- return []
240-
241- result = []
242- for i in range (count .value ):
243- result .append (value [i ].decode ('utf-8' ))
244-
245- BNFreeStringList (value , count )
246- return result
247-
248- @property
249- def state (self ):
250- return DSCViewState (sccore .BNDSCViewGetState (self .handle ))
251-
252- def get_name_for_address (self , address ):
253- name = sccore .BNDSCViewGetNameForAddress (self .handle , address )
254- if name is None :
255- return ""
256- result = name
257- return result
258-
259- def get_image_name_for_address (self , address ):
260- name = sccore .BNDSCViewGetImageNameForAddress (self .handle , address )
261- if name is None :
262- return ""
263- result = name
264- return result
265-
266- def find_symbol_at_addr_and_apply_to_addr (self , symbolAddress , targetAddress , triggerReanalysis ) -> None :
267- sccore .BNDSCFindSymbolAtAddressAndApplyToAddress (self .handle , symbolAddress , targetAddress , triggerReanalysis )
28+ class CacheImage :
29+ name : str
30+ headerAddress : int
31+ regionStarts : [int ]
32+
33+ def __str__ (self ):
34+ return repr (self )
35+
36+ def __repr__ (self ):
37+ return f"<CacheImage '{ self .name } ': { self .headerAddress :x} >"
38+
39+ def region_from_api (region ):
40+ return CacheRegion (
41+ SharedCacheRegionType (region .regionType ),
42+ region .name .decode ('utf-8' ),
43+ region .start ,
44+ region .size ,
45+ region .imageStart ,
46+ binaryninja .enums .SegmentFlag (region .flags )
47+ )
48+
49+ def image_from_api (image ):
50+ return CacheImage (
51+ image .name .decode ('utf-8' ),
52+ image .headerAddress ,
53+ image .regionStarts
54+ )
55+
56+ class SharedCacheController :
57+ def __init__ (self , view ):
58+ self .handle = sccore .BNGetSharedCacheController (view .handle )
59+
60+ @property
61+ def regions (self ):
62+ count = ctypes .c_ulonglong ()
63+ value = sccore .BNGetSharedCacheRegions (self .handle , count )
64+ if value is None :
65+ return []
66+ result = []
67+ for i in range (count .value ):
68+ result .append (region_from_api (value [i ]))
69+ sccore .BNSharedCacheFreeRegionList (value , count )
70+ return result
71+
72+
73+ @property
74+ def images (self ):
75+ count = ctypes .c_ulonglong ()
76+ value = sccore .BNGetSharedCacheImages (self .handle , count )
77+ if value is None :
78+ return []
79+ result = []
80+ for i in range (count .value ):
81+ result .append (image_from_api (value [i ]))
82+ sccore .BNSharedCacheFreeImageList (value , count )
83+ return result
0 commit comments