__CFString *__fastcall initializeUserAgentString(__CFString *result)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-“+” TO EXPAND]
v1 = *(_QWORD *)-[__NSCFURLSessionTask description]_ptr;
v16 = *(_QWORD *)-[__NSCFURLSessionTask description]_ptr;
if ( !sUserAgentString )
{
v2 = *(_QWORD *)-[__NSCFURLSessionTask _shouldUsePipelineHeuristics]_ptr;
result = (__CFString )MEMORY[0x1809308EC]((_QWORD *)-[__NSCFURLSessionTask _shouldUsePipelineHeuristics]_ptr, 0LL);// 第一次这里为空
v3 = result;
if ( !result )
{
if ( v1 == v16 )
JUMPOUT(0x18069E638uLL);
LABEL_26:
v13 = (__CFString *)MEMORY0x18054E604;// 这里没有调用
appendEscaped(v13, v14);
}
v4 = MEMORY0x180922154; // CFBundleGetMainBundle()
// Printing description of $x0:
// CFBundle 0x125501010 </var/containers/Bundle/Application/042728BB-9770-4DE3-B542-9E1E1BD50613/TestApp.app> (executable, loaded)
// (lldb) po [ $x0 class]
// __NSCFType
//
if ( v4 )
{
v5 = *(_QWORD *)-[__NSCFURLSessionTask _cookieAcceptPolicy]_ptr;
v6 = (const __CFString *)MEMORY0x18096B1E0;// CFBundleGetValueForInfoDictionaryKey()
if ( v6 ) // 判断app名字: TestApp
appendEscaped(v3, v6);
v7 = MEMORY0x1809CABD4;
if ( v7 )
{
v8 = (const __CFString *)MEMORY0x18094A384;// 这里有调用 CFBundleGetValueForInfoDictionaryKey()
// Printing description of $x1:
// CFBundleVersion
// Printing description of $x0:
// CFBundle 0x125501010 </var/containers/Bundle/Application/042728BB-9770-4DE3-B542-9E1E1BD50613/TestApp.app> (executable, loaded)
if ( v8 ) // v8 = 1
appendEscaped(v3, v8);
MEMORY0x18091CB34;
}
}
if ( MEMORY0x18092247C )
MEMORY[0x180983350](v3, 0LL, 6940118424LL);
else
MEMORY[0x180930A64](v3, 6940119712LL);
if ( MEMORY0x180961ABC // 这里通过bundle Id来获取CFBundle
// CFBundleGetBundleWithIdentifier(com.apple.CFNetwork)
// (lldb) po CFBundleGetBundleWithIdentifier(@“com.apple.CFNetwork”)
// CFBundle 0x1255065f0 </System/Library/Frameworks/CFNetwork.framework> (framework, loaded)
//
// (lldb) po CFBundleGetValueForInfoDictionaryKey(0x1255065f0, @“CFBundleVersion”)
// 758.5.3
// 这样就拿到CFNetwork的版本号了
&& (v9 = *(_QWORD *)-[__NSCFURLSessionTask set_cookieAcceptPolicy:]_ptr, MEMORY0x18096B1E0) )
{
v10 = 6940119096LL;
}
else
{
v10 = 6940118424LL;
}
MEMORY[0x180983350](v3, 0LL, v10);
*(_QWORD *)v15 = 4294967297LL;
v11 = (const __CFString *)copySysctl(v15); // 返回: Darwin, 参数将0x100000001取地址传入
// (lldb) x 0x16fd772c0
// 0x16fd772c0: 01 00 00 00 01 00 00 00 53 7f b2 ef d7 48 00 f9 …S…H…
// 0x16fd772d0: 40 ed 51 25 01 00 00 00 00 00 00 00 00 00 00 00 @.Q%…
// (lldb) po copySysctl(0x000000016fd772c0)
// Darwin
if ( v11 )
appendEscapedFormat(v3, (const __CFString *)&unk_19DA9CD98, v11);
v12 = MEMORY[0x180924CAC](v2, v3); // 参数将0x200000001取地址传入
// (lldb) x 0x000000016fd772c0
// 0x16fd772c0: 01 00 00 00 02 00 00 00 53 7f b2 ef d7 48 00 f9 …S…H…
// 0x16fd772d0: 40 ed 51 25 01 00 00 00 00 00 00 00 00 00 00 00 @.Q%…
// Printing description of $x0:
// 15.6.0
// (lldb) po copySysctl(0x000000016fd772c0)
// 15.6.0
// 通过copySysctl得到内核版本号
if ( !(MEMORY[0x18069E638](0LL, v12, &sUserAgentString) & 1) )// sUserAgentString这个变量就是全局保存userAgent的变量了
{
if ( v12 )
MEMORY0x18091CB34;
}
result = (__CFString *)MEMORY0x18091CB34;
}
if ( v1 != v16 )
goto LABEL_26;
return result;
}
// 取UserAgent
po _CFNetworkUserAgentString()
再分析copySysctl的汇编代码,
CFNetwork`copySysctl:
0x183413fd8 <+0>: stp x20, x19, [sp, #-0x20]!
0x183413fdc <+4>: stp x29, x30, [sp, #0x10]
0x183413fe0 <+8>: add x29, sp, #0x10 ; =0x10
0x183413fe4 <+12>: sub sp, sp, #0x90 ; =0x90
0x183413fe8 <+16>: adrp x19, 102820
0x183413fec <+20>: ldr x19, [x19, #0x110]
0x183413ff0 <+24>: ldr x19, [x19]
0x183413ff4 <+28>: stur x19, [x29, #-0x18]
0x183413ff8 <+32>: orr w8, wzr, #0x80
0x183413ffc <+36>: str x8, [sp]
0x183414000 <+40>: orr w1, wzr, #0x2
0x183414004 <+44>: add x2, sp, #0x8 ; =0x8
0x183414008 <+48>: mov x3, sp
0x18341400c <+52>: mov x4, #0x0
0x183414010 <+56>: mov x5, #0x0
0x183414014 <+60>: bl 0x1828daa3c ; sysctl
→ 0x183414018 <+64>: mov x8, x0
0x18341401c <+68>: mov x0, #0x0
0x183414020 <+72>: tbnz w8, #0x1f, 0x183414040 ; <+104>
0x183414024 <+76>: adrp x8, 102819
0x183414028 <+80>: ldr x8, [x8, #0x190]
0x18341402c <+84>: ldr x0, [x8]
0x183414030 <+88>: mov w2, #0x8000000
0x183414034 <+92>: movk w2, #0x100
0x183414038 <+96>: add x1, sp, #0x8 ; =0x8
0x18341403c <+100>: bl 0x182d0dca4 ; CFStringCreateWithCString
0x183414040 <+104>: ldur x8, [x29, #-0x18]
0x183414044 <+108>: sub x8, x19, x8
0x183414048 <+112>: cbnz x8, 0x18341405c ; <+132>
0x18341404c <+116>: sub sp, x29, #0x10 ; =0x10
0x183414050 <+120>: ldp x29, x30, [sp, #0x10]
0x183414054 <+124>: ldp x20, x19, [sp], #0x20
0x183414058 <+128>: ret
0x18341405c <+132>: bl 0x18293a604 ; __stack_chk_fail
结果就是在调用sysctl, 参数传的是0x200000001
(lldb) x 0x000000016fd0f208
0x16fd0f208: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
0x16fd0f218: b0 42 22 02 01 00 00 00 00 f3 d0 6f 01 00 00 00 .B"…o…
(lldb) po sysctl(0x0000000102224390, 2, 0x16fd0f208)
nil
(lldb) x 0x16fd0f208
0x16fd0f208: 31 35 2e 36 2e 30 00 00 00 00 00 00 00 00 00 00 15.6.0…
0x16fd0f218: b0 42 22 02 01 00 00 00 00 f3 d0 6f 01 00 00 00 .B"…o…
__int64 __fastcall cleanUpRequest(HTTPMessage *a1, __int64 a2, int a3, int a4)
{
v4 = a4;
v5 = a3;
v6 = a2;
v7 = a1;
v8 = *(_QWORD *)-[__NSCFURLSessionTask description]_ptr;
v45 = *(_QWORD *)-[__NSCFURLSessionTask description]_ptr;
if ( a1 )
{
HTTPMessage::Class(a1);
if ( *((_BYTE )v7 + 40) )
v9 = 0LL;
else
v9 = (signed __int64)v7 + 16;
}
else
{
v9 = 0LL;
}
if ( !(unsigned int)HTTPMessage::hasHeaderField(v9, 916625106LL) )
{
MEMORY[0x1806A66E4](&initControl, initializeUserAgentString);
HTTPMessage::setHeaderFieldStringValue(v9, 0x36A296D2LL, sUserAgentString); // 这里设置UserAgent的key为:0x36A296D2LL
}
if ( !(v6 & 0x8000000000000000LL) )
{
if ( !(_QWORD )(v9 + 136)
&& (_coreLogInternalError(
“/BuildRoot/Library/Caches/com.apple.xbs/Sources/CFNetwork/CFNetwork-758.5.3/HTTP/HTTPMessage/HTTPRequestParserClient.h”,
28),
!(_QWORD *)(v9 + 136))
|| MEMORY0x18092E554 )
{
HTTPMessage::setHeaderFieldScalarValue(v9, 839095792LL, v6);
}
}
if ( v5 )
{
HTTPMessage::setHeaderFieldStringValue(v9, 830641614LL, 956471107LL);
if ( v4 )
{
v10 = 956471107LL;
LABEL_19:
HTTPMessage::setHeaderFieldStringValue(v9, 891557509LL, v10);
goto LABEL_20;
}
}
else
{
HTTPMessage::setHeaderFieldStringValue(v9, 830641614LL, 943806246LL);
if ( v4 )
{
v10 = 943806246LL;
goto LABEL_19;
}
}
LABEL_20:
result = HTTPMessage::hasHeaderField(v9, 859903523LL);
if ( (_DWORD)result )
goto LABEL_65;
result = HTTPRequestParserClient::requestURL((HTTPRequestParserClient *)(v9 + 112));
v12 = result;
if ( !result )
goto LABEL_65;
v14 = MEMORY0x1809672CC;
v15 = v13;
if ( v14 == -1 )
{
v17 = 0;
v16 = 1;
}
else
{
v17 = OFSUB(v13, 1LL);
v16 = v13 - 1 < 0;
}
if ( !(v16 ^ v17) )
{
v18 = MEMORY[0x1809671A0](v12, 0LL, 0LL);
v19 = v18;
if ( v18 >= 1 )
{
if ( v18 >= 513 )
{
v20 = (char *)j____42____NSCFURLProxySessionConnection_suspend__block_invoke();
if ( !v20 )
goto LABEL_38;
}
else
{
v20 = &v44;
}
if ( MEMORY[0x1809671A0](v12, v20, v19) < 1 )
{
v24 = 0LL;
}
else
{
v21 = MEMORY[0x1809672CC](v12, 9LL, 0LL);
if ( v21 != -1 )
v15 = v21 - v14 + v22;
v23 = MEMORY0x18091BD18;
v24 = (HTTPHeaderValue *)MEMORY[0x18091BE64](v23, &v20[v14], v15, 513LL, 0LL);
}
if ( v20 != &v44 )
-__NSCFURLSessionTask countOfBytesExpectedToReceive;
if ( v24 )
goto LABEL_52;
}
}
LABEL_38:
result = MEMORY0x18098F3A0;
v25 = (const __CFString *)result;
if ( !result )
goto LABEL_65;
v26 = MEMORY0x18098F5D8;
if ( (unsigned int)_isIPAddress(v25, 0) )
{
v27 = &_kCFHTTPLiteralIPV6Format;
if ( v26 != -1 )
v27 = (__int64 *)&_kCFHTTPLiteralIPV6Format_WithPort;
v28 = *v27;
}
else if ( v26 == -1 )
{
v28 = 0LL;
}
else
{
v28 = 6940100000LL;
}
v29 = MEMORY0x18091BD18;
v30 = MEMORY[0x18094A898](v29, v25, 0LL, 0LL, 134217984LL);
if ( !v30 )
{
v31 = MEMORY0x18091BD18;
v30 = MEMORY[0x18094A898](v31, v25, 0LL, 0LL, 513LL);
if ( !v30 )
{
v42 = (void *)v25;
LABEL_64:
result = MEMORY0x18091CB34;
goto LABEL_65;
}
}
if ( v28 )
{
v32 = MEMORY0x18091BD18;
v33 = MEMORY[0x1809309FC](v32, 0LL, v28);
}
else
{
v33 = MEMORY0x18091A150;
}
v24 = (HTTPHeaderValue *)v33;
MEMORY0x18091CB34;
result = MEMORY0x18091CB34;
if ( v24 )
{
LABEL_52:
if ( MEMORY0x18092247C >= 1 && (unsigned int)MEMORY[0x1809478BC](v24, 0LL) == 91 )
{
v35 = MEMORY[0x18093D01C](v24, CFSTR(“%25”), 0LL);
if ( v35 != -1 )
{
v36 = MEMORY[0x18093D01C](v24, CFSTR(“]”), 0LL);
if ( v36 == -1 )
{
v39 = 0;
v37 = 1;
v38 = 0;
}
else
{
v39 = OFSUB(v36, v35);
v37 = v36 == v35;
v38 = v36 - v35 < 0;
}
if ( !((unsigned __int8)(v38 ^ v39) | v37) )
{
v40 = MEMORY0x18091BD18;
v41 = MEMORY[0x180948CFC](v40, 0LL, v24);
if ( v41 )
{
MEMORY0x180948FF0;
MEMORY0x18091CB34;
v24 = (HTTPHeaderValue *)v41;
}
}
}
}
if ( (unsigned int)HTTPHeaderValue::isValid(v24, v34) )
HTTPMessage::setHeaderFieldStringValue(v9, 859903523LL, v24);
v42 = (void *)v24;
goto LABEL_64;
}
LABEL_65:
if ( v8 != v45 )
{
v43 = (const __CFString *)MEMORY0x18054E604;
result = isIPV6LiteralAddress(v43);
}
return result;
}
发起请求时读取sUserAgentString的函数为:
CFNetwork`HTTPMessage::setHeaderFieldStringValue:
// __CFNetworkCopyPreferredLanguageCode 导出函数往上找HTTPMessage::setHeaderFieldStringValue, 再hook这个函数就可以得到sUserAgentString参数了