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[/sourcecode] 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!

WordPress Appliance - Powered by TurnKey Linux