安卓逆向 - 某东sign(基于unidbg主动调用)

本文仅供学习交流,只提供关键思路不会给出完整代码,严禁用于非法用途,拒绝转载,若有侵权请联系我删除!

目标app:5Lqs5LicYXBwMTEuMy4y

目标接口:aHR0cHM6Ly9hcGkubS5qZC5jb20vY2xpZW50LmFjdGlvbj9mdW5jdGlvbklkPXNlYXJjaA==
一、引言

接上篇安卓逆向 - 某东body参数算法还原_小馒头yy的博客-CSDN博客 我们抓到了关键字搜索的包,并且成功还原了body参数,今天我们来看看请求url中的sign是如何生成的。

二、分析Java层代码

1、熟练打开Jadx,搜索sign参数发现搜出来的结果太多了15179条,不好分析。过来人的经验是搜索put("sign" "sign"等关键字减小范围。

2、调整搜索策略后,明显少了很多条信息,我们依次点开查看上下文,使用Frida辅助动态分析

最终定位到如下关键行,使用Frida hook发现跟我们抓到的包一模一样。

 String signature = a.a().w().signature(a.a().c(), queryParameter, str, deviceUUID, b, versionName);

hook到结果:

st=1694351779782&sign=989c40fed76cc5b05b47825524b34e14&sv=122

跟进该方法,发现是个接口

选中该接口,查看其引用。继续跟进去分析代码,最后我们找到该native方法。说明该算法时调用so层的代码生成,我们后面将尝试使用Unidbg主动调用生成该sign。

  public static native String getSignFromJni(Context context, String str, String str2, String str3, String str4, String str5);

三、unidbg入门

1、unidbg介绍:允许您模拟 Android 本机库和实验性 iOS 模拟。unidbg 是一款基于 unicorn 和 dynarmic 的逆向工具, 可以直接调用 Android 和 IOS 的 so 文件,无论是黑盒调用 so 层算法,还是白盒 trace 输出 so 层寄存器值变化都是一把利器。官方github: GitHub - zhkl0228/unidbg: Allows you to emulate an Android native library, and an experimental iOS emulation

2、使用前置:需要有一定的Java基础

配置Java环境:推荐Java8

配置maven环境:https://maven.apache.org/download.cgi

开发工具IDEA:IntelliJ IDEA – 领先的 Java 和 Kotlin IDE

3、unidbg官方github有充足的例子,足够我们了解学习它。建议安装官方的流程都学习一遍,这对我们学习unidbg有极大好处。

四、基于unidbg主动调用生成sign

1、配置unidbg基础环境,clone官方代码,找到生成sign方法的so, 就是下方的libjdbitmapkit.so

2、编写基础代码,路径需要改成自己的,重点是 vm.callJNI_OnLoad(emulator, module);这步,我们期望能打印出动态注册方法的地址偏移

public class JdSignTest extends AbstractJni {

    private final AndroidEmulator emulator;
    private final VM vm;
    private PKCS7 pkcs7;
    private DvmClass dvmClass = null;

    public JdSignTest(){
        emulator = AndroidEmulatorBuilder.for32Bit().build();
        Memory memory = emulator.getMemory();
        memory.setLibraryResolver(new AndroidResolver(23));
        // 加载 apk
        vm = emulator.createDalvikVM(new File("D:\\resource\\reverse\\jd\\jd_11.3.2.apk"));
        vm.setVerbose(true);
        vm.setJni(this);
        // 加载 so
        DalvikModule dalvikModule = vm.loadLibrary(new File("D:\\resource\\reverse\\jd\\so\\libjdbitmapkit.so"), false);
        Module module = dalvikModule.getModule();
        // 调用 onload
        vm.callJNI_OnLoad(emulator, module);
    }
}

3、运行以上代码,报错了不要慌,这种一般都是so调用了Java层的方法,我们根据提示补充即可。

如,以上报错需要补充代码:

    @Override
    public DvmObject<?> getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
        if ("com/jingdong/common/utils/BitmapkitUtils->a:Landroid/app/Application;".equals(signature)){
            DvmClass dvmClass1 = vm.resolveClass("android/app/Activity");
            return vm.resolveClass("android/app/Application", dvmClass1).newObject(null);
        }
        return super.getStaticObjectField(vm, dvmClass, signature);
    }

unidbg的缺点就是这个,so层可以调用了很多地方,最多的是通过Jni调用Java方法,我们都需要补充上去,特别的费时间。缺的环境可能是:目标函数中通过 JNI 调用到了某个自己的 JAVA 方法、对linux虚拟文件的读写、对资源文件的读写、系统调用、Android系统库SO。

4、将所有缺的环境补全,成功打印出动态注册信息,注意 RegisterNative关键字,这个指的就是注册Java层的native方法,往后翻看到getSignFromJni(),分析其参数,和我们Java层的分析对应上了。

5、接下来模拟调用该方法,填充参数。

getSignFromJni(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

 直接以全类名调用,传的几个参数就是我们在Java层hook到的,都是明文,例:

StringObject str5 = new StringObject(vm,"11.3.2");       
DvmClass obj = vm.resolveClass("com/jingdong/common/utils/BitmapkitUtils");
DvmObject<?> context = vm.resolveClass("android/content/Context").newObject(null);
// 通过方法名称去调用
DvmObject<?> dvmObject = obj.callStaticJniMethodObject(emulator, "getSignFromJni(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
                context, str, str2,
                str3, str4, str5);

调用该方法,再次报错

    public static void main(String[] args) {
        JdSignTest test = new JdSignTest();
        test.getSignFromJni();
    }

我们根据报错,继续漫长的补环境。例:

    @Override
    public DvmObject<?> newObjectV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {
        if ("java/lang/StringBuffer-><init>()V".equals(signature)){
            return vm.resolveClass("java/lang/StringBuffer").newObject(new StringBuffer());
        }
        if ("java/lang/Integer-><init>(I)V".equals(signature)){
            Integer integer = vaList.getIntArg(0);
            return vm.resolveClass("java/lang/Integer").newObject(integer);
        }
        return super.newObjectV(vm, dvmClass, signature, vaList);
    }

 补环境的过程是漫长且痛苦的,最后跑出结果时也是真的爽

收工!

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
网传资源,如有侵权请联系/留言,资源过大,上传乃是下载链接,失效请留言,下面上大纲: 01.Android环境配置与常用工具介绍 02.Android smali 与 java 代码介绍1 : d% y( z) X- o& ~, e0 _; c1 I 03.Android smali 与 java 代码介绍2 c+ K& I/ q( b 04.Android smali 与 java 代码介绍3 % ]7 Z+ f! I! [5 S. O. N 05.Android smali 与 java 代码介绍4 7 A9 G6 c k; B 06.Android smali 与 java 代码介绍5 ; [. D3 O0 ~9 _0 ]3 W 07.常用Android快速定位关键点方法介绍 " v+ h0 Z5 x& }1 o4 c/ L 08.从0开始打造自己的破解代码库 09.Android 结构基础讲解 10.快速Hook代码搭建之 Cydia Substrate 11.快速Hook代码搭建之 Xposed 12.安装部署Android源码编译环境 13.Android源码目录结构与修改引导 / |3 T: f, f8 [2 @+ p 14.Android源码修改与刷机介绍 & D- q# v- o) o) ?/ u( A 15.Android Jni 编程 & Y6 ^/ J* G3 ] 16.arm 汇编代码讲解1 . J) E# f# h! Q4 x2 P+ K 17.arm 汇编代码讲解2 18.arm 汇编代码讲解3 19.arm 汇编代码讲解4 20.arm 汇编代码讲解5 ' B! y1 m7 _% U8 r2 G! R% h& L! a4 J0 B 21.class.dex文件格式讲解 22.Android 动态代码自修改原理 23.Android 动态代码自修改实现1 . F; Z5 @* D* r 24.Android 动态代码自修改实现2 25.Android dvm 脱壳1 26.elf结构详解1, d9 H, S" s2 }8 j' B6 v 27.elf结构详解2 8 A9 q+ O" `- v 28.elf文件变形与保护 1 g, b1 q, P( P& W, k3 F7 U 29.elf文件修复分析 9 K p" k/ `- s, w/ r: R( X 30.so加壳文件修复 31.常用调试检测方法与过检测方法 * G( L. J' P1 \+ }: N; r 32.Android源码定制添加反反调试机制 ' v/ q6 K1 {6 ] 33.Android dvm 脱壳2 34.Android dvm 脱壳3 H2 X- A# M4 s+ A6 K- b 35.Dalvik dex处理分析 ) x+ l1 l1 J R2 N) T" R) ^2 o 36.IDA脱壳脚本编写1) O7 `% E" Q. @1 X! o ~ 37.Odex修复方法 38.IDAOdex修复脚本编写 " X' w1 h: w3 N" u8 P5 z 39.Android 加壳原理 40.Android 加壳保护工具编写1 1 x4 k0 P/ V' C9 a( O 41.Android 加壳保护工具编写2 42.Android 加壳保护工具编写3
某flutter-app逆向分析是指对于一个使用flutter框架开发的应用进行逆向工程分析。逆向工程是通过分析应用的代码、二进制文件等来了解其内部实现细节。 首先,我们需要获取该应用的安装包文件(APK或IPA文件),然后进行解包操作,将其转换为可读取的文件目录结构。 接下来,我们可以使用一些工具来提取应用的资源文件、代码文件等。对于flutter-app来说,可以提取出dart文件,这是flutter的主要代码文件,其中包含了应用的逻辑实现。 通过阅读dart文件,我们可以了解应用的代码结构、数据模型、界面设计等。可以分析应用的逻辑实现方法,包括各种函数、类、方法的调用关系。 同时,还可以通过分析相关配置文件、资源文件等来了解应用的各种设置、资源加载方式等。 在逆向过程中,还可以使用一些调试工具来进一步了解应用的运行机制。例如,hook工具可以拦截应用的函数调用,并捕获输入输出数据,用于进一步分析。 逆向分析的目的可以有很多,比如了解应用的工作原理、发现潜在的漏洞或安全问题、提供参考用于自己的开发等。 需要注意的是,逆向分析需要遵守法律规定。未经授权的逆向分析可能侵犯他人的知识产权,涉及到隐私等方面的问题。因此,在进行逆向分析之前,应该了解并遵守当地相关法律法规,避免产生法律纠纷。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值