前言
WKWebView 是 iOS 应用中强大的组件,但如何在逆向工程中最好地利用它呢?本文将带您了解在逆向过程中遇到webview后的相关操作。这些技术将让您能够修改 WKWebView 行为,读写关键元素,接口拦截,并揭示更多有趣的可能性。
一、目标
了解如何在 iOS 逆向工程中处理 WKWebView,包括 元素读写和接口拦截的基本概念。
二、开发环境和工具清单
- mac系统
- Xcode13.2.1
- iOS15设备
三、流程
1、示例程序
手动创建一个示例程序,里面只包含了一个基本的webview容器,呈现的内容为某app的滑块url,基础代码如下:
@interfaceViewController()@property(nonatomic, strong) WKWebView *webview;@end@implementation ViewController
-(void)viewDidLoad {[super viewDidLoad];[self.view addSubview:self.webview];
NSURL *url =[NSURL URLWithString:@"https://xxx/xxx"];
NSURLRequest *request =[NSURLRequest requestWithURL:url];[self.webview loadRequest:request];}-(WKWebView *)webview {if(_webview == nil){
_webview =[[WKWebView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];}return _webview;}@end
界面效果图:
url的部分html代码如下:
2、拦截并修改html
由于h5里内容被包含在一个自定义标签里(shadow-root),而这自定义标签的模式为closed。我们需要拦截并把该标签的模式改为open,这样才能通过css选择器去获取对应的子元素。通过全局搜索发现自定义标签于xxx.js返回。直接上代码:
a、修改webview的初始化代码如下:
// 修复'https' is a URL scheme that WKWebView handles natively错误
Method m1 =class_getClassMethod([WKWebView class],@selector(handlesURLScheme:));
Method m2 =class_getClassMethod([ViewController class],@selector(hook_handlesURLScheme:));method_exchangeImplementations(m1, m2);
WKWebViewConfiguration *config =[[WKWebViewConfiguration alloc] init];// 设置当前对象来处理webview的https请求[config setURLSchemeHandler:self forURLScheme:@"https"];
_webview =[[WKWebView alloc] initWithFrame:[[UIScreen mainScreen] bounds] configuration:config];
b、实现处理https请求的协议:
-(void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
NSURLRequest *request = urlSchemeTask.request;
NSString *urlStr = request.URL.absoluteString;NSLog(@"req url =%@=", urlStr);[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){if(error){[urlSchemeTask didFailWithError:error];}else{if([urlStr containsString:@"xxx.js"]){// 获取xxx.js的内容
NSString *modifyData =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];// 查询attachShadow({mode:\"closed\"})并替换为attachShadow({mode:\"open\"})
modifyData =[modifyData stringByReplacingOccurrencesOfString:@"attachShadow({mode:\"closed\"})" withString:@"attachShadow({mode:\"open\"})"];// 覆盖xxx.js内容
data =[modifyData dataUsingEncoding:NSUTF8StringEncoding];}// 设置当前请求的返回信息[urlSchemeTask didReceiveResponse:response];[urlSchemeTask didReceiveData:data];[urlSchemeTask didFinish];}}] resume];}
2、修改html元素
修改按钮文案"拖动滑块完成上方拼图"为"移动端小陈",修改html元素和修改js基本上一样,关键代码如下:
NSString *modifyData =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];if([modifyData containsString:@"拖动滑块完成上方拼图"]){
modifyData =[modifyData stringByReplacingOccurrencesOfString:@"拖动滑块完成上方拼图" withString:@"移动端小陈"];// 替换html内容
data =[modifyData dataUsingEncoding:NSUTF8StringEncoding];}
3、获取img标签的值
简单的内容可通过查找替换处理。而复制的内容,还得用css选择器。咱们通过在webview中执行一段js来获取特定元素(注:获取到的结果只能是string类型),获取img标签的关键代码如下:
NSString *jsFunc =@"\
function getImgSrc(clsName) {\
var sliderImg = document.querySelector('#captcha-dialog').children[1].shadowRoot.querySelector('#slider').getElementsByClassName(clsName);\
if (sliderImg.length > 0) {\
var imgSrc = sliderImg[0].src;\
return imgSrc;\
} else {\
return "";\
}\
};getImgSrc('#cls-name#')";[webView evaluateJavaScript:[jsFunc stringByReplacingOccurrencesOfString:@"#cls-name#" withString:@"slider-img-bg"] completionHandler:^(NSString *backgroundData , NSError *error){NSLog(@"background =%@=", backgroundData);}];
4、接口拦截
修改某接口的请求参数,代码如下:
// 修改接口的请求if([urlStr containsString:@"xxx"]){
NSMutableDictionary *body =[NSJSONSerialization JSONObjectWithData:request.HTTPBody options:0 error:nil];
body =[body mutableCopy];
body[@"e"]=@(0);
NSMutableURLRequest *mutableRequest =[NSMutableURLRequest requestWithURL:request.URL.absoluteURL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
mutableRequest.HTTPMethod =@"POST";
mutableRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
mutableRequest.HTTPBody =[NSJSONSerialization dataWithJSONObject:body options:0 error:nil];
request = mutableRequest;}
修改某接口的响应和上边的修改js类型,大家自行尝试
总结
以上就是在逆向中遇到webview后的相关处理办法,希望能对你有所帮助。
源码请关住工众好后回复:webview源码
提示:阅读此文档的过程中遇到任何问题,请关住工众好【*
移动端Android和iOS开发技术分享
】或+99 君羊【
812546729
*】
版权归原作者 移动端小陈 所有, 如有侵权,请联系我们删除。