汇编代码:

; 状态: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)的更多相关文章

  1. [原]逆向iOS SDK -- _UIImageAtPath 的实现(SDK 5.1)

    注释过的反汇编代码:http://pan.baidu.com/share/link?shareid=3491166579&uk=537224442 伪代码(不精确,仅供参考): NSStrin ...

  2. [原]逆向iOS SDK -- “添加本地通知”的流程分析

    观点: 代码面前没有秘密 添加通知的 Demo 代码 - (void)scheduleOneLocalNotification { [[UIApplication sharedApplication] ...

  3. [原]逆向iOS SDK -- +[UIImage imageNamed:] 的实现

    汇编代码: ; Dump of assembler code for function +[UIImage imageNamed:] ; R0 = UIImage, R1 = "imageN ...

  4. [Office][C#] NPOI、OpenXML SDK、OpenOffice.org SDK 写入资料到 EXCEL 档案[转]

    原文地址:http://www.dotblogs.com.tw/chou/archive/2010/04/29/14912.aspx 一.簡介 要將資料寫入 EXCEL 檔案有許多的方法,但假如電腦不 ...

  5. Android SDK Tools和Android SDK Platform-tools

    SDK Platform 可以理解为版本,因此有 SDK Platform 7,SDK Platform 8等等Android SDK Tools 是各个版本都可通用的工具文件夹,里面有draw9pa ...

  6. 阿里云SDK手册之java SDK

    进行阿里云sdk开发的前提是已经购买阿里云的相关服务才能调用阿里的相关接口进行开发.最近公司在做云管控的项目,于是进行下摘录总结. 一. 环境准备 阿里云针对不同的开发语言提供不同的sdk,由于项目用 ...

  7. 打开SDK Manager检查Android SDK下载和更新失败的解决方法

    [故障描述] 打开SDK Manager检查Android  SDK状况,出现以下情况: Failed to fetch URL https://dl-ssl.google.com/android/r ...

  8. “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 ...

  9. 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 ...

随机推荐

  1. UML之轻松入门(2)-掌握Junit,让我们的开发更高效

         使用UML不仅能够形象化的表达我们的程序思想,并且能够帮助我们提高程序的质量.一个杂乱无章的程序让维护者望而生畏,其成本也可想而知.在面向程序设计(OOD)中有5条原则是帮助我们设计一个高效 ...

  2. 【高德地图API】从零开始学高德JS API(二)地图控件与插件——测距、圆形编辑器、鼠标工具、地图类型切换、鹰眼鱼骨

    原文:[高德地图API]从零开始学高德JS API(二)地图控件与插件——测距.圆形编辑器.鼠标工具.地图类型切换.鹰眼鱼骨 摘要:无论是控件还是插件,都是在一级API接口的基础上,进行二次开发,封装 ...

  3. 【百度地图API】如何制作多途经点的线路导航——驾车篇

    原文:[百度地图API]如何制作多途经点的线路导航--驾车篇 摘要: 休假结束,酸奶小妹要从重庆驾车去北京.可是途中要去西安奶奶家拿牛奶饼干呢!用百度地图API,能不能帮我实现这个愿望呢? ----- ...

  4. Java初认识--函数和数组

    一.函数 1.函数的定义 函数就是定义在类中的具有特定功能的一段独立小程序,函数也称为方法. java中最小的功能单元就是函数. 2.函数的格式 修饰符 返回值类型 函数名(参数类型 形式参数1,参数 ...

  5. asp.net 获得客户端 mac 地址

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  6. 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航

    原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...

  7. SQL点滴30—SQL中常用的函数

    原文:SQL点滴30-SQL中常用的函数 该文章转载自http://www.cnblogs.com/jiajiayuan/archive/2011/06/16/2082488.html 别人的总结,很 ...

  8. 学习PHP时的一些总结(四)

    目录的基本操作: 在系统的每个目录下都有两个特殊的目录"."和".." , 分别指示当前目录和当前目录的父目录. dirname()  返回目录的名称 path ...

  9. 开发环境准备:Ruby on Rails开发环境配置

    开发环境准备:Ruby on Rails开发环境配置 前情回顾 上次讲到Vmware虚拟机的安装配置以及Scientific Linux 6.X系统的安装.这回我们的主要任务是在Linux操作系统上完 ...

  10. 区域、模板页与WebAPI初步

    区域.模板页与WebAPI初步 一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域( ...