usefulConfig

前言

正文

tweak

  • /Package/Library/MobileSubstrate/DynamicLibraries/.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Filter</key>
  <dict>
    <key>Executables</key>
    <array>
      
      <string>nesessionmanager</string>
            <string>racoon</string>
            <string>configd</string>
            <string>mDNSResponder</string>
            <string>networkd</string>
    </array>
        
        <key>Bundles</key>
        <array>
            <string>com.apple.nesessionmanager</string>
        </array>
  </dict>
</dict>
</plist>

see also


<!-- ./class-dump -S -s -H /Users/hz/Desktop/得到/Payload/LuoJiFM-IOS.app/LuoJiFM-IOS -o ~/Desktop/DeDao -->




<!-- 网络请求是用的 DataService -->

<!-- DataServiceUtils 这个类是算加密, header之类的 -->

<!-- DDDataService 这个 应该是 DataServiceV2 的升级版 -->


<!-- FMEventDataService 封装的进行网络请求的地方 -->








<!-- addone.dylib. -->

CHLoadClass_(0xe0f8, objc_getClass("NSBundle"));
CHLoadClass_(0xe104, objc_getClass("UIDevice"));//修改设备名称
CHLoadClass_(0xe110, objc_getClass("NSDictionary"));
CHLoadClass_(0xe11c, objc_getClass("MMCrashReportExtLogMgr"));//崩溃记录
CHLoadClass_(0xe128, objc_getClass("JailBreakHelper"));//越狱检测
CHLoadClass_(0xe134, objc_getClass("ASIdentifierManager"));//修改广告标识

<!-- UIDevice -->

int __ZL21$UIDevice_name_methodP8UIDeviceP13objc_selector(void * arg0, void * arg1) {
    r0 = @"iPhone";
    return r0;
}


<!-- 防封补丁源码 -->


#import <Foundation/Foundation.h>
#import "CaptainHook/CaptainHook.h"
#import <AdSupport/AdSupport.h>

CHDeclareClass(ASIdentifierManager)

//广告标识符伪装
CHMethod0(NSUUID *, ASIdentifierManager, advertisingIdentifier)
{
    NSUUID *advertisingIdentifier;
    NSString *key = @"idfa";
    
    NSString *idfa = [[NSUserDefaults standardUserDefaults] stringForKey:key];
    
    if (idfa && idfa.length)
    {
        advertisingIdentifier = [[NSUUID alloc] initWithUUIDString:idfa];
    }
    else
    {
        advertisingIdentifier = [NSUUID UUID];
        
        [[NSUserDefaults standardUserDefaults] setObject:advertisingIdentifier.UUIDString forKey:key];
    }
    
    return advertisingIdentifier;
}

@class BaseAuthReqInfo, BaseRequest, ManualAuthAesReqData;

CHDeclareClass(ManualAuthAesReqData);

//bundleId 伪装(待完善)
CHMethod1(void, ManualAuthAesReqData, setBundleId, NSString *, bundleId)
{
    if ([bundleId isEqualToString:[NSBundle mainBundle].bundleIdentifier])
    {
        bundleId = @"com.tencent.xin";
    }
    
    CHSuper1(ManualAuthAesReqData, setBundleId, bundleId);
}

//clientSeqId 伪装
CHMethod1(void, ManualAuthAesReqData, setClientSeqId, NSString *, clientSeqId)
{
    NSString *key = @"clientSeqId";
    NSString *clientSeqId_fist = [[NSUserDefaults standardUserDefaults] stringForKey:key];
    if (!clientSeqId_fist || clientSeqId_fist.length == 0)
    {
        clientSeqId_fist = [[NSUUID UUID].UUIDString stringByReplacingOccurrencesOfString:@"-" withString:@""];
        [[NSUserDefaults standardUserDefaults] setObject:clientSeqId_fist forKey:key];
    }
    
    NSString *newClientSeqId;
    
    if ([clientSeqId containsString:@"-"])
    {
        NSRange range = [clientSeqId rangeOfString:@"-"];
        NSString *clientSeqId_last = [clientSeqId substringFromIndex:range.location];
        
        newClientSeqId = [NSString stringWithFormat:@"%@%@", clientSeqId_fist, clientSeqId_last];
    }
    else
    {
        newClientSeqId = clientSeqId_fist;
    }
    
    CHSuper1(ManualAuthAesReqData, setClientSeqId, newClientSeqId);
}

//deviceName 伪装
CHMethod1(void, ManualAuthAesReqData, setDeviceName, NSString *, deviceName)
{
    //设置为默认名称
    deviceName = @"iPhone";
    
    CHSuper1(ManualAuthAesReqData, setDeviceName, deviceName);
}

//过日志记录
@class MMCrashReportExtLogMgr;

CHDeclareClass(MMCrashReportExtLogMgr);

CHMethod2(void, MMCrashReportExtLogMgr, addLogInfo, int *, arg1, withMessage, const char *, arg2)
{
    return;
}

//过越狱检测
@class JailBreakHelper;

CHDeclareClass(JailBreakHelper);

CHMethod0(BOOL, JailBreakHelper, HasInstallJailbreakPluginInvalidIAPPurchase)
{
    return NO;
}

CHMethod1(BOOL, JailBreakHelper, HasInstallJailbreakPlugin, id, arg1)
{
    return NO;
}

CHMethod0(BOOL, JailBreakHelper, IsJailBreak)
{
    return NO;
}

//所有被hook的类和函数放在这里的构造函数中
CHConstructor
{
    @autoreleasepool
    {
        CHLoadLateClass(ASIdentifierManager);
        CHHook0(ASIdentifierManager, advertisingIdentifier);
        
        CHLoadLateClass(ManualAuthAesReqData);
        CHHook1(ManualAuthAesReqData, setBundleId);
        CHHook1(ManualAuthAesReqData, setClientSeqId);
        CHHook1(ManualAuthAesReqData, setDeviceName);
        
        CHLoadLateClass(MMCrashReportExtLogMgr);
        CHHook2(MMCrashReportExtLogMgr, addLogInfo, withMessage);
        
        CHLoadLateClass(JailBreakHelper);
        CHHook0(JailBreakHelper, HasInstallJailbreakPluginInvalidIAPPurchase);
        CHHook1(JailBreakHelper, HasInstallJailbreakPlugin);
        CHHook0(JailBreakHelper, IsJailBreak);
    }
}



<!-- 基础原理 : Objective-C Runtime  -->

https://jspatch.com/Index/sdk


JS 传递字符串给 OC,OC 通过 Runtime 接口调用和替换 OC 方法

<!-- 方法调用 :引入 JSPatch 后,可以通过以上 JS 代码创建了一个 UIView 实例,并设置背景颜色和透明度,涵盖了 require 引入类,JS 调用接口,消息传递,对象持有和转换,参数转换这五个方面-->

require('UIView')
var view = UIView.alloc().init()
view.setBackgroundColor(require('UIColor').grayColor())
view.setAlpha(0.5)



<!-- 1.require -->

在JS全局作用域上创建一个同名变量

<!-- 2.JS接口 -->

1)在require生成类对象时,把类名传入OC,OC 通过runtime方法找出这个类所有的方法返回给 JS,JS 类对象为每个方法名都生成一个函数,函数内容就是拿着方法名去 OC 调用相应方法

2)CoffieScript/JSX 都可以用 JS 实现一个解释器实现自己的语法

3)调用一个不存在方法时,能转发到一个指定函数去执行:简单的字符串替换,把 JS 脚本里的方法调用都替换掉

最后的解决方案是,在 OC 执行 JS 脚本前,通过正则把所有方法调用都改成调用 __c() 函数,再执行这个 JS 脚本,做到了类似 OC/Lua/Ruby 等的消息转发机制:

<!-- 3.消息传递 -->

JavaScriptCore 的接口

1)OC 端在启动 JSPatch 引擎时会创建一个 JSContext 实例,JSContext 是 JS 代码的执行环境,可以给 JSContext 添加方法,JS 就可以直接调用这个方法:

JSContext *context = [[JSContext alloc] init];
context[@"hello"] = ^(NSString *msg) {
    NSLog(@"hello %@", msg);
};
[_context evaluateScript:@"hello('word')"];     //output hello word



2)JS 通过调用 JSContext 定义的方法把数据传给 OC,OC 通过返回值传会给 JS。调用这种方法,它的参数/返回值 JavaScriptCore 都会自动转换,OC 里的 NSArray, NSDictionary, NSString, NSNumber, NSBlock 会分别转为JS端的数组/对象/字符串/数字/函数类型。



<!-- 4.对象持有/转换 -->

<!-- 5.类型转换 -->





<!-- 方法替换 -->

<!-- 1.基础原理 -->


OC上,每个类都是这样一个结构体:


struct objc_class {
  struct objc_class * isa;
  const char *name;
  ….
  struct objc_method_list **methodLists; /*方法链表*/
};

其中 methodList 方法链表里存储的是 Method 类型:


typedef struct objc_method *Method;
typedef struct objc_ method {
  SEL method_name;
  char *method_types;
  IMP method_imp;
};

Method 保存了一个方法的全部信息,包括 SEL 方法名,type 各参数和返回值类型,IMP 该方法具体实现的函数指针。



<!-- 替换 UIViewController 的 -viewDidLoad: 方法为例 -->

static void viewDidLoadIMP (id slf, SEL sel) {
   JSValue *jsFunction = …;
   [jsFunction callWithArguments:nil];
}

Class cls = NSClassFromString(@"UIViewController");
SEL selector = @selector(viewDidLoad);
Method method = class_getInstanceMethod(cls, selector);

//获得viewDidLoad方法的函数指针
IMP imp = method_getImplementation(method)

//获得viewDidLoad方法的参数类型
char *typeDescription = (char *)method_getTypeEncoding(method);

//新增一个ORIGViewDidLoad方法,指向原来的viewDidLoad实现
class_addMethod(cls, @selector(ORIGViewDidLoad), imp, typeDescription);

//把viewDidLoad IMP指向自定义新的实现
class_replaceMethod(cls, selector, viewDidLoadIMP, typeDescription);


https://blog.nelhage.com/2010/10/amd64-and-va_arg


<!-- JSPatch 是一个iOS 动态更新框架,只需在项目中引入极小的引擎,就可以使用JavaScript 调用任何Objective-C 原生接口,获得脚本语言的优势:为项目动态添加模块,或替换项目原生代码动态修复bug -->


<!-- 1、 打开Xcode, 新建Project, 选择 iOSOpenDev 中 CaptainHook Tweak, -->
添加依赖框架:JavaScriptCore.framework, libz.1.2.8.tbd

https://link.jianshu.com/?t=http://jspatch.com/Index/sdk


<!-- jsPatch.mm -->

//需要hook的方法


#import <JSPatchPlatform/JSPatch.h>


CHDeclareClass(MicroMessengerAppDelegate);

////JSPatch初始化

CHMethod(2, BOOL, MicroMessengerAppDelegate, application, id, arg1, didFinishLaunchingWithOptions, id, arg2)
{
    BOOL supBool = CHSuper(2, MicroMessengerAppDelegate, application, arg1, didFinishLaunchingWithOptions, arg2);
    [JSPatch startWithAppKey:@"xxx"];
    [JSPatch sync];
    return supBool;
}

//所有被hook的类和函数放在这里的构造函数中

__attribute__((constructor)) static void entry()
{
    CHLoadLateClass(MicroMessengerAppDelegate);
    CHHook(2, MicroMessengerAppDelegate, application, didFinishLaunchingWithOptions);
}


<!-- 方法调用 main.js-->

require('MMTableViewSectionInfo, MMTableViewCellInfo, MMTableViewInfo')

//打印所有 ViewController
defineClass('UIViewController', {
viewDidAppear:function(animated) {
            console.log(self)
        }
})    

//给 “我” 这个界面添加一个 cell
defineClass('MoreViewController', {
        addSettingSection:function() {
            self.ORIGaddSettingSection()
            var section = MMTableViewSectionInfo.sectionInfoDefaut()
            var cell = MMTableViewCellInfo.switchCellForSel_target_title_on(null, self, "Hello JSPatch", false)
            section.addCell(cell)
            var info = self.valueForKey("m_tableViewInfo")
            info.addSection(section)
    }   
})




必要参数:

-b 删除,覆盖以前建立的链接

-d 允许超级用户制作目录的硬链接

-f 强制执行

-i 交互模式,文件存在则提示用户是否覆盖

-n 把符号链接视为一般目录

-s 软链接(符号链接)

-v 显示详细的处理过程


实例5:给目录创建软链接

# 先备份 cp -r /Library/MobileSubstrate/DynamicLibraries ~/
     # rm -rf /Library/MobileSubstrate/DynamicLibraries
    # ios11 代码: dylib   干脆给他建立个软连接算了        /bin/ln -s   /usr/lib/TweakInject /Library/MobileSubstrate/DynamicLibraries 
    # cp -r  ~/DynamicLibraries /Library/MobileSubstrate/DynamicLibraries


<!-- ln -sv /opt/soft/test/test3 /opt/soft/test/test5 -->

ln -sv   /usr/lib/TweakInject /Library/MobileSubstrate/DynamicLibraries      这个相当于创建同名的软连接


WL-47:~ root# ls -lrt /Library/MobileSubstrate/DynamicLibraries
lrwxr-xr-x 1 root wheel 25 Feb 13 12:48 /Library/MobileSubstrate/DynamicLibraries -> ../../usr/lib/TweakInject


转载请注明: > usefulConfig

在操作过程或者文章有问题的话欢迎在 原文 里提问或指正。

赞赏支持

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少
最近的文章

ConfiguringWebApplications

前言 code,addWebClipToHomeScreen正文 Apple URL Scheme Reference. 例子 <!-- IOS Safari提供了两个私有接口: apple-touch-icon 和 apple-touch-icon-precomposed。 --><link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed-iphone...…

ios继续阅读
更早的文章

SBUserNotificationAlert

前言本文的重点是借助弹框信息,处理各个进程的错误。例如PPPD的MS-CHAP authentication failed: bad username or password正文 SBUserNotificationAlert -(void)setAlertHeader:(NSString *)arg1 ;VPN 连接 pppd MS-CHAP authentication failed: bad username or passwordVPN Connection...…

iOSre继续阅读
更多