作者:小编106 | 来源:互联网 | 2023-07-12 19:58
让别人的app变成自己的app系列阻拦网络请求后进行网址或者ip替换注:~本文仅用于学习研究,请勿用于非法用途需要ios企业签名可以联络我1113704624~破解APP的方法很多
让别人的app变成自己的app系列 -- 阻拦网络请求后进行网址或者ip替换
注: ~ 本文仅用于学习研究,请勿用于非法用途 需要ios企业签名 可以联络 我1113704624 ~
破解APP的方法很多,如砸壳破解逆行等,或者者修改Macho文件,但因为很多网站因为加了密,这些办法都不行.今天我们在这里讲一个终极办法阻拦网络请求或者者替换IP的方法.
1:应用场景
比方某些抢红包应用有设施锁或者者时间锁,按设施或者者按年付费,部分客户不想付费的话,我们可以通过阻拦网络,mock data 来破解此类应用;
少量人买了一套系统, app端访问的接口是写死在打包好的二进制文件,想部署多套应用无法部署.这个时候可以通过阻拦网络请求后进行服务器地址替换,完成多套部署.
2:实现原理
要想阻拦,我们需要先弄懂IOS的网络请求原理,请看下图
# 网络 <--> NSURLProtocol <--> 网络库
大部分的网络请求都要通过一个叫NSURLProtocol 的笼统类,既然都要通过这个笼统类,那我们是不是通过重载NSURLProtocol的方式进行网络请求的阻拦与过滤呢,答案当然是一定的.但世界上没有银弹,NSURLProtocol不能处理所有的问题,为什么呢.由于NSURLProtocol可以阻拦的网络请求包括NSURLSession,NSURLConnection。现在主流的iOS网络库,例如AFNetworking,Alamofire等网络库都是基于NSURLSession或者NSURLConnection的,所以这些网络库的网络请求都可以被NSURLProtocol所阻拦。
PS:基于CFNetwork的网络请求,以及WKWebView的请求是无法阻拦的。例如ASIHTTPRequest,MKNetwokit等网路库都是基于CFNetwork的,所以这些网络库的网络请求无法被NSURLProtocol阻拦。
3.实现步骤
1、创立NSURLProtocol子类
因为NSURLProtocol是一个笼统类,要使用它的时候需要创立它的一个子类。.m文件如下:
#import "ReplaceURLProtocol.h"// 为了避免canInitWithRequest和canonicalRequestForRequest的死循环static NSString *const URLProtocolHandledKey = @"URLProtocolHandledKey";// 老url网址static NSString *const old_url = @"baidu.com";// 新url网址static NSString *const new_url = @"google.com";@interface ReplaceURLProtocol()@property(nonatomic,strong)NSURLSession * session;@end@implementation ReplaceURLProtocol+(BOOL)canInitWithRequest:(NSURLRequest *)request{ return YES;}//改变请求request+(NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request{ // 业务逻辑写这里 return request;}//开始请求-(void)startLoading{ //业务逻辑写这里}//中止请求-(void)stopLoading{}#pragma mark ---- NSURLSessionDelegate/* NSURLSessionDelegate接到数据后,通过URLProtocol传出去 */- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{ if (error) { [self.client URLProtocol:self didFailWithError:error]; } else { [self.client URLProtocolDidFinishLoading:self]; }}- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler { [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; completionHandler(NSURLSessionResponseAllow); }- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{ [self.client URLProtocol:self didLoadData:data];}@end
2、注册protocol
基于NSURLConnection或者[NSURLSession sharedSession]创立的网络请求,在AppDelegate的didFinishLaunchingWithOptions方法中调用registerClass方法就可。
//注册protocol [NSURLProtocol registerClass:[ReplaceURLProtocol class]];returnYES;}
3、阻拦客户的网络请求
首先,在阻拦到网络请求后会先调用+(BOOL)canInitWithRequest:(NSURLRequest *)request方法。我们可以在该方法里进行能否解决这个阻拦的逻辑。如设置只对阻拦到的http或者https请求进行解决。
+(BOOL)canInitWithRequest:(NSURLRequest *)request{ // 不是网络请求,不解决 if (![request.URL.scheme isEqualToString:@"http"] && ![request.URL.scheme isEqualToString:@"https"]) { return NO; } // 指定阻拦网络请求,如:www.baidu.com if ([request.URL.absoluteString containsString:old_url]) { return YES; }else { return NO; }}
接着,会调用+(NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request在该方法中,我们可以对request进行解决。例如修改头部信息等。最后返回一个解决后的request实例。也可以在该方法里面将客户的请求域名替换成别的域名:
/** 设置我们自己的自己设置请求 可以在这里统一加上头之类的 @param request 应用的此次请求 @return 我们自己设置的请求 */+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { NSMutableURLRequest *mutableReqeust = [request mutableCopy]; // 设置已解决标志 [NSURLProtocol setProperty:@(YES) forKey:kProtocolHandledKey inRequest:mutableReqeust]; NSLog(@"************ 原始请求的url1 %@",request.URL); if ([request.URL host].length == 0) { return request; } NSString * originUrlStr = [request.URL absoluteString]; NSString * originHostStr = [request.URL host]; NSRange hostRange = [originUrlStr rangeOfString:originHostStr]; if (hostRange.location == NSNotFound) { return request; } //指定阻拦网络请求,如:www.baidu.com if ([request.URL.absoluteString containsString:old_url]) { //定向到百度搜索 NSString * ip = new_url; NSString * urlStr = [originUrlStr stringByReplacingCharactersInRange:hostRange withString:ip]; NSURL * url = [NSURL URLWithString:urlStr]; mutableReqeust.URL = url; NSLog(@"************ 替换后的url 1 %@",mutableReqeust.URL); return [mutableReqeust copy]; } else{ return request; }
4、转发
-(void)startLoading将解决过的request重新发送出去。发送的形式,可以是基于NSURLConnection,NSURLSession甚至CFNetwork。我们也可以在该方法里面设置网络代理商,如下我们设置一个代理商后,重新创立一个NSURLSession将网络请求发送出去:
// 重新父类的开始加载方法- (void)startLoading { NSMutableURLRequest * mutableRequest = [[self request] mutableCopy]; NSLog(@"************ 开始请求 %@",mutableRequest.URL); NSURLSessionConfiguration * cOnfiguration= [NSURLSessionConfiguration ephemeralSessionConfiguration];//创立一个临时会话配置 //网络请求 self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[[NSOperationQueue alloc] init]];// 注 这里也可以增加代理商 捕获客户请求数据 NSURLSessionTask * task = [self.session dataTaskWithRequest:self.request]; [task resume];//开始任务}
5、回调
上面使用的是NSURLSession请求,所以我们通过NSURLSessionDelegate来接收网络请求的数据(成功或者失败等信息):
#pragma mark ---- NSURLSessionDelegate/* NSURLSessionDelegate接到数据后,通过URLProtocol传出去 *///失败- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{ if (error) { [self.client URLProtocol:self didFailWithError:error]; //请求错误 } else { [self.client URLProtocolDidFinishLoading:self]; //完成加载 }}//接收到响应- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler { [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; //创立一个响应(缓存策略:不缓存) completionHandler(NSURLSessionResponseAllow); }//接收到数据- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{ [self.client URLProtocol:self didLoadData:data]; //接收到数据}
6、结束
在-(void)stopLoading完成网络请求的操作
//结束请求-(void)stopLoading{ [self.session invalidateAndCancel]; self.session = nil;}
欢迎加入iOS技术处理方案群,群聊号码:1060356414