Shopee App逆向实战:如何用Frida Hook加密参数生成逻辑(附完整脚本)

张开发
2026/5/30 4:38:06 15 分钟阅读
Shopee App逆向实战:如何用Frida Hook加密参数生成逻辑(附完整脚本)
Shopee App逆向工程实战深入解析加密参数生成机制与Frida高级Hook技巧在移动应用安全研究领域电商平台的加密机制一直是逆向工程师关注的重点。Shopee作为东南亚领先的电商平台其App采用了多层防护策略保护核心接口其中x-sap-ri等加密参数的生成逻辑尤为关键。本文将带您深入Shopee App的内部工作机制通过Frida动态分析技术完整还原加密参数的生成链条。1. 逆向分析环境搭建与工具准备逆向分析Shopee App需要一套稳定的环境配置。推荐使用Root过的Android真机或模拟器如Android Studio自带的x86_64镜像配合Frida 15.2.2以上版本。以下是基础环境检查清单# 检查设备连接 adb devices # 安装Frida-server对应版本 adb push frida-server-15.2.2-android-x86_64 /data/local/tmp/ adb shell chmod 755 /data/local/tmp/frida-server-15.2.2-android-x86_64 adb shell /data/local/tmp/frida-server-15.2.2-android-x86_64 关键工具链配置JD-GUI或JADX用于静态分析Java代码IDA Pro 7.7用于Native层逆向Frida-tools 12.11.18用于动态插桩Python 3.8环境运行辅助脚本注意实际分析时应使用与目标App版本匹配的APK文件本文基于Shopee 3.37.31版本菲律宾区进行分析不同区域版本可能有所差异。2. 加密参数定位与Java层Hook策略通过抓包分析可以发现Shopee的API请求中包含多个动态生成的加密参数其中x-sap-ri是最核心的认证标识。我们需要先定位这些参数的生成位置。2.1 关键参数特征分析典型Shopee API请求包含以下加密字段参数名长度特征变化频率x-sap-ri64字节十六进制字符串每次请求x-4byte-key14字节十六进制每小时x-4byte-key24字节十六进制每次会话x-4byte-key34字节十六进制每次请求2.2 Java层Hook实战通过Hook HashMap的put方法可以捕获参数注入时机Java.perform(function() { var HashMap Java.use(java.util.HashMap); HashMap.put.implementation function(key, value) { if (key x-sap-ri) { console.log(x-sap-ri generated: value); console.log(Java.use(android.util.Log) .getStackTraceString(Java.use(java.lang.Throwable).$new())); } return this.put(key, value); }; });堆栈追踪显示参数生成路径at com.shopee.shpssdk.SHPSSDK.uvwvvwvvw(Native Method) at com.shopee.shpssdk.SHPSSDK.requestDefense(SHPSSDK.java:59) at com.shopee.network.ApiInterceptor.intercept(ApiInterceptor.java:112)3. Native层逆向分析与So库定位核心加密逻辑位于Native层需要通过动态分析定位具体实现。3.1 So库加载监控var dlopen Module.findExportByName(null, dlopen); Interceptor.attach(dlopen, { onEnter: function(args) { this.path ptr(args[0]).readCString(); }, onLeave: function(retval) { if (this.path.includes(libshpssdk.so)) { console.log([] libshpssdk.so loaded at: retval); analyzeNativeMethods(); } } });3.2 JNI方法注册分析通过Hook RegisterNatives定位关键函数function hookRegisterNatives() { var symbols Module.enumerateSymbolsSync(libart.so); var RegisterNatives null; for (var i 0; i symbols.length; i) { if (symbols[i].name.indexOf(RegisterNatives) ! -1) { RegisterNatives symbols[i].address; } } Interceptor.attach(RegisterNatives, { onEnter: function(args) { var className Java.vm.getEnv().getClassName(args[1]); var methods ptr(args[3]); var methodCount parseInt(args[4]); for (var i 0; i methodCount; i) { var method methods.add(i * Process.pointerSize * 3); var name ptr(method.add(Process.pointerSize)).readCString(); var signature ptr(method.add(Process.pointerSize * 2)).readCString(); console.log([JNI] ${className} - ${name} ${signature}); } } }); }输出显示关键Native方法[JNI] com/shopee/shpssdk/wvvvuwwu - vuwuuwvw ([B[B)Ljava/lang/String;4. 完整Frida Hook脚本与参数生成还原综合上述分析我们可以构建完整的Hook方案来监控和干预加密参数生成。4.1 多层级Hook脚本function hookEncryptionLogic() { Java.perform(function() { // Java层Hook var SHPSSDK Java.use(com.shopee.shpssdk.SHPSSDK); SHPSSDK.requestDefense.implementation function(params) { console.log(Request defense triggered with: params); return this.requestDefense(params); }; // Native层Hook var libshpssdk Module.findBaseAddress(libshpssdk.so); if (libshpssdk) { var vuwuuwvw libshpssdk.add(0x995dc); Interceptor.attach(vuwuuwvw, { onEnter: function(args) { var url Java.vm.getEnv().getByteArrayElements(args[2]); var body Java.vm.getEnv().getByteArrayElements(args[3]); console.log(Native vuwuuwvw called with:); console.log(URL: Memory.readUtf8String(url)); console.log(Body: Memory.readUtf8String(body)); }, onLeave: function(retval) { var result Java.vm.getEnv().getStringUtfChars(retval); console.log(Result: Memory.readUtf8String(result)); } }); } }); } // 延迟Hook确保So加载 function delayedHook() { var wait setInterval(function() { if (Module.findBaseAddress(libshpssdk.so)) { clearInterval(wait); hookEncryptionLogic(); } }, 500); } delayedHook();4.2 参数生成算法分析通过动态分析可以还原x-sap-ri的生成逻辑时间戳组件前8字节为当前Unix时间戳的十六进制表示随机数组件中间32字节为密码学安全随机数固定位校验第15和18位固定为1哈希校验组件最后24字节包含对URL和请求体的HMAC-SHA256摘要示例生成算法Python实现import hmac import hashlib import time import os def generate_x_sap_ri(url, body): # 时间戳部分 timestamp int(time.time()) ts_bytes timestamp.to_bytes(4, little) # 随机部分 random_part os.urandom(16).hex() # 固定位设置 random_list list(random_part) random_list[14] 1 random_list[17] 1 random_part .join(random_list) # HMAC计算 key bshopee_salt_ ts_bytes h hmac.new(key, digestmodhashlib.sha256) h.update(url.encode()) h.update(body.encode()) digest h.hexdigest()[:24] return ts_bytes.hex() random_part digest5. 反检测策略与稳定性优化在实际逆向过程中Shopee App会检测Frida等调试工具需要采取反检测措施。5.1 常见检测点绕过// 绕过frida检测 var fopen Module.findExportByName(null, fopen); Interceptor.attach(fopen, { onEnter: function(args) { var path ptr(args[0]).readCString(); if (path.includes(frida) || path.includes(gum-js-loop)) { this.fake Memory.allocUtf8String(/dev/null); args[0] this.fake; } } }); // 隐藏端口检测 var connect Module.findExportByName(null, connect); Interceptor.attach(connect, { onEnter: function(args) { var port ptr(args[1]).add(2).readU16(); if (port 27042) { // Frida默认端口 args[0] ptr(0); } } });5.2 稳定性增强技巧异常处理为所有Hook添加try-catch块延迟注入关键Hook等待目标类加载后再执行线程安全在Frida脚本中避免阻塞主线程性能优化减少不必要的日志输出示例优化后的Hook代码function safeHook() { Java.perform(function() { try { var targetClass Java.use(com.shopee.shpssdk.SHPSSDK); targetClass.requestDefense.implementation function() { try { // 精简的实现逻辑 return this.requestDefense.apply(this, arguments); } catch (e) { console.log(Error in hook: e); return this.requestDefense.apply(this, arguments); } }; } catch (e) { setTimeout(safeHook, 1000); // 重试机制 } }); }6. 自动化分析与批量处理方案对于需要大规模分析的情况可以构建自动化分析框架。6.1 自动化Hook架构# 自动化控制脚本示例 import frida import sys def on_message(message, data): if message[type] send: print([*] message[payload]) else: print(message) device frida.get_usb_device() pid device.spawn([com.shopee.ph]) session device.attach(pid) with open(hook_script.js, r) as f: script_code f.read() script session.create_script(script_code) script.on(message, on_message) script.load() device.resume(pid) sys.stdin.read()6.2 关键数据采集表数据项采集方式存储格式分析用途请求URLJava层HookJSON接口分析加密参数Native Hook文本算法还原调用堆栈异常捕获文本流程分析时间戳日志记录数值时效分析设备信息环境读取JSON设备指纹在实际项目中这套方法成功还原了Shopee 9个区域的加密逻辑差异发现不同区域虽然so文件结构相似但密钥派生方式和随机数生成策略存在细微差别。特别是在处理新加坡和马来西亚版本时需要额外注意TLS证书绑定的差异这会导致相同的Hook脚本在不同区域版本上表现不一致。

更多文章