Frida HOOK入门之剪刀石头布破解
本帖最后由 Richor 于 2019-6-26 10:18 编辑个人觉得Frida是比Xpose更牛逼一丢丢的框架,今天用一个剪刀石头布的apk来说明一下frida HOOK
目标:让程序直接输出获胜1000次
第一步:搭建环境
(1)Python及其IDE
1.1安装python2.7或者python3.6 进入官网:https://www.python.org/ 选择Downloads>Windows下载相应版本 安装
1.2 Python IDE:我是使用pycharm,其他的IDE当然也可以
1.3模拟器选用雷电模拟器
(2)Frida环境搭建
2.1模拟器端环境
下载https://github.com/frida/frida/releases/download/12.0.8/frida-server-12.0.8-android-x86.xz即可并改名为Frida-server
打开CMD输入下面的指令
adb pushFrida-server/data/local/tmp/ adb shell "chmod 755 /data/local/tmp/Frida-server"
adb shell"/data/local/tmp/Frida-server &"
不要关闭此窗口,否则frida-server会掉
2.2Python端环境
打开pycharm,新建工程,打开新的CMD,输入以下指令
pip install frida
安装完成后查看进程
firda-ps -U
(3)程序分析
我们先用ak反编译看看代码
.class public Lcom/example/seccon2015/rock_paper_scissors/MainActivity;
.super Landroid/app/Activity;
.source "MainActivity.java"
# interfaces
.implements Landroid/view/View$OnClickListener;
# instance fields
.field P:Landroid/widget/Button;
.field S:Landroid/widget/Button;
.field cnt:I
.field flag:I
.field private final handler:Landroid/os/Handler;
.field m:I
.field n:I
.field r:Landroid/widget/Button;
.field private final showMessageTask:Ljava/lang/Runnable;
# direct methods
.method static constructor <clinit>()V
.locals 1
.prologue
.line 22
const-string v0, "calc"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
.line 23
return-void
.end method
.method public constructor <init>()V
.locals 1
.prologue
.line 13
invoke-direct {p0}, Landroid/app/Activity;-><init>()V
.line 15
const/4 v0, 0x0
iput v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->cnt:I
.line 25
new-instance v0, Landroid/os/Handler;
invoke-direct {v0}, Landroid/os/Handler;-><init>()V
iput-object v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->handler:Landroid/os/Handler;
.line 26
new-instance v0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity$1;
invoke-direct {v0, p0}, Lcom/example/seccon2015/rock_paper_scissors/MainActivity$1;-><init>(Lcom/example/seccon2015/rock_paper_scissors/MainActivity;)V
iput-object v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->showMessageTask:Ljava/lang/Runnable;
return-void
.end method
# virtual methods
.method public native calc()I
.end method
.method public onClick(Landroid/view/View;)V
.locals 10
.param p1, "v" # Landroid/view/View;
.prologue
const/4 v9, 0x3
const/4 v8, 0x2
const/4 v7, 0x0
const/4 v6, 0x1
.line 78
iget v5, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->flag:I
if-ne v5, v6, :cond_0
.line 109
:goto_0
return-void
.line 80
:cond_0
iput v6, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->flag:I
.line 82
const v5, 0x7f0c0052
invoke-virtual {p0, v5}, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v4
check-cast v4, Landroid/widget/TextView;
.line 83
.local v4, "tv3":Landroid/widget/TextView;
const-string v5, ""
invoke-virtual {v4, v5}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
.line 85
const v5, 0x7f0c0050
invoke-virtual {p0, v5}, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v2
check-cast v2, Landroid/widget/TextView;
.line 86
.local v2, "tv":Landroid/widget/TextView;
const v5, 0x7f0c0051
invoke-virtual {p0, v5}, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v3
check-cast v3, Landroid/widget/TextView;
.line 88
.local v3, "tv2":Landroid/widget/TextView;
iput v7, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->m:I
.line 89
new-instance v0, Ljava/util/Random;
invoke-direct {v0}, Ljava/util/Random;-><init>()V
.line 90
.local v0, "rm":Ljava/util/Random;
invoke-virtual {v0, v9}, Ljava/util/Random;->nextInt(I)I
move-result v5
iput v5, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->n:I
.line 92
new-array v1, v9, [Ljava/lang/String;
const-string v5, "CPU: Paper"
aput-object v5, v1, v7
const-string v5, "CPU: Rock"
aput-object v5, v1, v6
const-string v5, "CPU: Scissors"
aput-object v5, v1, v8
.line 93
.local v1, "ss":[Ljava/lang/String;
iget v5, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->n:I
aget-object v5, v1, v5
invoke-virtual {v3, v5}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
.line 95
iget-object v5, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->P:Landroid/widget/Button;
if-ne p1, v5, :cond_1
.line 96
const-string v5, "YOU: Paper"
invoke-virtual {v2, v5}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
.line 97
iput v7, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->m:I
.line 99
:cond_1
iget-object v5, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->r:Landroid/widget/Button;
if-ne p1, v5, :cond_2
.line 100
const-string v5, "YOU: Rock"
invoke-virtual {v2, v5}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
.line 101
iput v6, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->m:I
.line 103
:cond_2
iget-object v5, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->S:Landroid/widget/Button;
if-ne p1, v5, :cond_3
.line 104
const-string v5, "YOU: Scissors"
invoke-virtual {v2, v5}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
.line 105
iput v8, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->m:I
.line 108
:cond_3
iget-object v5, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->handler:Landroid/os/Handler;
iget-object v6, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->showMessageTask:Ljava/lang/Runnable;
const-wide/16 v8, 0x3e8
invoke-virtual {v5, v6, v8, v9}, Landroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z
goto :goto_0
.end method
.method protected onCreate(Landroid/os/Bundle;)V
.locals 1
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 60
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 61
const v0, 0x7f040018
invoke-virtual {p0, v0}, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->setContentView(I)V
.line 63
const v0, 0x7f0c004d
invoke-virtual {p0, v0}, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/Button;
iput-object v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->P:Landroid/widget/Button;
.line 64
const v0, 0x7f0c004f
invoke-virtual {p0, v0}, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/Button;
iput-object v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->S:Landroid/widget/Button;
.line 65
const v0, 0x7f0c004e
invoke-virtual {p0, v0}, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/Button;
iput-object v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->r:Landroid/widget/Button;
.line 67
iget-object v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->P:Landroid/widget/Button;
invoke-virtual {v0, p0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 68
iget-object v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->r:Landroid/widget/Button;
invoke-virtual {v0, p0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 69
iget-object v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->S:Landroid/widget/Button;
invoke-virtual {v0, p0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 71
const/4 v0, 0x0
iput v0, p0, Lcom/example/seccon2015/rock_paper_scissors/MainActivity;->flag:I
.line 72
return-void
.end method
反编译成java看看
package com.example.seccon2015.rock_paper_scissors;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random;
public class MainActivity extends Activity implements OnClickListener {
Button P;
Button S;
int cnt = 0;
int flag;
private final Handler handler = new Handler();
int m;
int n;
Button r;
private final Runnable showMessageTask = new Runnable() {
public void run() {
TextView tv3 = (TextView) MainActivity.this.findViewById(R.id.textView3);
MainActivity mainActivity;
if (MainActivity.this.n - MainActivity.this.m == 1) {
mainActivity = MainActivity.this;
mainActivity.cnt++;
tv3.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
} else if (MainActivity.this.m - MainActivity.this.n == 1) {
MainActivity.this.cnt = 0;
tv3.setText("LOSE +0");
} else if (MainActivity.this.m == MainActivity.this.n) {
tv3.setText("DRAW +" + String.valueOf(MainActivity.this.cnt));
} else if (MainActivity.this.m < MainActivity.this.n) {
MainActivity.this.cnt = 0;
tv3.setText("LOSE +0");
} else {
mainActivity = MainActivity.this;
mainActivity.cnt++;
tv3.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
}
if (1000 == MainActivity.this.cnt) {
tv3.setText("SECCON{" + String.valueOf((MainActivity.this.cnt + MainActivity.this.calc()) * 107) + "}");
}
MainActivity.this.flag = 0;
}
};
public native int calc();
static {
System.loadLibrary("calc");
}
/* Access modifiers changed, original: protected */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.P = (Button) findViewById(R.id.button);
this.S = (Button) findViewById(R.id.button3);
this.r = (Button) findViewById(R.id.buttonR);
this.P.setOnClickListener(this);
this.r.setOnClickListener(this);
this.S.setOnClickListener(this);
this.flag = 0;
}
public void onClick(View v) {
if (this.flag != 1) {
this.flag = 1;
((TextView) findViewById(R.id.textView3)).setText("");
TextView tv = (TextView) findViewById(R.id.textView);
TextView tv2 = (TextView) findViewById(R.id.textView2);
this.m = 0;
this.n = new Random().nextInt(3);
tv2.setText(new String[]{"CPU: Paper", "CPU: Rock", "CPU: Scissors"});
if (v == this.P) {
tv.setText("YOU: Paper");
this.m = 0;
}
if (v == this.r) {
tv.setText("YOU: Rock");
this.m = 1;
}
if (v == this.S) {
tv.setText("YOU: Scissors");
this.m = 2;
}
this.handler.postDelayed(this.showMessageTask, 1000);
}
}
}
我们就可以得到CPU生成状态的位置在onclick
(4)Frida HOOK
我们得到目标的条件是
m=0 n=1cnt=999
我们开始编写python的代码
import frida, sys
def on_message(message, data):
if message['type'] == 'send':
print(" {0}".format(message['payload']))
else:
print(message)
jscode = """
Java.perform(function () {
var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
//开始hook onClick方法需要注意这个function是传参数的所以我们hook时别忘了
//public void onClick(View paramView){}
MainActivity.onClick.implementation = function (v) {
this.onClick(v);
//修改m,n的值
this.m.value = 0;
this.n.value = 1;
this.cnt.value = 999;
send("Success!")
}
});
"""
process = frida.get_usb_device().attach('com.example.seccon2015.rock_paper_scissors')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()
最终结果
pip install frida-tools
pip install frida-tools
前排为大神鼓掌,可惜我看不懂啊,😭😭 如果能讲的更详细一点就好了,第三步贴了一段smali代码,结果还是靠反编译java来的 ccraker 发表于 2019-6-26 11:12
如果能讲的更详细一点就好了,第三步贴了一段smali代码,结果还是靠反编译java来的
Smali代码和java代码一样的,Java更加直观一点 虽然没有看懂个,但是还是为楼主鼓掌 为什么一运行,app就退出了 懂这些是不是得先会英语?
{:1_926:} 第三步跳的有点快,有点😳懵逼 学习一下,非常好,谢谢 学习了!剪刀石头布
页:
[1]