Commented SpringBoard Icon List Method Disassembly

This is the full disassembly listing of the icon list retrieving method in SpringBoard 1.1.1, I’ve added the comments to ease the reading. Based on this disassembly listing, it’s easy to create a patch to enable the SpringBoard multipage scrolling.

NOTE: The scrolling feature has already been in the SpringBoard, Apple just didn’t open it to public yet. The following is the restrictions Apple has put into the SpringBoard, at line #41 ~ #48:

LDR     R0, =psz_SBPlatformController
LDR     R1, =psz_sharedInstance
LDR     R0, [R0]
LDR     R1, [R1]
BL      _objc_msgSend
LDR     R1, =psz_allowedDisplayIdentifiers
LDR     R1, [R1]
BL      _objc_msgSend

The above lines is equivalent to an Object-C statement:

NSArray *displayIDs = [ [SBPlatformController sharedInstance] allowedDisplayIdentifiers ];


It definies which applications are allowed to be displayed in the SpringBoard. Later at lines #198 ~ #200:

DR     R1, =psz_containsObject
LDR     R0, [SP,#0x64+displayIDs]
MOV     R2, R4                  ; // bundleID
LDR     R1, [R1BL   _objc_msgSend
TST  R0, #0xFF
BEQ  next_role

The above code is similar to the following Object-C code:

if (![displayIDs containsObject:bundleID]) // bundleID is application's ID
   // skip this application
else
   // go on to display application icon

There’re two methods to remove the above restrictions, modify displayIDs or skip the bundleID checking, the current patch is using the second method: the BEQ instruction is replaced by a NOP.

The complete disassembly listing of the method:

; - (void)_addItemsToIconList:(id)items fromPath:(id)path withTags:(id)tags;

_addItemsToIconList_fromPath_withTags           ; DATA XREF: __inst_meth:000ACD00o

func_param      = -0x64
path            = -0x60
items           = -0x5C
self            = -0x58
dir             = -0x54
displayIDs      = -0x50
dirName         = -0x4C
bIsDefaultRole  = -0x48
dirFullname     = -0x44
bundle          = -0x40
dict            = -0x3C
roleArray       = -0x38
nRoleIndex      = -0x34
nRoleCount      = -0x30
value_SBIconClass= -0x2C
displayName     = -0x28
value_Arguments = -0x24
var_8           = -8
tags            =  0

                STMFD   SP!, {R4-R7,LR}
                ADD     R7, SP, #0x14+var_8
                LDR     R1, =psz_fileSystemRepresentation
                STMFD   SP!, {R8,R10,R11}
                SUB     SP, SP, #0x44
                STR     R0, [SP,#0x64+self]
                LDR     R1, [R1]
                MOV     R0, R3                  ; // path
                STR     R2, [SP,#0x64+items]
                STR     R3, [SP,#0x64+path]
                BL      _objc_msgSend           ; // [path fileSystemPresentation];
                BL      _opendir                ; DIR *dir = opendir([path fileSystemPresentation]);
                CMP     R0, #0
                STR     R0, [SP,#0x64+dir]
                BEQ     return                  ; if (dir == nil)
                                                ;    goto ...
                LDR     R0, =psz_SBPlatformController
                LDR     R1, =psz_sharedInstance
                LDR     R0, [R0]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; // [SBPlatformController sharedInstance]
                LDR     R1, =psz_allowedDisplayIdentifiers
                LDR     R1, [R1]
                BL      _objc_msgSend           ; NSArray *displayIDs
                                                ;     = [ [SBPlatformController sharedInstance]
                                                ;         allowedDisplayIdentifiers ];
                STR     R0, [SP,#0x64+displayIDs]
                B       read_next_direntry
; ---------------------------------------------------------------------------

loop_check_direntry                             ; CODE XREF: _addItemsToIconList_fromPath_withTags+690j
                LDR     R0, =_kCFAllocatorDefault_ptr
                LDR     R2, =0x8000100          ; // kCFStringEncodingUTF8
                ADD     R1, R1, #8              ; // dirEntry->d_name;
                LDR     R0, [R0]
                LDR     R5, =psz_isEqualToString
                LDR     R0, [R0]
                BL      _CFStringCreateWithCString ;
                                                ; NSString * dirName
                                                ;     = CFStringCreateWithCString(kCFAllocatorDefault,
                                                ;                                 dirEntry->d_name,
                                                ;                                 kCFStringEncodingUTF8);
                LDR     R1, =psz_pathExtension
                LDR     R1, [R1]
                STR     R0, [SP,#0x64+dirName]
                BL      _objc_msgSend           ; NSString *ext = [dirName pathExtension];
                LDR     R1, [R5]
                LDR     R2, =cfstr_app
                MOV     R4, R0
                BL      _objc_msgSend           ; // [ext isEqualToString:@"app"];
                TST     R0, #0xFF
                BNE     process_direntry        ; if ([ext isEqualToString:@"app"])
                                                ;    goto ...
                MOV     R0, R4
                LDR     R1, [R5]
                LDR     R2, =cfstr_wdgt
                BL      _objc_msgSend           ; // [ext isEqualToString:@"wdgt"];
                TST     R0, #0xFF
                BEQ     release_direntry        ; if (![ext isEqualToString:@"wdgt"])
                                                ;    goto ...

process_direntry                                ; CODE XREF: _addItemsToIconList_fromPath_withTags+A4j
                LDR     R1, =psz_stringByAppendingPathComponent
                LDR     R2, [SP,#0x64+dirName]
                LDR     R0, [SP,#0x64+path]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; // [path stringByAppendingPathComponent:dirName]
                LDR     R2, =psz_alloc
                LDR     R1, [R2]
                STR     R0, [SP,#0x64+dirFullname] ;
                                                ; NSString * dirFullname
                                                ;     = [path stringByAppendingPathComponent:dirName];
                LDR     R0, =psz_NSBundle
                LDR     R0, [R0]
                BL      _objc_msgSend           ; // [NSBundle alloc];
                LDR     R1, =psz_initWithPath
                LDR     R2, [SP,#0x64+dirFullname]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; NSBundle *bundle
                                                ;     = [[NSBundle alloc] initWithPath:dirFullname];
                LDR     R1, =psz_infoDictionary
                LDR     R1, [R1]
                STR     R0, [SP,#0x64+bundle]
                BL      _objc_msgSend           ; NSDictionary *dict = [bundle infoDictionary];
                LDR     R1, =psz__rolesForInfoPlist
                LDR     R1, [R1]
                STR     R0, [SP,#0x64+dict]
                LDR     R2, [SP,#0x64+dict]
                LDR     R0, [SP,#0x64+self]
                BL      _objc_msgSend           ; NSArray *roleArray = [self _rolesForInfoPlist:dict];
                LDR     R3, =psz_count
                LDR     R1, [R3]
                STR     R0, [SP,#0x64+roleArray]
                BL      _objc_msgSend           ; int nRoleCount = [roleArray count];
                CMP     R0, #0
                MOVNE   R2, #0
                STR     R0, [SP,#0x64+nRoleCount]
                STRNE   R2, [SP,#0x64+value_SBIconClass] ;
                                                ; if (nRoleCount)
                                                ; {
                                                ;    value_SBIconClass = nil;
                STRNE   R2, [SP,#0x64+displayName] ;    displayName = nil;
                BNE     begin_direntry_loop     ;    goto...
                                                ; }
                LDR     R1, =psz_objectForKey
                LDR     R2, =cfstr_SBIconClass
                LDR     R0, [SP,#0x64+dict]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; value_SBIconClass
                                                ;     = [dict objectForKey:@"SBIconClass"];
                LDR     R1, =psz_displayNameForRoleDefinition_inBundle
                LDR     R2, [SP,#0x64+dict]
                LDR     R3, [SP,#0x64+bundle]
                LDR     R1, [R1]
                STR     R0, [SP,#0x64+value_SBIconClass]
                LDR     R0, [SP,#0x64+self]
                BL      _objc_msgSend           ; displayName
                                                ;     = [self displayNameForRoleDefinition:dict
                                                ;                                 inBundle:bundle];
                LDR     R3, [SP,#0x64+nRoleCount]
                MOV     R2, #1
                STR     R3, [SP,#0x64+roleArray]
                STR     R2, [SP,#0x64+nRoleCount]
                STR     R0, [SP,#0x64+displayName]

begin_direntry_loop                             ; CODE XREF: _addItemsToIconList_fromPath_withTags+148j
                MOV     R3, #0
                STR     R3, [SP,#0x64+nRoleIndex] ; nRoleIndex = 0;
                STR     R3, [SP,#0x64+bIsDefaultRole] ; bIsDefaultRole = false;
                B       check_index
; ---------------------------------------------------------------------------

loop_next_role                                  ; CODE XREF: _addItemsToIconList_fromPath_withTags+670j
                LDR     R1, =psz_objectAtIndex
                LDR     R2, [SP,#0x64+nRoleIndex]
                LDR     R0, [SP,#0x64+roleArray]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; role = [roleArray objectAtIndex:roleIndex];
                LDR     R10, =psz_objectForKey  ; R10 = objectForKey
                LDR     R2, =cfstr_LaunchArguments
                LDR     R1, [R10]
                MOV     R6, R0                  ; R6 = role;
                BL      _objc_msgSend           ; NSString * value_Arguments
                                                ;     = [role objectForKey:@"LaunchArguments"]
                LDR     R1, [R10]               ; // objectForKey
                LDR     R2, =cfstr_Role_0
                STR     R0, [SP,#0x64+value_Arguments]
                MOV     R0, R6                  ; // role
                BL      _objc_msgSend           ; NSString * value_Role
                                                ;     = [role objectForKey:@"Role"];
                LDR     R1, =psz_bundleIdentifier
                LDR     R1, [R1]
                MOV     R5, R0                  ; R5 = value_Role;
                LDR     R0, [SP,#0x64+bundle]
                BL      _objc_msgSend           ; NSString * bundleID = [bundle bundleIdentifier]
                CMP     R5, #0
                MOV     R4, R0                  ; R4 = bundleID;
                BEQ     check_bundled           ; if (!value_Role)
                                                ;    goto...
                LDR     R1, =psz_stringByAppendingFormat
                LDR     R2, =cfstr___
                MOV     R3, R5                  ; // value_Role;
                LDR     R1, [R1]
                BL      _objc_msgSend           ; bundleID
                                                ;     = [bundleID stringByAppendingFormat:@"-%@",
                                                ;                                         value_Role]
                MOV     R4, R0                  ; R4 = bundleID;

check_bundled                                   ; CODE XREF: _addItemsToIconList_fromPath_withTags+1F8j
                LDR     R1, =psz_containsObject
                LDR     R0, [SP,#0x64+displayIDs]
                MOV     R2, R4                  ; // bundleID
                LDR     R1, [R1]
                BL      _objc_msgSend           ; BOOL found =[displayIDs containsObject:bundleID];
                TST     R0, #0xFF
                BEQ     next_role               ; if (!found) // NOP this to allow scrolling
                                                ;    goto ...
                LDR     R1, =psz__updateSchemesForRoleDefinition_displayIdentifier
                LDR     R0, [SP,#0x64+self]
                MOV     R2, R6                  ; // role
                LDR     R1, [R1]
                MOV     R3, R4                  ; // bundleID
                BL      _objc_msgSend           ; [self _updateSchemesForRoleDefinition:role
                                                ;                     displayIdentifier:bundleID];
                CMP     R6, #0
                BEQ     check_args              ; if (!role)
                                                ;    goto ...
                LDR     R1, [R10]               ; // objectForKey
                LDR     R2, =cfstr_SBIconClass
                MOV     R0, R6                  ; // role
                BL      _objc_msgSend           ; NSString * value_SBIconClass
                                                ;     = [role objectForKey:@"SBIconClass"];
                LDR     R1, =psz_displayNameForRoleDefinition_inBundle
                MOV     R2, R6                  ; // role
                LDR     R3, [SP,#0x64+bundle]
                LDR     R1, [R1]
                STR     R0, [SP,#0x64+value_SBIconClass]
                LDR     R0, [SP,#0x64+self]
                BL      _objc_msgSend           ; NSString * displayName
                                                ;     = [self displayNameForRoleDefinition:role
                                                ;                                 inBundle:bundle];
                STR     R0, [SP,#0x64+displayName]

check_args                                      ; CODE XREF: _addItemsToIconList_fromPath_withTags+24Cj
                LDR     R1, =psz_length
                LDR     R0, [SP,#0x64+value_Arguments]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; len = [value_Arguments length];
                CMP     R0, #0                  ; if (len == 0)
                BEQ     init_app                ;    goto ...
                LDR     R2, =psz_alloc
                LDR     R0, =psz_NSArray
                LDR     R1, [R2]
                LDR     R0, [R0]
                BL      _objc_msgSend           ; // [NSArray alloc]
                LDR     R1, =psz_initWithObjects_count
                ADD     R2, SP, #0x64+value_Arguments
                MOV     R3, #1
                LDR     R1, [R1]
                BL      _objc_msgSend           ; NSMutableArray * array
                                                ;     = [[NSArray alloc] initWithObjects:&value_Arguments
                                                ;                                  count:1];

init_app                                        ; CODE XREF: _addItemsToIconList_fromPath_withTags+294j
                MOV     R8, R0                  ; R8 = array (or nil);
                LDR     R1, =psz_applicationWithPath_roleID_plist
                LDR     R0, =psz_SBApplication
                LDR     R3, [SP,#0x64+dict]
                LDR     R1, [R1]
                LDR     R0, [R0]
                LDR     R2, [SP,#0x64+dirFullname]
                STR     R3, [SP,#0x64+func_param]
                MOV     R3, R5                  ; // value_Role
                BL      _objc_msgSend           ; SBApplication * app
                                                ;     = [SBApplication applicationWithPath:dirFullname
                                                ;                                   roleID:value_Role
                                                ;                                    plist:dict];
                LDR     R2, =psz_count
                LDR     R1, [R2]
                MOV     R5, R0                  ; R5 = app;
                MOV     R0, R8                  ; // array
                BL      _objc_msgSend           ; // [array count];
                CMP     R0, #0
                BEQ     setup_demorole          ; if ([array count] == 0)
                                                ;    goto ...
                LDR     R1, =psz_setActivationSetting_value
                MOV     R0, R5                  ; // app
                MOV     R2, #0x200000
                LDR     R1, [R1]
                MOV     R3, R8                  ; // array
                BL      _objc_msgSend           ; [app setActivationSetting:0x200000 value:array];

setup_demorole                                  ; CODE XREF: _addItemsToIconList_fromPath_withTags+300j
                LDR     R1, =psz_setDemoRole
                LDR     R2, =cfstr_SBDemoRole
                LDR     R0, [SP,#0x64+dict]
                LDR     R4, [R1]
                LDR     R1, [R10]               ; // objectForKey
                BL      _objc_msgSend           ; // [dict objectForKey:@"SBDemoRole"];
                MOV     R1, R4                  ; // setDemoRole
                MOV     R2, R0
                MOV     R0, R5                  ; // app
                BL      _objc_msgSend           ; [app setDemoRole:[dict objectForKey:@"SBDemoRole"]];
                LDR     R1, =psz_setDisplayName
                MOV     R0, R5                  ; // app
                LDR     R2, [SP,#0x64+displayName]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; [app setDisplayName:displayName];
                LDR     R3, [SP,#0x64+bIsDefaultRole]
                CMP     R3, #0
                BNE     check_is_default_role   ; // objectForKey
                LDR     R2, [SP,#0x64+nRoleCount]
                SUB     R3, R2, #1              ; R3 = nRoleCount - 1;
                LDR     R2, [SP,#0x64+nRoleIndex]
                CMP     R2, R3
                MOVEQ   R3, #1                  ; if (nRoleCount - 1 == nRoleIndex)
                STREQ   R3, [SP,#0x64+bIsDefaultRole] ; bIsDefaultRole = true;
                BEQ     release_app

check_is_default_role                           ; CODE XREF: _addItemsToIconList_fromPath_withTags+360j
                LDR     R1, [R10]               ; // objectForKey
                LDR     R2, =cfstr_IsDefaultRole
                MOV     R0, R6                  ; // role
                BL      _objc_msgSend           ; // [role objectForKey:@"IsDefaultRole"];
                LDR     R1, =psz_boolValue
                LDR     R1, [R1]
                BL      _objc_msgSend           ; // [[role objectForKey:@"IsDefaultRole"] boolValue]
                UXTB    R0, R0
                STR     R0, [SP,#0x64+bIsDefaultRole] ;
                                                ; bIsDefaultRole
                                                ;     = [[role objectForKey:@"IsDefaultRole"] boolValue];

release_app                                     ; CODE XREF: _addItemsToIconList_fromPath_withTags+37Cj
                LDR     R3, [SP,#0x64+bIsDefaultRole]
                LDR     R1, =psz_setIsDefaultRole
                MOV     R0, R5                  ; // app
                SXTB    R2, R3                  ; // bIsDefaultRole
                LDR     R1, [R1]
                BL      _objc_msgSend           ; [app setIsDefaultRole:bIsDefaultRole];
                LDR     R2, =psz_release
                MOV     R0, R8                  ; // array
                LDR     R1, [R2]
                BL      _objc_msgSend           ; [array release];
                LDR     R1, =psz_bundleID
                MOV     R0, R5                  ; // app
                LDR     R1, [R1]
                BL      _objc_msgSend           ; // [app bundleID]
                CMP     R0, #0
                BNE     bundle_ok               ; if ([app bundleID])
                                                ;    goto...
                LDR     R0, =cfstr_SpringBoard_expects_a_bundle_at
                LDR     R1, [SP,#0x64+dirFullname]
                BL      _NSLog                  ; NSLog(@"SpringBoard expects a bundle at %@", dirFullname);
                B       next_role               ; //
; ---------------------------------------------------------------------------

bundle_ok                                       ; CODE XREF: _addItemsToIconList_fromPath_withTags+3E0j
                LDR     R3, =psz_alloc
                LDR     R0, =psz_NSMutableArray
                LDR     R1, [R3]
                LDR     R0, [R0]
                BL      _objc_msgSend           ; NSMutableArray *array
                                                ;     = [NSMutableArray alloc];
                LDR     R1, =psz_init
                LDR     R1, [R1]
                BL      _objc_msgSend           ; [array init];
                LDR     R3, =psz_displayIdentifier
                LDR     R2, =psz_addObject
                LDR     R1, [R3]
                LDR     R4, [R2]
                MOV     R8, R0                  ; R8 = array;
                MOV     R0, R5                  ; // app
                BL      _objc_msgSend           ; // [app displayIdentifier]
                MOV     R1, R4                  ; // addObject
                MOV     R2, R0
                MOV     R0, R8                  ; // array
                BL      _objc_msgSend           ; [array addObject:[app displayIdentifier]];
                LDR     R2, [SP,#0x64+tags]
                CMP     R2, #0
                BEQ     tags_is_null            ; if (!tags)
                                                ;    goto...
                LDR     R1, =psz_addObjectsFromArray
                MOV     R0, R8                  ; // array
                LDR     R1, [R1]
                BL      _objc_msgSend           ; [array addObjectsFromArray:tags];

tags_is_null                                    ; CODE XREF: _addItemsToIconList_fromPath_withTags+448j
                LDR     R0, [SP,#0x64+dict]
                LDR     R1, [R10]               ; // objectForKey
                LDR     R2, =cfstr_SBAppTags
                BL      _objc_msgSend           ; value_SBAppTags
                                                ;     = [dict objectForKey:@"SBAppTags"];
                SUBS    R11, R0, #0             ; R11 = value_SBAppTags;
                BEQ     dictvalue_is_not_array  ; if (!value_SBAppTags)
                                                ;    goto...
                LDR     R1, =psz_isKindOfClass
                LDR     R0, =psz_NSArray
                LDR     R4, [R1]
                LDR     R1, =psz_class
                LDR     R0, [R0]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; // [NSArray class]
                MOV     R1, R4                  ; // isKindOfClass
                MOV     R2, R0                  ; // [NSArray class]
                MOV     R0, R11                 ; // value_SBAppTags
                BL      _objc_msgSend           ; // [value_SBAppTags isKindOfClass:[NSArray class]];
                TST     R0, #0xFF
                BEQ     dictvalue_is_not_array  ; if (![value_SBAppTags isKindOfClass:[NSArray class]])
                                                ;    goto...
                LDR     R1, =psz_addObjectsFromArray
                MOV     R0, R8                  ; // array
                MOV     R2, R11                 ; // value_SBAppTags
                LDR     R1, [R1]
                BL      _objc_msgSend           ; [array addObjectsFromArray:value_SBAppTags];

dictvalue_is_not_array                          ; CODE XREF: _addItemsToIconList_fromPath_withTags+470j
                                                ; _addItemsToIconList_fromPath_withTags+4A4j
                MOV     R0, R6                  ; // role
                LDR     R1, [R10]               ; // objectForKey
                LDR     R2, =cfstr_SBAppTags
                BL      _objc_msgSend           ; value_SBAppTags
                                                ;     = [role objectForKey:@"SBAppTags"];
                SUBS    R11, R0, #0             ; R11 = value_SBAppTags;
                BEQ     set_tags                ; if (!value_SBAppTags)
                                                ;    goto...
                LDR     R1, =psz_isKindOfClass
                LDR     R0, =psz_NSArray
                LDR     R4, [R1]
                LDR     R1, =psz_class
                LDR     R0, [R0]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; // [NSArray class]
                MOV     R1, R4                  ; // isKindOfClass
                MOV     R2, R0
                MOV     R0, R11                 ; // value_SBAppTags
                BL      _objc_msgSend           ; // [value_SBAppTags isKindOfClass:[NSArray class]];
                TST     R0, #0xFF
                BEQ     set_tags                ; if (![value_SBAppTags isKindOfClass:[NSArray class]])
                                                ;    goto...
                LDR     R1, =psz_addObjectsFromArray
                MOV     R0, R8                  ; // array
                MOV     R2, R11                 ; // value_SBAppTags
                LDR     R1, [R1]
                BL      _objc_msgSend           ; [array addObjectsFromArray:value_SBAppTags];

set_tags                                        ; CODE XREF: _addItemsToIconList_fromPath_withTags+4D0j
                                                ; _addItemsToIconList_fromPath_withTags+504j
                LDR     R1, =psz_setTags
                MOV     R2, R8                  ; // array
                MOV     R0, R5                  ; // app
                LDR     R1, [R1]
                BL      _objc_msgSend           ; [app setTags:array];
                LDR     R3, =psz_release
                MOV     R0, R8                  ; // array
                LDR     R1, [R3]
                BL      _objc_msgSend           ; [array release];
                LDR     R2, [SP,#0x64+value_SBIconClass]
                CMP     R2, #0
                BEQ     get_icon_class          ; if (!value_SBIconClass)
                                                ;    goto...
                MOV     R0, R2
                BL      _NSClassFromString      ; id iconClass = NSClassFromString(value_SBIconClass);
                CMP     R0, #0
                BNE     setup_icon              ; if (!iconClass)
                                                ;    goto...

get_icon_class                                  ; CODE XREF: _addItemsToIconList_fromPath_withTags+548j
                LDR     R0, =psz_SBApplicationIcon
                LDR     R1, =psz_class
                LDR     R0, [R0]
                LDR     R1, [R1]
                BL      _objc_msgSend           ; iconClass = [SBApplication class]

setup_icon                                      ; CODE XREF: _addItemsToIconList_fromPath_withTags+558j
                LDR     R3, =psz_alloc
                LDR     R1, [R3]
                BL      _objc_msgSend           ; [iconClass alloc];
                LDR     R1, =psz_initWithApplication
                MOV     R2, R5                  ; // app
                LDR     R1, [R1]
                BL      _objc_msgSend           ; NSApplicationIcon *appIcon
                                                ;     = [iconClass initWithApplication:app];
                SUBS    R4, R0, #0              ; R4 = appIcon
                BEQ     next_role               ; if (!appIcon)
                                                ;    goto...
                LDR     R1, =psz_setIsRevealable
                LDR     R2, =cfstr_SBIsRevealable
                MOV     R0, R6                  ; // role
                LDR     R8, [R1]
                LDR     R1, [R10]               ; // objectForKey
                BL      _objc_msgSend           ; value_SBIsRevealable = [role objectForKey:@"SBIsRevealable"];
                LDR     R1, =psz_boolValue
                LDR     R1, [R1]
                BL      _objc_msgSend           ; bIsRevealable = [value_SBIsRevealable boolValue];
                MOV     R1, R8                  ; // setIsRevealable
                SXTB    R2, R0                  ; R2 = bIsRevealable;
                MOV     R0, R4                  ; // appIcon
                BL      _objc_msgSend           ; [appIcon setIsRevealable:bIsRevealable];
                LDR     R1, =psz_addTarget_action_forEvents
                LDR     R3, =psz_clickedIcon
                MOV     R2, #0x40
                LDR     R1, [R1]
                LDR     R3, [R3]
                MOV     R0, R4                  ; // appIcon
                STR     R2, [SP,#0x64+func_param]
                LDR     R2, [SP,#0x64+self]
                BL      _objc_msgSend           ; [appIcon addTarget:self
                                                ;             action:@selector(clickedIcon)
                                                ;          forEvents:0x40];
                LDR     R2, =psz_displayIdentifier
                MOV     R0, R5                  ; // app
                LDR     R1, [R2]
                BL      _objc_msgSend           ; displayID = [app displayIdentifier]
                SUBS    R5, R0, #0              ; R5 = displayID;
                BEQ     release_icon            ; if (!displayID)
                                                ;    goto...
                LDR     R0, [SP,#0x64+items]
                LDR     R1, [R10]               ; // objectForKey
                MOV     R2, R5                  ; // displayID
                BL      _objc_msgSend           ; value_displayID = [items objectForKey:displayID];
                CMP     R0, #0
                BEQ     display_id_value_is_null ; if (!value_displayID)
                                                ;    goto...
                LDR     R3, [SP,#0x64+self]
                LDR     R2, =psz_addObject
                LDR     R0, [R3,#0x2C]          ; NSMutableArray *_duplicateIcons;
                LDR     R1, [R2]
                MOV     R2, R4                  ; // appIcon
                BL      _objc_msgSend           ; [_duplicateIcons addObject:appIcon];
                B       release_icon
; ---------------------------------------------------------------------------

display_id_value_is_null                        ; CODE XREF: _addItemsToIconList_fromPath_withTags+618j
                LDR     R0, [SP,#0x64+items]
                MOV     R1, R5                  ; // displayID
                MOV     R2, R4                  ; // appIcon
                BL      _CFDictionarySetValue   ; //void CFDictionarySetValue (
                                                ; //   CFMutableDictionaryRef dict,
                                                ; //   const void *key,
                                                ; //   const void *value
                                                ; //);
                                                ; CFDictionarySetValue(items, displayID, appIcon);

release_icon                                    ; CODE XREF: _addItemsToIconList_fromPath_withTags+600j
                                                ; _addItemsToIconList_fromPath_withTags+634j
                LDR     R3, =psz_release
                MOV     R0, R4                  ; // appIcon
                LDR     R1, [R3]
                BL      _objc_msgSend           ; [appIcon release];

next_role                                       ; CODE XREF: _addItemsToIconList_fromPath_withTags+22Cj
                                                ; _addItemsToIconList_fromPath_withTags+3F0j ...
                LDR     R2, [SP,#0x64+nRoleIndex] ; //
                ADD     R2, R2, #1              ; //
                STR     R2, [SP,#0x64+nRoleIndex] ; nRoleIndex++;

check_index                                     ; CODE XREF: _addItemsToIconList_fromPath_withTags+19Cj
                LDR     R3, [SP,#0x64+nRoleIndex]
                LDR     R2, [SP,#0x64+nRoleCount]
                CMP     R3, R2
                BLT     loop_next_role          ; if (roleIndex < roleCount)
                                                ;    goto...

release_direntry                                ; CODE XREF: _addItemsToIconList_fromPath_withTags+BCj
                LDR     R3, =psz_release
                LDR     R0, [SP,#0x64+dirName]
                LDR     R1, [R3]
                BL      _objc_msgSend           ; [dirName release];

read_next_direntry                              ; CODE XREF: _addItemsToIconList_fromPath_withTags+60j
                LDR     R0, [SP,#0x64+dir]      ; DIR *
                BL      _readdir                ; struct dirent *dirEntry
                                                ;     = readdir(dir);
                SUBS    R1, R0, #0              ; R1 = dirEntry;
                BNE     loop_check_direntry     ; if (dirEntry)
                                                ;    goto ...
                LDR     R0, [SP,#0x64+dir]      ; DIR *
                BL      _closedir               ; closedir(dir);

return                                          ; CODE XREF: _addItemsToIconList_fromPath_withTags+38j
                SUB     SP, R7, #0x18
                LDMFD   SP!, {R8,R10,R11}
                LDMFD   SP!, {R4-R7,PC}
; End of function _addItemsToIconList_fromPath_withTags

NOTE: My scrolling patch is based on this listing, what I did was converting the above disassembly to Object-C source lines, compiling a shared dynamic library, then interposing the library to override the default method. Although the reversing is a time consuming stuff, it’s very interesting to convert the ARM disassembly to Object-C source. Since Apple’s development tools generate very reversing friendly executables, the Object-C source created from the disassembly is almost exactly the same as the original.


One Comment

  1. Posted March 19, 2008 at 11:21 pm | Permalink

    Nice site!

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*