逆向--砸壳,破解,逆向,拦截,重定向之路

-- 拦截网络请求后进行网址或ip替换

注: ~ 本文仅用于学习研究,请勿用于非法用途 ~

破解APP的方法很多,如砸壳破解逆行等,或者修改Macho文件,但由于很多网站由于加了密,这些办法都不行.今天我们在这里讲一个终极办法拦截网络请求或者替换IP的方法.

1:应用场景

  • \color{red}{除去设备锁,或时间锁}
    比如某些抢红包应用有设备锁或者时间锁,按设备或者按年付费,部分用户不想付费的话,我们可以通过拦截网络,mock data 来破解此类应用;

  • \color{red}{部署多套授权的系统}
    一些人买了一套系统, 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()<NSURLSessionDelegate>
@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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容