APP逆向 day14 某货逆向

2025-10-01 22:45:54

一.前言

今天和大家来讲一下识货app的搜索接口,今天这个没有逆向,但是和大家说一下绕过app的强制更新和绕过frida的反调试等

二.app版本选择

我们会讲讲老版本和新版本

识货-7.0.0-->老版本 识货-7.73.0-->新版本 我们选择这两个版本,老版本点开会强制更新

为什么我们要选择老版本呢?

因为在有的app中,老版本还能用,而且逆向难度低,所以我们今天就要和大家说一下老版本的绕过了。

我们下载好老版本之后,进去可以看到这个页面,提示我们要更新了,我们现在就是要绕过强制更新。

三.绕过强制更新

1 以后使用老版本app,会遇到两种更新情况 - 1 选择更新,取消按钮,取消掉继续使用,直接取消,继续抓包操作即可,此时app的接口,肯定都是能用的 - 2 强制更新,弹出更新框,直接覆盖app,必须更新,否则用不了app了,有可能它的某些接口用不了了,绕过更新后,看看接口还能不能用,如果不能用了,需要重新选择版本 2 强制更新 -1 车智赢:强制更新,断网,进入app,再联网即可绕过 -app一启动,向后端发送请求,获取最新版本号,跟本地版本比较,如果版本相差比较大,就会强制更新,一般情况下,代码会在首页上,这种情况,我们只需要切换到别的页面(断网),这个代码不执行,就绕过了 -2 识货:断网,绕过不了,只要连上网,又需要更新,通过hook,hook到弹窗,让窗不弹 -反编译,找到弹窗位置,通过hook,让代码不执行

3.1 反编译找到窗口位置

我们反编译之后,看到提示框,我们直接搜索最新版本

点进去

可以发现,是执行了 UpdateDialog进行提示更新,show方法弹出更新框,那我们就点进去,把这个方法给hook掉,记住hook得使用spawn(不记得了去我前面看)

3.2 hook绕过强制更新

然后我们就手机执行frida,进行端口转发,获取前台运行包名(因为spawn需要包名),再来执行hook,这里因为hook代码比较特殊,所以我就给出给大家hook代码

import frida

import sys

#spwan 自动运行

rdev = frida.get_remote_device()

pid = rdev.spawn(["com.hupu.shihuo"]) #这里添加的是包名

session = rdev.attach(pid)

scr = """

Java.perform(function () {

var UpdateDialog = Java.use("com.azhon.appupdate.dialog.UpdateDialog"); // Java.use("需要hook的地方的包名和大类名")=

UpdateDialog.show.implementation = function(str){

//构造方法的重载 比如new aaa这种

console.log("明文:",str);

console.log("不再弹出更新框了")

return res;

}

});

"""

script = session.create_script(scr)

def on_message(message, data):

print(message, data)

script.on("message", on_message)

script.load()

rdev.resume(pid)

sys.stdin.read()

这个hook上后,发现每次启动app都会闪退,那我们可以知道,这个是因为这款app精心了frida检测,那我们现在就来绕过frida检测

四.绕过frida反调试

写好了hook,运行时,发现,app一执行,里面就崩了,但是不执行hook,app顺利运行 识货这款app,做了frida的反调试,检测到只要frida脚本在运行,app就自动结束 -1 删某些so文件(今天学这种) -2 ptrace占坑 -3 frida加强版 识货这款app--》使用第一种可以绕过 识货这种公司,一般情况下,公司的安全人员写了一个so文件,检测是否在运行frida的hook,如果检测到,就把app强制终止 安全人员写的so,一般情况下跟app业务无关,只用来做hook的检测,这种情况下,我们可以尝试删除这个so文件尝试一下,如果删除了,app还能顺利运行,说明这个so跟业务是无关的,就可以删除 像识货,得物这种app就是这样的 于是,我们要找到 是那个so文件,做了检测,把so文件删除即可 如何定位是哪个so文件? 使用一个通用脚本---》所有app都可以用 原理是:通过hook安卓底层--》实现依次打印这款app运行时,加载了那些so文件---》通用 当加载到某个so,app闪退了,说明就是这个so文件做了frida检测--》删除这个so文件尝试 这种方式,并不适用于所有app--》以后只能尝试

这里给出hook所有so文件的代码

4.1 找到哪一个so文件检测

import frida

import sys

rdev = frida.get_remote_device()

pid = rdev.spawn(["com.hupu.shihuo"]) #放入包名

session = rdev.attach(pid)

scr = """

Java.perform(function () {

var dlopen = Module.findExportByName(null, "dlopen");

var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");

Interceptor.attach(dlopen, {

onEnter: function (args) {

var path_ptr = args[0];

var path = ptr(path_ptr).readCString();

console.log("[dlopen:]", path);

},

onLeave: function (retval) {

}

});

Interceptor.attach(android_dlopen_ext, {

onEnter: function (args) {

var path_ptr = args[0];

var path = ptr(path_ptr).readCString();

console.log("[dlopen_ext:]", path);

},

onLeave: function (retval) {

}

});

});

"""

script = session.create_script(scr)

def on_message(message, data):

print(message, data)

script.on("message", on_message)

script.load()

rdev.resume(pid)

sys.stdin.read()

这个代码是通用的,只需要改变包名就好,执行到哪个文件中断了,就说明是哪个so文件作怪,删掉就好,但是如果发现删除完之后不能用,那就不能采用这个方法。

发现在这里停止,那么就说明是这个so文件作怪,我们就去把这个so文件删除就好

4.2 删除那个so文件

/data/app/~~Y0T7lai_U0oUCJog9GF-8A==/com.hupu.shihuo-O3JD2hiXKDpyGx8Ibl4sRA==/lib/arm64/libmsaoaidsec.so

我们刚刚得到的是这个so文件

那我们就要把他删除

1 进入到手机内部,删除这个so文件即可 adb shell su cd /data/app/~~Y0T7lai_U0oUCJog9GF-8A==/com.hupu.shihuo-O3JD2hiXKDpyGx8Ibl4sRA==/lib/arm64 rm -rf libmsaoaidsec.so

2 删除后,再进行绕过强制更新的hook即可

现在就能进去了

五.抓包分析

5.1 直接抓包

抓包发现,都是一些静态资源,然后获得的数据都是乱码,所以一定是做了代理检测,在安卓开发中OkHttp发送请求,设置 `Proxy.NO_PROXY`,基于系统代理都是抓不到包,我们就要绕过绕过,抓更底层的包,socket,需要借助app配合 。

这里给出app是SocksDroid,给出官网

GitHub - PeterCxy/SocksDroidhttps://github.com/PeterCxy/SocksDroid下载好安装到手机就好了

5.2 绕过app代理检测

1 手机端:安装 SocksDroid 2 charles上,配置代理socks包,如下图

3 再SocksDroid配置charles代理

4 在手机端--》去掉原来的代理

配置好了就能完全抓到数据了

抓完包大多数人肯定看到逆向值就想逆向,实际上是不需要逆向的

六.结果演示

七.各种Hook脚本

这里给大家介绍几个通用脚本,在我们搜索不到的时候可以试试

7.1 hook--Map

import frida

import sys

rdev = frida.get_remote_device()

session = rdev.attach("识货")

scr = """

Java.perform(function () {

var TreeMap = Java.use('java.util.TreeMap');

var Map = Java.use("java.util.Map");

TreeMap.put.implementation = function (key,value) {

if(key=="data"){

console.log(key,value);

}

var res = this.put(key,value);

return res;

}

});

"""

script = session.create_script(scr)

def on_message(message, data):

print(message, data)

script.on("message", on_message)

script.load()

7.2 hook--StringBuilder

import frida

import sys

rdev = frida.get_remote_device()

session = rdev.attach("识货")

scr = """

Java.perform(function () {

var StringBuilder = Java.use("java.lang.StringBuilder");

StringBuilder.toString.implementation = function () {

var res = this.toString();

console.log(res);

return res;

}

});

"""

script = session.create_script(scr)

def on_message(message, data):

print(message, data)

script.on("message", on_message)

script.load()

sys.stdin.read()

7.3 hook--Base64

import frida

import sys

rdev = frida.get_remote_device()

session = rdev.attach("识货")

scr = """

Java.perform(function () {

var Base64 = Java.use("android.util.Base64");

Base64.encodeToString.overload('[B', 'int').implementation = function (bArr,val) {

var res = this.encodeToString(bArr,val);

console.log("加密了-->",res);

return res;

}

});

"""

script = session.create_script(scr)

def on_message(message, data):

print(message, data)

script.on("message", on_message)

script.load()

sys.stdin.read()

# 通过查看输出,那请求的数据搜索,发现hook到了

7.5 hook--拦截器

//hook_Interceptor.js 文件名

Java.perform(function () {

var Builder = Java.use('okhttp3.OkHttpClient$Builder');

Builder.addInterceptor.implementation = function (inter) {

console.log(JSON.stringify(inter) );

return this.addInterceptor(inter);

};

})

//最后执行frida -Uf com.hupu.shihuo -l hook_Interceptor.js -o all_interceptor3.txt

7.6 确定是哪个拦截器做的加密和解密

import frida

import sys

rdev = frida.get_remote_device()

session = rdev.attach("识货")

scr = """

Java.perform(function () {

var a = Java.use("cn.shihuo.modulelib.startup.core.c.a");

a.intercept.implementation = function (chain) {

var req = chain.request();

var httpUrl = req.url().toString();

if( httpUrl.indexOf("https://sh-gateway.shihuo.cn/v4/services/sh-goodsapi/app_swoole_shoe/preload/single") != -1 ){

console.log('执行前',httpUrl);

}

var res = this.intercept(chain); // 执行自己这个拦截器

// var response = chain.proceed(req);

return res;

}

});

"""

script = session.create_script(scr)

def on_message(message, data):

print(message, data)

script.on("message", on_message)

script.load()

sys.stdin.read()

以上常用hook都讲完了,里面代码都是根据识货给的,具体还需要自己修改

八.总结

今天主要是讲了绕过强制更新和绕过frida检测,和一些常用hook

补充

有不懂的地方可以主页咨询我,有求必应