【iOS逆向与安全】越狱检测与过检测附ida伪代码

首先在网上查找一些检测代码

放入项目运行,用 ida 打开后 F5 得到下面的

__int64 __usercall sub_10001B3F0@<X0>(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8, __int64 a9, __int64 a10, __int64 a11, __int64 a12, ...)
{__int64 v12; // x0__int64 v13; // x21int v14; // w20__int64 v15; // x0__int64 v16; // x21int v17; // w22BOOL v18; // w23BOOL v19; // w24BOOL v20; // w25int v21; // w22char *v22; // x21__int64 v23; // x0__int64 v24; // x20__int64 result; // x0__int64 v26; // x0__int64 v27; // x21__int64 v28; // x0__int64 v29; // x22__int64 v30; // x0__int64 v31; // x20__int64 v32; // x0__int64 v33; // x20const char *v34; // [xsp+1C0h] [xbp+70h]va_list va; // [xsp+1C0h] [xbp+70h]__int64 v36; // [xsp+1C8h] [xbp+78h]__int64 v37; // [xsp+1D0h] [xbp+80h]__int64 v38; // [xsp+1D8h] [xbp+88h]va_list va1; // [xsp+1E0h] [xbp+90h]va_start(va1, a12);va_start(va, a12);v34 = va_arg(va1, const char *);v36 = va_arg(va1, _QWORD);v37 = va_arg(va1, _QWORD);v38 = va_arg(va1, _QWORD);v12 = ((__int64 (__fastcall *)(void *))sub_104BFCC20)(&OBJC_CLASS___NSFileManager);v13 = ((__int64 (__fastcall *)(__int64))objc_retainAutoreleasedReturnValue)(v12);v14 = sub_104C07D60();((void (__fastcall *)(__int64))objc_release)(v13);v15 = ((__int64 (__fastcall *)(void *))sub_104BFCC20)(&OBJC_CLASS___NSFileManager);v16 = ((__int64 (__fastcall *)(__int64))objc_retainAutoreleasedReturnValue)(v15);v17 = sub_104C07D60();((void (__fastcall *)(__int64))objc_release)(v16);v18 = stat("/Library/MobileSubstrate/MobileSubstrate.dylib", (struct stat *)va1) == 0;v19 = stat("/Applications/Cydia.app", (struct stat *)va1) == 0;v20 = stat("/var/lib/cydia/", (struct stat *)va1) == 0;v21 = (stat("/var/cache/apt", (struct stat *)va1) == 0 || v20 || v19 || v18) | v17 | v14;if ( dladdr(&_stat, (Dl_info *)va) )v21 |= strcmp(v34, "/usr/lib/system/libsystem_kernel.dylib") != 0;v22 = getenv("DYLD_INSERT_LIBRARIES");v23 = ((__int64 (__fastcall *)(void *))sub_104C831E0)(&unk_1063357B0);v24 = ((__int64 (__fastcall *)(__int64))objc_retainAutoreleasedReturnValue)(v23);if ( v22 || v21 ){sub_104C65B80();((void (__fastcall *)(__int64))objc_release)(v24);v26 = ((__int64 (__fastcall *)(void *))sub_104C2B780)(&unk_1063457C8);v27 = ((__int64 (__fastcall *)(__int64))objc_retainAutoreleasedReturnValue)(v26);v28 = sub_104C031E0();v29 = ((__int64 (__fastcall *)(__int64))objc_retainAutoreleasedReturnValue)(v28);v30 = ((__int64 (__fastcall *)(void *))sub_104C8B4A0)(&OBJC_CLASS___NSString);v31 = ((__int64 (__fastcall *)(__int64))objc_retainAutoreleasedReturnValue)(v30);((void (__fastcall *)(void *))sub_104C96DA0)(&unk_106361810);((void (__fastcall *)(__int64))objc_release)(v31);((void (__fastcall *)(__int64))objc_release)(v29);((void (__fastcall *)(__int64))objc_release)(v27);v32 = ((__int64 (__fastcall *)(void *))sub_104BDFEA0)(&unk_10633F200);v33 = ((__int64 (__fastcall *)(__int64))objc_retainAutoreleasedReturnValue)(v32);((void (__fastcall *)(void *))sub_104C86300)(&unk_10633F250);result = ((__int64 (__fastcall *)(__int64))objc_release)(v33);}else{sub_104C05A80();((void (__fastcall *)(__int64))objc_release)(v24);result = ((__int64 (__fastcall *)(void *))sub_104BE4C00)(&OBJC_CLASS___UIView);}return result;
}

用 frida hook


frida-trace -UF -i "stat" -f xxx
frida-trace -UF -i "dladdr" -f xxxxlog(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');

hook stat

/** Auto-generated by Frida. Please modify to match the signature of stat.* This stub is currently auto-generated from manpages when available.** For full API reference, see: https://frida.re/docs/javascript-api/*/{/*** Called synchronously when about to call stat.** @this {object} - Object allowing you to store state for use in onLeave.* @param {function} log - Call this function with a string to be presented to the user.* @param {array} args - Function arguments represented as an array of NativePointer objects.* For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.* It is also possible to modify arguments by assigning a NativePointer object to an element of this array.* @param {object} state - Object allowing you to keep state across function calls.* Only one JavaScript function will execute at a time, so do not worry about race-conditions.* However, do not use this to store function arguments across onEnter/onLeave, but instead* use "this" which is an object for keeping state local to an invocation.*/onEnter(log, args, state) {log(`stat(fildes=${args[0]}, buf=${args[1]})`);log(`stat(fildes=${(args[0].readUtf8String())}]`);this.args0 = args[0]; // 入参this.args2 = args[1]; // 返回值指针},/*** Called synchronously when about to return from stat.** See onEnter for details.** @this {object} - Object allowing you to access state stored in onEnter.* @param {function} log - Call this function with a string to be presented to the user.* @param {NativePointer} retval - Return value represented as a NativePointer object.* @param {object} state - Object allowing you to keep state across function calls.*/onLeave(log, retval, state) {log(`before:=${retval}`);var newstr = this.args0 .readUtf8String();//oldNSStr.toString();if(newstr.search("Cydia")>0
||  newstr.search("MobileSubstrate")>0
||  newstr.search("private---")>0
||  newstr.search("cydia")>0
||  newstr.search("Applications")>0
||  newstr.search("apt")>0){log("=========checkJB=hook===========" );//var str = ObjC.classes.NSString.stringWithString_('{"ret":0,"msg":null,"data":{"c":3,"t":6,"w":60,"fc":1}}');  // 对应的oc语法:NSString *str = [NSString stringWithString:@"hi with!"];//args[2] = str;retval.replace(0xf1)  // 修改返回值 0xfffffffffffffffflog(`before:=${retval}`);log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');}}
}

hook md5

frida-trace -UF -i "CC_MD5" -f xxxxxxx.xxx.xxxx

/** Auto-generated by Frida. Please modify to match the signature of CC_MD5.* This stub is currently auto-generated from manpages when available.** For full API reference, see: https://frida.re/docs/javascript-api/*/{/*** Called synchronously when about to call CC_MD5.** @this {object} - Object allowing you to store state for use in onLeave.* @param {function} log - Call this function with a string to be presented to the user.* @param {array} args - Function arguments represented as an array of NativePointer objects.* For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.* It is also possible to modify arguments by assigning a NativePointer object to an element of this array.* @param {object} state - Object allowing you to keep state across function calls.* Only one JavaScript function will execute at a time, so do not worry about race-conditions.* However, do not use this to store function arguments across onEnter/onLeave, but instead* use "this" which is an object for keeping state local to an invocation.*/onEnter(log, args, state) {log('CC_MD5()');this.args0 = args[0]; // 入参this.args2 = args[2]; // 返回值指针},/*** Called synchronously when about to return from CC_MD5.** See onEnter for details.** @this {object} - Object allowing you to access state stored in onEnter.* @param {function} log - Call this function with a string to be presented to the user.* @param {NativePointer} retval - Return value represented as a NativePointer object.* @param {object} state - Object allowing you to keep state across function calls.*/onLeave(log, retval, state) {var ByteArray = Memory.readByteArray(this.args2, 16);var uint8Array = new Uint8Array(ByteArray);var str = "";for(var i = 0; i < uint8Array.length; i++) {var hextemp = (uint8Array[i].toString(16))if(hextemp.length == 1){hextemp = "0" + hextemp}str += hextemp;}log(`CC_MD5(${this.args0.readUtf8String()})`);    // 入参log(`CC_MD5()=${str}=`);  }
}

fishhook

rebind_symbols((struct rebinding[1]){{"stat", my_stat, (void *)&orig_stat}}, 1);rebind_symbols((struct rebinding[1]){{"strcmp", my_strcmp, (void *)&orig_strcmp}}, 1);
//***********************abort********************************
//void     abort(void) __dead2;void abort_hook(void) {
}
static void (*abort_old)(void);//int     stat(const char *, struct stat *) __DARWIN_INODE64(stat);
static int     (*orig_stat)(const char *age1, struct stat * age2) ;
static int my_stat(const char *age1, struct stat *age2){//NSLog(@"[orig_stat =================]");printf("[orig_stat =hook================]\n my_stat  age1=%s ,Cydia=%s\n ",age1,strstr(age1, "Cydia"));int isfind = 0;if(strstr(age1, "Cydia") != NULL){isfind = 1;}else if (strstr(age1, "cydia") != NULL){isfind = 1;}else if (strstr(age1, "MobileSubstrate") != NULL){isfind = 1;}else if (strstr(age1, "Applications") != NULL){isfind = 1;}else if (strstr(age1, "apt") != NULL){isfind = 1;}if(isfind == 1){NSLog(@" ========hook=stat===%s\n ",age1);return 1;//返回不存在}return orig_stat(age1,age2);
}//strcmp
//如果返回值 < 0,则表示 str1 小于 str2。
//如果返回值 > 0,则表示 str2 小于 str1。
//如果返回值 = 0,则表示 str1 等于 str2。
//int     strcmp(const char *__s1, const char *__s2);
static int (*orig_strcmp)(const char *__s1, const char *__s2);
static int my_strcmp(const char *__s1, const char *__s2){if(strstr(__s2, "libsystem_kernel") != NULL){NSLog(@" ========hook=strcmp===%s %s\n ",__s1,__s2);return 0;//返回相等}return orig_strcmp(__s1,__s2);
}

下面是网上找的源码


//这里都是一些越狱后的手机带的一些框架和工具,未越狱的手机是装不上的。
- (void)isOk0 {NSString *cydiaPath = @"/Applications/Cydia.app";NSString *aptPath = @"/private/var/lib/apt/";NSString *applications = @"/User/Applications/";NSString *Mobile = @"/Library/MobileSubstrate/MobileSubstrate.dylib";NSString *bash = @"/bin/bash";NSString *sshd =@"/usr/sbin/sshd";NSString *sd = @"/etc/apt";if ([[NSFileManager defaultManager] fileExistsAtPath:cydiaPath]) {exit(0);}if ([[NSFileManager defaultManager] fileExistsAtPath:aptPath]) {exit(0);}if([[NSFileManager defaultManager] fileExistsAtPath:cydiaPath]) {exit(0);}if([[NSFileManager defaultManager] fileExistsAtPath:aptPath]) {exit(0);}if ([[NSFileManager defaultManager] fileExistsAtPath:applications]){exit(0);}if ([[NSFileManager defaultManager] fileExistsAtPath:Mobile]){exit(0);}if ([[NSFileManager defaultManager] fileExistsAtPath:bash]){exit(0);}if ([[NSFileManager defaultManager] fileExistsAtPath:sshd]){exit(0);}if ([[NSFileManager defaultManager] fileExistsAtPath:sd]){exit(0);}
}

- (void)isOK1 {//可能存在hook了NSFileManager方法,此处用底层C stat去检测// /Library/MobileSubstrate/MobileSubstrate.dylib 最重要的越狱文件,几乎所有的越狱机都会安装MobileSubstrate// /Applications/Cydia.app/ /var/lib/cydia/绝大多数越狱机都会安装struct stat stat_info;if (0 == stat("/Library/MobileSubstrate/MobileSubstrate.dylib", &stat_info)) {exit(0);}if (0 == stat("/Applications/Cydia.app", &stat_info)) {exit(0);}if (0 == stat("/var/lib/cydia/", &stat_info)) {exit(0);}if (0 == stat("/var/cache/apt", &stat_info)) {exit(0);}if (0 == stat("/var/lib/apt", &stat_info)) {exit(0);}if (0 == stat("/etc/apt", &stat_info)) {exit(0);}if (0 == stat("/bin/bash", &stat_info)) {exit(0);}if (0 == stat("/bin/sh", &stat_info)) {exit(0);}if (0 == stat("/usr/sbin/sshd", &stat_info)) {exit(0);}if (0 == stat("/usr/libexec/ssh-keysign", &stat_info)) {exit(0);}if (0 == stat("/etc/ssh/sshd_config", &stat_info)) {exit(0);}
}
//strcmp
//如果返回值 < 0,则表示 str1 小于 str2。
//如果返回值 > 0,则表示 str2 小于 str1。
//如果返回值 = 0,则表示 str1 等于 str2。
- (void)isOK2 {//可能存在stat也被hook了,可以看stat是不是出自系统库,有没有被攻击者换掉//这种情况出现的可能性很小int ret;Dl_info dylib_info;int (*func_stat)(const char *,struct stat *) = stat;if ((ret = dladdr(&func_stat, &dylib_info))) {NSLog(@"lib:%s",dylib_info.dli_fname);      //如果不是系统库,肯定被攻击了if (strcmp(dylib_info.dli_fname, "/usr/lib/system/libsystem_kernel.dylib")) {    //不相等,肯定被攻击了,相等为0exit(0);}}
}
- (void)isOK3 {//列出所有已链接的动态库://通常情况下,会包含越狱机的输出结果会包含字符串: Library/MobileSubstrate/MobileSubstrate.dylib 。uint32_t count = _dyld_image_count();for (uint32_t i = 0 ; i < count; ++i) {NSString *name = [[NSString alloc]initWithUTF8String:_dyld_get_image_name(i)];if ([name containsString:@"Library/MobileSubstrate/MobileSubstrate.dylib"]) {exit(0);}}
}
- (void)isOK4 {//如果攻击者给MobileSubstrate改名,但是原理都是通过DYLD_INSERT_LIBRARIES注入动态库//那么可以,检测当前程序运行的环境变量char *env = getenv("DYLD_INSERT_LIBRARIES");if (env != NULL) {exit(0);}
}
//对于这些函数,不建议单独写方法,容易被hook掉,所以最好是写在不能被hook的函数里,比如application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions。。。
//谁TM会hook程序的初始化函数。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/101740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NodeJs中使用JSONP和Cors实现跨域

跨域是为了解决浏览器请求域名&#xff0c;协议&#xff0c;端口不同的接口&#xff0c;相同的接口是不需要实现跨域的。 1.使用JSONP格式实现跨域 实现步骤 动态创建一个script标签 src指向接口的地址 定义一个函数和后端调用的函数名一样 实现代码 -- 在nodejs中使用http内…

java 中集合与数组的相互转换

1.集合转数组 如果需要把一个数组转换为集合&#xff0c;Arrays.asList 包装器可以达到这个目的。例如&#xff1a; String[] values . . HashSet staff new HashSet<>(Arrays.asList(values)); 2.数组转集合 Object [] values staff.toArray(); 不过&#xff0c;这…

单目标应用:墨西哥蝾螈优化算法(Mexican Axolotl Optimization,MAO)求解微电网优化MATLAB

一、微网系统运行优化模型 微电网优化模型介绍&#xff1a; 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 二、墨西哥蝾螈优化算法MAO 墨西哥蝾螈优化算法&#xff08;Mexican Axolotl Optimization&#xff0c;MAO&#xff09;由Yenny Villuendas-Rey 1等人于2021…

棱镜七彩参编!开源领域4项团体标准正式发布

近日&#xff0c;中电标2023年第27号团体标准公告正式发布&#xff0c;《T/CESA 1270.2-2023 信息技术 开源治理 第 2 部分&#xff1a;企业治理评估模型》、《T/CESA 1270.3-2023 信息技术 开源治理 第 3 部分&#xff1a;社区治理框架》、《T/CESA 1270.5-2023 信息技术 开源…

FastAPI学习-27 使用@app.api_route() 设置多种请求方式

对同一个访问函数设置多个http 请求方式 api_route 使用 使用methods 参数设置请求方式 from fastapi import FastAPIapp FastAPI() app.api_route(/demo/b, methods[get, post]) async def demo2(): return {"msg": "demo2 success"}判断请求方式…

查询资源消耗

import subprocess def get_cpu_usage(pid, duration): output subprocess.check_output([‘pidstat’, ‘-d’, ‘-p’, str(pid), ‘1’, str(duration)]).decode(‘utf-8’) lines output.strip().split(’\n’) cpu_usage [] for line in lines[4:]: fields line.spli…

uniapp 单位rpx ,设计稿尺寸px处理方式

1.使用postcss-px2rpx 插件做全局的单位转换 npm install postcss-px2rpx -D npm 安装 2.postcss.config.js修改 module.exports {plugins: {postcss-px2rpx: {// 设计稿宽度&#xff0c;默认750designWidth: 750,// 需要转换的最小像素值&#xff0c;默认1pxminPixelValue: 1…

IDEA 2023.2.2图文安装教程及下载

IDE 系列的第二个年度更新现已发布&#xff0c;涵盖 IntelliJ IDEA、WebStorm、PyCharm、DataGrip、GoLand、DataSpell 以及 All Products Pack 订阅中包含的其他工具。该版本还包括多项用户体验增强功能&#xff0c;例如 Search Everywhere&#xff08;随处搜索&#xff09;中…

上个月Balada Injector攻击中有超过17,000个WordPress网站被黑

导语 最近&#xff0c;一场名为Balada Injector的攻击活动引起了广泛关注。这次攻击以WordPress网站为目标&#xff0c;据统计&#xff0c;有超过17,000个网站受到了感染。在本文中&#xff0c;我们将详细介绍这次攻击的概述、攻击手段以及如何保护自己的网站。 攻击概述 Balad…

bash上下键选择选项demo脚本

效果如下&#xff1a; 废话不多说&#xff0c;上代码&#xff1a; #!/bin/bashoptions("111" "222" "333" "444") # 选项列表 options_index0 # 默认选中第一个选项 options_len${#options[]}echo "请用上下方向键进行选择&am…

Flutter配置Android SDK路径

在使用VSCode作为开发Flutter的工具时&#xff0c;当选择调试设备时&#xff0c;通常看不到android的模拟器&#xff0c;只能看到Chrome之类的。 原因就是Flutter找不到Android的SDK路径&#xff0c;所以无法识别模拟器&#xff0c;我们用flutter doctor命令检查环境时&#xf…

vuex入门

文章目录 一、vuex简介1.1 概述1.2 核心 二、使用2.1 安装2.2 创建store模块2.3 在src/store/index.js中写入内容2.4.在src/main.js中导入并使用store实例2.5.在views新建vuex目录,添加Page1.vue和Page2.vue文件2.6.配置路由2.7.在LeftNav.vue添加内容 三、存取值3.1 state直接…

C/C++ 线程超详细讲解(系统性学习day10)

目录 前言 一、线程基础 1.概念 2.一个进程中多个线程特征 2.1 线程共有资源 2.2 线程私有资源 3.线程相关的api函数 3.1 创建线程 创建线程实例代码如下&#xff1a; 需要特别注意的是&#xff1a; -lpthread和-pthread的区别 3.2 给线程函数传参 传参实例代码如…

pytoch M2芯片测试

今天才发现我的新片是M2芯片&#xff0c;而不是M1芯片&#xff0c;有点尴尬 参考网址 https://www.oldcai.com/ai/pytorch-train-MNIST-with-gpu-on-mac/ 测试结果如下 M2_cpu.py # https://www.oldcai.com/ai/pytorch-train-MNIST-with-gpu-on-mac/ import torch from tor…

antd Form shouldUpdate 关联展示 form 数组赋值

form 数组中嵌套数值更新 注意&#xff1a;数组是引用类型 项目需求&#xff0c;表单中包含多个产品信息&#xff0c;使用form.list 数组嵌套&#xff0c;提货方式如果是邮寄展示地址&#xff0c;如果是自提&#xff0c;需要在该条目中增加两项 代码如下&#xff1a;// An hi…

acwing算法基础之基础算法--双指针算法

目录 1 知识点2 模板 1 知识点 双指针算法的核心思想&#xff1a; for (int i 0; i < n; i) {for (int j 0; j < m; j) {//do somethings} }利用某些性质&#xff08;比如单调性&#xff09;&#xff0c;将上面朴素算法优化到 O ( N ) O(N) O(N)。 以输出空格间隔的…

Nacos(替代Eureka)注册中心

Nacos初步学习 Nacos 是一个开源的服务注册和配置中心&#xff0c;它允许您注册、注销和发现服务实例&#xff0c;并提供了配置管理的功能。下面是Nacos的最基础用法&#xff1a; 1. 服务注册和发现&#xff1a; 首先&#xff0c;您需要将您的应用程序或服务注册到Nacos中。…

黑马JVM总结(三十一)

&#xff08;1&#xff09;类加载器-概述 启动类加载器-扩展类类加载器-应用程序类加载器 双亲委派模式&#xff1a; 类加载器&#xff0c;加载类的顺序是先依次请问父级有没有加载&#xff0c;没有加载自己才加载&#xff0c;扩展类加载器在getParent的时候为null 以为Boots…

《设计一款2轮车充电桩系统》

以深圳为例&#xff0c;深圳有400万台电动2轮车&#xff0c;以每个月电费20元计算&#xff0c;深圳每个月用在2轮车充电上的费用为8000万左右。1年10个亿的市场规模。 前景可观&#xff0c;竞争也非常激烈。 本文主要讨论技术实现方案。 方法&#xff1a; 24v/36v直流输出 需…

接口自动化测试 —— 协议、请求流程

一、架构 CRM客户关系管理系统 SAAS Software As A Service 软件即服务 PAAS Platform AS A Service 平台即服务 快速交付→ 快&#xff1a;自己去干、有结果、事事有回音、持续改进 单体架构——》垂直架构——》面向服务架构——》微服务架构&#xff08;分布式&#xf…