前言WKWebView 是 iOS 应用中强大的组件,但如何在逆向工程中最好地利用它呢?本文将带您了解在逆向过程中遇到webview后的相关操作。这些技术将让您能够修改 WKWebView 行为,读写关键元素,接口拦截,并揭示更多有趣的可能性。 
  
 
一、目标了解如何在 iOS 逆向工程中处理 WKWebView,包括 元素读写和接口拦截的基本概念。  
二、开发环境和工具清单 
三、流程1、示例程序手动创建一个示例程序,里面只包含了一个基本的webview容器,呈现的内容为某app的滑块url,基础代码如下: @interface ViewController () 
​ 
@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后的相关处理办法,希望能对你有所帮助。  
 |