天天看點

android 擷取usb serialnumber,iOS9擷取手機序列号serialNumber(UDID)

前言

在iOS7之前我們可以通過- (NSString *)uniqueIdentifier這個方法擷取iPhone的唯一辨別符,也叫作UDID。不過自從iOS7蘋果就把這個方法給禁了,此時我們想要擷取iPhone的唯一辨別符就很困難。

不過蘋果提供一個叫做IDFA的辨別符,這個IDFA是廣告辨別符用來追蹤廣告投放的,不過使用者可以在設定中手動重置IDFA,可靠性很低,目前常見的兩種标記iPhone的方式為

openUDID

IDFA或UUID+keychain

這兩種模式都有個弊端,使用者重置手機或者刷機唯一辨別符會發生變化,不過對于大多數情況是夠用了。看來蘋果是把路給封死了,有沒有辦法拿到之前的UDID呢?我們注意到iPhone的設定通用關于裡面有手機的硬體資訊,其中有一個serialNumber,這個serialnumber就是我們查詢手機是否過保的依據,那麼它肯定是唯一的,是以下文是圍繞這個進行的探索。最終是可以拿到這個serialNumber的, 不過由于蘋果的沙盒限制,是以隻能在越獄機中拿到,如果想在非越獄機中拿到必須添加entitlements檔案來擷取權限,可想而知這個應用是無法上架的。下文僅作為逆向工程的一種思路和探索。

正文

一、SSH連接配接手機(USB模式)

1.映射端口

LeonLei-MBP:~ gaoshilei$ /Users/gaoshilei/Desktop/reverse/USBSSH/tcprelay.py -t 22:6666

Forwarding local port 6666 to remote port 22

2.連接配接手機,并且用grep指令快速篩選目前我們要調試的應用Preferences,附加debugserver開始1234端口等待lldb調試

LeonLei-MBP:~ gaoshilei$ ssh [email protected] -p 6666

iPhone-5S:~ root# ps -e | grep Pre

270 ?? 0:00.29 /System/Library/PrivateFrameworks/MobileSoftwareUpdate.framework/XPCServices/com.apple.MobileSoftwareUpdate.CleanupPreparePathService.xpc/com.apple.MobileSoftwareUpdate.CleanupPreparePathService

1192 ?? 0:14.26 /var/db/stash/_.fP74Fg/Applications/Preferences.app/Preferences

1289 ttys000 0:00.01 grep Pre

iPhone-5S:~ root# debugserver *:1234 -a "Preferences"

[email protected](#)PROGRAM:debugserver PROJECT:debugserver-340.3.51.1

for arm64.

Attaching to process Preferences...

Listening to port 1234 for a connection from *...

3.完成以上兩步接下來就可以進行lldb調試了,首先要把遠端(手機)的1234端口映射到本地,跟前面提到的SSH端口映射一樣

LeonLei-MBP:~ gaoshilei$ /Users/gaoshilei/Desktop/reverse/USBSSH/tcprelay.py -t 1234:1234

Forwarding local port 1234 to remote port 1234

二、通過LLDB、IDA尋找線索

lldb的調試端口已經打開,此時我們可以進入調試

LeonLei-MBP:~ gaoshilei$ lldb

(lldb) process connect connect://localhost:1234

Process 1192 stopped

* thread #1: tid = 0x523a6, 0x000000019a3c8a40 libsystem_kernel.dylib`mach_msg_trap + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP

frame #0: 0x000000019a3c8a40 libsystem_kernel.dylib`mach_msg_trap + 8

libsystem_kernel.dylib`mach_msg_trap:

-> 0x19a3c8a40 : ret

libsystem_kernel.dylib`mach_msg_overwrite_trap:

0x19a3c8a44 : movn x16, #0x1f

0x19a3c8a48 : svc #0x80

0x19a3c8a4c : ret

此時我們已經成功進入Preferences的調試階段,先c一下,讓程式繼續運作

(lldb) c

Process 1192 resuming

這麼做的原因是我們待會要列印image的基位址偏移,有可能在我們列印的image list中沒有我們想要的image。

此時我們已經找到到Preference.framework的基位址偏移,見下圖

(lldb) im li -o -f

[ 0] 0x00000000000dc000 /var/db/stash/_.fP74Fg/Applications/Preferences.app/Preferences(0x00000001000dc000)

[ 1] 0x0000000100100000 /Library/MobileSubstrate/MobileSubstrate.dylib(0x0000000100100000)

[ 2] 0x0000000002e50000 /Users/gaoshilei/Library/Developer/Xcode/iOS DeviceSupport/9.1 (13B143)/Symbols/System/Library/PrivateFrameworks/BulletinBoard.framework/BulletinBoard

[ 3] 0x0000000002e50000 /Users/gaoshilei/Library/Developer/Xcode/iOS DeviceSupport/9.1 (13B143)/Symbols/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation

[ 4] 0x0000000002e50000 /Users/gaoshilei/Library/Developer/Xcode/iOS DeviceSupport/9.1 (13B143)/Symbols/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit

[ 44] 0x0000000002e50000 /Users/gaoshilei/Library/Developer/Xcode/iOS DeviceSupport/9.1 (13B143)/Symbols/System/Library/PrivateFrameworks/Preferences.framework/Preferences

我們要找的image的序号在這裡是44,它的基位址偏移為0x2e50000,我們把從iPhone中導出的PrivateFrameworks中的Preferences.framework丢到IDA中進行分析,這個二進制檔案比較小,很快就分析完成,在前面我們已經知道iPhone的唯一序列号serial number是通過PSListController生成的,并且我們知道這是一個cell,我們要去調試[PSListController tableView:cellForRowAtIndexPath:]這個方法,從中找到cell值的來源,進而找到擷取序列号的方法。

__text:00000001908040C8 ; -[PSListController tableView:cellForRowAtIndexPath:]

__text:00000001908040C8 __PSListController_tableView_cellForRowAtIndexPath__

__text:00000001908040C8 ; DATA XREF: __objc_const:000000019C069B88�o

__text:00000001908040C8

__text:00000001908040C8 var_80 = -0x80

__text:00000001908040C8 var_78 = -0x78

__text:00000001908040C8 var_70 = -0x70

__text:00000001908040C8 var_68 = -0x68

__text:00000001908040C8 var_60 = -0x60

__text:00000001908040C8 var_50 = -0x50

__text:00000001908040C8 var_40 = -0x40

__text:00000001908040C8 var_30 = -0x30

__text:00000001908040C8 var_20 = -0x20

__text:00000001908040C8 var_10 = -0x10

__text:00000001908040C8

__text:00000001908040C8 STP X28, X27, [SP,#var_60]!

__text:00000001908040CC STP X26, X25, [SP,#0x60+var_50]

__text:00000001908040D0 STP X24, X23, [SP,#0x60+var_40]

__text:00000001908040D4 STP X22, X21, [SP,#0x60+var_30]

__text:00000001908040D8 STP X20, X19, [SP,#0x60+var_20]

__text:00000001908040DC STP X29, X30, [SP,#0x60+var_10]

__text:00000001908040E0 ADD X29, SP, #0x60+var_10

__text:00000001908040E4 SUB SP, SP, #0x20

__text:00000001908040E8 MOV X21, X3

__text:00000001908040EC MOV X20, X0

__text:00000001908040F0 MOV X0, X2

__text:00000001908040F4 BL 0x96C400A0

__text:00000001908040F8 MOV X26, X0

__text:00000001908040FC ADRP X8, #[email protected]

__text:0000000190804100 LDR X1, [X8,#[email protected]]

__text:0000000190804104 MOV X0, X20

__text:0000000190804108 MOV X2, X21

__text:000000019080410C BL 0x96C39BC0

__text:0000000190804110 MOV X2, X0

__text:0000000190804114 ADRP X8, #[email protected] ; NSArray *_specifiers;

__text:0000000190804118 LDRSW X27, [X8,#[email protected]] ; NSArray *_specifiers;

__text:000000019080411C LDR X0, [X20,X27]

__text:0000000190804120 ADRP X8, #[email protected]

……

我們在Preference.framework中基位址為0x190804114的位置打個斷點,具體的做法是:

(lldb) br s -a 0x190804114+0x2e50000

Breakpoint 1: where = Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 76, address = 0x0000000193654114

Process 1192 stopped

* thread #1: tid = 0x523a6, 0x0000000193654114 Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 76, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1

frame #0: 0x0000000193654114 Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 76

Preferences`-[PSListController tableView:cellForRowAtIndexPath:]:

-> 0x193654114 : adrp x8, 53965

0x193654118 : ldrsw x27, [x8, #516]

0x19365411c : ldr x0, [x20, x27]

0x193654120 : adrp x8, 53960

這裡斷點這樣打是因為系統加載可執行檔案和各種framework的時候會有一個位址偏移,我們在打斷點的時候要把這個偏移量加上,這樣我們打的斷點才是準确的。

可以看到我們已經成功打了一個斷點,斷點的address = 0x193654114。此時我們列印變量x0和x27的值

(lldb) po $x0

13

(lldb) po $x27

1104

我們執行ni讓程式繼續(這裡的ni指令相當于Xcode的那個下箭頭指令,也就是下一行)

(lldb) ni

Process 1192 stopped

* thread #1: tid = 0x523a6, 0x0000000193654118 Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 80, queue = 'com.apple.main-thread', stop reason = instruction step over

frame #0: 0x0000000193654118 Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 80

Preferences`-[PSListController tableView:cellForRowAtIndexPath:]:

-> 0x193654118 : ldrsw x27, [x8, #516]

0x19365411c : ldr x0, [x20, x27]

0x193654120 : adrp x8, 53960

0x193654124 : ldr x22, [x8, #1368]

(lldb) ni

Process 1192 stopped

* thread #1: tid = 0x523a6, 0x000000019365411c Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 84, queue = 'com.apple.main-thread', stop reason = instruction step over

frame #0: 0x000000019365411c Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 84

Preferences`-[PSListController tableView:cellForRowAtIndexPath:]:

-> 0x19365411c : ldr x0, [x20, x27]

0x193654120 : adrp x8, 53960

0x193654124 : ldr x22, [x8, #1368]

0x193654128 : mov x1, x22

(lldb) po $x27

848

(lldb) po $x0

13

我們ni的兩次,程式已經走到0x19080411C的位置,然後我們繼續列印變量x0和x27的值

(lldb) po $x0

13

(lldb) po $x27

1104

列印出來的x0和x27都是随機數,還是沒有什麼收獲,我們繼續

(lldb) ni

Process 1192 stopped

* thread #1: tid = 0x523a6, 0x0000000193654120 Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 88, queue = 'com.apple.main-thread', stop reason = instruction step over

frame #0: 0x0000000193654120 Preferences`-[PSListController tableView:cellForRowAtIndexPath:] + 88

Preferences`-[PSListController tableView:cellForRowAtIndexPath:]:

-> 0x193654120 : adrp x8, 53960

0x193654124 : ldr x22, [x8, #1368]

0x193654128 : mov x1, x22

0x19365412c : bl 0x199a89bc0 ; objc_msgSend

(lldb) po $x0

<__nsarrayi>(

G: > 0x12ff50cf0,

>,

G: > 0x12ff51680,

>,

>,

>,

>,

>,

>,

>,

>,

>,

>,

>,

>,

>,

>,

G: > 0x131031e90,

>,

G: > 0x131029dc0,

>

)

我們讓程式執行下一步,發現此時x0已經有值了,可以明顯的看出,x0的值是在0x190804114~0x19080411C這段代碼生成的,下面我們的工作重點就是尋找這段代碼幹了什麼,勝利就在眼前!下面我們驗證一下這裡面到底有沒有我們要的序列号:

(lldb) po [[$x0 objectAtIndex:13] class]

PSSpecifier

(lldb) po [[$x0 objectAtIndex:13] properties]

{

cellObject = "; layer = >";

id = SerialNumber;

isCopyable = 1;

value = DNPMVG0EFF9V;

}

我們列印數組中存放cell資料的object屬于哪個類,發現是PSSpecifier,我們找到之前導出的類的頭檔案,發現這個類有一個叫做properties的執行個體方法,我們調用一下發現我們要的序列号就在裡面value = DNPMVG0EFF9V,這跟iPhone設定中看到的序列号是一緻的。猜測這個數組裡面存放着系統設定中PSUIAboutController中所有cel的資料,這個數組下一個肯定要傳遞到cell生成的方法中,這個就不做驗證了,大事重要,我們繼續找序列号的生成方法。

這個PSSpecifier中有一個AboutDataSource對象,這個非常可疑,從名稱上可以判斷,這個類是專門用于資料處理的,不過在這之前我們還是先驗證一下,在0x190804114~0x19080411C這段位址中,執行了_PSListController._specifiers,我們從PSListController的頭檔案(下文有講怎麼擷取)中可以看到有一個specifiers屬性,我們在IDA分析的檔案中找到[PSListController specifiers],我們先定位到方法在二進制檔案中的位置:

__text:00000001907FE4A8 ; -[PSListController specifiers]

__text:00000001907FE4A8 __PSListController_specifiers_ ; DATA XREF: __objc_const:000000019C069A08�o

__text:00000001907FE4A8

__text:00000001907FE4A8 var_40 = -0x40

__text:00000001907FE4A8 var_30 = -0x30

__text:00000001907FE4A8 var_20 = -0x20

__text:00000001907FE4A8 var_10 = -0x10

__text:00000001907FE4A8

__text:00000001907FE4A8 STP X24, X23, [SP,#var_40]!

__text:00000001907FE4AC STP X22, X21, [SP,#0x40+var_30]

__text:00000001907FE4B0 STP X20, X19, [SP,#0x40+var_20]

__text:00000001907FE4B4 STP X29, X30, [SP,#0x40+var_10]

__text:00000001907FE4B8 ADD X29, SP, #0x40+var_10

__text:00000001907FE4BC MOV X19, X0

__text:00000001907FE4C0 ADRP X8, #[email protected] ; NSArray *_specifiers;

__text:00000001907FE4C4 LDRSW X22, [X8,#[email protected]] ; NSArray *_specifiers;

__text:00000001907FE4C8 LDR X8, [X19,X22]

__text:00000001907FE4CC CBNZ X8, loc_1907FE5E0

__text:00000001907FE4D0 ADRP X8, #[email protected] ; id _dataSource;

__text:00000001907FE4D4 LDRSW X8, [X8,#[email protected]] ; id _dataSource;

__text:00000001907FE4D8 LDR X9, [X19,X8]

__text:00000001907FE4DC CBZ X9, loc_1907FE550

__text:00000001907FE4E0 ADRP X9, #_O[email protected]PAGE ; bool _requestingSpecifiersFromDataSource;

__text:00000001907FE4E4 LDRSW X23, [X9,#_O[email protected]PAGEOFF] ; bool _requestingSpecifiersFromDataSource;

__text:00000001907FE4E8 MOV W9, #1

__text:00000001907FE4EC STRB W9, [X19,X23]

__text:00000001907FE4F0 LDR X20, [X19,X8]

__text:00000001907FE4F4 ADRP X8, #[email protected]

__text:00000001907FE4F8 LDR X1, [X8,#[email protected]]

__text:00000001907FE4FC MOV X0, X19

__text:00000001907FE500 BL 0x96C39BC0

__text:00000001907FE504 MOV X29, X29

__text:00000001907FE508 BL 0x96C41EF0

__text:00000001907FE50C MOV X21, X0

__text:00000001907FE510 ADRP X8, #[email protected]

__text:00000001907FE514 LDR X1,

……

然後在這裡面下個斷點看看會發生什麼

(lldb) br s -a 0x1907FE4D0+0x198e58640

Breakpoint 9: where = Preferences`-[PSListController specifiers] + 40, address = 0x000000019364e4d0

我們從設定中進入通用>關于,發現一開始就走到了這個斷點,我們猜測,一進入關于頁面,系統會首先把所有cell的資料都準備好,然後加載UI

Process 1192 stopped

* thread #1: tid = 0x523a6, 0x000000019364e4d0 Preferences`-[PSListController specifiers] + 40, queue = 'com.apple.main-thread', stop reason = breakpoint 9.1

frame #0: 0x000000019364e4d0 Preferences`-[PSListController specifiers] + 40

Preferences`-[PSListController specifiers]:

-> 0x19364e4d0 : adrp x8, 53971

0x19364e4d4 : ldrsw x8, [x8, #536]

0x19364e4d8 : ldr x9, [x19, x8]

0x19364e4dc : cbz x9, 0x19364e550 ;

我們列印變量x8和x9的值,看一下系統做了什麼

(lldb) po $x8

(lldb) po $x9

PSUIAboutController

并沒有資料之類的東西值得我們關注,讓斷點繼續往下走,走到0x19364e4dc的位置,我們再次列印變量x8和x9的值

(lldb) n

Process 1192 stopped

* thread #1: tid = 0x523a6, 0x000000019364e4dc Preferences`-[PSListController specifiers] + 52, queue = 'com.apple.main-thread', stop reason = instruction step over

frame #0: 0x000000019364e4dc Preferences`-[PSListController specifiers] + 52

Preferences`-[PSListController specifiers]:

-> 0x19364e4dc : cbz x9, 0x19364e550 ;

0x19364e4e0 : adrp x9, 53971

0x19364e4e4 : ldrsw x23, [x9, #540]

0x19364e4e8 : orr w9, wzr, #0x1

(lldb) po $x8

952

(lldb) po $x9

此時的變量x9已經變成了AboutDataSource,這裡驗證了我們上一步的猜想,是以我們重點來研究它,我們先找到這個類在哪個framework中,這裡使用的是grep指令

LeonLei-MBP:~ gaoshilei$ grep AboutDataSource -r /Users/gaoshilei/Desktop/reverse/iOS-Runtime-Headers-9.1

/Users/gaoshilei/Desktop/reverse/iOS-Runtime-Headers-9.1/PrivateFrameworks/PreferencesUI.framework/AboutDataSource.h:@interface AboutDataSource : PSSpecifierDataSource {

這裡要說明一下iOS-Runtime-Headers-9.1這個檔案夾是iOS9.1系統的所有頭檔案(共有+私有),這個你可以自己導(iOS9之後隻能用runtime導,class-dump已經不行了),你也可以拿現成的用,github上面已經有雷鋒把所有系統的頭檔案都導出來了,直接下載下傳就可以了。我們發現AboutDataSource這個類在PrivateFrameworks/PreferencesUI.framework中,先看一下這個類裡面有什麼方法和屬性,有一個方法- (void)_loadValues; 我們對它進行分析。這裡又要借助IDA分析,把PreferencesUI這個二進制檔案丢到IDA裡面,在0x19091EBB8這個位置打個斷點

(lldb) br s -a 0x19091EBB8+0x2e50000

Breakpoint 3: where = PreferencesUI`-[AboutDataSource _loadValues] + 1956, address = 0x000000019376ebb8

接下來我們進入關于來觸發斷點

(lldb) po (char *) $x28

"_setValue:forSpecifierWithKey:"

在這裡列印變量x28的值,發現它是一個方法名,從名稱來看是給specifier指派的,看來我們要尋找的真相已經很近了,讓代碼走到下面的位置0x19376ebd8

Process 2107 stopped

* thread #1: tid = 0xe8e23, 0x000000019376ebd8 PreferencesUI`-[AboutDataSource _loadValues] + 1988, queue = 'com.apple.main-thread', stop reason = instruction step over

frame #0: 0x000000019376ebd8 PreferencesUI`-[AboutDataSource _loadValues] + 1988

PreferencesUI`-[AboutDataSource _loadValues]:

-> 0x19376ebd8 : bl 0x198e58640 ; MGCopyAnswer

0x19376ebdc : mov x22, x0

0x19376ebe0 : mov x1, x19

0x19376ebe4 : bl 0x199a89bc0 ; objc_msgSend

(lldb) po $x0

SerialNumber

此時我們列印的x0是一個NSCFConstantString,本質就是一個NSString,繼續ni讓程式運作到0x19376ebdc

Process 2107 stopped

* thread #1: tid = 0xe8e23, 0x000000019376ebdc PreferencesUI`-[AboutDataSource _loadValues] + 1992, queue = 'com.apple.main-thread', stop reason = instruction step over

frame #0: 0x000000019376ebdc PreferencesUI`-[AboutDataSource _loadValues] + 1992

PreferencesUI`-[AboutDataSource _loadValues]:

-> 0x19376ebdc : mov x22, x0

0x19376ebe0 : mov x1, x19

0x19376ebe4 : bl 0x199a89bc0 ; objc_msgSend

0x19376ebe8 : cbnz x0, 0x19376ec4c ;

(lldb) po $x0

DNPMVG0EFF9V

在這裡我們列印了變量x0的值為DNPMVG0EFF9V,這就是我們苦苦尋找的序列号。不難看出,序列号就是在0x19376ebd8這行拿到的,範圍越來越小,敵人無路可逃!下面我們就要對這行進行分析,我們按照之前的步驟,再次走到0x19376ebd8這個位置,這不過這次我們不要step-over,我們用si跳入看看

(lldb) si

Process 2107 stopped

* thread #1: tid = 0xe8e23, 0x0000000198e58640 libMobileGestalt.dylib`MGCopyAnswer, queue = 'com.apple.main-thread', stop reason = instruction step into

frame #0: 0x0000000198e58640 libMobileGestalt.dylib`MGCopyAnswer

libMobileGestalt.dylib`MGCopyAnswer:

-> 0x198e58640 : movz x1, #0

0x198e58644 : b 0x198e58648 ; ___lldb_unnamed_symbol64$$libMobileGestalt.dylib

libMobileGestalt.dylib`___lldb_unnamed_symbol64$$libMobileGestalt.dylib:

0x198e58648 : stp x24, x23, [sp, #-64]!

0x198e5864c : stp x22, x21, [sp, #16]

此時跳入了一個靜态庫libMobileGestalt.dylib,我們可以在usr/lib/ibMobileGestalt.dylib找到它,我們将它扔進IDA,用目前的addr減去libMobileGestalt.dylib的基位址偏移得到它的靜态位址0x196008640,對應的是一個函數MGCopyAnswer

__text:0000000196008640

__text:0000000196008640 ; =============== S U B R O U T I N E =======================================

__text:0000000196008640

__text:0000000196008640

__text:0000000196008640 EXPORT _MGCopyAnswer

__text:0000000196008640 _MGCopyAnswer ; CODE XREF: sub_196005958+30�p

__text:0000000196008640 ; sub_196006258+28�p ...

__text:0000000196008640 MOV X1, #0

__text:0000000196008644 B sub_196008648

__text:0000000196008644 ; End of function _MGCopyAnswer

這個函數最外層隻有兩行代碼,将立即數0賦給x1,然後跳進了子程式sub_196008648,跳進去之後進行了一些很複雜的運算,這裡就不做介紹了,裡面的實作大概是這樣的:

x0是作為一個參數傳入的,并且這裡x0的值為SerialNumber,在位址為0x196008678的地方,這個函數中x1變成了一串随機數,有點像MD5加密之後的東西,應該是“鑰匙”

(lldb) po (char*) $x1

"l92SaBpqIvQs+KBljuwGA"

在0x196008690這裡,我們setp-into這個函數,在函數的末尾傳回值的地方0x196007474打個斷點,列印傳回值x0

(lldb) po $x0

DNPMVG0EFF9V

這裡的x0由SerialNumber變成了真正的序列号,并且就是在0x196008690對應的子程式sub_19600738C裡面拿到的,是以我們就這樣一個猜測,在MGCopyAnswer函數中,x0作為一個參數傳入,并且在内部進行了一系列複雜的運算,拿到了擷取序列号的“鑰匙”x1,然後在sub_19600738C中拿到了最終的序列号。這裡筆者也沒有對序列号的拿到在進行進一步的深究,這裡蘋果做了很大的限制,再繼續研究恐怕也是收獲不大,而且我們在這裡已經能拿到序列号了。

三、驗證結果

接下來就是驗證的過程了,我們寫一個tweak來驗證,當然也可以用其他方式來驗證:

tweak的建立這裡就不贅述了,我把我的tweak和makefile檔案内容貼一下:

tweak檔案:

tweak.xm:

extern "C" NSString *MGCopyAnswer(NSString*);

%hook SpringBoard

- (void)applicationDidFinishLaunching:(id)application {

%orig;

NSString *serialNumber = [NSString stringWithFormat:@"%@",[MGCopyAnswer(@"SerialNumber") autorelease]];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:serialNumber message:nil delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];

[alert show];

}

%end

這裡注入系統的SpringBoard,在SB啟動的時候hook住applicationDidFinishLaunching:函數,并且在這個函數裡面添加擷取序列号的代碼,并且以彈框的形式展現出來。

makefile檔案:

THEOS_DEVICE_IP = 192.168.0.115

include $(THEOS)/makefiles/common.mk

TWEAK_NAME = SerialNumber

SerialNumber_FILES = Tweak.xm

include $(THEOS_MAKE_PATH)/tweak.mk

SerialNumber_LDFLAGS = -lMobileGestalt

after-install::

install.exec "killall -9 SpringBoard"

其中有一行SerialNumber_LDFLAGS = -lMobileGestalt千萬要注意,使用的時候要加載這個靜态庫,因為SpringBoard加載的時候我也不确定是否有加載這個庫,然後我們驗證一下吧!

android 擷取usb serialnumber,iOS9擷取手機序列号serialNumber(UDID)

序列号驗證-擷取

android 擷取usb serialnumber,iOS9擷取手機序列号serialNumber(UDID)

序列号驗證-系統