2016-06-19 8 views
1

Когда я пытаюсь подключить MGCopyAnswer, я получаю сбой. Я пытаюсь сделать это на взломанном iPhone 5s в iOS 8.3, в файлах arm64.libMobileGestalt.dylib разбился при подключении MGCopyAnswer для ARM64

#import <substrate.h> 

extern "C" CFTypeRef MGCopyAnswer(CFStringRef); 
MSHook(CFTypeRef, MGCopyAnswer, CFStringRef key) 
{ 
  return _MGCopyAnswer(key); 
} 

%ctor 
{ 
  NSString *appID = [[NSBundle mainBundle] bundleIdentifier]; 
  if ( appID && [appID isEqualToString:@"com.test.test"])   { 
    MSHookFunction(MGCopyAnswer, MSHake(MGCopyAnswer)); 
  } 
} 

Makefile:

ARCHS = armv7 armv7s arm64 
TARGET = iphone:latest:8.0 
test2_FRAMEWORKS = UIKit 

include theos/makefiles/common.mk 

TWEAK_NAME = test2 
test2_FILES = Tweak.xm 
test2_LIBRARIES = MobileGestalt 

include $(THEOS_MAKE_PATH)/tweak.mk 

after-install:: 
  install.exec "killall -9 SpringBoard" 

Краш журнала:

Version: 1.44 (1.4) 
Code Type: ARM-64 (Native) 
Parent Process: launchd [1] 

Date/Time:           2016-04-25 01:09:31.810 +0800 
Launch Time:         2016-04-25 01:09:31.564 +0800 
OS Version:          iOS 8.3 (12F70) 
Report Version:      105 

Exception Type:  EXC_BAD_INSTRUCTION (SIGILL) 
Exception Codes: 0x0000000000000001, 0x000000000068fe68 
Triggered by Thread:  0 

Thread 0 name:  Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0   libMobileGestalt.dylib          0x0000000195af7e84 0x195af4000 + 16004 
1   libMobileGestalt.dylib          0x0000000195af82bc MGGetBoolAnswer + 32 
2   AppSupport                      0x000000018b020594 __CPIsInternalDevice_block_invoke + 16 
3   libdispatch.dylib               0x0000000196c99950 _dispatch_client_callout + 12 
4   libdispatch.dylib               0x0000000196c9a828 dispatch_once_f + 92 
5   AppSupport                      0x000000018b02057c CPIsInternalDevice + 60 
6   UIKit                           0x0000000189b58750 ___UIApplicationUsesAlternateUI_block_invoke + 12 
7   libdispatch.dylib               0x0000000196c99950 _dispatch_client_callout + 12 
8   libdispatch.dylib               0x0000000196c9a828 dispatch_once_f + 92 
9   UIKit                           0x0000000189923750 UIApplicationInitialize + 1872 
10  UIKit                           0x0000000189922b1c UIApplicationMain + 320 

MGCopyAnswer: 
->  0x193a7fe84 <+0>:  .long  0x002d7c28                ; unknown opcode 
    0x193a7fe88 <+4>:  .long  0x00000001                ; unknown opcode 
    0x193a7fe8c <+8>:  stp    x20, x19, [sp, #32] 
    0x193a7fe90 <+12>: stp    x29, x30, [sp, #48] 
    0x193a7fe94 <+16>: add    x29, sp, #48 
    0x193a7fe98 <+20>: sub    sp, sp, #48 
    0x193a7fe9c <+24>: mov    x19, x1 
    0x193a7fea0 <+28>: mov    x22, x0 
    0x193a7fea4 <+32>: movz   w0, #0 
    0x193a7fea8 <+36>: bl     0x193a7f564               ; ___lldb_unnamed_function54$$libMobileGestalt.dylib 
    0x193a7feac <+40>: orr    w1, wzr, #0x1 
    0x193a7feb0 <+44>: mov    x0, x22 
    0x193a7feb4 <+48>: bl     0x193a7f5fc               ; ___lldb_unnamed_function56$$libMobileGestalt.dylib 
    0x193a7feb8 <+52>: mov    x21, x0 
    0x193a7febc <+56>: movz   w20, #0 
    0x193a7fec0 <+60>: cbz    x21, 0x193a7fefc          ; <+120> 
    0x193a7fec4 <+64>: ldr    w20, [x21, #148] 
    0x193a7fec8 <+68>: mov    x0, x21 
orig_MGCopyAnswer 
    0x104234000: movz   x1, #0 
    0x104234004: stp    x24, x23, [sp, #-64]! 
    0x104234008: stp    x22, x21, [sp, #16] 
    0x10423400c: ldr    x16, #8 
    0x104234010: br     x16 
    0x104234014: .long  0x93a7fe8c                 
    0x104234018: .long  0x00000001                ; unknown opcode 

Что я делаю неправильно?

ответ

0

Попробуйте этот код:

#import <substrate.h> 

static CFTypeRef (*orig_MGCopyAnswer)(CFStringRef str); 
CFTypeRef new_MGCopyAnswer(CFStringRef str) 
{ 
    return orig_MGCopyAnswer(str); 
} 

%ctor 
{ 
    NSString *appID = [[NSBundle mainBundle] bundleIdentifier]; 
    if (appID && [appID isEqualToString:@"com.test.test"]) { 
    void * MGCopyAnswerFn = MSFindSymbol(NULL, "_MGCopyAnswer"); 
    MSHookFunction(MGCopyAnswerFn, (void *) new_MGCopyAnswer, (void **)& orig_MGCopyAnswer); 
    } 
} 
1

Вы не можете подключить MGCopyAnswer напрямую, потому что это слишком короткий.

Когда CydiaSubstrate перехватывает функцию C, он сортирует перезаписывает версию сборки goto your_function; в начале исходной функции. Этот «goto» в ARM64 имеет размер 16 байт, что означает, что если исходная функция слишком короткая (< 16 байтов), CydiaSubstrate может разливать и искажать соседние функции.

Именно по этой причине проблема MGCopyAnswer. Реализация MGCopyAnswer в основном (на 9.3.2 arm64):

01 00 80 d2  movz x1, #0 
01 00 00 14  b MGCopyAnswer_internal  

, который находится всего в 8 байт (< 16 байт). Таким образом, CydiaSubstrate испортит 8 байтов после окончания MGCopyAnswer.

К сожалению, MGCopyAnswer_internal сразу после MGCopyAnswer, и еще хуже, эта функция и вызывается MGGetBoolAnswer. Поскольку MGCopyAnswer_internal поврежден, вы получаете авария EXC_BAD_INSTRUCTION внутри libMobileGestalt.

Хорошей новостью для MGCopyAnswer является то, что вы могли бы просто зацепить MGCopyAnswer_internal! Это дополнительное преимущество, которое многие связанные функции, такие как MGGetBoolAnswer, MGCopyAnswerWithError, MGCopyMultipleAnswers и т. Д., Также могут ответить на ваши изменения. Плохо то, что MGCopyAnswer_internal полностью внутренне, и нет никаких символов, указывающих на него. Мы могли бы рассчитывать на то, что MGCopyAnswer_internal ровно 8 байт после MGCopyAnswer на ARM64, и развивать этот безобразный хак:.

static CFPropertyListRef (*orig_MGCopyAnswer_internal)(CFStringRef prop, uint32_t* outTypeCode); 
CFPropertyListRef new_MGCopyAnswer_internal(CFStringRef prop, uint32_t* outTypeCode) { 
    return orig_MGCopyAnswer_internal(prop, outTypeCode); 
} 

extern "C" MGCopyAnswer(CFStringRef prop); 

static CFPropertyListRef (*orig_MGCopyAnswer)(CFStringRef prop); 
CFPropertyListRef new_MGCopyAnswer(CFStringRef prop) { 
    return orig_MGCopyAnswer(prop); 
} 

%ctor { 
    uint8_t MGCopyAnswer_arm64_impl[8] = {0x01, 0x00, 0x80, 0xd2, 0x01, 0x00, 0x00, 0x14}; 
    const uint8_t* MGCopyAnswer_ptr = (const uint8_t*) MGCopyAnswer; 
    if (memcmp(MGCopyAnswer_ptr, MGCopyAnswer_arm64_impl, 8) == 0) { 
     MSHookFunction(MGCopyAnswer_ptr + 8, (void*)new_MGCopyAnswer_internal, (void**)&orig_MGCopyAnswer_internal); 
    } else { 
     MSHookFunction(MGCopyAnswer_ptr, (void*)new_MGCopyAnswer, (void**)&orig_MGCopyAnswer); 
    } 
} 

(Это только проверяет arm64 на 9.3.2 Другие платформы могут врезаться по-разному, и имеют разный ассемблерный код, поэтому вам может потребоваться добавить дополнительные условия, чтобы ввести крюк-MGCopyAnswer_internal. YMMV!)