Before read this article, I have to say something. Because the book are using iOS 8 & ArmV7 & IDA environment, therefore, some solution are not fit in my situation, I using iOS10.2 & Arm64 & Hooper. So, I decided to recording my whole debugging process and share to the iOSRE community.
First of all, I need to thanks the author “snakeninny” of books iOS Reversing engineering, and many other
experts in the iOSRE QQ group, also my company team give me so many time to kill this book. All people
give me so many suggestions to through this struggle debugging stage.
Finally! I use my environment to found out the final goal “My Number” value.
This article is not a rewrite version of the book chapter 6.2, which it just an update information of iOS 10.2, Arm64, Hooper V4. Enjoy it! If you have any issues, please feel free to contact me (iOSRE QQ Wangdu).
In book page 187, the PhonesettingListController instance method didn’t have cellForRowAtIndexPath, but in my case that I do have it in PhoneSettingsListController.
We go to PhoneSettingsListController set br at 0x0000000196825334 mov x0, x20, and enter ni. Now we knew the x0 has the my number value. Which means in PhoneSettingsListController’s x20 are the return value of my nubmer value.
Keeping track up, we will see the x20 has an cbz x20, loc_196825328 instruction, which mean is x20 == 0 will jump to loc_196825328.
The interesting thing happen when set br at 0x1968252d8 mov x20, x3, everytime I ni to 0x19ce8d2f0 <+44>: str x21, [sp], it will jump to PhoneSettingsController, and go back to PhoneSettingsListController, with next row text value (the next row is Announce Call). So here we can know PhoneSettingsController use msgSendSuper2 to call super class’s cellForRowAtIndexPath, which has a for loop to insert value to the cell.
But this for loop doesn’t means nothing, because “maybe” the real phone number not get from both these two place:
Back to set br at “0000000196825334 mov x0, x20” (Figure 6-5), which this br is the key step. It previous br is a “0000000196825330 bl 0x18f0f2630”, therefore, we can assume this branch is to call a method to get the cell text value. Let’s set br at this bl. After try some work on this br, still can’t figure out useful information, therefore, I decide go track up those previous bl. Finally I found one of bl (Figure 6-9) will call msgSendSuper2! The $x0 will contain the My Number Value, but I can’t see any MOV value to the $x0 after this msgSendSuper2. So I assume the $x0 are already be inserted value by super class.
Ok, let’s use pclass to check it’s super class:
(lldb) pclass [PhoneSettingsListController new]
| | PSViewController
| | | UIViewController
| | | | UIResponder
| | | | | NSObject
This PSListController maybe has tableView:cellForRowAtIndexPath, let’s use po [PSListController _shortMethodDescription] to check it:
We got it, let’s try hooper to see it’s instruction structure:
It is very long! But first, we just need to make sure this PSListController cellForRowAtIndexPath really has the my phone number, therefore, we just need to set br at bottom (blue square) of this process tree.
Here is the result. It did has the phone number value, and we can know the key argument is $x24:
So far, we knew this PSListController definetly is the key to retrieve the phone number, and the key arg is x24, but this process tree has many x24, how can we know which bl (msgSend) is the right place? According to the book, we can use dichotomy ways to check the process. Take closely we can start at loc_18a7854444 process, because before go to the end of process, all the upper process will go to this block. We try to set br at the first bl “000000018a785450 bl 0x18750f4e8”.
The first bl in this process block has no phone number value. So let’s try second one. Ok, two bl all has no target number, therefore, we assume the value must comes from 2 blocks between this block and the end of this process block (Figure 6-13).
According to Figure 6-15, we can try set br at two bl. After try this two bl, finally knew after the second bl executed, which I set the br at the “00000018a785494 adrp x8, #0x1a5deb000”, the $x24 has the phone number.
We are almost there! Let’s set br at this the second bl and to see it’s argument value.
Yes!!!Finally, we use iOS10.2 and Arm64 tracking all the way down found the same target with iOSRE books page. 196, give us a applause!
Just like books said, the $x1 is the (char *) $46 = 0x00000001a438e50e “refreshCellContentsWithSpecifier:”, and po the $x2 can know PSSpecifier. And other information about $x2 are all just as same as book page. 196, so I just pass this explanation, keep going forward.
But the next page. 197 are different with reality again! in Hooper v4 we can’t see which instruction are relate to PhoneSettingsTelephony, it only so a green string. But if you hover mouse on that green string it will come out many information, even though I don’t know what it’s meaning (But after this article I knew those green string meaning, see this link). Never mind, we still can use what we learned before, try to set br to see when is the phone number retrieved! First, see the PhoneSettingsController myNumber structures, I try to simply take a guess at cbnz instruction, because books say in myNumber it will try to check the phone number value, if no value then show “unknow” on iphone:
At this br, we found this bl will return $x0 a phone value
Let’s use s command in lldb to step into the bl.
Wow, we found out here has PhoneSettingTelephony myNumber, just like iOSRE books said, but the book didn’t show how to find it, so here is the way i found it by using books skills.
Greate it work! We can test by cycript to see is it really can get number. Just like books told, the phone number will shop up only when user into the phone setting interface, and the mobilePhoneSetting.bundle loaded, our goal is to find out an other way that no need to loaded the bundle to get the number. Let’s try check the [PhoneSettingsTelephony myNumber]!
The whole process tree of this [PhoneSettingsTelephony myNumber] is very big (Figure 6-24), but we can easily to see an one key method called in this process (Figure 6-25).
Very clear, this picture show the key method is called PhoneSettingsGetMyNumber(). But wait….it is not as same as books’s method “PhoneSettingsCopyMyNumber”. Anyway, because iOS8 to iOS10 are at least two years. The naming of method still make sense. Let’s check this PhoneSettingsGetMyNumber() (Figure 6-26)
According to the books, it also methion about the PhoneSettingsCopyFormattedNumberBySIMCountry. In this PhoneSettingsGetMyNumber still has similar method call “PhoneSettingsGetsFormattedNumberBySIMCountry”. We also very sure before the …BySIMCountry method, the PhoneSettingsGetMyNumber must already get the number and pass it to the formatter method. The Figure 6-26 show before the formatter method only have on bl. Let’s step into it to see the logic.
Bang! We found CTSettingCopyMyPhoneNumber method, finally back to books instrusction again.
Because Hooper not just like IDA can see the bl method, only show the address… So can not double click to track the bl. Therefore, what I did is to copy the string “CTSettingCopyMyPhoneNumber” into search bar. Then it show out the location of this method! I go to the Path on my Xcode System:
/Users/xxxx/Library/Developer/Xcode/iOS DeviceSupport/10.2 (14C77)/Symbols/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony.
The path is not on the iPhone just like MobilePhoneSettings.bundle. After drop into the hooper choose arm64 we can see the inside logic of method, you can compare books page 198 & 199.
In the end follow book’s instructment, we perfectly sure CTSettingCopyMyPhoneNumber is the final method, and by reading the assembly instrunction we also know this method has no argument (according to the book), and the return value is a NSCFString.
Thanks you for your patience, I will skip the rest of steps in the book, because I believe after reading this article you already have ability to overcome other obstacles. Bless you my friend. Welcome contact with me have further discussion.