android逆向基础教程二

andorid 源码查看地址:  Android Code Search   AOSPXRefAndroidXRef

通过android 逆向基础教程一学习了常见 frida hook的一些基本手法,本次接着上次学习案例继续学习frida hook 相关知识点。

  1. hook 构造函数
  2. 调用系统的类和函数
  3. 动态加载dex 
  4. 注册Class, 注册接口的实现
  5. 打印调用栈
  6. smali 汇编知识

hook Getenv 修改str 返回值为"Imyang"即可绕过,直接调用StartActivity执行指定Activity方式直接跳到第八关

 因为重点学习Frida hook ,因此侧重 hook 解决以上问题,但实际生活中,以达到目的为重,尤其是相关比赛过程中,因此熟悉阅读 smali 很有必要。

androidkiller 快速修改到关键位置配合 hook 效果也很不错。

if 判断 next 参数bool,类构造函数可对next 修改next 变量,hook够着函数并调用 next=true;

smali 汇编下的构造函数,非常简单,因此修改哪里一眼能看出,熟悉构造函数在Smali 汇编中的声明定义。

frida hook 实现方式如下:

调用系统函数 startActivity 要了解app启动过程,方式为找到ActivityThread-->currentApplication-->getApplicationContext 获取当前上下文(查询android 源码方式)

function hook_MainActivity() {
  Java.perform(function() {
      var MainActivity = Java.use("com.example.androiddemo.MainActivity");
      //frida -U --no-pause -f com.example.androiddemo -l hook.js
      //--no-pause -f apk启动之前就把frida的脚本注入进apk进程里
      var System = Java.use("java.lang.System");
      System.getenv.overload('java.lang.String').implementation = function(name) {
          var env = this.getenv(name);
          if (name == "USER") {
              env = "Imyang";
          }
          console.log("getenv:", name, env);
          return env;
      }
      var FridaActivity7 = Java.use("com.github.lastingyang.androiddemo.Activity.FridaActivity7");
      //hook 构造函数
      FridaActivity7.$init.implementation = function() {
          this.$init();
          this.next.value = true;
      }
  });
}
function call_startActivity() {
  Java.perform(function() {
      //调用系统的类和函数
      var ActivityThread = Java.use("android.app.ActivityThread");    
      var application = ActivityThread.currentApplication();
      var context = application.getApplicationContext();
      console.log(context);
      var FridaActivity7 = Java.use("com.github.lastingyang.androiddemo.Activity.FridaActivity7");
​
      var Intent = Java.use("android.content.Intent");
      Java.scheduleOnMainThread(function() {
          var intent = Intent.$new(context, FridaActivity7.$new().getClass());
          intent.setFlags(0x10000000);
          console.log(intent);
          context.startActivity(intent);
      })
      var FridaActivity7=Java.use("com.github.lastingyang.androiddemo.Activity.FridaActivity7");
      FridaActivity7.$init.implementation=function(){
        this.$init();
        this.next.value=true;
      }
  });  
}
function main(){
    hook_MainActivity();
}
setImmediate(main);

 完成通关后,分析下一关的逻辑。

Android studio 编译解密算法(异或)为 Dex push到测试机

public class DecodeUtil {
    private final String password = "\u0013YQWZQ\u0012Fx$/a.5a.&";
    private String a(String str) {
        char[] charArray = str.toCharArray();
        for (int i = 0; i < charArray.length / 2; i++) {
            char c = charArray[i];
            charArray[i] = (char) (charArray[(charArray.length - i) - 1] ^ 'A');
            charArray[(charArray.length - i) - 1] = (char) (c ^ '2');
        }
        return new String(charArray);
    }
}
/*dex 打包
android d8
```shell
AndroidDemo\app\build\intermediates\javac\debug\classes>Local\Android\Sdk\build-tools\30.0.2\d8.bat 
adb push 
```
在代码实现过程中我们将password 字符串解密,而通过修改smali 获取解密内容也是很容易,当然,修改跳转直接到第九关更没用难度。我们通过修改加密函数做解密 password ,与代码一样,异或的异或回去。

上面对 a加密方法改为解密后,修改传入password 字符串查看日志就可得到解密后的password 日志打印出来。
frida 动态加载dex 
为了学习 frida 动态加载dex ,我们将解密算法打包为dex,frida 动态加载dex方式完成解密,因为大多数我们的解密算法没有那么简单。
//动态加载dex     openClassFile -->load    
function load_dex(){
    var DecodeUitlsDex=Java.openClassFile("/data/local/tmp/DecodeUtil.dex");
    console.log("DecodeUtilsDex:",DecodeUitlsDex);
    Java.perform(function(){
        DecodeUitlsDex.load();
        var DecodeUtils=Java.use("com.example.androiddemo.DecodeUtil")
        console.log(DecodeUtils);
        var FridaActivity8=Java.use("com.github.lastingyang.androiddemo.Activity.FridaActivity8");
        Java.scheduleOnMainThread(function(){
            console.log(DecodeUtils.$new().a(FridaActivity8.$new().password.value)); //new dex 中的a方法传入解密字符串password
​
        })
    });
}
function hook_FridaActivity8(){
    Java.perform(function(){
        var FridaActivity8 = Java.use("com.github.lastingyang.androiddemo.Activity.FridaActivity8");
        FridaActivity8.a.implementation=function(str){
            str="go to next check!";
            var result=this.a(str);
            console.log(str,result);
            return result;
        }
    })
}

注册Class, 注册接口的实现

最后一关通过调用接口方法做判断条件,通过frida 注册class,注册接口的实现check() 返回为真。

 

//注册Class, 注册接口的实现
function hook_FridaActivity9(){
    Java.perform(function(){
        var Frida9Interface=Java.use("com.github.lastingyang.androiddemo.Activity.FridaActivity9$Frida9Interface");
        console.log(Frida9Interface);
       var Frida9InterfaceImpl= Java.registerClass({
            name:"com.github.lastingyang.androiddemo.Activity.FridaActivity9.Frida9InterfaceImpl",
            implements:[Frida9Interface],
            methods:{
                check(){
                    console.log("Frida9InterfaceImpl.check");
                    return true;
                }
            }
        });
        var FridaActivity9=Java.use("com.github.lastingyang.androiddemo.Activity.FridaActivity9");
        FridaActivity9.getInstance.implementation=function(){
            console.log("FridaActivity9.getInstance");
            return Frida9InterfaceImpl.$new();
        }
    });
}

打印调用栈

//打印调用栈
function printStackTrace() {
    Java.perform(function() {
        var Exception = Java.use("java.lang.Exception");
        var exception = Exception.$new();
        var stackTrace = exception.getStackTrace().toString();
        console.log("==========================\r\n" + stackTrace.replaceAll(",", "\r\n") 
            + "\r\n==========================");
        exception.$dispose();
    });
}
function hook_FridaActivity10(){
    Java.perform(function(){
        var FridaActivity10=Java.use("com.github.lastingyang.androiddemo.Activity.FridaActivity10");
        FridaActivity10.onCheck.implementation=function(){
            printStackTrace();
            console.log("FridaActivity10.onCheck");
        }
    })
}

Guess you like

Origin blog.csdn.net/qq_37431937/article/details/122461807