
样本地址: aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9hcHBzLzc0NjE5NDg=
ssl pinning 绕过
首先抓包直接打开是没有网络的,我用算法助手的升级版 trustMe 也不行,说明普通的 ssl pinning 是没用的,说明可能是在 so 层做的防护,hook 一下 dlopen,看一下哪些 so 在最前面进行加载的,也不说最前面吧,相对靠前

大名鼎鼎的六神,网上一搜就知道是 libsscronet.so 中对 so 进行的 ssl pinning 校验的,拖到 ida 中分析一下
问一下 ai,对于这种 so,我应该关注哪些函数

进去之后在导入函数中搜一下
SSL_CTX_set_custom_verify 这个函数就很像啊,跟刚才 gpt 跟我说的不能说有点类似,只能说一模一样了,进去看一下
// attributes: thunk__int64 SSL_CTX_set_custom_verify(){ return __imp_SSL_CTX_set_custom_verify();}发现就是个跳板函数,会跳转到 __imp_SSL_CTX_set_custom_verify 这个函数,这个函数继续往下跟发现跟不到个啥了,导入函数,C 语言中应该有相应的代码实现,直接问下 gpt 有没有相关的原型函数
void SSL_CTX_set_custom_verify( SSL_CTX *ctx, int mode, enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert));其中的这个 mode 一般有以下取值
SSL_VERIFY_NONE // 0x00SSL_VERIFY_PEER // 0x01SSL_VERIFY_FAIL_IF_NO_PEER_CERT // 0x02SSL_VERIFY_PEER_IF_NO_OBC // 0x04SSL_VERIFY_CLIENT_ONCE // 0x08其他的都不重要,知道 mode 为 0 是不进行强校验就够了,也就是说我可以直接 hook 这个函数,返回 0 就可以了,可以使用 frida 脚本,进行 hook 就能够抓包了
function hook_dlopen(module_name, fun) { var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext"); if (android_dlopen_ext) { Interceptor.attach(android_dlopen_ext, { onEnter: function (args) { var pathptr = args[0]; if (pathptr) { this.path = (pathptr).readCString(); if (this.path.indexOf(module_name) >= 0) { this.canhook = true; } } }, onLeave: function (retval) { if (this.canhook) { let verifyadd = Module.getExportByName("libsscronet.so","SSL_CTX_set_custom_verify"); Interceptor.attach(verifyadd,{ onEnter(args){ Interceptor.attach(args[2],{ onLeave(retval){ console.log("Hook成功!强制verify返回 0x0"); retval.replace(0x0); } }) } }) } } }); }}
hook_dlopen("libsscronet.so");接着,我是直接抓的登录包,毕竟抓这个包最明显

参数也确实挺多的,这就是大名鼎鼎的六神吗
这种大型的 app,这种关键参数涉及到的算法不太可能是在 Java 层生成的(因为我刚才搜索字段,直接给 jadx 卡死了,占22G 内存,总共才 32G 啊),那就只能是在 native 层生成的,像请求头这种东西,一般是在发包请求之前进行构造的吧,还是继续分析 libsscronet.so 这个库,那它是在哪儿添加的请求头呢?
参考了一下大佬的文章,发现是在 http_request_headers.cc 这个文件中进行添加的

跳转过去,对这个函数进行 hook,应该就是在这儿添加的请求头
const soName = "libsscronet.so";const base = Module.findBaseAddress(soName);
if (base === null) { console.log("[-] module not found");} else { const idaBase = 0x0; const funcOffset = 0x37ED64; const target = base.add(funcOffset - idaBase); Interceptor.attach(target, { onEnter(args) { var key = args[1].readPointer().readCString(); var value = args[2].readPointer().readCString();
// console.log("\n==== sub_37ED64 called ===="); // console.log("key = " + key); // console.log("value = " + value); if(key == "X-Gorgon"){ console.log("X-Gorgon堆栈信息如下") console.log(key,'==>',value); console.log('SetHeaders called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n'); }
},
onLeave(retval) { // console.log("ret = " + retval); } });}得到的信息如下:

跳转到偏移 0x47abc8 处,看一下

这里的 v153 代表 key,v157 代表 value,从这里看不太可能是在这个网络库中进行生成的,继续往上进行溯源

而当我看到 v73 的时候,直接给我引向了 X23 寄存器

在之前的 frida 代码中继续看一下这个寄存器指向的值是在哪儿,找 gpt 给我写了一份 frida hook 的代码,hook 结果如下(不得不多,ai 真是太好用了):
[Pixel 2::抖音 ]->========== BLR X23 ==========[target ] 0x79a67f3e38[module ] `libmetasec_ml`.so[offset ] 0x2a6e38[symbol ] 0x79a67f3e38 libmetasec_ml.so!0x2a6e38[x0/v74] 0x7a7a468e40 -> https://log0-misc-lf.amemv.com/service/2/app_log/?version_code=380000&device_platform=android&device_id=4285258443570425&aid=1128&iid=4285258442771721&tt_data=a[x1/v75] 0x787c223d00 -> cookiepassport_csrf_token=43311270ac30c95568130c5db23a83e8; passport_csrf_token_default=43311270ac30c95568130c5db23a83e8; store-region=cn-yn; store-region-src=did; install_id=4285258442771721; ttreq=1$3b3ffd2e9bc05d9f58d58ec2561b0f25fdd413ad; odin_tt=87d6142c75744770c2aaf6011f3cf458125cc74125923869cf45448563276f68a5a773584bb305de007f5969b3438c1990a2abf706b965e1cbb08f7c8d61ac37c433ecd67ea7464b5c0d52815eade962log-encode-typezstdlog-encode-token0x-tt-dtAAATEBUCNJWPC5KV7FWGOTXDPYJ2DVUKD6KCB5EDEEPLX3HZ4C76BU46M2VJYG2YUF2T45VSXEBAN37FBI2UI54KJBCLRTPUHJF3AT63PL4ITCVG555LCHHJVVTU7FGX3G7E277OXE364WWTTKSMN3Yactivity_now_client1773932331119x-ss-req-ticket1773932379205x-vc-bdturing-sdk-version4.1.1.cnsdk-version2passport-sdk-settingsdevice_transfer_s_0,device_transfer_ab_0passport-sdk-version601581content-typeapplication/octet-stream;tt-data=ax-ss-stub86245E39DA5BFEC362A9DD92634D85C1content-length7942x-tt-store-regioncn-ynx-tt-store-region-srcdidx-tt-request-tags=-1;p=0x-ss-dp1128x-tt-trace-id01-069bfdeb0df396b7b4cbcf95f2e10468-069bfdeb0df396b7-00user-agentcom.ss.android.ugc.aweme/380001 (Linux; U; Android 10; zh_CN_#Hans; Pixel 2; Build/QQ3A.200805.001; Cronet/TTNetVersion:6f1e308d 2025-12-08 QuicVersion:21ac1950 2025-11-18)accept-encodinggzip, deflate, br
---- target enter ----[arg0] 0x7a7a468e40 -> https://log0-misc-lf.amemv.com/service/2/app_log/?version_code=380000&device_platform=android&device_id=4285258443570425&aid=1128&iid=4285258442771721&tt_data=a[arg1] 0x787c223d00 -> cookiepassport_csrf_token=43311270ac30c95568130c5db23a83e8; passport_csrf_token_default=43311270ac30c95568130c5db23a83e8; store-region=cn-yn; store-region-src=did; install_id=4285258442771721; ttreq=1$3b3ffd2e9bc05d9f58d58ec2561b0f25fdd413ad; odin_tt=87d6142c75744770c2aaf6011f3cf458125cc74125923869cf45448563276f68a5a773584bb305de007f5969b3438c1990a2abf706b965e1cbb08f7c8d61ac37c433ecd67ea7464b5c0d52815eade962log-encode-typezstdlog-encode-token0x-tt-dtAAATEBUCNJWPC5KV7FWGOTXDPYJ2DVUKD6KCB5EDEEPLX3HZ4C76BU46M2VJYG2YUF2T45VSXEBAN37FBI2UI54KJBCLRTPUHJF3AT63PL4ITCVG555LCHHJVVTU7FGX3G7E277OXE364WWTTKSMN3Yactivity_now_client1773932331119x-ss-req-ticket1773932379205x-vc-bdturing-sdk-version4.1.1.cnsdk-version2passport-sdk-settingsdevice_transfer_s_0,device_transfer_ab_0passport-sdk-version601581content-typeapplication/octet-stream;tt-data=ax-ss-stub86245E39DA5BFEC362A9DD92634D85C1content-length7942x-tt-store-regioncn-ynx-tt-store-region-srcdidx-tt-request-tags=-1;p=0x-ss-dp1128x-tt-trace-id01-069bfdeb0df396b7b4cbcf95f2e10468-069bfdeb0df396b7-00user-agentcom.ss.android.ugc.aweme/380001 (Linux; U; Android 10; zh_CN_#Hans; Pixel 2; Build/QQ3A.200805.001; Cronet/TTNetVersion:6f1e308d 2025-12-08 QuicVersion:21ac1950 2025-11-18)accept-encodinggzip, deflate, br[ret ] 0x7962937600 -> X-Perseus # 1eaeee5ynOZskw1llR2hm8+lJKhgcJPtKXM6OkB1vcOil+HVeDQiP+Ut/EXHY4DxpD9rXqytpWqczMCvDv2roCE/eRlLg1x6GgYLRp2JjHNQv4jOyzqnsRn1XRkvrtg9OTpjtCU0TGZtC52v3EPZLc4k4FQH7qvWdvuf62n8T3bgbSPEHLFeOqzdXvB56iNpYrAzV8u5tHbWvq4q/+0BFFrQSZ0iW8HXX3SeSQL0nvv9/pji4hRtoWZwg8prIAakJykHIPDggP+d+z7uw9cWQ4Nyy+ZhK1EShp9D3oBpZBpcPK4N+ywV2ddocGXewx2gpNz5DLOymxyd6Jg1xhn6/ePdmp0UHLlPWslMJ2+D5QS51M6MsWgNs0TEzlPUzmeYR6vt1bnGVix6tYxSSziobNrThnSLpeiy1EFruU9dGEScCMkZu72ihet8y5WctEXcbylIwjBhWLD6bEKV4fpIDF3hYDfGSDqvEQTroPWhNudoVaajZlw0nEz/TLmj7hLcW89l2lfZWynQgxTnBvdBOzqGCgN9vyEopBG8RInm4+I28sxATas9B5sojhectRbSCzSLWCIYOHboPxPLSjdeMOoVoVWoXbRc8WP4UKuUg+YVrBW31X4R1v9tvyGjzsWxWTK5iQdCVyOWmXrBtPKUDHI9mTZnHfXeTsRtsZKjwySV0B40BMN9GOaoA2l4ltGXO1eNB9nOobbBrP73sFCZzFXLrgnAo/KDxCRcUGE+/dhwlAoGs0FgtvORo5mHDY8v7x1Dv5vXax8uqW+bYFuFh3vu6OSp/rIJYa+KzYnRSRXbe+Zu9MzMxSi9NIFuQB1cCPAdBTjlaJhlQAZHB+HCGh7f8fG6bcpock9/wXeQFDoibFWR1lNiGIDnNMYtHBdTM6CnRHYtlKpW+0C+BhA/u+Q==X-Medusa # 2jA+8aeCVl0PJlBP4CsW+A0k5GJdG4AAN7JZxNnkc3L4Auhy097W94A0oAJIHmIQSzh4JlOFbEmCqNTjyPiNUlDX+Go/Aev2LLy3Wbb4LuRMXtUiaZ5riW7/gE4JPovQqf71xz8hEVCHavVVSZBCzb+ModMO6eToxM3wTPQA6+D8fS4KZQphjENUVIVb4nHDq+MLLUtAJ+t5nCyZqQX54bJd57z9mOF07JJbd0x+Hx9JBlSYNHl2tGtVDixKKOtS5zgnYQvwcRmmLkTu+IbhUANZk2mH+uljhw3l7Wri8HZ8+VOHBdcnK6oSSK093U9JEppDDdMrdcSesnhOhMaUSjXcsM3aYY8L9p6z//aep+0saX-Argus # 3iw+8aQ==X-Helios # 4mzldD91aKzfTcF8SCMCCGn4tdFZJxImB4NNpRlikIYB7KvtbX-Ladon # 5r3kMdQ==X-Khronos # 61773932427X-Gorgon # 78404a00c0405a19810f52af5ffa35cc68fa1f92bebe2762947e0对上了,这里请求参数中也正好是 \r\n 作为分割的,最后的返回值就是七神
跳转到 libmetasec_ml.so 中的偏移地址0x2a6e38

发现处在 sub_2A6E38,这个应该就是外部加密参数生成的 so 中的加密函数了,接着就可以 hook 一下这个函数,看一下参数是什么,接着好去到 unidbg 中进行模拟加密参数的生成,写一下 frida 代码
const base = Module.findBaseAddress("libmetasec_ml.so");var func_addr = base.add(0x2A6E38);console.log("baseAddr from hook", base);Interceptor.attach(func_addr, { onEnter: function (args) { console.log("=============入参开始==================") var arg0 = args[0].readUtf8String(); var arg1 = args[1].readUtf8String(); console.log("参数1" + arg0); console.log("参数2" + arg1); }, onLeave: function (retval) { console.log("返回值地址:: " + retval); console.log("返回值:: " + retval.readUtf8String()); console.log("=============返回值结束==================") }});hook 结果如下:
参数 1 就是请求的 url+一堆参数拼接起来的结果,这一点跟 web 有点像,参数 2 就是一堆的请求参数,用 \r\n 进行分割
unidbg 模拟执行
先弄个架子在这儿,这个用 ai 改造了一下
package com.douyin;
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.linux.android.AndroidEmulatorBuilder;import com.github.unidbg.linux.android.AndroidResolver;import com.github.unidbg.linux.android.dvm.AbstractJni;import com.github.unidbg.linux.android.dvm.BaseVM;import com.github.unidbg.linux.android.dvm.DalvikModule;import com.github.unidbg.linux.android.dvm.DvmClass;import com.github.unidbg.linux.android.dvm.VaList;import com.github.unidbg.linux.android.dvm.VM;import com.github.unidbg.memory.Memory;import com.github.unidbg.hook.hookzz.HookZz;import com.github.unidbg.hook.hookzz.IHookZz;import com.github.unidbg.hook.hookzz.HookEntryInfo;import com.github.unidbg.arm.context.RegisterContext;import com.github.unidbg.virtualmodule.android.AndroidModule;
import java.io.File;
public class DouYin extends AbstractJni implements IOResolver {
// ========== 每次新项目只改这里 ==========
// 模拟器位数:so在armeabi-v7a目录下填false,arm64-v8a目录下填true private static final boolean IS_64BIT = true;
// app包名(随意,一般填真实包名) private static final String PROCESS_NAME = "com.ss.android.ugc.aweme";
// apk路径,不需要apk时填null(填null时LOAD_BY_NAME必须为false) private static final String APK_PATH = "apks/douyin/douyin.apk";
// so加载方式: // false = 传文件路径(用SO_PATH),不依赖apk,最常用 // true = 传库名(用SO_NAME),unidbg自动去apk内查找,必须提供APK_PATH private static final boolean LOAD_BY_NAME = true; private static final String SO_PATH = ""; // LOAD_BY_NAME=false时生效 private static final String SO_NAME = "metasec_ml"; // LOAD_BY_NAME=true时生效,不带lib前缀和.so后缀
// 是否打印JNI调用细节,调试时改true private static final boolean VERBOSE = true;
// ========================================
public static AndroidEmulator emulator; public static Memory memory; public static VM vm; public static Module module;
// 1. 构造方法 —— 初始化模拟器 public DouYin() {
// 1. 创建模拟器(32/64位由IS_64BIT控制) emulator = IS_64BIT ? AndroidEmulatorBuilder.for64Bit().setProcessName(PROCESS_NAME).addBackendFactory(new Unicorn2Factory(true)).build() : AndroidEmulatorBuilder.for32Bit().setProcessName(PROCESS_NAME).addBackendFactory(new Unicorn2Factory(true)).build();
// 2. 获取内存对象 memory = emulator.getMemory();
// 3. 设置安卓SDK版本(只支持19、23) memory.setLibraryResolver(new AndroidResolver(23));
// 4. 创建虚拟机 vm = APK_PATH != null ? emulator.createDalvikVM(new File(APK_PATH)) : emulator.createDalvikVM(); vm.setJni(this); vm.setVerbose(VERBOSE);
// 5. 加载so文件(两种方式由LOAD_BY_NAME控制) DalvikModule dm = LOAD_BY_NAME ? vm.loadLibrary(SO_NAME, false) : vm.loadLibrary(new File(SO_PATH), false);
// 6. 动态注册才需要执行JNI_OnLoad dm.callJNI_OnLoad(emulator);
// 7. 获取module对象(后续拿基址、偏移等) module = dm.getModule();
}
// 5. main方法 —— 右键直接运行 public static void main(String[] args) { DouYin douYin = new DouYin(); }
@Override public FileResult resolve(Emulator emulator, String pathname, int oflags) { System.out.println("pathname:" + pathname); return null; }}运行,发现报错

这个一般就是当前的这个 so 文件依赖于 android.so 文件,这个 unidbg 为我们实现了相关的虚拟模块
new AndroidModule(emulator,vm).register(memory);接着又发现 Jni 层在寻找 MS 这个类,但是我在 unidbg 中并没有引用这个类啊,你肯定是找不到的啊

去 jadx 看了一下这个类,发现继承 i2 这个类,i2 又继承 y2 这个类

在 JNI_Onload 调用之前声明这个类就可以了
MS = vm.resolveClass("com.bytedance.mobsec.metasec.ml.MS",vm.resolveClass("ms.bd.c.i2",vm.resolveClass("ms.bd.c.y2")));继续,发生报错
java.lang.UnsupportedOperationException: com/bytedance/mobsec/metasec/ml/MS->b(IIJLjava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; at com.github.unidbg.linux.android.dvm.AbstractJni.callStaticObjectMethodV(AbstractJni.java:504) at com.github.unidbg.linux.android.dvm.AbstractJni.callStaticObjectMethodV(AbstractJni.java:438) at com.github.unidbg.linux.android.dvm.DvmMethod.callStaticObjectMethodV(DvmMethod.java:59) at com.github.unidbg.linux.android.dvm.DalvikVM64$112.handle(DalvikVM64.java:1836)往上找,就找到了下面的这个地方

先看一下参数是什么
@Overridepublic DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) { switch(signature){ case "com/bytedance/mobsec/metasec/ml/MS->b(IIJLjava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;":{ int arg = vaList.getIntArg(0); System.out.println("参数==>"+arg); } } return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);}得到的结果是:

然后就可以直接补了,去 jadx 中看一下这个分支,可以发现返回值就是 2,补上

ok,继续,然后又报错了
java.lang.UnsupportedOperationException: java/lang/Long->longValue()J at com.github.unidbg.linux.android.dvm.AbstractJni.callLongMethodV(AbstractJni.java:236) at com.github.unidbg.linux.android.dvm.AbstractJni.callLongMethodV(AbstractJni.java:231) at com.github.unidbg.linux.android.dvm.DvmMethod.callLongMethodV(DvmMethod.java:84)补上
@Overridepublic long callLongMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) { switch (signature){ case "java/lang/Long->longValue()J":{ return (Long)dvmObject.getValue(); } } return super.callLongMethodV(vm, dvmObject, signature, vaList);}然后,然后这儿就结束了,接着就需要进行主动调用了

它的这个参数太多了,干脆就直接写成一个文件的形式然后读取吧
public void metaSec() throws IOException { byte[] urlBytes = Files.readAllBytes(Paths.get("apks/douyin/url.txt")); byte[] headerBytes = Files.readAllBytes(Paths.get("apks/douyin/headers.txt"));
MemoryBlock urlBlock = memory.malloc(urlBytes.length + 1, true); UnidbgPointer urlPtr = urlBlock.getPointer(); urlPtr.write(0, urlBytes, 0, urlBytes.length);
MemoryBlock headerBlock = memory.malloc(headerBytes.length + 1, true); UnidbgPointer headerPtr = headerBlock.getPointer(); headerPtr.write(0, headerBytes, 0, headerBytes.length);
Number result = module.callFunction(emulator, 0x2A6E38, urlPtr, headerPtr);
UnidbgPointer resultPtr = memory.pointer(result.longValue()); System.out.println(resultPtr.getString(0));
}接着又报错

这个还是跟上面一样,去 jadx 中进行查看
然后报错
java.lang.UnsupportedOperationException: java/lang/Integer->getBytes(Ljava/lang/String;)[B at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:417) at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:262)直接补就行
@Overridepublic DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) { switch (signature) { case "java/lang/Integer->getBytes(Ljava/lang/String;)[B": { String str = dvmObject.getValue().toString(); String charset = vaList.getObjectArg(0).getValue().toString(); System.out.println("getBytes str=" + str + " charset=" + charset); try { return new ByteArray(vm, str.getBytes(charset)); } catch (Exception e) { return new ByteArray(vm, str.getBytes()); } } } return super.callObjectMethodV(vm, dvmObject, signature, vaList);}接着又出现了
参数==>33554433参数==>33554434去 jadx 找就行
接着,又报错
java.lang.UnsupportedOperationException: java/lang/Thread->getStackTrace()[Ljava/lang/StackTraceElement; at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:417) at com.douyin.DouYin.callObjectMethodV(DouYin.java:161) at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:262) at com.github.unidbg.linux.android.dvm.DvmMethod.callObjectMethodV(DvmMethod.java:89) at com.github.unidbg.linux.android.dvm.DalvikVM64$32.handle(DalvikVM64.java:559)直接补
case "java/lang/Thread->getStackTrace()[Ljava/lang/StackTraceElement;":{ StackTraceElement[] elements = Thread.currentThread().getStackTrace(); DvmObject[] objs = new DvmObject[elements.length]; for (int i = 0; i < elements.length; i++) { objs[i] = vm.resolveClass("java/lang/StackTraceElement").newObject(elements[i]); } return new ArrayObject(objs);}继续报错
java.lang.UnsupportedOperationException: java/lang/StackTraceElement->getClassName()Ljava/lang/String; at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:417) at com.douyin.DouYin.callObjectMethodV(DouYin.java:170) at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:262) at com.github.unidbg.linux.android.dvm.DvmMethod.callObjectMethodV(DvmMethod.java:89)直接补
case "java/lang/StackTraceElement->getClassName()Ljava/lang/String;":{ StackTraceElement stackTraceElement = (StackTraceElement)dvmObject.getValue(); return new StringObject(vm,stackTraceElement.getClassName());}继续报错
java.lang.UnsupportedOperationException: java/lang/StackTraceElement->getMethodName()Ljava/lang/String; at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:417) at com.douyin.DouYin.callObjectMethodV(DouYin.java:167) at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:262) at com.github.unidbg.linux.android.dvm.DvmMethod.callObjectMethodV(DvmMethod.java:89)直接补
case "java/lang/StackTraceElement->getMethodName()Ljava/lang/String;":{ StackTraceElement stackTraceElement = (StackTraceElement)dvmObject.getValue(); return new StringObject(vm,stackTraceElement.getMethodName());}仍在报错
java.lang.UnsupportedOperationException: java/lang/Thread->getBytes(Ljava/lang/String;)[B at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:417) at com.douyin.DouYin.callObjectMethodV(DouYin.java:171) at com.github.unidbg.linux.android.dvm.AbstractJni.callObjectMethodV(AbstractJni.java:262) at com.github.unidbg.linux.android.dvm.DvmMethod.callObjectMethodV(DvmMethod.java:89)在补之前还需要补一下这个分支的数据
参数==>16777233返回个版本号 继续补
case "java/lang/Thread->getBytes(Ljava/lang/String;)[B":{ String arg = vaList.getObjectArg(0).getValue().toString(); return new ByteArray(vm,arg.getBytes(StandardCharsets.UTF_8));}接着,就能够出值了

能不能用,不知道,算法分析后面再写吧,参数太多了,一篇文章不一定能写完
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 167 天
部分内容可能已过时
评论
还没有评论,来写第一条吧。