app安全之安卓native层安全分析(一):frida 与unidbg

Android基础进阶 - 消息机制 之Native层分析,Android面试回忆录 synchronized (this) { msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; //如果消息链表为空,或者插入的Message比消息链表第一个消息要执行的更早,直接插入到头部 if (p == null || when == 0 || when < p.when) 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》 【docs.qq.com/doc/DS 阅读详情

前言

这个专题是根据白龙,龙哥的unidbg博客的案例,进行从0开始到安全分析的流程,核心部分会借鉴龙哥的unidbg,通过借鉴大佬的思路,完整的分析某个so层的加密参数

各位朋友也可以直接读龙哥的博客,我只是用我的角度进一步加工一下

原文地址:SO入门实战教程一:OASIS_so学习路线_白龙~的博客-优快云博客

分析

首先拿到这个app,安装啥的就不多说了。

进入到注册界面:

点击获取验证码,然后这边抓包工具抓到的包:

然后,这里面的【sign】就是今天的重点了。

用神秘的工具脱壳完之后,有如下的dex:

把这些dex,全部选中,拖进jadx 

快速定位

接下来开始找sign所在的位置,先看看抓包工具这边的参数,根据这些键名,一顿搜,总能找到一些

先搜下【sign】,虽然搜出来的结果不多,但是感觉有很多干扰项

 进最后那个,到这里,

这些参数看着很像,用frida hook,得知,发现并没有走到这里

搜【ua】

进到这里,发现很可疑,好多参数都对上了

啥都不说,先用objection hook下,然后app端点击【重新发送】看看:

可以,这不直接就定位逻辑了

但是我们要找【sign】,所以还得再看看,jadx查看发现,这个方法反编译效果不太好,问题不大,记住这个dex名,然后用GDA 打开这个dex,这就挺好,基本都反编译出来了

反正看着确实可疑,但是这三个方法,还不确定到底是是哪个方法里有【sign】部分,所以这里直接hook 它这个a,b,c三个方法,然后app点下重新获取

ok,发现最后的方法里基于有我们要的sign,这边再来下,用抓包工具对比下,谨慎一点,别搞半天没搞对位置:

重新hook下,然后抓包工具打开看看

对上了,ok,就是这里了【g.a.c.g.c.a】

在jadx里,反编译失败:

问题不大,用GDA看:

这不就越来越接近了吗,嘻嘻,点进去:

hook下这个c方法看看,ok,对上了

 接着一顿分析后再进入这里

 ok,进到了native层,那么核心的逻辑就在这里了。

像这种,常规的方法怎么解决呢?

  • 如果你是为了拿数据,赶工期的话,那你可以直接主动调用这个方法
  • 如果你是为了纯算还原的话,那就把这个so文件拖进ida一顿分析了
  • 那么假如,这个方法的纯算很复杂,而你又不想主动调用,感觉很low的话,那你就可以尝试用unidbg了

unidbg,就是本系列文章的重点了。

unidbg简介

什么是unidbg

unidbg 是一个基于 unicorn 的安全分析工具,可以实现黑盒调用安卓和 iOS 中的 so 文件

unidbg是凯神写的一个开源的java项目

使用场景

因为现在的大多数 app 把核心的加密算法放到了 so 文件中(比如本例的app),你要想破解签名算法,必须能够破解 so 文件。但C++ 的安全分析远比 Java 的安全分析要难得多,有各种混淆啊,ollvm啥的,所以好多时候是没法纯算还原破解的

那么你是否有过一个想法,能不能把安卓的环境模拟出来,但是又脱离了安卓真机的环境,就可以直接使用so里的方法呢?

unidbg 就是这样一个工具,它模拟好了好几种虚拟环境,他不需要直接运行 app,也无需安全分析so 文件,而是直接找到对应的 JNI 接口,然后用 unicorn 引擎(也不止这一个引擎)直接执行这个 so 文件,所以效率也比较高。

配置unidbg

1.首先,用git 把这个项目clone 下来:

zhkl0228/unidbg: Allows you to emulate an Android native library, and an experimental iOS emulation (github.com)

2.再用idea(写java项目那个编辑器)打开,

首次打开,右下角会下载很多依赖环境,等待即可 

然后随便找一个项目,执行下main方法,有正常输出,说明环境配置好了:

执行结果:

ok,这就很nice。 

frida调试

接下来,先用ida 打开那个目标so文件

等左下角这个数据没有再变的时候,说明加载好了

接下来找导出表【export】,或者在左边的栏里搜【java】

发现并没有任何东西,那么这里就是动态注册的so方法了。

什么是动态注册、静态注册

静态注册(又叫静态绑定),就是,so的方法名直接export导出表里,且命名格式为【java_app包名_方法名】,比如 java_com_sina_oasxxx_nativeapi_s

动态注册(又叫动态绑定)就是export到处表里没有的就是动态注册。

那么这里我们的目标方法就是动态注册的了,那咋办,看看JNI_load方法:

按下【tab】键,会由上面的汇编代码反编译为c代码:

再按下【\】反斜杠,可读性更强点:

但是这里发现,一顿while 和if,根据龙哥的博客说的,大概率是ollvm混淆。那咋办?

用yang神的hook_native脚本来hook出目标函数的偏移地址 ,然后加上so的基址,就可以得到目标函数的地址了(看是thumb还是arm,thumb要加1,arm不用)

frida_hook_libart/hook_RegisterNatives.js at master · lasting-yang/frida_hook_libart (github.com)

用frida hook一下,结果到这就报错退出了

就很尴尬,看看,他报的哪个class名,用来过滤下试试:

重新运行frida试试,可以,这下直接就定位到我们要的方法的位置了:

这里有朋友估计会说,卧槽,这不都出来了吗,这地址,拿着直接用啊,不急,我重启脚本看看:仔细看,fnptr地址变了,fnoffset和后面的jni-load + 的地址没变的

 多次hook发现确实如此,因为这里就是上面说的动态注册,所以这个fnptr,也就是so的基址,app没启动一次就会变,但是目标方法的偏移值是不会变的。ok

用frida hook so看看:

相关的hoo so,有个大佬总结的很好:

分类: frida | 凡墙总是门 (kevinspider.github.io)

ok,这里我们hook下,拿下入参和返回值看看:

  

function inline_hook() {

    var so_addr = Module.findBaseAddress("liboasiscore.so");

    console.log("so_addr:", so_addr);

    if (so_addr) {

        var sub = so_addr.add(0x116cc); // 不用加1,是arm架构

        console.log("The addr_0x116cc:", sub);

        Java.perform(function () {

            Interceptor.attach(sub,

                {

                    onEnter: function (args) {

                        console.log("addr_0x116cc OnEnter :", this.context.PC,

                            this.context.x1, this.context.x5,

                            this.context.x10);

                    },

                    onLeave: function (retval) {

                        console.log("retval is :", retval)

                    },

                })

        })

    }

}





setTimeout(inline_hook, 1000)

运行结果:

 发现并不可读,没事,反正至少是有了

  

function stringToBytes(str) {

  return hexToBytes(stringToHex(str))

}



function stringToHex(str) {

  return str

    .split('')

    .map(function (c) {

      return ('0' + c.charCodeAt(0).toString(16)).slice(-2)

    })

    .join('')

}



function hexToBytes(hex) {

  for (let bytes = [], c = 0; c < hex.length; c += 2) bytes.push(parseInt(hex.substr(c, 2), 16))

  return bytes

}



function hexToString(hexStr) {

  let hex = hexStr.toString()

  let str = ''

  for (let i = 0; i < hex.length; i += 2) str += String.fromCharCode(parseInt(hex.substr(i, 2), 16))

  return str

}

  

function inline_hook() {

    var so_addr = Module.findBaseAddress("liboasiscore.so");

    console.log("so_addr:", so_addr);

    if (so_addr) {

        // var sub = so_addr.add(0x116cc); // 不用加1,是arm架构

        console.log("The addr_0x116cc:", so_addr);

        var ss = "aid=01A8SBOtNRVqsR1ywgkR4tHsZEsgXkGDrgKO2OvFBeThKWZDE.&cfrom=28B5295010&cuid=0&noncestr=L83x8Z40132Wan450y736563n3kmWj&phone=138469655665&platform=ANDROID&timestamp=1681790293128&ua=Xiaomi-MI6__oasis__3.5.8__Android__Android9&version=3.5.8&vid=2010511512550&wm=20004_90024";

        var add_addr = so_addr.add(0x116cc); // 32位需要加1

        var add = new NativeFunction(add_addr, 'pointer', ['pointer', 'int']);

        console.log(add)

        var result = add(stringToByte(Memory.allocUtf8String(ss)), false)

        console.log("add2 result is ->" + result.readCString());

    }



}

function stringToByte(str) {

    var ch, st, re = [];

    for (var i = 0; i < str.length; i++) {

        ch = str.charCodeAt(i);

        st = [];

        do {

            st.push(ch & 0xFF);

            ch = ch >> 8;

        } while (ch);

        re = re.concat(st.reverse());

    }   // return an array of bytes

    return re;

}



setTimeout(inline_hook, 2000)

尝试主动调用,调试了很久,就是不行

突然反应过来,这个so文件有ollvm混淆啊,虽然用yang神的代码hook到了偏移地址,但是他内部可能并不是这些参数,而我们又没法直接分析,那没法了。其实以上的代码,在其他地方是可以用的,

那接下来咋办?上unidbg吧

unidbg调试

上面用了frida+ida调试,发现有的时候没法搞啊,那么这里,终于要用unidbg来模拟执行生成上面目标app的sign了

 先创建一个文件,把该有的都放进去

然后再oasis里写代码,照着龙哥的搞就完了:注意文件路径,跟你实际的路径保持一致

  

package com.sina;



import com.github.unidbg.AndroidEmulator;

import com.github.unidbg.Module;

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.DalvikModule;

import com.github.unidbg.linux.android.dvm.VM;

import com.github.unidbg.memory.Memory;



import java.io.File;



public class oasis extends AbstractJni {

    private final AndroidEmulator emulator;

    private final VM vm;

    private final Module module;



    oasis() {

        // 创建模拟器实例,进程名建议依照实际进程名填写,可以规避针对进程名的校验

        emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.sina.oasis").build();

        // 获取模拟器的内存操作接口

        final Memory memory = emulator.getMemory();

        // 设置系统类库解析

        memory.setLibraryResolver(new AndroidResolver(23));

        // 创建Android虚拟机,传入APK,Unidbg可以替我们做部分签名校验的工作

        vm = emulator.createDalvikVM(new File("unidbg-android\\src\\test\\java\\com\\sina\\lvzhou.apk"));

        // 加载目标SO

        DalvikModule dm = vm.loadLibrary(new File("unidbg-android\\src\\test\\java\\com\\sina\\liboasiscore.so"), true); // 加载so到虚拟内存

        //获取本SO模块的句柄,后续需要用它

        module = dm.getModule();

        vm.setJni(this); // 设置JNI

        vm.setVerbose(true); // 打印日志



        dm.callJNI_OnLoad(emulator); // 调用JNI OnLoad

    };



    public static void main(String[] args) {

        oasis test = new oasis();

    }

}

 然后运行一下,没啥问题,说明架子是搭上了

仔细看这里,这样也把我们要的方法的地址拿到了。舒服啊

用前面frida 的对比,好像不太一样,问题不大

再来看看代码:

再来仔细看看他这个main干了啥:

调用

架子搭好了,接下来调用,调用有两种方式,一种是符号(symbol)调用,一种是地址调用,符号调用对应静态注册,地址调用对应动态注册。那么根据前面的解析,这里我们只能选用地址调用了

先看看我们要调用的方法:

有两个参数,一个byte数组,一个boolean,然后native层的方法,默认前面会自动加两个参数 ,一个jni env,一个jobject

还是上面的frida脚本,先hook下,看看入参和返回:

ok,直接拿着这个str参数的值去unidbg构造:

注意,如果你用的旧版,也就是龙哥案例的代码,直接报错:

新版得这么用,运行结果:

package com.sina;



import com.github.unidbg.AndroidEmulator;

import com.github.unidbg.Module;

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.DalvikModule;

import com.github.unidbg.linux.android.dvm.VM;

import com.github.unidbg.linux.android.dvm.array.ByteArray;

import com.github.unidbg.memory.Memory;

import com.sun.jna.Pointer;



import java.io.File;

import java.nio.charset.StandardCharsets;

import java.util.ArrayList;

import java.util.List;

import java.lang.Number;



public class oasis extends AbstractJni {

    private final AndroidEmulator emulator;

    private final VM vm;

    private final Module module;



    oasis() {

        // 创建模拟器实例,进程名建议依照实际进程名填写,可以规避针对进程名的校验

        emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.sina.oasis").build();

        // 获取模拟器的内存操作接口

        final Memory memory = emulator.getMemory();

        // 设置系统类库解析

        memory.setLibraryResolver(new AndroidResolver(23));

        // 创建Android虚拟机,传入APK,Unidbg可以替我们做部分签名校验的工作

        vm = emulator.createDalvikVM(new File("unidbg-android\\src\\test\\java\\com\\sina\\lvzhou.apk"));

        // 加载目标SO

        DalvikModule dm = vm.loadLibrary(new File("unidbg-android\\src\\test\\java\\com\\sina\\liboasiscore.so"), true); // 加载so到虚拟内存

        //获取本SO模块的句柄,后续需要用它

        module = dm.getModule();

        vm.setJni(this); // 设置JNI

        vm.setVerbose(true); // 打印日志



        dm.callJNI_OnLoad(emulator); // 调用JNI OnLoad

    };



    public static void main(String[] args) {

        oasis test = new oasis();

        System.out.println(test.getSign());

    }

    public String getSign(){

        List<Object> list = new ArrayList<>(10);

        list.add(vm.getJNIEnv()); // arg1,env

        list.add(0); // arg2,jobject

        String keywords = "aid=01A8SBOtNRVqsR1ywgkR4tHsZEsgXkGDrgKO2OvFBeThKWZDE.&cfrom=28B5295010&cuid=0&noncestr=L83x8Z40132Wan450y736563n3kmWj&phone=xxxxx&platform=ANDROID&timestamp=1681790293128&ua=Xiaomi-MI6__oasis__3.5.8__Android__Android9&version=3.5.8&vid=2010511512550&wm=20004_90024";

        byte[] keyB = keywords.getBytes(StandardCharsets.UTF_8);

        ByteArray inbarr = new ByteArray(vm,keyB);

        list.add(vm.addGlobalObject(inbarr)); //arg3

        list.add(0); //arg4

//        Number number = module.callFunction(emulator,0xC365,list.toArray())[0];

        Number number = module.callFunction(emulator,0xC365,list.toArray());

        String result = vm.getObject(number.intValue()).getValue().toString();

        return result;

    }

}

  

验证下结果,对上了,舒服:

结语

unidbg的实用之处就在这里,相信不用我多说,你已经发现了很多妙用之处

app安卓逆向之native层代码静态分析基础 app安卓逆向之Native层代码静态分析基础Native层代码静态分析1.背景分析2.概述3.开始3.1 ARM指令3.2 IDA基本使用方法3.3 Java层调用Native层方法原理3.4 Native层代码的修改3.5 So文件替换4.总结 Native层代码静态分析 1.背景分析 在安卓逆向的过程当中会遇到以下场景 经过上一阶段的Java层代码静态分析以及动态调试,发现加密参数的生成方法调用了Native层方法 经过对Native层代码分析后修改对应代码,替换原so文件发现app运行异常 针对 阅读详情

相关推荐

frida 常用的一些demo 打印native 函数的堆栈 参数,返回值 等

import frida, sys jscode = “”" var str_name_so = “libxxxx.so”; //要hook的so名 var str_name_func = “getxxxx”; //要hook的函数名 var n_addr_func = Module.findExportByName(str_name_so , str_name_func); console.log(“func ShowMessageBoxID addr is —” + n_addr

qq_36535153的博客 1万+

安卓分层

Android的分4层,java应用程序,java框架,本地框架和java运行环境,Linux内核空间 Native层就是本地框架。Java应用程序无需过多解释,基本可以理解为各个App,由Java语言实现。 Java框架层就是常说的Framework,这层里东西很多也很复杂,比如说主要的一些系统服务如ActivityManagerService、PackageManagerService等,

s546725246的专栏 1223

app安全之安卓native层安全分析(八):unidbg补前置环境+IO重定向

SO逆向入门实战教程七:main_unidbg 重定向_白龙~的博客-优快云博客还是那句,我会借鉴龙哥的文章,以一个初学者的角度,加上自己的理解,把内容丰富一下,尽量做到不在龙哥的基础上画蛇添足。1.找不到该native方法引入的哪个so文件时,用hook_RegisterNative脚本分析2.执行结果发现不对返回空指针时,很大可能是逻辑问题,需要结合jnitrace分析3.报dirfd=-100,就是读取文件错误,需要指导程序到正确的路径4.补文件读取有两个方法。

app安全逆向、移动开发、tls/ja3、爬虫、反爬 4330

andrid分层的概念------native层

Android的分4层,java应用程序,java框架,本地框架和java运行环境,Linux内核空间 Java应用程序无需过多解释,基本可以理解为各个App,由Java语言实现。 Java框架层(系统服务)就是常说的Framework,这层里东西很多也很复杂,比如说主要的一些系统服务如ActivityManagerService、PackageManagerService等,我们编写的An

ffmxnjm的博客 2万+

Unidbg实战:Android Native层签名算法逆向与模拟执行

在移动安全与逆向工程领域,Native层加密算法分析是核心技术挑战之一。其原理在于Android应用将核心逻辑编译为so动态库,通过JNI接口与Java层交互,以提升代码安全性和执行效率。这项技术的工程价值在于能够有效对抗动态调试和静态反编译,保护关键业务逻辑如API签名、数据加密等。在实际应用场景中,逆向工程师常需分析网络协议、实现自动化脚本或进行安全审计。针对此类需求,Unidbg模拟执行框架提供了一种高效解决方案,它允许在PC端虚拟环境中直接运行so库代码,绕过了反调试检测和环境依赖问题。本文以某州A

weixin_34379433的博客 423

unidbg集成xHook实现Android Native层动态分析与Hook

在Android安全研究与逆向工程领域,动态库(.so文件)的Hook技术是核心分析手段,用于拦截和修改函数行为以理解或干预程序逻辑。其原理通常基于动态链接机制,通过修改函数指针(如PLT/GOT表)实现调用重定向。这项技术的价值在于能够在不修改源码的情况下,动态监控、调试和改变程序执行流,广泛应用于加密算法分析、协议逆向、漏洞挖掘及风控对抗等场景。其中,unidbg作为模拟执行工具,提供了脱离真实设备的沙盒环境,而xHook作为高效的PLT Hook库,专注于拦截动态库间的函数调用。两者的结合,使得在模拟

weixin_34375251的博客 365

app安全之安卓native层安全分析(五):unidbg黑盒调用

SO逆向入门实战教程五:qxs_白龙~的博客-优快云博客还是那句,我会借鉴龙哥的文章,以一个初学者的角度,加上自己的理解,把内容丰富一下,尽量做到不在龙哥的基础上画蛇添足,哈哈。本篇和上一篇感觉的挺简单的,所以没有啥总结的。

app安全逆向、移动开发、tls/ja3、爬虫、反爬 1383

Unidbg与Frida实战:逆向分析移动App签名算法x-sign

在移动应用安全与自动化测试领域,算法逆向是理解核心业务逻辑、进行安全审计的关键技术。其基本原理是通过动态与静态分析相结合,还原被保护在Native层的核心算法逻辑。这项技术的核心价值在于,它能够突破应用层的混淆与加密,直接触及数据生成与校验的本质,为安全研究、自动化脚本编写和协议分析提供坚实基础。在实际应用场景中,签名算法(如常见的x-sign)的逆向尤为典型,它通常涉及参数拼接、哈希计算与编码转换。本文将以某鱼App的x-sign算法为例,深入讲解如何利用Unidbg进行模拟执行与深度Trace,并结合F

weixin_28622215的博客 929

app安全之安卓native层安全分析(六):frida调试跟栈+unidbg补环境大动作

SO逆向入门实战教程六:s_白龙~的博客-优快云博客还是那句,我会借鉴龙哥的文章,以一个初学者的角度,加上自己的理解,把内容丰富一下,尽量做到不在龙哥的基础上画蛇添足,哈哈。1.treemap需要注意下,在unidbg里需要继承map,abstractmap2.varArg.getObjectArg(0)可以获取该方法的参数,0,指第一个,1指第二个。

app安全逆向、移动开发、tls/ja3、爬虫、反爬 9597

实战:用Frida+Unidbg逆向分析绿洲APP的sign加密(附完整代码)

本文通过实战案例,详细讲解了如何运用Frida动态Hook与Unidbg模拟执行两大工具,逆向分析Android应用绿洲APP的sign加密算法。文章从Java层定位到SO层核心函数,解决了ARM架构兼容性问题,并最终识别出MD5加盐的签名生成逻辑,为移动端安全研究和协议分析提供了完整的方法论与代码参考。

weixin_29323049的博客 999

从Web JS到安卓App:用Frida和Unidbg搞定爬虫逆向的30个实战案例(附视频)

本文深入探讨了如何构建跨平台逆向工具链,通过Frida和Unidbg等核心工具应对Web JS和安卓App的复杂反爬机制。文章提供了30个实战案例,涵盖加密定位、反反爬设计、分层逆向等方法,帮助爬虫工程师高效解决各类逆向挑战。

weixin_30847865的博客 322

app安全之安卓native层安全分析(三):ida使用+unidbg补环境

SO逆向入门实战教程三:V2-Sign_unidbg context_白龙~的博客-优快云博客还是那句,我会借鉴龙哥的文章,以一个初学者的角度,加上自己的理解,把内容丰富一下,尽量做到不在龙哥的基础上画蛇添足,哈哈。1.看so的调用逻辑,如果有loadlibrary的同时有调用某个方法,unidbg模拟执行的时候也要先调用这个方法2.如果加载so文件的时候,给定的第二个参数是false,加上so文件有字符串加密和混淆的话就会乱码,所以这里最好给为true,ida里,shift+F7,可以看。

app安全逆向、移动开发、tls/ja3、爬虫、反爬 3564

Frida与Unidbg实战:逆向分析移动端API签名算法

在移动应用安全与数据通信领域,API签名是保障请求合法性、防止数据篡改与重放攻击的核心安全机制。其原理通常基于哈希算法(如MD5、SHA系列)或消息认证码(HMAC),对请求参数、时间戳及密钥进行特定组合与计算,生成唯一的身份凭证。这项技术的价值在于为客户端与服务器间的通信建立了可信验证层,广泛应用于金融支付、社交网络、电商平台等涉及敏感数据交互的场景。本文聚焦于**Frida动态注入**与**Unidbg模拟执行**两大逆向工程利器的协同运用,通过一个完整案例,系统演示如何定位、分析并最终复现一个典型移动

weixin_34199335的博客 396

Frida+Unidbg实战:移动App登录协议逆向与加固指南

客户端签名机制是移动应用安全的核心防线,其本质是通过加密算法对请求参数生成不可伪造的校验凭证。原理上依赖密钥管理、时间戳防重放、随机数不可预测性及Native层逻辑混淆等多重设计。技术价值在于阻断自动化攻击、保障身份真实性与接口调用合法性。典型应用场景包括登录认证、支付签名、API限频校验等。然而,当盐值硬编码、nonce可预测、时间戳未绑定设备时,协议极易被逆向复现。本文基于Frida动态Hook与Unidbg模拟执行双引擎,系统拆解登录签名生成流程,覆盖Java层入口定位、JNI调用链捕获、so算法还原

weixin_30907935的博客 770

逆向某黄鱼x-sign算法:从Frida动态调试到Unidbg完整复现

本文详细介绍了逆向分析某黄鱼App核心x-sign签名算法的完整流程。通过Frida动态调试快速定位关键函数,再结合Unidbg进行静态模拟与深度分析,形成了一套高效的Native层算法逆向方法论。文章涵盖环境搭建、Hook技巧、Trace追踪、断点调试及算法逻辑复现,为移动安全研究人员提供了从动态探测到静态模拟的实战指南。

weixin_29323365的博客 1137

逆向分析App加密算法:绕过Frida反调试与Unidbg模拟执行实战

在移动应用安全领域,加密算法与反调试技术是核心攻防点。MD5等哈希算法常用于参数签名,而Frida作为主流动态分析工具,常面临反调试检测。理解JNI调用、内存映射检测及ptrace机制,是绕过防护的基础。通过Hook关键系统函数、过滤特征字符串,可有效规避检测,为算法分析创造条件。利用Unidbg模拟执行框架,能在非安卓环境中复现Native层加密逻辑,实现算法还原与批量签名生成。本文聚焦生鲜超市App的paramsMD5算法,结合Frida反反调试与Unidbg实战,详解从对抗加固到算法模拟的完整流程。

weixin_33220360的博客 677
上一篇: 反爬虫之有个操作也许可以检测aiohttp、httpx,requests也尴尬?
下一篇: app安全之安卓native层安全分析(二):unidbg+ida使用+过签名校验
geekbyte.
博客等级 码龄11年 308粉丝 75原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值