藿香正气 发表于 2017-5-27 15:25

Frida使用和Hook代码整理

本帖最后由 藿香正气 于 2018-5-14 10:46 编辑

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。
有不对的地方也请各位老大斧正







kwing112 发表于 2017-9-19 15:40

本帖最后由 kwing112 于 2017-9-19 15:43 编辑

Interceptor.attach(Module.findExportByName("libtest.so","Java_com_example_kwing_frdtest_MainActivity_getInt"),
{
      onEnter:function(args)
      {
                console.log("inside ndk "+args.toInt32());//args2就是传进来的int参数,,直接修改是不行的
               
      },
      onLeave:function (retval)
      {
                retval.replace(1000);
      }
});
""" 改成这样是可以hook到ndk函数的,,但是我修改参数还是不成功,有熟悉的指导下

gaybc 发表于 2018-1-8 16:29

kwing112 发表于 2017-9-19 15:40
Interceptor.attach(Module.findExportByName("libtest.so","Java_com_example_kwing_frdtest_MainActivity ...

我只有retval.replace(0)才能成功 不然都是读取已释放内存
不知现在有否解决方案?

tt9527 发表于 2017-5-27 15:53

怒抢一楼

受伤的小猪 发表于 2017-5-27 19:06

高手啊11

mayl8822 发表于 2017-5-27 19:17

厉害了我的哥, 感谢分享

chenjingyes 发表于 2017-5-28 00:43

楼主幸苦了谢谢分享

尕可 发表于 2017-5-28 10:29

火钳刘明{:1_931:}

fisher 发表于 2017-5-28 13:14

使用python和javascrip进行hook模块的开发

{:17_1083:}JavaScript你少打了一个t

ods1997 发表于 2017-5-29 06:08

楼主辛苦了

tfrist 发表于 2017-5-29 09:19

辛苦了谢谢分享

Three_fish 发表于 2017-5-29 10:39

谢谢分享
页: [1] 2 3 4 5
查看完整版本: Frida使用和Hook代码整理