逆向iOS SDK -- _UIImageAtPath 的實現(SDK 6.1)
彙編程式碼:
; 狀態:R0 = imageFileName, R1 = mainBundle, R2 = isRetina PUSH {R4-R7,LR}; R0 = imageFileName, R1 = mainBundle, R2 = isRetina ADD R7, SP, #0xC PUSH.W {R8,R10,R11} STR.W R2, [SP,#0x18+var_1C]! MOV R4, R0 ; R4 = R0 = imageFileName MOV R0, #(selRef_length - 0x17BB0); selRef_length MOV R10, R1 ; R10 = R1 = mainBundle ADD R0, PC ; selRef_length LDR R1, [R0] ; "length" MOV R0, R4 ; R0 = R4 = imageFileName BLX.W _objc_msgSend; [imageFileName length] MOVS R6, #0 ; R6 = 0 CMP R0, #0 ; check if R0 is 0 BEQ.W loc_17D1C; if R0 is 0, goto the label MOV R0, R4 ; R0 = R4 = imageFileName MOV R1, R10 ; R1 = R10 = mainBundle BL __UICacheNameForImageAtPath; arg_0:imageFileName, arg_1:mainBundle, result:com.proteas.hello_Default.png MOVW R8, #(:lower16:(__MergedGlobals_36 - 0x17BD4)) MOV R5, R0 ; R5 = R0 = imageCacheName MOVT.W R8, #(:upper16:(__MergedGlobals_36 - 0x17BD4)) ADD R8, PC ; __MergedGlobals_36 ADD.W R11, R8, #0x10; R11 = R8 + 16 MOV R0, R11 ; lock, OSSpinLock*, 訪問全域性變數,加鎖 BLX.W _OSSpinLockLock; arg_0: OSSpinLock* LDR.W R0, [R8,#(dword_62C524 - 0x62C510)]; R0 = cachedImageMap, key:imageCacheName, value:UIImageObject MOVS R6, #0 ; R6 = 0 CBZ R0, loc_17BEC; if cachedImageMap is nil, goto the label MOV R1, R5 ; R1 = R5 = imageCacheName BLX.W _CFDictionaryGetValue; CFDictionaryGetValue(cachedImageMap, imageCacheName) MOV R6, R0 ; R6 = R0 = cachedUIImageObject loc_17BEC: MOV R0, #(selRef_retainCount - 0x17BF8); selRef_retainCount ADD R0, PC ; selRef_retainCount LDR R1, [R0]; "retainCount" MOV R0, R6 ; R0 = R6 = cachedUIImageObject BLX.W _objc_msgSend; [cachedUIImageObject retainCount] CBNZ R0, loc_17C08; if retainCount of cachedUIImageObject is not 0, goto the label MOV R0, R11 ; lock BLX.W _OSSpinLockUnlock B loc_17C50 loc_17C08: MOV R0, #(selRef__isCached - 0x17C14); selRef__isCached ADD R0, PC ; selRef__isCached LDR R1, [R0] ; R1 = "_isCached" MOV R0, R6 ; R0 = R6 = cachedUIImageObject BLX.W _objc_msgSend; R0 = isCached TST.W R0, #0xFF; check if R0 is true BNE loc_17C46; if not cached, goto the label MOV R0, #(selRef_retain - 0x17C2C); selRef_retain ADD R0, PC ; selRef_retain LDR R1, [R0] ; "retain" MOV R0, R6 ; R0 = R6 = cachedUIImageObject BLX.W _objc_msgSend; [cachedUIImageObject retain] MOVW R0, #(:lower16:(selRef__setCached_ - 0x17C40)) MOVS R2, #1 ; R2 = 1 MOVT.W R0, #(:upper16:(selRef__setCached_ - 0x17C40)) ADD R0, PC ; selRef__setCached_ LDR R1, [R0] ; "_setCached:" MOV R0, R6 ; R0 = R6 = cachedUIImageObject BLX.W _objc_msgSend ; [cachedUIImageObject _setCached:YES] loc_17C46: MOV R0, R11 ; lock BLX.W _OSSpinLockUnlock;釋放鎖 CMP R6, #0 ; check if cachedUIImageObject is nil BNE loc_17D1C; if not nil, goto the label loc_17C50: MOVW R3, #(:lower16:(_GetImageAtPath+1 - 0x17C60)) MOV R0, R4 ; R0 = R4 = imageFileName MOVT.W R3, #(:upper16:(_GetImageAtPath+1 - 0x17C60)) LDR R2, [SP,#0x1C+var_1C]; R2 = isRetina ADD R3, PC ; _GetImageAtPath ; R3 = _GetImageAtPath MOV R1, R10 ; R1 = R10 = mainBundle BL __UIImageCallFunctionForAppropriatePath; arg_0:imageFileName, arg_1 = mainBundle, arg_2 = isRetina, arg_3 = _GetImageAtPath MOV R6, R0 ; R6 = R0 = UIImageObject CMP R6, #0 ; check if UIImageObject is nil BEQ loc_17D1C; if failed, goto label MOV R0, R11 ; lock BLX.W _OSSpinLockLock LDR.W R0, [R8,#0x14]; R0 = pointer to imageCacheMap CBNZ R0, loc_17CAE; R1 = R5 = imageCacheName MOVW R0, #(:lower16:(_kCFTypeDictionaryKeyCallBacks_ptr - 0x17C86)) MOVS R1, #0 ; R1 = capacity = 0 MOVT.W R0, #(:upper16:(_kCFTypeDictionaryKeyCallBacks_ptr - 0x17C86)) MOVS R3, #0 ; R3 = valueCallBacks = 0 ADD R0, PC ; _kCFTypeDictionaryKeyCallBacks_ptr LDR R2, [R0] ; _kCFTypeDictionaryKeyCallBacks MOVS R0, #0 ; R0 = allocator = NULL BLX.W _CFDictionaryCreateMutable ; R0 = cachedImageMap MOVW R1, #(:lower16:(_kCFTypeDictionaryValueCallBacks_ptr - 0x17C9E)) MOVS R2, #0 ; R2 = keyCallBacks = NULL MOVT.W R1, #(:upper16:(_kCFTypeDictionaryValueCallBacks_ptr - 0x17C9E)) STR.W R0, [R8,#0x14] ADD R1, PC ; _kCFTypeDictionaryValueCallBacks_ptr MOVS R0, #0 ; R0 = allocator = NULL LDR R3, [R1] ; _kCFTypeDictionaryValueCallBacks MOVS R1, #0 ; R1 = capacity = 0 BLX.W _CFDictionaryCreateMutable STR.W R0, [R8,#0x18] LDR.W R0, [R8,#0x14] loc_17CAE: MOV R1, R5 ; R1 = R5 = imageCacheName BLX.W _CFDictionaryContainsKey CBNZ R0, loc_17CF8; if has cached, goto the label MOVW R0, #(:lower16:(selRef__setNamed_ - 0x17CC4)) MOVS R2, #1 ; R2 = YES MOVT.W R0, #(:upper16:(selRef__setNamed_ - 0x17CC4)) ADD R0, PC ; selRef__setNamed_ LDR R1, [R0] ; "_setNamed:" MOV R0, R6 ; R0 = R6 = UIImageObject BLX.W _objc_msgSend; [UIImageObject _setNamed:YES] MOVW R0, #(:lower16:(selRef__setCached_ - 0x17CD8)) MOVS R2, #1 MOVT.W R0, #(:upper16:(selRef__setCached_ - 0x17CD8)) ADD R0, PC ; selRef__setCached_ LDR R1, [R0] ; "_setCached:" MOV R0, R6 BLX.W _objc_msgSend; [UIImageObject _setCached:YES] LDR.W R0, [R8,#0x14]; R0 = cachedImageMap MOV R1, R5 ; R1 = R5 = imageCacheName MOV R2, R6 ; R2 = R6 = UIImageObject BLX.W _CFDictionarySetValue; arg_0:cachedImageMap, arg_1 = imageCacheName, arg_2 = imageObject LDR.W R0, [R8,#0x18] MOV R1, R6 ; R1 = R6 = UIImageObject MOV R2, R5 ; R2 = R5 = imageCacheName BLX.W _CFDictionarySetValue; arg_0: dictionary, arg_1: imageObject, arg_2 = imageCacheName B loc_17D16 loc_17CF8: MOV R0, #(selRef_release - 0x17D04); selRef_release ADD R0, PC ; selRef_release LDR R1, [R0] ; "release" MOV R0, R6 ; R0 = R6 = UIImageObject BLX.W _objc_msgSend; [UIImageObject release] LDR.W R0, [R8,#0x14]; R0 = cachedImageMap MOV R1, R5 ; R1 = R5 = imageCacheName BLX.W _CFDictionaryGetValue MOV R6, R0 ; R6 = R0 = result UIImage instance loc_17D16: MOV R0, R11 ; lock BLX.W _OSSpinLockUnlock; release spin lock loc_17D1C: MOV R0, R6 ; R0 = R6 = nil ADD SP, SP, #4 POP.W {R8,R10,R11} POP {R4-R7,PC} |
虛擬碼:
NSDictionary *gCachedImageMapNameToImage =nil; NSDictionary *gCachedImageMapImageToName =nil; _UIImageAtPath(NSString *imageFileName,NSBundle *mainBundle,BOOL isRetina) { if ([imageFileNamelength] ==0) return nil; if (gCachedImageMapNameToImage ==nil) { gCachedImageMapNameToImage = [[NSMutableDictionaryalloc]init]; gCachedImageMapImageToName = [[NSMutableDictionaryalloc]init]; } NSString *imageCacheName =_UICacheNameForImageAtPath(imageFileName, mainBundle); UIImage *cachedImage = [gCachedImageMapNameToImageobjectForKey:imageCacheName]; if (cachedImage ==nil) { cachedImage = _UIImageCallFunctionForAppropriatePath(imageFileName, mainBundle, isRetina,_UIImageAtPath); if (cachedImage == nil) { return nil; } else { [gCachedImageMapNameToImagesetObject:cachedImageforKey:imageCacheName]; [gCachedImageMapImageToNamesetObject:imageCacheNameforKey:cachedImage]; [cachedImage _setNamed:YES]; [cachedImage _setCached:YES]; } } else { if (![cachedImage _isCached]) { [cachedImage _setCached:YES]; } } return cachedImage; } |
相關文章
- 實現Facebook SDK
- 基於 Agora SDK 實現 iOS 端的多人視訊互動GoiOS
- 限流 SDK 的設計與實現
- iOS sdk打包知識iOS
- 乾貨|淺談iOS端短影片SDK技術實現iOS
- iOS不用官方SDK實現微信和支付寶支付XHPayKitiOS
- Fluwx:微信SDK在Flutter上的實現Flutter
- 使用Swift快速整合環信IM iOS SDK並實現單聊SwiftiOS
- Cordova-iOS SDK封裝iOS封裝
- 轉載-iOS SDK開發iOS
- Agora iOS SDK-多人聊天GoiOS
- 美顏sdk常用功能的實現原理
- Xamarin.iOS除錯提示需要iOS SDKiOS除錯
- 有米iOS惡意SDK分析iOS
- iOS/Android 影片編輯SDKiOSAndroid
- iOS iPhone SDK 包含哪些東西?iOSiPhone
- 騰訊地圖SDK Flutter外掛實現地圖Flutter
- 來自銳動天地的直播ios SDKiOS
- 美顏sdk動態貼紙的實現流程
- 影片直播美顏sdk趣味功能的實現流程
- 如何實現一個簡單易用的 RocketMQ SDKMQ
- Spaces SDK:專為實時協作功能開發設計的SDK
- 美顏SDK中的美顏功能是怎麼實現的?美顏SDK的工作原理是什麼?
- SDK 開發使用 VirtualAPK 實現外掛化APK
- 如何實現 OpenAPI 多語言 SDK 開發?API
- [教程] 使用 Agora SDK 實現視訊對話應用 HouseParty – 附 iOS 原始碼GoiOS原始碼
- [教程] 使用 Agora SDK 實現視訊對話應用 HouseParty - 附 iOS 原始碼GoiOS原始碼
- 直播美顏SDK是怎樣實現美顏的?
- 短影片美顏sdk濾鏡功能的實現流程
- 關於Platform SDK和Windows SDKPlatformWindows
- 瀏覽器SVG的Javascript SDK庫: Ample SDK瀏覽器SVGJavaScript
- 基於聲網 Flutter SDK 實現互動直播Flutter
- 【高德地圖SDK】如何實現軌跡平滑移動?地圖
- flutter 呼叫環信sdk 實現即時通訊Flutter
- 美顏SDK中磨皮功能的演算法實現演算法
- 直播美顏SDK祛痘功能是怎麼實現的?
- 直播美顏SDK的功能實現流程——美白、磨皮
- Dart SDK在Flutter SDK中的儲存路徑DartFlutter