传说中的路痴 发表于 2017-6-4 10:21:11

Frida使用和Hook代码整理

0x0001 一些废话
小弟最近学习Hook技术,一直使用的是substrate和xposed,这两种框架给我的感觉功能是非常强大的,但是有一些不稳定,有的时候安装模块软重启后机器就起不来了(也可能是我的代码写的不叫渣,总之遇到一些坑),只能进入recovery模式删除模块。最近找到了一个轻量级的hook框架这几天使用了一下感觉非常不错,她就是Firda,她的优点就是比较轻量级,使用python和javascrip进行hook模块的开发,缺点的话我感觉就是js我不太会,下面就上代码吧


0x0002 安装
安装很简单,需要python环境在linux、win的环境都可以,下面就是我在windwos下安装,
1.Python环境就不用多说了 安装后配置环境变量,我使用的是2.7.X的版本
2.安装piphttps://pypi.python.org/pypi/pip, 到这里下载pip-9.0.1.tar.gz (md5, pgp)的安装包,解压后,在命令行下进入这个目录,运行 python setup install 等一会安装就完成了
再讲pip所在的 python\Scripts 添加到命令行,pip就可以用了
3.安装frIDA 运行命令pip install frida 就好了
4.下载 服务端 https://github.com/frida/frida/releases 到这里找到frida-server-10.0.8-android-arm.xz这里根据自己手机的平台选择就可以了 大多数是android-arm


0x0003 使用
链接手机usb 打开调试模式
1.adb push frida-server-10.0.8-android-arm /data/local/tmp
然后使用root 启动就行了

2.打开另一个命令行
adb forward tcp:27042 tcp:27042
adb forward tcp 27043 tcp 27043
然后输入 frida-ps -R
就会看到手机里所有的进程

0x0004 开始测试


先是目标应用,分为两部分 java + ndk
package com.example.hooktest.jiami;
public class Jiami {
      public int jiami(int i ,int j) {
                return i*10 + j*11;
      }
}


package com.example.hooktest;


import com.example.hooktest.jiami.Jiami;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{

      static {
                System.loadLibrary("test");
      }
         
      private TextView tv;
      private Button btn;
      @Override
      protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                tv = (TextView) findViewById(R.id.tv);
                btn = (Button) findViewById(R.id.btn);
                btn.setOnClickListener(this);
      }
         
      native public String getString();

      @Override
      public void onClick(View v) {
                // TODO Auto-generated method stub
                Jiami mi = new Jiami();
                tv.setText(getString() + mi.jiami(10, 20));
      }
         
}


下面是ndk的

#include <jni.h>
#include <string.h>
#include <android/log.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>


#defineLOGI(...)__android_log_print(ANDROID_LOG_INFO, "hooktest", __VA_ARGS__)

int getInt(int i)
{
      return i+99;
}

JNIEXPORT jstring JNICALL
Java_com_example_hooktest_MainActivity_getString(JNIEnv* env,jobject thiz)
{
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#define ABI "armeabi-v7a/NEON"
#else
#define ABI "armeabi-v7a"
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__mips__)
#define ABI "mips"
#else
#define ABI "unknown"
#endif
      LOGI("[+] %d\n", getInt(1));
      return (*env)->NewStringUTF(env, ABI);
}


测试是要对jiami这个函数进行hook,也可以对这个函数进行调用生成加密后的数据,第二个是对jni这个接口函数进行调用,也可以调用getInt这个 c函数 下面是代码
Hook_java_method.py

#coding=utf-8
import frida
import sys
session = frida.get_remote_device().attach("com.example.hooktest")
#print session.enumerate_modules()

jscode = """
Java.perform(function(){
    send("Running Script");

    var getString = undefined;
    exports = Module.enumerateExportsSync("libtest.so");
    for(i=0; i<exports.length; i++){
      if(exports.name == "Java_com_example_hooktest_MainActivity_getString"){
            getString = exports.address;
            send("getInt is at " + getString);
            break;
      }
    }

      var getInt = undefined;
    exports = Module.enumerateExportsSync("libtest.so");
    for(i=0; i<exports.length; i++){
      if(exports.name == "getInt"){
            getInt = exports.address;
            send("getInt is at " + getInt);
            break;
      }
    }
    var fungetInt = new NativeFunction(getInt, 'int', ['int']);
   
    Interceptor.attach(getString,{
      onEnter: function (args) {
                send("onEnter");
                var res = fungetInt(99999);
                send(res);
            },
            onLeave: function (retval) {
                     send("onLeave");
            }

         
    });
});
"""

def on_message(message, data):
      print message
script = session.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()



这个是调用jiami函数
call_java_method

#coding=utf-8
import frida
import sys
session = frida.get_remote_device().attach("com.example.hooktest")
#print session.enumerate_modules()

jscode = """
Java.perform(function () {
    var jiami = Java.use("com.example.hooktest.jiami.Jiami");
    var instance = jiami.$new();
    var res = instance.jiami(100,200);
    send(res);
});
"""

def on_message(message, data):
      print message

script = session.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()



这个是调用getInt函数

#coding=utf-8
import frida
import sys
session = frida.get_remote_device().attach("com.example.hooktest")
#print session.enumerate_modules()

jscode = """
Java.perform(function(){
    send("Running Script");

    var getString = undefined;
    exports = Module.enumerateExportsSync("libtest.so");
    for(i=0; i<exports.length; i++){
      if(exports.name == "Java_com_example_hooktest_MainActivity_getString"){
            getString = exports.address;
            send("getInt is at " + getString);
            break;
      }
    }

      var getInt = undefined;
    exports = Module.enumerateExportsSync("libtest.so");
    for(i=0; i<exports.length; i++){
      if(exports.name == "getInt"){
            getInt = exports.address;
            send("getInt is at " + getInt);
            break;
      }
    }
    var fungetInt = new NativeFunction(getInt, 'int', ['int']);
   
    Interceptor.attach(getString,{
      onEnter: function (args) {
                send("onEnter");
                var res = fungetInt(99999);
                send(res);
            },
            onLeave: function (retval) {
                     send("onLeave");
            }

         
    });
});
"""

def on_message(message, data):
      print message
script = session.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()


先看一下正常结果

小弟最后一个问题就是 没法hook住 getInt这个函数,只能对他进行调用,不是哪位老大可以对这个很熟进行hook。
有不对的地方也请各位老大斧正


重庆生活网c 发表于 2018-10-28 20:01:43

好东西哦,大家不要光看不顶

初相见 发表于 2018-11-12 22:34:56

楼主加油,我们都看好你哦。
页: [1]
查看完整版本: Frida使用和Hook代码整理