@@ -53,7 +53,7 @@ def __init__(self, extractionCtx: ExtractionContext) -> None:
5353 # create a map of image paths and their addresses
5454 self ._images : dict [bytes , int ] = {}
5555 for image in self ._dyldCtx .images :
56- imagePath = self ._dyldCtx .readString (image .pathFileOffset )
56+ imagePath = self ._dyldCtx .fileCtx . readString (image .pathFileOffset )
5757 self ._images [imagePath ] = image .address
5858 pass
5959
@@ -166,14 +166,16 @@ def _getDepInfo(self, dylib: dylib_command) -> _DependencyInfo:
166166 """
167167
168168 dylibPathOff = dylib ._fileOff_ + dylib .dylib .name .offset
169- dylibPath = self ._dyldCtx .readString (dylibPathOff )
169+ dylibPath = self ._machoCtx . fileCtx .readString (dylibPathOff )
170170 if dylibPath not in self ._images :
171171 self ._logger .warning (f"Unable to find dependency: { dylibPath } " )
172172 return None
173173
174174 imageAddr = self ._images [dylibPath ]
175- imageOff = self ._dyldCtx .convertAddr (imageAddr )
176- context = MachOContext (self ._dyldCtx .file , imageOff )
175+ imageOff , dyldCtx = self ._dyldCtx .convertAddr (imageAddr )
176+
177+ # Since we're not editing the dependencies, this should be fine.
178+ context = MachOContext (dyldCtx .fileCtx , imageOff )
177179 return _DependencyInfo (dylibPath , imageAddr , context )
178180
179181 def _readDepExports (
@@ -201,9 +203,13 @@ def _readDepExports(
201203 # Some images like UIKit don't have exports
202204 return []
203205
206+ linkeditFile = self ._dyldCtx .convertAddr (
207+ depInfo .context .segments [b"__LINKEDIT" ].seg .vmaddr
208+ )[1 ].fileCtx .file
209+
204210 try :
205211 depExports = dyld_trie .ReadExports (
206- depInfo . context . file ,
212+ linkeditFile ,
207213 exportOff ,
208214 exportSize ,
209215 )
@@ -250,21 +256,19 @@ def _enumerateSymbols(self) -> None:
250256 self ._logger .warning ("Unable to find LC_SYMTAB." )
251257 return
252258
253- dysymtab : dysymtab_command = self ._machoCtx .getLoadCommand (
254- ( LoadCommands . LC_DYSYMTAB ,)
259+ linkeditFile = self ._machoCtx .fileForAddr (
260+ self . _machoCtx . segments [ b"__LINKEDIT" ]. seg . vmaddr
255261 )
256- if not dysymtab :
257- self ._logger .warning ("Unable to find LC_DYSYMTAB." )
258262
259263 for i in range (symtab .nsyms ):
260264 self ._statusBar .update ()
261265
262266 # Get the symbol and its address
263267 entryOff = symtab .symoff + (i * nlist_64 .SIZE )
264- symbolEntry = nlist_64 (self . _machoCtx .file , entryOff )
268+ symbolEntry = nlist_64 (linkeditFile .file , entryOff )
265269
266270 symbolAddr = symbolEntry .n_value
267- symbol = self . _machoCtx .readString (symtab .stroff + symbolEntry .n_strx )
271+ symbol = linkeditFile .readString (symtab .stroff + symbolEntry .n_strx )
268272
269273 if symbolAddr == 0 :
270274 continue
@@ -450,10 +454,11 @@ def getStubHelperData(self, address: int) -> int:
450454 If unable to get the bind data, return None.
451455 """
452456
453- if not (helperOff := self ._dyldCtx .convertAddr (address )):
457+ helperOff , ctx = self ._dyldCtx .convertAddr (address ) or (None , None )
458+ if helperOff is None :
454459 return None
455460
456- ldr , b , data = self . _dyldCtx .readFormat (helperOff , "<III" )
461+ ldr , b , data = ctx . fileCtx .readFormat (helperOff , "<III" )
457462
458463 # verify
459464 if (
@@ -516,19 +521,20 @@ def getResolverData(self, address: int) -> Tuple[int, int]:
516521
517522 SEARCH_LIMIT = 0xC8
518523
519- if not (stubOff := self ._dyldCtx .convertAddr (address )):
524+ stubOff , ctx = self ._dyldCtx .convertAddr (address ) or (None , None )
525+ if stubOff is None :
520526 return None
521527
522528 # test stp and mov
523- stp , mov = self . _dyldCtx .readFormat (stubOff , "<II" )
529+ stp , mov = ctx . fileCtx .readFormat (stubOff , "<II" )
524530 if (
525531 (stp & 0x7FC00000 ) != 0x29800000
526532 or (mov & 0x7F3FFC00 ) != 0x11000000
527533 ):
528534 return None
529535
530536 # Find the branch instruction
531- dataSource = self . _dyldCtx .file
537+ dataSource = ctx . fileCtx .file
532538 branchInstrOff = None
533539 for instrOff in range (stubOff , stubOff + SEARCH_LIMIT , 4 ):
534540 # (instr & 0xFE9FF000) == 0xD61F0000
@@ -557,16 +563,16 @@ def getResolverData(self, address: int) -> Tuple[int, int]:
557563 return None
558564
559565 # Test if there is a stp before the bl and a ldp before the braaz
560- adrp = self . _dyldCtx .readFormat (blInstrOff + 4 , "<I" )[0 ]
561- ldp = self . _dyldCtx .readFormat (branchInstrOff - 4 , "<I" )[0 ]
566+ adrp = ctx . fileCtx .readFormat (blInstrOff + 4 , "<I" )[0 ]
567+ ldp = ctx . fileCtx .readFormat (branchInstrOff - 4 , "<I" )[0 ]
562568 if (
563569 (adrp & 0x9F00001F ) != 0x90000010
564570 or (ldp & 0x7FC00000 ) != 0x28C00000
565571 ):
566572 return None
567573
568574 # Hopefully it's a resolver...
569- imm = (self . _dyldCtx .readFormat (blInstrOff , "<I" )[0 ] & 0x3FFFFFF ) << 2
575+ imm = (ctx . fileCtx .readFormat (blInstrOff , "<I" )[0 ] & 0x3FFFFFF ) << 2
570576 imm = self .signExtend (imm , 28 )
571577 blResult = address + (blInstrOff - stubOff ) + imm
572578
@@ -609,10 +615,11 @@ def _getStubNormalLdrAddr(self, address: int) -> int:
609615 be determined.
610616 """
611617
612- if not (stubOff := self ._dyldCtx .convertAddr (address )):
618+ stubOff , ctx = self ._dyldCtx .convertAddr (address ) or (None , None )
619+ if stubOff is None :
613620 return None
614621
615- adrp , ldr , br = self . _dyldCtx .readFormat (stubOff , "<III" )
622+ adrp , ldr , br = ctx . fileCtx .readFormat (stubOff , "<III" )
616623
617624 # verify
618625 if (
@@ -645,10 +652,11 @@ def _getAuthStubNormalLdrAddr(self, address: int) -> int:
645652 not be determined.
646653 """
647654
648- if not (stubOff := self ._dyldCtx .convertAddr (address )):
655+ stubOff , ctx = self ._dyldCtx .convertAddr (address ) or (None , None )
656+ if stubOff is None :
649657 return None
650658
651- adrp , add , ldr , braa = self . _dyldCtx .readFormat (
659+ adrp , add , ldr , braa = ctx . fileCtx .readFormat (
652660 stubOff ,
653661 "<IIII"
654662 )
@@ -684,10 +692,11 @@ def _getStubNormalTarget(self, address: int) -> int:
684692 BR x16
685693 """
686694
687- if not (stubOff := self ._dyldCtx .convertAddr (address )):
695+ stubOff , ctx = self ._dyldCtx .convertAddr (address ) or (None , None )
696+ if stubOff is None :
688697 return None
689698
690- adrp , ldr , br = self . _dyldCtx .readFormat (stubOff , "<III" )
699+ adrp , ldr , br = ctx . fileCtx .readFormat (stubOff , "<III" )
691700
692701 # verify
693702 if (
@@ -716,10 +725,11 @@ def _getStubOptimizedTarget(self, address: int) -> int:
716725 BR x16
717726 """
718727
719- if not (stubOff := self ._dyldCtx .convertAddr (address )):
728+ stubOff , ctx = self ._dyldCtx .convertAddr (address )
729+ if stubOff is None :
720730 return None
721731
722- adrp , add , br = self . _dyldCtx .readFormat (stubOff , "<III" )
732+ adrp , add , br = ctx . fileCtx .readFormat (stubOff , "<III" )
723733
724734 # verify
725735 if (
@@ -748,10 +758,11 @@ def _getAuthStubNormalTarget(self, address: int) -> int:
748758 11 0a 1f d7 braa x16=>__auth_stubs::_CCRandomCopyBytes,x17
749759 """
750760
751- if not (stubOff := self ._dyldCtx .convertAddr (address )):
761+ stubOff , ctx = self ._dyldCtx .convertAddr (address )
762+ if stubOff is None :
752763 return None
753764
754- adrp , add , ldr , braa = self . _dyldCtx .readFormat (stubOff , "<IIII" )
765+ adrp , add , ldr , braa = ctx . fileCtx .readFormat (stubOff , "<IIII" )
755766
756767 # verify
757768 if (
@@ -787,10 +798,11 @@ def _getAuthStubOptimizedTarget(self, address: int) -> int:
787798 1bfcb5d2c 20 00 20 d4 trap
788799 """
789800
790- if not (stubOff := self ._dyldCtx .convertAddr (address )):
801+ stubOff , ctx = self ._dyldCtx .convertAddr (address )
802+ if stubOff is None :
791803 return None
792804
793- adrp , add , br , trap = self . _dyldCtx .readFormat (stubOff , "<IIII" )
805+ adrp , add , br , trap = ctx . fileCtx .readFormat (stubOff , "<IIII" )
794806
795807 # verify
796808 if (
@@ -819,10 +831,11 @@ def _getAuthStubResolverTarget(self, address: int) -> int:
819831 1f 0a 1f d6 braaz x16=>FUN_195bee070
820832 """
821833
822- if not (stubOff := self ._dyldCtx .convertAddr (address )):
834+ stubOff , ctx = self ._dyldCtx .convertAddr (address )
835+ if stubOff is None :
823836 return None
824837
825- adrp , ldr , braaz = self . _dyldCtx .readFormat (stubOff , "<III" )
838+ adrp , ldr , braaz = ctx . fileCtx .readFormat (stubOff , "<III" )
826839
827840 # verify
828841 if (
@@ -1024,14 +1037,19 @@ def _enumerateSymbolPointers(self) -> Dict[bytes, Tuple[int]]:
10241037 dyldInfo : dyld_info_command = self ._machoCtx .getLoadCommand (
10251038 (LoadCommands .LC_DYLD_INFO , LoadCommands .LC_DYLD_INFO_ONLY )
10261039 )
1040+
1041+ linkeditFile = self ._machoCtx .fileForAddr (
1042+ self ._machoCtx .segments [b"__LINKEDIT" ].seg .vmaddr
1043+ )
1044+
10271045 if dyldInfo :
10281046 records : List [_BindRecord ] = []
10291047 try :
10301048 if dyldInfo .weak_bind_size :
10311049 # usually contains records for c++ symbols like "new"
10321050 records .extend (
10331051 _bindReader (
1034- self . _machoCtx ,
1052+ linkeditFile ,
10351053 dyldInfo .weak_bind_off ,
10361054 dyldInfo .weak_bind_size
10371055 )
@@ -1041,7 +1059,7 @@ def _enumerateSymbolPointers(self) -> Dict[bytes, Tuple[int]]:
10411059 if dyldInfo .lazy_bind_off :
10421060 records .extend (
10431061 _bindReader (
1044- self . _machoCtx ,
1062+ linkeditFile ,
10451063 dyldInfo .lazy_bind_off ,
10461064 dyldInfo .lazy_bind_size
10471065 )
@@ -1098,7 +1116,7 @@ def _addToMap(ptrSymbol: bytes, ptrAddr: int, section: section_64):
10981116 continue
10991117
11001118 # Try to symbolize though indirect symbol entries
1101- symbolIndex = self . _machoCtx .readFormat (
1119+ symbolIndex = linkeditFile .readFormat (
11021120 self ._dysymtab .indirectsymoff + ((sect .reserved1 + i ) * 4 ),
11031121 "<I"
11041122 )[0 ]
@@ -1109,10 +1127,10 @@ def _addToMap(ptrSymbol: bytes, ptrAddr: int, section: section_64):
11091127 and symbolIndex != (INDIRECT_SYMBOL_ABS | INDIRECT_SYMBOL_LOCAL )
11101128 ):
11111129 symbolEntry = nlist_64 (
1112- self . _machoCtx . file ,
1130+ linkeditFile ,
11131131 self ._symtab .symoff + (symbolIndex * nlist_64 .SIZE )
11141132 )
1115- symbol = self . _machoCtx .readString (
1133+ symbol = linkeditFile .readString (
11161134 self ._symtab .stroff + symbolEntry .n_strx
11171135 )
11181136
@@ -1157,6 +1175,14 @@ def _fixStubHelpers(self) -> None:
11571175 if not dyldInfo :
11581176 return
11591177
1178+ textFile = self ._machoCtx .fileForAddr (
1179+ self ._machoCtx .segments [b"__TEXT" ].seg .vmaddr
1180+ )
1181+
1182+ linkeditFile = self ._machoCtx .fileForAddr (
1183+ self ._machoCtx .segments [b"__LINKEDIT" ].seg .vmaddr
1184+ )
1185+
11601186 # the stub helper section has the stub binder in
11611187 # beginning, skip it.
11621188 helperAddr = helperSect .addr + STUB_BINDER_SIZE
@@ -1168,7 +1194,7 @@ def _fixStubHelpers(self) -> None:
11681194 if (bindOff := self ._arm64Utils .getStubHelperData (helperAddr )) is not None :
11691195 record = next (
11701196 _bindReader (
1171- self . _machoCtx ,
1197+ linkeditFile ,
11721198 dyldInfo .lazy_bind_off + bindOff ,
11731199 dyldInfo .lazy_bind_size ,
11741200 ),
@@ -1190,7 +1216,7 @@ def _fixStubHelpers(self) -> None:
11901216 bindPtrOff += record .offset
11911217
11921218 newBindPtr = struct .pack ("<Q" , helperAddr )
1193- self . _machoCtx .writeBytes (bindPtrOff , newBindPtr )
1219+ textFile .writeBytes (bindPtrOff , newBindPtr )
11941220 helperAddr += REG_HELPER_SIZE
11951221 continue
11961222
0 commit comments