zoukankan      html  css  js  c++  java
  • [原]逆向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;

    }

     

  • 相关阅读:
    【Codeforces 349B】Color the Fence
    【Codeforces 459D】Pashmak and Parmida's problem
    【Codeforces 467C】George and Job
    【Codeforces 161D】Distance in Tree
    【Codeforces 522A】Reposts
    【Codeforces 225C】Barcode
    【Codeforces 446A】DZY Loves Sequences
    【Codeforces 429B】Working out
    【Codeforces 478C】Table Decorations
    【Codeforces 478C】Table Decorations
  • 原文地址:https://www.cnblogs.com/Proteas/p/3175713.html
Copyright © 2011-2022 走看看