request和response
概述:
- 调试网络信息:request和response
- 如果Charles抓包抓不到详情,可以考虑写插件hook代码实现
- 举例
- Apple账号登录过程,抓包失败
- 【未解决】iOS逆向Apple账号:用Charles抓包signin/v2/login的请求和响应的详情数据
 - 【未解决】Mac中Charles抓包:https请求始终只是显示CONNECT无法查看到详情数据
 
 - 后来转去用之前的插件hook代码
- 主要hook的点是:
- request
NSMutableURLRequest-[NSMutableURLRequest allHTTPHeaderFields]-[NSMutableURLRequest addValue:forHTTPHeaderField:]-[NSMutableURLRequest setValue:forHTTPHeaderField:]-[NSMutableURLRequest setAllHTTPHeaderFields:]-[NSMutableURLRequest setHTTPBody:]
NSURLRequest+[NSURLRequest requestWithURL:]+[NSURLRequest requestWithURL:cachePolicy:timeoutInterval:]-[NSURLRequest initWithURL:]-[NSURLRequest initWithURL:cachePolicy:timeoutInterval:]-[NSURLRequest allHTTPHeaderFields]
 - response
NSHTTPURLResponse-[NSHTTPURLResponse initWithURL:]-[NSHTTPURLResponse allHeaderFields]-[NSHTTPURLResponse initWithURL:statusCode:HTTPVersion:headerFields:]-[NSHTTPURLResponse statusCode]
 
 - request
 
 - 主要hook的点是:
 
 - Apple账号登录过程,抓包失败
 
 - 举例
 - 如果Charles抓包抓不到详情,可以考虑写用frida去hook打印
- TODO:去试试效果,把结果整理过来
 
 
 - 如果Charles抓包抓不到详情,可以考虑写插件hook代码实现
 
详解:
写插件hook代码
代码
/*==============================================================================
 Request
==============================================================================*/
/*------------------------------------------------------------------------------
 NSMutableURLRequest
------------------------------------------------------------------------------*/
%hook NSMutableURLRequest
-(void)setHTTPBody:(NSData *)bodyData{
//    iosLogInfo("bodyData=%@", bodyData);
   NSURL *reqUrl = [self URL];
   iosLogInfo("reqUrl=%{public}@: bodyData=%{public}@", reqUrl, bodyData);
   return %orig;
}
//-(NSDictionary<NSString *,NSString *>)*allHTTPHeaderFields{
//-(NSDictionary<NSString *,NSString *>)allHTTPHeaderFields{
-(id)allHTTPHeaderFields{
//    NSDictionary<NSString *,NSString *> allHeaderDict = %orig;
   id allHeaderDict = %orig;
   NSURL *reqUrl = [self URL];
//    if ((allHeaderDict != nil) && ([[allHeaderDict allKeys] count])) {
   if (nonEmptyHeader(allHeaderDict)){
       if( [allHeaderDict count] > 3){
//            iosLogInfo("allHeaderDict=%{public}@ : reqUrl=%{public}@", allHeaderDict, reqUrl);
//            NSString* headerUrlNSStr = [NSString initWithFormat:@"reqUrl=%{public}@, allHeaderDict=%{public}@", reqUrl, allHeaderDict]
//            NSString* headerUrlNSStr = [NSString stringWithFormat:@"reqUrl=%{public}@, allHeaderDict=%{public}@", reqUrl, allHeaderDict];
//            NSString* headerUrlNSStr = [NSString stringWithFormat:@"reqUrl=%@, allHeaderDict=%@", reqUrl, allHeaderDict];
           NSString* headerUrlNSStr = [NSString stringWithFormat:@"NSMutableURLRequest:allHTTPHeaderFields reqUrl=%@, allHeaderDict=%@", reqUrl, allHeaderDict];
           logPossibleLargeStr(headerUrlNSStr);
           gNoUse = 1;
       }
   }
   return allHeaderDict;
}
- (void)addValue:(NSString *)value forHTTPHeaderField:(NSString *)field{
   NSURL *reqUrl = [self URL];
   iosLogInfo("field=%{public}@, value=%{public}@ : reqUrl=%{public}@", field, value, reqUrl);
   %orig;
}
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field{
   NSURL *reqUrl = [self URL];
   iosLogInfo("field=%{public}@, value=%{public}@ : reqUrl=%{public}@", field, value, reqUrl);
   %orig;
}
- (void) setAllHTTPHeaderFields:(id)newAllHeaders{
   NSURL *reqUrl = [self URL];
   iosLogInfo("newAllHeaders=%{public}@ : reqUrl=%{public}@", newAllHeaders, reqUrl);
   %orig;
}
%end
/*------------------------------------------------------------------------------
NSURLRequest
------------------------------------------------------------------------------*/
%hook NSURLRequest
+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval{
    NSLog(@"jailAppleAccount requestWithURL: URL=%@, cachePolicy=%lu, timeoutInterval=%f", URL, (unsigned long)cachePolicy, timeoutInterval);
    return %orig;
}
+ (instancetype)requestWithURL:(NSURL *)URL{
    NSLog(@"jailAppleAccount requestWithURL: URL=%@", URL);
    return %orig;
}
- (instancetype)initWithURL:(NSURL *)URL{
    NSLog(@"jailAppleAccount initWithURL: URL=%@", URL);
    return %orig;
}
- (instancetype)initWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval{
    NSLog(@"jailAppleAccount initWithURL: URL=%@, cachePolicy=%lu, timeoutInterval=%f", URL, (unsigned long)cachePolicy, timeoutInterval);
    return %orig;
}
-(NSDictionary*)allHTTPHeaderFields{
   NSDictionary* allHeaderDict = %orig;
   NSURL *reqUrl = [self URL];
//    if ((allHeaderDict != nil) && ([[allHeaderDict allKeys] count])) {
   if (nonEmptyHeader(allHeaderDict)){
       if( [allHeaderDict count] > 3){
//            iosLogInfo("allHeaderDict=%{public}@ : reqUrl=%{public}@", allHeaderDict, reqUrl);
           NSString* reqHeaderUrlStr = [NSString stringWithFormat:@"NSURLRequest:allHTTPHeaderFields reqUrl=%@, allHeaderDict=%@", reqUrl, allHeaderDict];
           logPossibleLargeStr(reqHeaderUrlStr);
           gNoUse = 1;
       }
   }
   return allHeaderDict;
}
/*==============================================================================
Response
==============================================================================*/
/*------------------------------------------------------------------------------
NSHTTPURLResponse
------------------------------------------------------------------------------*/
%hook NSHTTPURLResponse
- (NSHTTPURLResponse*)initWithURL:(NSURL *)url statusCode:(NSInteger)statusCode HTTPVersion:(NSString *)HTTPVersion headerFields:(NSDictionary<NSString *,NSString *> *)headerFields{
   NSHTTPURLResponse* newUrlResp =  %orig;
   iosLogInfo("url=%{public}@,statusCode=%ld,HTTPVersion=%@,headerFields=%{public}@ -> newUrlResp=%{public}@", url, statusCode, HTTPVersion, headerFields, newUrlResp);
   return newUrlResp;
}
-(NSDictionary *)allHeaderFields{
   NSURL* curUrl = [self URL];
   NSDictionary* allHeader = %orig;
   //    iosLogInfo("curUrl=%{public}@ : allHeader=%{public}@", curUrl, allHeader);
   NSString* respUrlHeaderStr = [NSString stringWithFormat:@"NSHTTPURLResponse:allHeaderFields curUrl=%@ : allHeader=%@", curUrl, allHeader];
   logPossibleLargeStr(respUrlHeaderStr);
   return allHeader;
}
-(NSInteger)statusCode{
   NSURL* curUrl = [self URL];
   NSInteger respStatusCode = %orig;
   iosLogInfo("respStatusCode=%ld : curUrl=%{public}@", respStatusCode, curUrl);
   return respStatusCode;
}
%end
输出
- https://setup.icloud.com/setup/signin/v2/login
- request
- headers
- Accept = "/";
 - "Accept-Encoding" = "gzip, deflate, br";
 - "Accept-Language" = "zh-CN,zh-Hans";
 - Authorization = "Basic YWRtaW5AY3JpZm...3NjRlRrUzB0dW0wc0Nwang2RURMTjRpbz1QRVQ=";
 - "Content-Length" = 694;
 - "Content-Type" = "application/xml";
 - "Device-UDID" = abdc0dd...8433a;
 - "X-Apple-I-Device-Configuration-Mode" = 0;
 - "X-MMe-Client-Info" = "
";  - "X-MMe-Country" = CN;
 - "X-MMe-Language" = "zh-Hans-CN";
 - "X-Mme-Device-Id" = abdc0dd...8433a;
 
 
 - headers
 - response
- headers
- "Apple-Originating-System" = UnknownOriginatingSystem;
 - "Cache-Control" = "no-cache, no-store, private";
 - Connection = "keep-alive";
 - "Content-Encoding" = gzip;
 - "Content-Length" = 4213;
 - "Content-Type" = "application/xml; charset=UTF-8";
 - Date = "Mon, 05 Jun 2023 09:44:17 GMT";
 - Server = "AppleHttpServer/3faf4ee9434b";
 - "Set-Cookie" = "show-china-terms=false;Expires=Thu, 01-Jan-1970 00:00:01 GMT;Path=/setup;HttpOnly";
 - "Strict-Transport-Security" = "max-age=31536000; includeSubDomains";
 - Via = "63119...319:8ef2...35a6b:hktko1";
 - "X-Apple-Edge-Response-Time" = 3589;
 - "X-Apple-Jingle-Correlation-Key" = 4QJS...P4;
 - "X-Apple-Request-UUID" = "e4132a7d-b..0-4..e-8..f-6387...7f";
 - "X-Responding-Instance" = "setupservice:45100103:pv43p51ic-zteg06100801:8003:2316B377:36c327430fe1";
 - "access-control-expose-headers" = "X-Apple-Request-UUID,Via";
 - "apple-seq" = 0;
 - "apple-tk" = false;
 - "x-apple-user-partition" = 51;
 
 
 - headers
 
 - request