CydiaSubstrate的简单使用

来源:互联网 发布:淘宝充气娃娃哪家好 编辑:程序博客网 时间:2024/06/06 03:04

CydiaSubstrate

CydiaSubstrate 是绝大部分tweak正常工作的基础,主要分为三部分:MobileHooker,CydiaSubstrate,Safe mode

MobileHooker

MobileHooker的作用是替换系统函数(即hook)

// 作用于OC函数,可直接替换掉方法  void MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP *result);

(Logos语法对此函数进行了封装,但底层实现完全基于MSHookMessageEx)

// 作用于C , C++void MSHookFunction(void* function, void* replacement, void** original);

(通过编写汇编指令,在进程执行到function时转而执行replacement,同时保存function的指令返回其地址,可选择性的执行function,并保证进程能够执行完replacement后继续正常执行)
ps:之前hook必须进行越狱才能操作,现在直接汇编就能实现hook

repalce替换进程—>下表进程由上向下执行进程

正常执行的进程1 勾住函数A替换为函数B的进程2 ☟Instructions ☟Instructions ☟FunctionA ☟FunctionB (FunctionA暂存) ☟Instructions ☟Instructions

进程先执行一些指令,在原本应该执行的函数A的地方跳转到了函数B的位置执行函数B,同时函数A的 代码被MobielHooker暂时保存了下来。在函数B中,可以选择是否执行函数A,在函数B执行完成 后,则会继续执行剩下的指令。(ps:MSHookFunction的指令长度是有限制的,至少为8字节,如 果要hook住那些段函数该怎么办?—->一种变通的方法是hook住短函数内部调用的其他函数—- 短函数之所以短,是因为内部一般都是调用了其他函数,由其他函数来做出实际操作。因此,把长度 符合要求的其他函数作为MSHookFunction的目标,然后在replacement里做一些逻辑判断,将它 与函数关联上,再把对应的短函数的修改写在这里)

MobileLoader

MobileLoader的作用是加载第三方dylib。在iOS启动时,会由launched将MobileLoader载入内存,然后MobileLoader会根据dylib的同名plist文件指定的作用范围,有选择的在不同进程里通过dlopen函数打开目录/Library/MobileSubstrate/DynamicLibraries/下的所有dylib.

Safe mode

应用的质量良莠不齐,程序崩溃再说难免,因为tweak的本质是dylib,寄生在别的进程里,一旦出错,可能导致整个进程崩溃,而一旦崩溃的是SpringBoard等系统进程,则会造成iOS瘫痪,所以CydiaSubstrate引入了Safe mode,它会补获SIGTRAP、SIGTBRT、SIGILL、SIGBUS、SIGSEGV、SIGSYS这六种信号,然后进入安全模式。
(ps:在安全模式里,所有基于CydiaSubstrate的第三方dylib会被禁用,便于查找于修复;如果设备因为dylib的原因无法进入系统,比如,开机一直卡在白苹果上,或者进度圈不停地转—>home+lock+然后音量上键禁用CydiaSubstrate,系统重启后再查错与排修,修复后重启iOS,CydiaSubstrate会自动重启)

demo1核心代码

// MSFindSymbol的作用--->查找待hook的symbol,函数的指令被放在内存中,当进程需要执行这个函数时,它必须要知道去内存的哪个地方找到这个函数,然后执行它的指令,也就是说// 进程要根据函数名,找到它在内存中的地址,而这个名称与地址的映射关系,是存储在"symbol table"中的-----"symbol table" 中的symbol就是这个函数的名称,进程会根据这个// symbol找到它在内存中的地址.然后跳转过去执行.#import <substrate.h>void (*old_ZN8CPPClass11CPPFuctionEPKc)(void *, const char *);void new__ZN8CPPClass11CPPFunctionEPKc(void *hiddenThis, const char *arg0){    if (strcmp(arg0,"this is a short C function!") == 0)         old_ZN8CPPClass11CPPFuctionEPKc(hiddenThis,"this is a hijacked short C function form new__ZN8CPPClass11CPPFunctionEPKc!");    else old_ZN8CPPClass11CPPFuctionEPKc(hiddenThis,"this is a hijacked c++ function");}void (*old_CFunction)(const char *);void new_CFunction(const char *arg0){    old_CFunction("this is a hijacked C function!");  // call the original CFunction}void (*old_ShortCFuntion)(const char *);void new_ShortCFunction(const char *arg0){    old_ShortCFuntion("this is a hijacked short C function form new_ShortCFunction!"); // call the original ShortCFunction}%ctor{    @autoreleasepool    {        MSImageRef image = MSGetImageByName("/Application/iostargetapphhly.app/iostargetapphhly");        void *__ZN8CPPClass11CPPFunctionEPKc = MSFindSymbol(image,"__ZN8CPPClass11CPPFunctionEPKc");        if (__ZN8CPPClass11CPPFunctionEPKc) NSLog(@"iosre : found cppfunction!");        MSHookFunction((void *)__ZN8CPPClass11CPPFunctionEPKc, (void *)&new__ZN8CPPClass11CPPFunctionEPKc, (void **)&old_ZN8CPPClass11CPPFuctionEPKc);        void *_CFunction = MSFindSymbol(image,"_CFunction");        if (_CFunction) NSLog(@"iosre:found CFunction");        MSHookFunction((void *)_CFunction, (void *)&new_CFunction, (void **)&old_CFunction);        void *_ShortCFunction = MSFindSymbol(image, "_ShortCFunction");        if (_ShortCFunction) NSLog(@"iosre: found ShortCFunction");        MSHookFunction((void *)_ShortCFunction, (void *)&new_ShortCFunction, (void **)&old_ShortCFuntion); // This MSHookFunction will fail because ShortCFunction is too short to be hooked    }}

demo2核心代码

////  RootViewController.cpp//  ssd////  Created by esirnus on 16/5/23.//  Copyright © 2016年 esirnus. All rights reserved.//#import "RootViewController.h"class CPPClass{public:    void CPPFunction(const char *);};void CPPClass::CPPFunction(const char *args0){    for (int i = 0; i < 66; i++) // 这个循环可以有足够长的时间来验证 MSHookFunction    {        u_int32_t randomNumber;        if (i % 3 == 0) randomNumber = arc4random_uniform(i);        NSProcessInfo *processInfo = [NSProcessInfo processInfo];        NSString *hostName = processInfo.hostName;        int pid = processInfo.processIdentifier;        NSString *globallyUniqueString = processInfo.globallyUniqueString;        NSString *processName = processInfo.processName;        NSArray *junks = @[hostName,globallyUniqueString,processName];        NSString *junk = @"";        for (int j = 0; j < pid; j++)        {            if (pid % 6 == 0) junk = junks[j % 3];        }        if (i % 68 == 1) NSLog(@"Junk: %@",junk);    }    NSLog(@"HHLY: CPPFunction:%s",args0);}extern "C" void CFunction(const char *args0){    for (int i = 0; i < 66; i++)    {        u_int32_t randomNumber;        if (i % 3 == 0) randomNumber = arc4random_uniform(i);        NSProcessInfo *processInfo = [NSProcessInfo processInfo];        NSString *hostName = processInfo.hostName;        int pid = processInfo.processIdentifier;        NSString *globallyUniqueString = processInfo.globallyUniqueString;        NSString *processName = processInfo.processName;        NSArray *junks = @[hostName,globallyUniqueString,processName];        NSString *junk = @"";        for (int j = 0; j < pid; j++)        {            if (pid % 6 == 0) junk = junks[j % 3];        }        if (i % 68 == 1) NSLog(@"Junk: %@",junk);    }    NSLog(@"HHLY: CFunction:%s",args0);}extern "C" void shortCFunction(const char *args0) // shortCFunction is too short to be hooked{    CPPClass cppclass;    cppclass.CPPFunction(args0);}@implementation RootViewController- (void)loadView {    self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];    //    self.view  = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];    self.view.backgroundColor = [UIColor redColor];}- (void)viewDidLoad{    [super viewDidLoad];    CPPClass cppclass;    cppclass.CPPFunction("this is cpp function");    CFunction("this is c function");    shortCFunction("this is a short C function");}@end

Demo说明

Demo—>iostargetapphhly目的:验证MSHookFunction对Function的指令总长度有限制

  • 说明:针对MobileHooker的使用,CPPClass::CPPFunction,一个CFunction和一个ShortCFunction,作为hook的对象,CPPClass::CPPFunction和CFunction的目的是为了增加这两个函数的长度,使得针对它们俩的MSHookFunction生效,而ShortCFunction会因长度太短,导致针对它的MSHookFunction失效

Demo—>hhlydemoioshookertweak目的:间接hook短函数

  • 对函数(ShortCFunction)直接hook失败了,而对短函数内部调用的其他函数hook是有效的,可通过判断参数,检测它的调用者是ShortCFunction,这样既可实现间接hook短函数

  • MSHookFunction的指令长度是有限制的,至少为8字节,如果要hook住那些段函数该怎么办?—->一种变通的方法是hook住短函数内部调用的其他函数—-短函数之所以短,是因为内部一般都是调用了其他函数,由其他函数来做出实际操作。因此,把长度符合要求的其他函数作为MSHookFunction的目标,然后在replacement里做一些逻辑判断,将它与函数关联上,再把对应的短函数的修改写在这里)

本文代码及相关包完整版本上传在github上Demo/MobileHooker文件夹下(https://github.com/Esirnus/iOSSecurity-Attack)

1 0
原创粉丝点击