【iOS安全】JS 调用Objective-C中WKWebview Handler的三种方式

有三种实现途径

1. WKScriptMessageHandler

OC部分:注册并实现Handler
将OC中的方法"nativeMethod"注册为JavaScript Message Handler,从而WebView中的JavaScript代码可以调用该方法

// Register in Objective-C code
- (void)setupWKWebView
{// [WKWebViewConfiguration alloc]返回一个被分配和初始化的WKWebViewConfiguration对象的指针// init方法是WKWebViewConfiguration类的实例方法WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];configuration.userContentController = [[WKUserContentController alloc] init];// 将OC中的方法"nativeMethod"注册为JavaScript Message Handler,从而可以在WebView中执行JavaScript代码时调用该方法[configuration.userContentController addScriptMessageHandler:self // addScriptMessageHandler是方法名,self是参数1name:@"nativeMethod"]; // name是参数2// 初始化WKWebViewWKWebView *webView = [[WKWebView alloc]initWithFrame:self.view.frameconfiguration:configuration];
}// Handler method defined in WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController //userContentController是参数1didReceiveScriptMessage:(WKScriptMessage *)message //message是参数2
{if ([message.name isEqualToString:@"nativeMethod"]) // 当JS端调用的是nativeMethod时{... //OC端的handler逻辑实现}
}

JS部分:调用Handler
调用"nativeMethod"

// Invoke in JavaScript code
window.webkit.messageHandlers.nativeMethod.postMessage();

2. WebViewJavascriptBridge

OC部分:注册并实现Handler
注册名为"nativeMethod"的Handler

// OC中 调用bridgeForWebView:方法,来初始化WebViewJavascriptBridge
// self.bridge将被设置为WKWebView的navigationDelegate属性
self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView];[self.bridge registerHandler:@"nativeMethod" //参数1,JS端以这个函数名调用该注册的native方法handler: //参数2的参数名,冒号后面跟着参数2的参数值,是一个block;当JS端调用nativeMethod方法时,OC端执行该block^(id data, WVJBResponseCallback responseCallback) // ^代表后面是一个block // data是JS端传递过来的数据// responseCallback是 OC端的 block 执行完毕之后,往 JS 端传递的数据{... // block中的代码,这些代码在JS端调用nativeMethod时被执行}
];

JS部分:调用Handler

WebViewJavascriptBridge.callHandler('nativeMethod', data, function(responseData) {// 处理来自Objective-C的响应数据console.log(response); 
});

例如我们使用Frida分析出来,某app的wkwebview中有如下handler:

{callNavigationSelectView = "<__NSMallocBlock__: 0x281d4a440>";checkNotificationPermission = "<__NSMallocBlock__: 0x281d4b240>";clickControlToShare = "<__NSMallocBlock__: 0x281d4bf00>";couponPaySuccess = "<__NSMallocBlock__: 0x281d4a780>";doQRScan = "<__NSMallocBlock__: 0x281d4bf80>";faceDetect = "<__NSMallocBlock__: 0x281d4bcc0>";getDeviceAlipay = "<__NSMallocBlock__: 0x281d4a4c0>";getDeviceId = "<__NSMallocBlock__: 0x281d4a800>";getDeviceInfo = "<__NSMallocBlock__: 0x281d4a680>";getLocation = "<__NSMallocBlock__: 0x281d4a600>";getNetworkStatus = "<__NSMallocBlock__: 0x281d4b0c0>";getOtherDeviceInfo = "<__NSMallocBlock__: 0x281d4b540>";getSMDeviceId = "<__NSMallocBlock__: 0x281d4a2c0>";getTripEmail = "<__NSMallocBlock__: 0x281db04c0>";getUserInfo = "<__NSMallocBlock__: 0x281d4a540>";goToKF = "<__NSMallocBlock__: 0x281d4a340>";goToVideoPlayer = "<__NSMallocBlock__: 0x281d4a700>";hideLoadingDialog = "<__NSMallocBlock__: 0x281d4b3c0>";jdPayHandle = "<__NSMallocBlock__: 0x281d4b900>";jumpToMiniPro = "<__NSMallocBlock__: 0x281d4a380>";requestNotificationPermission = "<__NSMallocBlock__: 0x281d4af00>";saveImage = "<__NSMallocBlock__: 0x281d4a500>";sendMsg = "<__NSMallocBlock__: 0x281d4a5c0>";shareOnTheWebviewPage = "<__NSMallocBlock__: 0x281d4a640>";shareWxImages = "<__NSMallocBlock__: 0x281d4b4c0>";shareWxMinipg = "<__NSMallocBlock__: 0x281d4a580>";startAuthoritySetting = "<__NSMallocBlock__: 0x281d4a300>";startNetworkSetting = "<__NSMallocBlock__: 0x281d4a7c0>";statusBarShare = "<__NSMallocBlock__: 0x281d4ad40>";uploadTripEmail = "<__NSMallocBlock__: 0x281d49b40>";webviewClose = "<__NSMallocBlock__: 0x281d4a740>";webviewGoBack = "<__NSMallocBlock__: 0x281d4a480>";
}

这时候在JS端就可以这么调用:

WebViewJavascriptBridge.callHandler('getLocation', function(response) {console.log(response); 
});

确实能调用起来
在这里插入图片描述

3. DSBridge

这个不是很常见

OC部分:

@implementation JsObject
- (NSString *) nativeMethod:(NSString *) msg
{...
}
@endDWKWebView* dwebview = [[DWKWebView alloc] initWithFrame:bounds];
[dwebview addJavascriptObject:[[JsObject alloc] init] namespace:nil];

JS部分:

var dsBridge=require("dsbridge");
var str=dsBridge.call("nativeMethod","arg");

参考:
Medusa Attack: Exploring Security Hazards of {In-App}{QR} Code Scanning[C]//32nd USENIX Security Symposium (USENIX Security 23). 2023: 4607-4624.

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

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

相关文章

算法通关村番外篇-数组实现队列

大家好我是苏麟 , 今天来用数组实现一下队列 . 数组实现队列 顺序存储结构存储的队列称为顺序队列&#xff0c;内部使用一个一维数组存储&#xff0c;用一个队头指针 front 指向队列头部节点(即使用int类型front来表示队头元素的下标)&#xff0c;用一个队尾指针rear(有的地方…

vue3中pdf打印问题处理

1 get请求参数问题 之前的请求是post得不到参数&#xff0c;今天发现的问题很奇怪&#xff0c;从前端进入网关&#xff0c;网关居然得不到参数。 前端代码 const print () > {let linkUrlStr proxy.$tool.getUrlStr(proxy.$api.invOrder.psiInvOrder.printSalOutstock,{a…

【Java】面向对象程序设计 期末复习总结

语法基础 数组自带长度属性 length&#xff0c;可以在遍历的时候使用&#xff1a; int []ages new int[10];for (int i 0; i < ages.length; i)System.out.println(ages[i]); 数组可以使用增强式for语句进行只读式遍历&#xff1a; int[] years new int[10];for (int ye…

Git(3):Git环境常用命令

1 获取本地仓库 要使用Git对我们的代码进行版本控制&#xff0c;首先需要获得本地仓库 &#xff08;1&#xff09;在电脑的任意位置创建一个空目录&#xff08;例如test&#xff09;作为我们的本地Git仓库 &#xff08;2&#xff09;进入这个目录中&#xff0c;点击右键打开…

ElasticSearch数据同步

文章目录 ElasticSearch数据同步1. 同步调用2. 异步通知3. 监听binlog4. 工作中处理同步的问题 ElasticSearch数据同步 ElasticSearch中酒店数据来自于mysql数据库&#xff0c;因此MySQL数据发生改变时&#xff0c;ElasticSearch也必须跟着改变&#xff0c;这个就是ElasticSear…

一个基于SpringBoot+Thymeleaf渲染的图书管理系统

功能: 用户: a.预约图书 b.查看预约记录 c.还书 管理员: a.添加图书 b.处理预约(借书) c.查看借阅记录 另: 1.当用户过了还书日期仍旧未还书时会发邮件通知 2.当有书被还时发邮件通知预约书的用户到图书馆进行借书

八大算法排序@冒泡排序(C语言版本)

冒泡排序 概念 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单直观的排序算法&#xff0c;它重复地遍历待排序序列&#xff0c;一次比较两个相邻的元素&#xff0c;如果它们的顺序错误就将它们交换过来。通过多次的遍历&#xff0c;使得最大的元素逐渐移动到待排序序…

【人工智能】百度智能云千帆AppBuilder,快速构建您的专属AI原生应用

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》&#xff0c;此序列是《人工智能》专栏文章。 这是2024年第5篇文章&#xff0c;此篇文章是进行人工智能相关的实践序列文章&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&…

docker小白第十一天

docker小白第十一天 dockerfile分析 Dockerfile是用来构建Docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。即构建新镜像时会用到。 构建三步骤&#xff1a;编写dockerfile文件-docker build命令构建镜像-docker run镜像 运行容器实例。即一…

气缸功能块(SMART PLC梯形图代码)

有关气缸功能块的更多介绍,可以参考下面链接文章: https://rxxw-control.blog.csdn.net/article/details/125459568https://rxxw-control.blog.csdn.net/article/details/125459568CODESYS平台双通气缸功能块 https://rxxw-control.blog.csdn.net/article/details/12544822…

Linux 进程(七) 进程地址空间

虚拟地址/线性地址 学习c语言的时候我们经常会用到 “&” 符号&#xff0c;以及下面这张表&#xff0c;那么取出来的地址是否对应的是真实的物理地址呢&#xff1f;下面我们来写代码一步一步的验证。 从上面这张图不难看出&#xff0c;从正文代码&#xff0c;到命令行参数环…

Django Web 开发实战-实现用户管理系统(部门管理、用户管理、注册登录、文件上传)

简介 基于Django Python Web框架 MySQL Bootstrap 开发的用户管理系统。支持增删改查、模糊搜索、分页。 功能介绍 部门管理---》已完成 用户管理---》已完成 认证&#xff08;注册/登录&#xff09;---》开发中 数据统计---》待开发 文件上传---》待开发 效果图 部门…

Rust圣经 阅读 数值类型

基本类型 Rust 每个值都有其确切的数据类型&#xff0c;分为两类&#xff1a;基本类型和复合类型。 基本类型往往是一个最小化原子类型&#xff0c;无法解构为其它类型&#xff08;一般意义上来说&#xff09;&#xff0c;由以下组成&#xff1a; 数值类型&#xff1a;有符号…

印象笔记03 衍生软件使用

印象笔记03 衍生软件使用 Verse 以下内容来源于官方介绍 VERSE是一款面向未来的智能化生产力工具&#xff0c;由印象笔记团队诚意推出。 你可以用VERSE&#xff1a; 管理数字内容&#xff0c;让信息有序高效运转&#xff1b;搭建知识体系&#xff0c;构建你的强大知识库&am…

CMU15-445-Spring-2023-Project #0 - C++ Primer

前置任务。 Task #1 - Copy-On-Write Trie Copy-on-write (COW) Trie 在进行修改时&#xff0c;不会立即复制整个数据结构。相反&#xff0c;它会在需要修改的节点被多个引用的时候才进行复制。当要对某个节点进行写操作&#xff08;添加子节点或者继续向下insert&#xff09…

修改多选框el-checkbox样式, 大小,背景色

修改多选框el-checkbox样式, 大小,背景色 /* 背景透明 */ .el-checkbox__inner {background: transparent;border: 1px solid #00ffe5; } /* 选中样式 */ .el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-indeterminate .el-checkbox__inner {b…

灸哥问答:分布式系统中数据一致性的问题如何解决

在分布式系统&#xff0c;数据一致性的问题是一个老生常谈&#xff0c;必须面对的一个问题&#xff0c;而且又极具挑战和复杂度的一个问题&#xff0c;针对数据一致性的问题&#xff0c;没有一个简单的单一的解决方案可以圆满解决&#xff0c;是需要结合具体的场景&#xff0c;…

人工智能技术在教育行业有哪些应用?

人工智能技术在教育行业有以下几个主要应用&#xff1a; 1. 个性化学习&#xff1a;人工智能可以根据学生的学习情况和特点&#xff0c;提供个性化的学习内容和教学方法。通过分析学生的学习数据和行为模式&#xff0c;AI 可以给予针对性的建议和反馈&#xff0c;帮助学生更好地…

环境准备-VMware安装

照顾到很多人不是很会环境搭建&#xff0c;我这里会将搭建的步骤讲的细致点 第一步&#xff0c;VMware下载。目的是通过VMware搭建Linux服务器&#xff0c;因为大家大部分还是Windows的电脑&#xff0c;我们先下载虚拟机搭建一个Linux系统的服务器 下载完成之后&#xff0c;点…

Java Synchronized 和 ReentrantLock

目录 介绍 synchronized synchronized 修饰实例方法 修饰静态类方法 synchronized 修饰代码块 实现细节 ReentrantLock ReentrantLock 基本使用 公平锁实现 读写锁&#xff08;ReentrantReadWriteLock&#xff09; 1. 创建读写锁对象&#xff1a; 2. 通过读写锁对象…