[原]逆向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 ([imageFileName length] == 0) returnnil; 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) { returnnil; } else { [gCachedImageMapNameToImagesetObject:cachedImage forKey:imageCacheName]; [gCachedImageMapImageToNamesetObject:imageCacheName forKey:cachedImage]; [cachedImage _setNamed:YES]; [cachedImage _setCached:YES]; } } else { if (![cachedImage _isCached]) { [cachedImage _setCached:YES]; } } return cachedImage; } |
[原]逆向iOS SDK -- _UIImageAtPath 的实现(SDK 6.1)的更多相关文章
- [原]逆向iOS SDK -- _UIImageAtPath 的实现(SDK 5.1)
注释过的反汇编代码:http://pan.baidu.com/share/link?shareid=3491166579&uk=537224442 伪代码(不精确,仅供参考): NSStrin ...
- [原]逆向iOS SDK -- “添加本地通知”的流程分析
观点: 代码面前没有秘密 添加通知的 Demo 代码 - (void)scheduleOneLocalNotification { [[UIApplication sharedApplication] ...
- [原]逆向iOS SDK -- +[UIImage imageNamed:] 的实现
汇编代码: ; Dump of assembler code for function +[UIImage imageNamed:] ; R0 = UIImage, R1 = "imageN ...
- [Office][C#] NPOI、OpenXML SDK、OpenOffice.org SDK 写入资料到 EXCEL 档案[转]
原文地址:http://www.dotblogs.com.tw/chou/archive/2010/04/29/14912.aspx 一.簡介 要將資料寫入 EXCEL 檔案有許多的方法,但假如電腦不 ...
- Android SDK Tools和Android SDK Platform-tools
SDK Platform 可以理解为版本,因此有 SDK Platform 7,SDK Platform 8等等Android SDK Tools 是各个版本都可通用的工具文件夹,里面有draw9pa ...
- 阿里云SDK手册之java SDK
进行阿里云sdk开发的前提是已经购买阿里云的相关服务才能调用阿里的相关接口进行开发.最近公司在做云管控的项目,于是进行下摘录总结. 一. 环境准备 阿里云针对不同的开发语言提供不同的sdk,由于项目用 ...
- 打开SDK Manager检查Android SDK下载和更新失败的解决方法
[故障描述] 打开SDK Manager检查Android SDK状况,出现以下情况: Failed to fetch URL https://dl-ssl.google.com/android/r ...
- “AIR SDK 0.0: AIR SDK location “...\devsdks\AIRSDK\Win” does not exist.”问题解决~
原文同步至:http://www.waylau.com/air-sdk-0-0-air-sdk-location-does-not-exist-address/ 导入AS3项目时提示“AIR SDK ...
- Android sdk platform,sdk tools,sdk Build tools,sdk platform tools 的关系
1. sdk platform 简单理解为系统版本 最新级别: 28:Android 9 27:Android 8.1 26:Android 8.0 25:Android 7.1 24:Android ...
随机推荐
- C#操作Xml:XmlSerializer 对象的Xml序列化和反序列化
这篇随笔对应的.Net命名空间是System.Xml.Serialization:文中的示例代码需要引用这个命名空间. 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中:内存中的对 ...
- hdu 2066 一个人的旅行 最短路径
一个人的旅行 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- java中文件的相对路径以及jar中文件的读取
Java中File类的构造函数需要我们传入一个pathname,当我们传入以"/"开头的pathname表示绝对路径,其他均表示相对路径. 一:绝对路径名:是完整的路径名,不需要任 ...
- 聊聊单元測试(一)——EasyMock
一.单元測试是保证软件质量的重要方法. 单元測试是对系统中某个模块功能的验证,但我们总会遇到这样那样的问题,导致測试代码非常难编写.最直接的一个原因便是强耦合关系,被測试者依赖一些不easy构造,比較 ...
- hdu 4932 Miaomiao's Geometry(暴力)
题目链接:hdu 4932 Miaomiao's Geometry 题目大意:在x坐标上又若干个点,如今要用若干条相等长度的线段覆盖这些点,若一个点被一条线段覆盖,则必须在这条线的左端点或者是右端点, ...
- 国内首篇介绍JanOS物联网操作系统的文章 - 如何把你的手机主板打造成物联网平台
天地会珠海分舵注:如无意外,您现在正在看的将是国内首篇且是唯一一篇介绍炙手可热的物联网的操作系统JanOS的文章!不信你去百度!希望大家能喜欢.但本文只是引言,更多信息请还是访问JanOS的官网:ht ...
- Java集合之LinkedHashSet源码分析
1.简介 我们知道Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.根据源码实现中的注释我们可以知道LinkedHashSet是具有可预知迭代顺序的Set接 ...
- [译]Java垃圾回收器的类型
说明:这篇文章来翻译来自于Javapapers 的Types of Java Garbage Collectors 在这部分的教程中我们将讲到可使用的四种不同类型的Java垃圾回收器.垃圾回收是Jav ...
- CSS移动
#hand { width: 170px; height: 236px; position: absolute; top: 178px; left: 390px; background: url('h ...
- JS中的模块规范(CommonJS,AMD,CMD)
JS中的模块规范(CommonJS,AMD,CMD) 如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已. 现在就看看吧, ...