Bypassing Anti-Debugging Protection in iOS Version of Amap Application 7.2.0

Giới thiệu về Amap15 Tháng 2 Amap là nhà cung cấp hàng đầu Trung Quốc về nội dung bản đồ số, giải pháp định vị và dịch vụ vị trí. Bản đồ tích hợp sẵn trên iPhone sử dụng dữ liệu từ Amap, cho thấy độ tin cậy của Amap Hôm qua, tôi bỗng nảy ra ý tưởng thực hiện một tính năng không được chính thức cung cấp bởi Amap. Tôi quyết định thử hack để thêm tính năng này vào ứng dụng. Tuy nhiên, khi cố gắng gắn LLDB, tôi đã gặp phải tình huống đáng ngạc nhiên sau……

1. Thất bại khi kết nối LLDB

FunMaker-5:~ root# debugserver *:1234 -a "AMapiPhone"
debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-320.2.89
 for armv7.
Attaching to process AMapiPhone...
Segmentation fault: 11

Rõ ràng, ứng dụng Amap đã có cơ chế chống debug động. Để vô hiệu hóa cơ chế bảo vệ này, chúng ta cần hiểu rõ phương pháp bảo vệ mà nó sử dụng. Vì phương pháp chống debug động duy nhất hiện có là ptrace, chúng ta bắt đầu bằng cách kiểm tra nó.

2. Khởi động AMapiPhone bằng LLDB

FunMaker-5:~ root# debugserver -x backboard *:1234 /var/mobile/Containers/Bundle/Application/1C86F6A1-E50A-434E-B08E-C39C200EFA0A/AMapiPhone.app/AMapiPhone
debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-320.2.89
for armv7.
Listening to port 1234 for a connection from *...

(lldb) process connect connect://localhost:1234
Process 5171 stopped
* thread #1: tid = 0x1433, 0x1feb8000 dyld`_dyld_start, stop reason = signal SIGSTOP
    frame #0: 0x1feb8000 dyld`_dyld_start
dyld`_dyld_start:
-> 0x1feb8000:  mov    r8, sp
   0x1feb8004:  sub    sp, sp, #16
   0x1feb8008:  bic    sp, sp, #7
   0x1feb800c:  ldr    r3, [pc, #112]            ; _dyld_start + 132

LLDB đã dừng lại, chúng ta thử lệnh "c" để xem kết quả:

(lldb) c
Process 5171 resuming
Process 5171 exited with status = 45 (0x0000002d) 

Quá trình đã thoát ngay lập tức, thêm bằng chứng cho thấy ứng dụng Amap chứa chức năng chống debug. Không có gì để bàn cãi, chúng ta hãy xem cách vô hiệu hóa cơ chế bảo vệ này.

3. Đặt breakpoint tại ptrace, tìm vị trí gọi ptrace

Dựa trên bài viết này, chúng ta có thể biết rằng cách xác định vị trí gọi ptrace rất đơn giản: chỉ cần đặt breakpoint tại ptrace:

FunMaker-5:~ root# debugserver -x backboard *:1234 /var/mobile/Containers/Bundle/Application/1C86F6A1-E50A-434E-B08E-C39C200EFA0A/AMapiPhone.app/AMapiPhone
debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-320.2.89
 for armv7.
Listening to port 1234 for a connection from *...
Got a connection, launched process /var/mobile/Containers/Bundle/Application/1C86F6A1-E50A-434E-B08E-C39C200EFA0A/AMapiPhone.app/AMapiPhone (pid = 678).

snakeninnysiMac:~ snakeninny$ /Applications/OldXcode.app/Contents/Developer/usr/bin/lldb 
(lldb) process connect connect://localhost:1234
Process 6907 stopped
* thread #1: tid = 0x1afb, 0x1fe54000 dyld`_dyld_start, stop reason = signal SIGSTOP
    frame #0: 0x1fe54000 dyld`_dyld_start
dyld`_dyld_start:
-> 0x1fe54000:  mov    r8, sp
   0x1fe54004:  sub    sp, sp, #16
   0x1fe54008:  bic    sp, sp, #7
   0x1fe5400c:  ldr    r3, [pc, #112]            ; _dyld_start + 132
(lldb) b ptrace
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
(lldb) c
Process 6907 resuming
1 location added to breakpoint 1
Process 6907 stopped
* thread #1: tid = 0x1afb, 0x37031e64 libsystem_kernel.dylib`__ptrace, queue = 'com.apple.main-thread, stop reason = breakpoint 1.1
    frame #0: 0x37031e64 libsystem_kernel.dylib`__ptrace
libsystem_kernel.dylib`__ptrace:
-> 0x37031e64:  ldr    r12, [pc, #4]             ; ptrace + 12

libsystem_kernel.dylib`ptrace + 4:
   0x37031e68:  ldr    r12, [pc, r12]
   0x37031e6c:  b      0x37031e74                ; ptrace + 16
   0x37031e70:  rsbeq  pc, r11, #48
(lldb) p/x $lr
(unsigned int) $0 = 0x000dbd19
(lldb) image list -o -f
  0] 0x000d1000 /private/var/mobile/Containers/Bundle/Application/1C86F6A1-E50A-434E-B08E-C39C200EFA0A/AMapiPhone.app/AMapiPhone(0x00000000000d5000)

Vậy người gọi ptrace nằm tại vị trí 0xdbd19 - 0xd1000 = 0xAD19, như hình dưới:

image796×353 63.4 KB Ý nghĩa của đoạn mã này rất rõ ràng, nó gọi động ptrace để đạt mục đích chống debug động. Đoạn mã này nằm bên trong hàm sub_ACF0, chúng ta hãy xem người gọi rõ ràng của sub_ACF0:

Chỉ có một hàm là sub_AD24. Hãy xem cách triển khai bên trong nó: image542×672 59.6 KB Đó là hàm main. Vậy là Amap đã đạt được mục đích chống debug động bằng cách gọi động hàm ptrace trong hàm main, mọi người có thể tham khảo. ### 4. Vô hiệu hóa hàm sub_ACF0

Theo bài viết này, chúng ta có thể hook bất kỳ hàm nào có dạng sub_xxx trong cửa sổ Functions của IDA. Mã cốt lõi của tweak như sau:

#import <substrate.h>
#import <mach-o/dyld.h>
#import <dlfcn.h>

void (*old_protect_func)(void);

void new_protect_func(void)
{
        // old_protect_func();
        NSLog(@"iOSRE: bypassing protection");
}

%ctor
{
        @autoreleasepool
        {
                unsigned long _protect_func = (_dyld_get_image_vmaddr_slide(0) + 0xACF0) | 0x1;
                if (_protect_func) NSLog(@"iOSRE: Found protection function!");
                MSHookFunction((void *)_protect_func, (void *)&new_protect_func, (void **)&old_protect_func);
        }
}

Biên dịch, đóng gói và cài đặt, chúng ta xem hiệu quả debug động với tweak này:

(lldb) process connect connect://localhost:1234
Process 10222 stopped
* thread #1: tid = 0x27ee, 0x1fea3000 dyld`_dyld_start, stop reason = signal SIGSTOP
    frame #0: 0x1fea3000 dyld`_dyld_start
dyld`_dyld_start:
-> 0x1fea3000:  mov    r8, sp
   0x1fea3004:  sub    sp, sp, #16
   0x1fea3008:  bic    sp, sp, #7
   0x1fea300c:  ldr    r3, [pc, #112]            ; _dyld_start + 132
(lldb) c
Process 10222 resuming
(lldb) 2015-02-09 19:55:05.129 AMapiPhone[737:10222] iOSRE: Found protection function!
2015-02-09 19:55:05.478 AMapiPhone[737:10222] iOSRE: bypassing protection
2015-02-09 19:55:06.598 AMapiPhone[737:10222] DiskCookieStorage changing policy from 2 to 0, cookie file: file:///private/var/mobile/Containers/Data/Application/6AE478A8-7838-4C33-B716-D2810ED78CB9/Library/Cookies/Cookies.binarycookies
2015-02-09 19:55:07.596 AMapiPhone[737:10222] reInit /var/mobile/Containers/Data/Application/6AE478A8-7838-4C33-B716-D2810ED78CB9/Documents/autonavi/data/cache/vmap4res/style-icons-upate-recorder.data
vmap_basedb_create-offline /var/mobile/Containers/Data/Application/6AE478A8-7838-4C33-B716-D2810ED78CB9/Documents/autonavi/data/vmap/

LLDB đã thành công vào bên trong ứng dụng Amap, nhiệm vụ hoàn thành~ Bắt đầu hack thôi!

Thẻ: iOS reverse engineering anti-debug bypass ptrace Substrate Amap

Đăng vào ngày 24 tháng 5 lúc 18:39