Tiktok版本: 33.2.5 (24年1月25日)
1、前言
通过对Tiktok抓包发现TikTok的所有http请求的头部增加了参数签名(x-argus、x-goron、x-khronos、x-ladon):
2、获取关键函数
直接将apk文件用jadx工具反编译,搜索关键字x-argus等,未搜索到任何关键字:
使用frida hook java层 Header对象的构造方法,发现有监控到https请求头设置,但是始终没有发现签名字段
var Header = Java.use("X.2jn");
Header.$init.implementation = function(key, val) {
console.log(key + " : " + val);
this.$init(key, val);
}
接着尝试hook interceptor拦截器,打印出请求头部,结果输出的请求头部中还是没有签名字段
//添加intercept
var Request = Java.use("X.LGn");
Request.LIZJ.implementation = function(intercept){
var newObj = Java.cast(intercept, Java.use("java.lang.Object"));
//console.log(newObj.getClass());
var new_cls = newObj.getClass();
var class_name = new_cls.getName();
if(!mmp[class_name]) {
mmp[class_name] = 1;
var hook_class = Java.use(class_name);
hook_class.intercept.implementation = function(tt){
var res = this.intercept(tt);
/* var rq = tt.request();
console.log(rq.getUrl()); */
var request = getFieldVal(res, "LIZ");
//console.log(getFieldVal(request, "LIZ"));
//console.log(getFieldVal(request, "LIZJ"));
//console.log(getFieldVal(request, "LJI"));
var headers = getFieldVal(request, "LIZLLL");
//console.log(headers);
//console.log("----------------------------------------------------");
return res;
}
}
this.LIZJ(intercept);
}
Java层找了一遍始终找不到签名关键字符串,那很大可能是在native层设置,在native层在 https请求发出时进行设置。TikTok使用 cronet网络库 。将libsscronet拖IDA反编译,搜索 x-gorfon 关键字,确实找到了:
结合 cronet源码,找到Native层设置请求Header函数:
void HttpRequestHeaders::SetHeader(const base::StringPiece& key,
const base::StringPiece& value) {
DCHECK(HttpUtil::IsValidHeaderName(key.as_string()));
// TODO(ricea): Revert this. See crbug.com/627398.
CHECK(HttpUtil::IsValidHeaderValue(value.as_string()));
HeaderVector::iterator it = FindHeader(key);
if (it != headers_.end())
it->value.assign(value.data(), value.size());
else
headers_.push_back(HeaderKeyValuePair(key, value));
}
定位到该libsscronet中偏移为:0x2C44BC,HOOK该地址并打印出参数:
var SetHeaders = lib.base.add(0x2C44BC);
Interceptor.attach(SetHeaders, {
onEnter: function (args) {
var key = args[1].readPointer().readUtf8String(); //第一个属性是字符串的地址, 第二个属性长度
var val = args[2].readPointer().readUtf8String();
console.log(key + " : " + val);
},
onLeave: function (retval) {
}
});
这次全部头部都可以看到了,完美!
然后打印设置参数签名字段时的调用栈:
var SetHeaders = lib.base.add(0x2C44BC);
Interceptor.attach(SetHeaders, {
onEnter: function (args) {
var key = args[1].readPointer().readUtf8String(); //第一个属性是字符串的地址, 第二个属性长度
var val = args[2].readPointer().readUtf8String();
if(key.indexOf("X-Gorgon") !== -1) {
console.log(key + " : " + val);
console.log('SetHeaders called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log("---------------------------end----------------------------------");
}
},
onLeave: function (retval) {
}
});
有两处调用,分别是 0x3a662c 和 0x2c4b78:
分别对两处进行反编译分析,0x3a662c 更像是tiktok定制的设置相关header处,关键代码反编译:
v128是从某个函数调用返回的结果,对该结果分割处理就得到了参数签名字段,因此用frida hook这里,然后输出调用时的两个参数查看
直接对0x3A658C地址进行HOOK,并打印出x0和x1寄存器的值,同时打印出X23寄存器的值:
var test = lib.base.add(0x3A658C);
Interceptor.attach(test, {
onEnter: function (args) {
console.log(args[0].readUtf8String());
console.log(args[1].readUtf8String());
console.log("X23:" + this.context.x23);
},
onLeave: function (retval) {
}
});
输出如下:
https://pitaya-ttp2.us.tiktokv.com/api/v2/pitaya/distribute
cookie
passport_csrf_token=5766c07398074a324465468bd4bab579; passport_csrf_token_default=5766c07398074a324465468bd4bab579; d_ticket=474b6c31b9b433d344ad9368558503f7c0b97; multi_sids=7158650562190427178%3A41a587d2b1bda3bdf9a41a6ad5e966dd; cmpl_token=AgQQAPNSF-RPsLNmTGWesB0T_9hlCYxU_4dFYNGQWw; sid_guard=41a587d2b1bda3bdf9a41a6ad5e966dd%7C1706690864%7C5183999%7CSun%2C+31-Mar-2024+08%3A47%3A43+GMT; uid_tt=7ea855d54c1e8757b958a57c70ae4460747f060968a2b87122b64b9885ef693c; uid_tt_ss=7ea855d54c1e8757b958a57c70ae4460747f060968a2b87122b64b9885ef693c; sid_tt=41a587d2b1bda3bdf9a41a6ad5e966dd; sessionid=41a587d2b1bda3bdf9a41a6ad5e966dd; sessionid_ss=41a587d2b1bda3bdf9a41a6ad5e966dd; store-idc=useast5; store-country-code=us; store-country-code-src=uid; tt-target-idc=useast5; tt-target-idc-sign=TTaFL_-1FbxEnf7WPS8zSLktQ9q_ifo6_mDz3Av0v8FRvfiClSjLH0kitsJa9NPbyFwN8SuqcgAf5RVQ_6pupKVUrkkLUROrihSkzo6xgNW-cni9Upf7Cb8L-lH6iXsKuLG9rjNatWULp7Q0ttS4Hru25ZA2_piENXsxaYc_89Z_ZgwyZhzLe4dXLBLDW4YtWrXAazxRLpNwkL_LQ8fnueZBRmZgJ0QNA3SyztUm9UnjDrqCZtTsTqrOS6zSxPoOfEL0UFxY12F5qPCgX84eh3_gifeiXxcmNkHZgPTNwSX0NOpTEw9kYLc9zOEWQ1IPMgXEgGZueXyYE-gHE7GfSrGZq41r_KC6qgb26LryHaXNg324JZbTPRBbz-AwRyHE0YeexTdtw260Yid1TDSUQx6jbHI7zDxMfCE9cJCPJye25D3Uj3hP7TsPt4bBkCt5jaHGdXvMIHeGDXSDfnhZy0HU64KS3Yh9sVNSA3nniaYgC4T2mekD3k4KvvmFIB74; install_id=7330181047176857374; ttreq=1$ef5245324d322906a97679c1d5607b943302a796; odin_tt=1aa7c920ceb63edc6557473a4e1787da2c6a470b275459df0bc31298c6923c6e66dc4673cf75b9373e546e2654bc598fda5ba22e95d91ceb33de9a5ebdeb90ff7c27f43f5e7825b5ba92ac9ea05f8932; msToken=7DDzVQRIMB7ctDaC0N7hcu7PbQ4dQmHhHa9Ggd1-kGq0ZuDkSXR3cxNzjfie5mEcNUksJSMEhiniITA8vwhqdOkXXJgm5tbe6-3Cf_ZdS8hSWMQBslxhNYshHyweLw==
x-vc-bdturing-sdk-version
2.3.5.i18n
x-bd-kmsv
0
x-tt-dm-status
login=1;ct=1;rt=1
x-ss-req-ticket
1707126766871
x-bd-client-key
#baXvVHqzV2VM8S1JcXbNUSdy2etUU3s95T2Yea6/0XO4pibZxVQ/PXaR09LfGTqLTlCPYtNGJ26+tkzb
pns_event_id
75
content-type
application/json; charset=utf-8
content-length
919
x-tt-store-region
us
x-tt-store-region-src
uid
x-ss-dp
1233
x-tt-trace-id
00-78af3eb21065b9fc3a23cbc6058a04d1-78af3eb21065b9fc-01
user-agent
com.zhiliaoapp.musically/2023302050 (Linux; U; Android 11; en; Mi 9T Pro; Build/RKQ1.200826.002; Cronet/TTNetVersion:996128d2 2024-01-12 QuicVersion:ce58f68a 2024-01-12)
accept-encoding
gzip, deflate, br
X23:0x790584aee0
参数1是https请求的url,参数2看起来是https请求的header, X23的地址位于 libmetasec_ov.so模块的0x88ee0处。这样基本可以确定0x88ee0 是获取签名的关键函数。
对该函数HOOK并打印参数和返回值:
function waitForModule(moduleName) {
return new Promise(resolve => {
const interval = setInterval(() => {
const module = Process.findModuleByName(moduleName);
if (module != null) {
clearInterval(interval);
resolve(module);
}
}, 0);
});
}
waitForModule("libmetasec_ov.so").then((lib) => {
logger(`[*][+] Found libsscronet at: ${lib.base}`)
hook_tt_get_sig(lib);
});
function hook_tt_get_sig(lib) {
var get_sig = lib.base.add(0x88ee0);
Interceptor.attach(get_sig, {
onEnter: function (args) {
console.log("arg0:" + args[0].readUtf8String());
console.log("arg1:" + args[1].readUtf8String());
},
onLeave: function (retval) {
console.log("retval: " + retval.readUtf8String());
}
});
}
arg0:https://log16-normal-useast8.us.tiktokv.com/service/2/app_alert_check/?device_id=7330167195161052677&aid=1233&tt_info=dGMFEAAAcbZMj0j60zx0QZ36CmqwscC_mg_FI33giq8TCyxwgZ0k7cu5UKyTp1L9dV-LfNfW4lXh%0Ar0nUiGJiKZ3gDTrfQD3ReFJzPYPt0nAafGTrwTYpE-PyqOZoVMC5oDuJFBWuFqqya6HwUuGxN5yO%0AP49E6kSu1rM_1-xY36xXTYPC8gekr5bUXyHyfmxJnNIap0t8JqKQW72gWlmb7RGJWnEqALZSuTrS%0ATlIvTOFF4LzJrprGoRGAbUs0pqvYanBTbQfZ8c-8VUd8A1FOepNFvxnnbv6168SjPh9alAq0NGfz%0AgYkwcsVvqb5POQBKWMJskxct2mcizBAqpKVQsDteOKuuci_QYcniwyQ7B5AF-nQsWAhLmuJVb_ya%0A3a3Dt6701GKDFSB7ObdAdK7JU5xlLCeevWdvdXCWvtDURvMiB1lhnCTf2lF--_UEmTCx5TxkHDnK%0AJUYq36SEDO1I1K5dy9PDtJ4HhgpdraMbymScFDrVVZAdflINaUbBcXSGrbjyRrfGke4Zi0LivqZq%0A1cRpYWELr9AoDT48PziFXh6Bmj3CXGRJAa-d0XdNtyDvvik5PhCeqN8PTH1PwA6vv7VsqkpnLny0%0APtL34eTrw0ThDdJQGH3UTr9jVNixJZ4dMTLhu8MZJCaNpEgAoWhWOPErTN9O3YkOutVsDXiqgjIJ%0AG8lpRCK2LGWEIoZXa0qKBtzG0nvO52hs6XRFER6t6wSm1Ix2alR_SlxnzdMnqRxTdHkc_KU-QJ2d%0A_fThvP_9TseeU1T1T5miiLEOsrRqlYEmV_h48Zh-lPteWeMnGb-h4T4c_K6k8B6nWSUA3blq1M6J%0A7qW6dmcdhNpRfXP3WGsLa0D1XqUkPhhIS5Y6bd5N3yLxy_Q%3D%0A&iid=7330181047176857374&ac=wifi&channel=googleplay&app_name=musical_ly&version_code=330205&version_name=33.2.5&device_platform=android&os=android&ab_version=33.2.5&ssmix=a&device_type=Mi+9T+Pro&device_brand=Xiaomi&language=en&os_api=30&os_version=11&openudid=3e2d515cedf5f2b2&manifest_version_code=2023302050&resolution=1080*1920&dpi=480&update_version_code=2023302050&_rticket=1707127562679&is_pad=0¤t_region=NZ&app_type=normal&sys_region=US&mcc_mnc=53028&timezone_name=Pacific%2FAuckland&residence=NZ&app_language=en&carrier_region=NZ&ac2=wifi5g&uoo=0&op_region=NZ&timezone_offset=43200&build_number=33.2.5&host_abi=arm64-v8a&locale=en®ion=US&ts=1707127561&cdid=5c3ed0c6-8aaf-4018-9fb1-f7ada8bcea34&cronet_version=996128d2_2024-01-12&ttnet_version=4.2.137.48-tiktok&use_store_region_cookie=1
arg1:cookie
passport_csrf_token=5766c07398074a324465468bd4bab579; passport_csrf_token_default=5766c07398074a324465468bd4bab579; d_ticket=474b6c31b9b433d344ad9368558503f7c0b97; multi_sids=7158650562190427178%3A41a587d2b1bda3bdf9a41a6ad5e966dd; cmpl_token=AgQQAPNSF-RPsLNmTGWesB0T_9hlCYxU_4dFYNGQWw; sid_guard=41a587d2b1bda3bdf9a41a6ad5e966dd%7C1706690864%7C5183999%7CSun%2C+31-Mar-2024+08%3A47%3A43+GMT; uid_tt=7ea855d54c1e8757b958a57c70ae4460747f060968a2b87122b64b9885ef693c; uid_tt_ss=7ea855d54c1e8757b958a57c70ae4460747f060968a2b87122b64b9885ef693c; sid_tt=41a587d2b1bda3bdf9a41a6ad5e966dd; sessionid=41a587d2b1bda3bdf9a41a6ad5e966dd; sessionid_ss=41a587d2b1bda3bdf9a41a6ad5e966dd; store-idc=useast5; store-country-code=us; store-country-code-src=uid; tt-target-idc=useast5; tt-target-idc-sign=TTaFL_-1FbxEnf7WPS8zSLktQ9q_ifo6_mDz3Av0v8FRvfiClSjLH0kitsJa9NPbyFwN8SuqcgAf5RVQ_6pupKVUrkkLUROrihSkzo6xgNW-cni9Upf7Cb8L-lH6iXsKuLG9rjNatWULp7Q0ttS4Hru25ZA2_piENXsxaYc_89Z_ZgwyZhzLe4dXLBLDW4YtWrXAazxRLpNwkL_LQ8fnueZBRmZgJ0QNA3SyztUm9UnjDrqCZtTsTqrOS6zSxPoOfEL0UFxY12F5qPCgX84eh3_gifeiXxcmNkHZgPTNwSX0NOpTEw9kYLc9zOEWQ1IPMgXEgGZueXyYE-gHE7GfSrGZq41r_KC6qgb26LryHaXNg324JZbTPRBbz-AwRyHE0YeexTdtw260Yid1TDSUQx6jbHI7zDxMfCE9cJCPJye25D3Uj3hP7TsPt4bBkCt5jaHGdXvMIHeGDXSDfnhZy0HU64KS3Yh9sVNSA3nniaYgC4T2mekD3k4KvvmFIB74; install_id=7330181047176857374; ttreq=1$ef5245324d322906a97679c1d5607b943302a796; odin_tt=1aa7c920ceb63edc6557473a4e1787da2c6a470b275459df0bc31298c6923c6e66dc4673cf75b9373e546e2654bc598fda5ba22e95d91ceb33de9a5ebdeb90ff7c27f43f5e7825b5ba92ac9ea05f8932; msToken=KaEq98vvNTLCC9vvMJwobggElABP3DvaLMgNf9zMFpurwzHDGdnJbn7NJ53sdDQ6iyM_yaDcpgAxLQevASt6DqNlXZ7NNzYuOFnU6EHixIwVOy6KOhAVe2XkyGq47g==
x-tt-multi-sids
7158650562190427178%3A41a587d2b1bda3bdf9a41a6ad5e966dd
sdk-version
2
x-bd-kmsv
0
x-tt-dm-status
login=1;ct=1;rt=1
x-tt-token
0441a587d2b1bda3bdf9a41a6ad5e966dd041679e9cfeb96c72898bb183b8222bb1073d351793c1da7dca678b7cfc8c54af218b43f5dd2a4e0c8a71da5e1c2c8c45699afd524957260286c4b116e0df117c1c87de2a72c1faf791269c934718e8616e-1.0.1
x-ss-req-ticket
1707127562691
x-bd-client-key
#baXvVHqzV2VM8S1JcXbNUSdy2etUU3s95T2Yea6/0XO4pibZxVQ/PXaR09LfGTqLTlCPYtNGJ26+tkzb
multi_login
1
passport-sdk-version
19
pns_event_id
22
x-vc-bdturing-sdk-version
2.3.5.i18n
x-ss-dp
1233
x-tt-trace-id
00-78bb64b11065b9fc3a23cbc6055904d1-78bb64b11065b9fc-01
user-agent
com.zhiliaoapp.musically/2023302050 (Linux; U; Android 11; en; Mi 9T Pro; Build/RKQ1.200826.002; Cronet/TTNetVersion:996128d2 2024-01-12 QuicVersion:ce58f68a 2024-01-12)
accept-encoding
gzip, deflate, br
retval: X-Argus
DXfY6mO6hlrcmaQgpgzBwrXD6AJCuKss3FonR0C+ub/vtTBhj92rDuroEsi57jh6qUM04M1lRoxdSx2brJ7D+fkvjPnDFGwEbHLhGu8oR7wrdOU1TNIbzQoI+UMmLg8ySyqHEiFWG8l3XWHXbaJDgsmCZv1Zry2v9g0ORukQvDUfhxKgdBwPFAeQf8MxZDE4AuGzTWJ5QxZcIQUlGgAynnKqvPrzQiauq8xcD99TyYrrZVNfdBS5RsVfZZWTeI7dLjxMoV+grZVc9Bp7FViXJ7G4zIzkSvpEWMjI+fzUN3EClwzg+rcrCQOUZ1tsiREzOGnLoAAX91uXBq/QQ9xGy4/+9Vw7W5izejUj0lamUT0eoi5hLFDxKFtrqgRzRVd6ABu8Pc7hT0Bt/WKDpUKn7WTZB8S95kv9MnN3sEkfsX42s1lhAGlI+ZbC8J8d5xWaTKpkIItRm289PHZ9iiSqhz6q8fpwPBEAz3mrqJbrJsXP6Zub6iUZajGTNg9lc0urDbHJb3SvsOB3TsM4TMk83Kf1zTy9xcEL8ScQtWXMvdvi21lc1Mm3oAdFU+LXQ6zwekz4yzEMqaIfCqPTThehF/H0z9zlzz6CNCCJQTdDneTfiA==
X-Gorgon
8404203b0000114869cdb5ab8afdb91780878d0dc9ec86447c3f
X-Khronos
1707127563
X-Ladon
3iXZQdDtf+Q2E+rNj0dWBJ+O3XXJVszo5g4df4lQV1NNdQBz
如上,确定无误,四个签名字段和值是一块返回,以行分割后分别设置在请求头中。
3、直接调用
废话不说了,配置环境过程以及一些细节卡了很久,直接上代码:
package com.zhiliaoapp.musically;
import capstone.api.Instruction;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.arm.backend.Unicorn2Factory;
import com.github.unidbg.file.FileResult;
import com.github.unidbg.file.IOResolver;
import com.github.unidbg.file.linux.AndroidFileIO;
import com.github.unidbg.hook.HookListener;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.linux.android.dvm.jni.ProxyClassFactory;
import com.github.unidbg.linux.file.SimpleFileIO;
import com.github.unidbg.listener.TraceCodeListener;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.memory.MemoryBlock;
import com.github.unidbg.memory.SvcMemory;
import com.github.unidbg.pointer.UnidbgPointer;
import sun.rmi.runtime.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class MetaSec extends AbstractJni implements IOResolver<AndroidFileIO> {
private final AndroidEmulator emulator;
private final VM vm;
private final Module module;
private Symbol free;
public MetaSec() {
emulator = AndroidEmulatorBuilder.for64Bit()
.setProcessName("com.zhiliaoapp.musically")
.addBackendFactory(new Unicorn2Factory(true))
.build(); // 创建模拟器实例,要模拟32位或者64位,在这里区分
final Memory memory = emulator.getMemory(); // 模拟器的内存操作接口
//SvcMemory svcMemory = emulator.getSvcMemory();
memory.setLibraryResolver(new AndroidResolver(23)); // 设置系统类库解析
vm = emulator.createDalvikVM(); // 创建Android虚拟机
vm.setVerbose(false); // 设置是否打印Jni调用细节
vm.setJni(this);
//载入依赖so库
vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/libPitayaObject.so"), false);
vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/libAndroidPitayaProxy.so"), false);
vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/libc++_shared.so"), false);
//模块绑定的java层类
DvmClass k = vm.resolveClass("ms/bd/o/k");
DvmClass a0 = vm.resolveClass("ms/bd/o/a0",k);
vm.resolveClass("com/bytedance/mobsec/metasec/ov/MS", a0);
//加载目标模块
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/libmetasec_ov.so"), false);
module = dm.getModule();
//emulator.traceCode(module.base, module.base + module.size);
dm.callJNI_OnLoad(emulator); // 手动执行JNI_OnLoad函数
free = module.findSymbolByName("free", true);
//读取测试参数
String url = readFile("unidbg-android/src/test/resources/test_url.txt");
MemoryBlock block = memory.malloc(url.length(),true);
UnidbgPointer url_ptr = block.getPointer();
url_ptr.write(url.getBytes());
String header = readFile("unidbg-android/src/test/resources/test_header.txt");
System.out.println(header);
MemoryBlock block_header = memory.malloc(header.length(),true);
UnidbgPointer header_ptr = block_header.getPointer();
header_ptr.write(header.getBytes());
//emulator.traceCode(module.base, module.base + module.size);
//调用目标签名函数
Number number = module.callFunction(emulator,
0x88ee0,
url_ptr, header_ptr);
block.free();
block_header.free();
if(number.longValue() != 0) {
//输出返回值
UnidbgPointer result = memory.pointer(number.longValue());
System.out.println(result.getString(0));
//调用者释放内存
free.call(emulator, number.longValue);
}
}
public static void main(String[] args) throws Exception {
new MetaSec();
}
@Override
public FileResult<AndroidFileIO> resolve(Emulator<AndroidFileIO> emulator, String pathname, int oflags) {
System.out.println("PATHNAME:" + pathname);
// if (pathname.equals("/system/lib/libc.so")){
// System.out.println("LIBSO");
// File reg = new File("unidbg-android\\src\\main\\resources\\android\\sdk23\\lib\\libc.so");
// return FileResult.<AndroidFileIO>success(new SimpleFileIO(oflags,reg,pathname));
// }
// if (pathname.equals("/proc/self/exe")){
// System.out.println("EXE");
// return FileResult.<AndroidFileIO>success(new SimpleFileIO(oflags, new File("E:\\Douyin\\unidbg-0.9.7\\unidbg-android\\src\\test\\resources\\dylib\\base.apk"), pathname));
// }
// if (pathname.equals("/sys/devices/system/cpu/online")){
// System.out.println("ONLINE");
// return FileResult.<AndroidFileIO>success(new SimpleFileIO(oflags, new File("E:\\Douyin\\unidbg-0.9.7\\unidbg-android\\src\\test\\resources\\dylib\\online"), pathname));
// }
return null;
}
@Override
public int getStaticIntField(BaseVM vm, DvmClass dvmClass, String signature) {
System.out.println("getStaticIntField: " + signature);
if ("com/bytedance/mobsec/metasec/ov/MS->a()V".equals(signature)) {
return 0x40;
}
throw new UnsupportedOperationException(signature);
}
@Override
public void callVoidMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
System.out.println("callVoidMethod: " + signature);
switch (signature) {
case "com/bytedance/mobsec/metasec/ov/MS->a()V":
System.out.println("> Patched: com/bytedance/mobsec/metasec/ov/MS->a()V");
return;
}
super.callVoidMethod(vm, dvmObject, signature, varArg);
}
@Override
public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
System.out.println(signature);
switch (signature) {
case "com/bytedance/mobsec/metasec/ov/MS->b(IIJLjava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;":
return null;
}
throw new UnsupportedOperationException(signature);
}
private String readFile(String fileName) {
String res="";
try{
FileInputStream fin = new FileInputStream(new File(fileName));
int length = fin.available();
byte [] buffer = new byte[length];
fin.read(buffer);
res = new String(buffer);
fin.close();
}
catch(Exception e){
e.printStackTrace();
}
return res;
}
}
测试通过
未完待续
1、libsscronet.so中怎么拿到 libmetasec_ov.so中参数签名函数地址的(libmetasec_ov.so初始化时传入了libsscronet.so中的回调传递)。
2、X-Argus是什么串(加密后的 protobuf数据,包含运行时信息、设备、渠道等)