有三种实现途径

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是参数1

name:@"nativeMethod"]; // name是参数2

// 初始化WKWebView

WKWebView *webView =

[[WKWebView alloc]

initWithFrame:self.view.frame

configuration:configuration];

}

// Handler method defined in WKScriptMessageHandler

- (void)userContentController:

(WKUserContentController *)userContentController //userContentController是参数1

didReceiveScriptMessage:(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

{

...

}

@end

DWKWebView* 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.

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: