|
本帖最后由 xkang 于 2018-8-20 16:38 编辑
之前的安卓逆向内购以及简单的Hook 有些小伙伴提到 想了解HOOK游戏教程
寻思着讲讲 于是在论坛搜了一下 Frida 发现没有 就写了这个教程 假如撞车了多尴尬
成功目标获取到SECCON
上一篇帖子传送门:
安卓逆向-——实现内购以及HOOK法干掉签名校验
https://www.52hb.com/thread-39146-1-1.html
(出处: 吾爱汇编论坛)
声明:
此次教程涉及到的CODE&APK来源于Frida官网
教程环境:Mac Book Pro(Linux)
教程大纲:1.安装Frida以及genymotion模拟器&python2.7或者python3.6,ADB
2.调试Frida
3.分析APK的calc&code
4.HOOK APK
1.安装Frida以及genymotion模拟器&python2.7或者python3.6,ADB
1.1安装python2.7或者python3.6
进入官网:https://www.python.org/ 选择Downloads>Windows 下载相应版本 安装
1.2安装ADB
进入官网:http://adbshell.com/downloads 选择下载ADB Kits 下载 安装
注意ADB版本问题 ADB版本一定要一致 比如server是40 那么client也必须是40
1.3安装genymotion模拟器
进入官网:http://www.genymotion.net/ 需要先注册在下载 安装
1.4安装Frida
Windows 打开CMD 输入sudo pip install frida-tools
Linux 打开终端 输入sudo pip install frida-tools
[backcolor=rgba(0, 0, 0, 0.7)]等待安装完成即可之后 终端(CMD)打开Python 输入import frida 没报错即是成功
[backcolor=rgba(0, 0, 0, 0.7)]之后需要下载Frida-server
https://github.com/frida/frida/releases/download/12.0.8/frida-server-12.0.8-android-x86.xz 即可 并改名为Frida-server
2.调试Frida
终端(CMD)输入以下命令
adb devices
这样就成功了 接下来在输入以下命令 adb root
adb push Frida-server /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/Frida-server"
adb shell "/data/local/tmp/Frida-server &"
此处注意 frida server开启后不要关闭 另起窗口执行其他命令
之后再输入 frida-ps -U
一切OK 这样frida就可以 用了
3.分析APK的calc&code
APK下载地址:https://github.com/ctfs/write-ups-2015/tree/master/seccon-quals-ctf-2015/binary/reverse-engineering-android-apk-1
目标:Please win 1000 times in rock-paper-scissors
3.1 分析APK
windows将APK拖进Android Killer即可
MAC 需要安装Android Crack Tool
得到MainActivity代码
[Java] 纯文本查看 复制代码 public class MainActivity
extends Activity
implements View.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 localTextView = (TextView)MainActivity.this.findViewById(2131492946);
MainActivity localMainActivity;//可以看出赢了cnt值加一 平手和输了都归零 cnt=999 即可成功
if (MainActivity.this.n - MainActivity.this.m == 1)//if (MainActivity.this.m - MainActivity.this.n == 1) 结合下面m=0,1,2 推断我们需要m,n得什么值
{
localMainActivity = MainActivity.this;
localMainActivity.cnt += 1;
localTextView.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
}
for (;;)
{
if (1000 == MainActivity.this.cnt) {//calc()算法 可以通过这个直接获取到成功结果 通过IDA分析 可以知道 MainActivity.this.calc() 返回固定int值7
//最终结果 “107749"正确答案 后面说IDA分析 (1000+7)*107
localTextView.setText("SECCON{" + String.valueOf((MainActivity.this.cnt + MainActivity.this.calc()) * 107) + "}");
}
MainActivity.this.flag = 0;
return;
if (MainActivity.this.m - MainActivity.this.n == 1)
{
MainActivity.this.cnt = 0;
localTextView.setText("LOSE +0");
}
else if (MainActivity.this.m == MainActivity.this.n)
{
localTextView.setText("DRAW +" + String.valueOf(MainActivity.this.cnt));
}
else if (MainActivity.this.m < MainActivity.this.n)
{
MainActivity.this.cnt = 0;
localTextView.setText("LOSE +0");
}
else
{
localMainActivity = MainActivity.this;
localMainActivity.cnt += 1;
localTextView.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
}
}
}
};
static
{
System.loadLibrary("calc");
}
public native int calc();
public void onClick(View paramView)
{
if (this.flag == 1) {}
for (;;)
{
return;
this.flag = 1;
((TextView)findViewById(2131492946)).setText("");
TextView localTextView2 = (TextView)findViewById(2131492944);
TextView localTextView1 = (TextView)findViewById(2131492945);
this.m = 0;
this.n = new Random().nextInt(3);//随机三个数 代表剪刀石头布//m代表玩家 n代表电脑
int i = this.n;
localTextView1.setText(new String[] { "CPU: Paper", "CPU: Rock", "CPU: Scissors" }[i]);//n值定电脑出什么
if (paramView == this.P)
{
localTextView2.setText("YOU: Paper");
this.m = 0;
}
if (paramView == this.r)
{
localTextView2.setText("YOU: Rock");
this.m = 1;
}
if (paramView == this.S)
{
localTextView2.setText("YOU: Scissors");
this.m = 2;
}
this.handler.postDelayed(this.showMessageTask, 1000L);//判断是否获胜达到 1000次 showMessageTask()为主要方法
}
}
protected void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2130968600);
this.P = ((Button)findViewById(2131492941));
this.S = ((Button)findViewById(2131492943));
this.r = ((Button)findViewById(2131492942));
this.P.setOnClickListener(this);
this.r.setOnClickListener(this);
this.S.setOnClickListener(this);
this.flag = 0;
}
}
IDA 分析libcalc.so
calc得7
4.HOOK APK
4.1HOOK模块
[Python] 纯文本查看 复制代码 import frida, sys
//hook代码,采用javascript编写
jscode = """
//填写javascript代码
Java.perform(function () {
//定义变量MainActivity,Java.use指定要使用的类
var MainActivity = Java.use('包名.MainActivity');
//hook该类下的onCreate方法,重新实现它
MainActivity.onCreate.implementation = function () {
//填写实现方法
}
});
"""
//自定义回调函数
def on_message(message, data):
if message['type'] == 'send':
print(" {0}".format(message['payload']))
else:
print(message)
process = frida.get_usb_device().attach('应用完整包名')//包名通过frida-ps -U获得
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()
4.2HOOK实现
我们只要让cnt=1000 一直赢 就成功了
先来看看条件 首先从上面的代码可以看到 只有win cnt才加一 其他都不加 那我们一直赢不就好了
[Java] 纯文本查看 复制代码 if (MainActivity.this.n - MainActivity.this.m == 1)
{
localMainActivity = MainActivity.this;
localMainActivity.cnt += 1;
localTextView.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
}
for (;;)
{
if (1000 == MainActivity.this.cnt) {
localTextView.setText("SECCON{" + String.valueOf((MainActivity.this.cnt + MainActivity.this.calc()) * 107) + "}");
}
MainActivity.this.flag = 0;
return;
if (MainActivity.this.m - MainActivity.this.n == 1)
{
MainActivity.this.cnt = 0;
localTextView.setText("LOSE +0");
}
else if (MainActivity.this.m == MainActivity.this.n)
{
localTextView.setText("DRAW +" + String.valueOf(MainActivity.this.cnt));
}
else if (MainActivity.this.m < MainActivity.this.n)
{
MainActivity.this.cnt = 0;
localTextView.setText("LOSE +0");
}
else
{
localMainActivity = MainActivity.this;
localMainActivity.cnt += 1;
localTextView.setText("WIN! +" + String.valueOf(MainActivity.this.cnt));
}
从这一段代码可以分析出要想一直赢 那么成立的条件为m=0 n=1 cnt=999
那我们只要修改m , n的值
[Java] 纯文本查看 复制代码 public void onClick(View paramView)
{
if (this.flag == 1) {}
for (;;)
{
return;
this.flag = 1;
((TextView)findViewById(2131492946)).setText("");
TextView localTextView1 = (TextView)findViewById(2131492944);
TextView localTextView2 = (TextView)findViewById(2131492945);
this.m = 0;
this.n = new Random().nextInt(3);
int i = this.n;
localTextView2.setText(new String[] { "CPU: Paper", "CPU: Rock", "CPU: Scissors" }[i]);
if (paramView == this.P)
{
localTextView1.setText("YOU: Paper");
this.m = 0;
}
if (paramView == this.r)
{
localTextView1.setText("YOU: Rock");
this.m = 1;
}
if (paramView == this.S)
{
localTextView1.setText("YOU: Scissors");
this.m = 2;
}
this.handler.postDelayed(this.showMessageTask, 1000L);
}
}
那么需要hook onClick(View paramView)方法
[Python] 纯文本查看 复制代码 import frida, sys
def on_message(message, data):
if message['type'] == 'send':
print("[/i][i] {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()
ok 了 成功获取
有木有更简单的方法呢 显然是有的
[Java] 纯文本查看 复制代码 if (1000 == MainActivity.this.cnt) {
localTextView.setText("SECCON{" + String.valueOf((MainActivity.this.cnt + MainActivity.this.calc()) * 107) + "}");
}
我们可以看到 假设直接hook calc()方法获取返回值 直接计算得到SECCON 完全可以
[Java] 纯文本查看 复制代码
jscode = """
Java.perform(function () {
var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
MainActivity.onCreate.implementation = function () {
var returnValue = this.calc();
var result = (1000+returnValue)*107;
console.log("returnValue :" returnValue, "resullt :" resullt )
}
});"""
就这样了 就不贴图了
如有什么讲的不妥的 地方 还请多多包涵
毕竟码了这么多字 给个评分 好不好
|
评分
-
参与人数 28 | 威望 +1 |
HB +131 |
THX +16 |
收起
理由
|
禽大师
| |
+ 1 |
|
|
猫妖的故事
| |
+ 1 |
|
|
longge188
| |
|
+ 1 |
[吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少! |
attackmyth
| |
|
+ 1 |
[吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守! |
magicwk
| |
+ 1 |
|
|
消逝的过去
| |
+ 2 |
|
|
冷亦飞
| |
+ 1 |
|
|
l278785481
| |
+ 1 |
|
|
小菜虫
| |
+ 1 |
|
|
temp
| |
+ 1 |
+ 1 |
|
fjgh
| |
+ 2 |
+ 1 |
[吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守! |
嘿嚯哈
| |
+ 2 |
+ 1 |
|
在天一方
| |
+ 2 |
|
[吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少! |
我是小垃圾
| |
+ 2 |
+ 1 |
[吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意! |
bnjzzheng
| |
|
+ 1 |
[吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩! |
成丰羽
| |
+ 1 |
|
[吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意! |
阿桂哥
| |
|
+ 1 |
[吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意! |
6378895
| |
+ 1 |
+ 1 |
[吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩! |
dhway
| |
|
+ 1 |
|
CraftDeadMRC
| |
|
+ 1 |
|
lies
| |
+ 1 |
|
|
Klop1314
| |
+ 1 |
|
[快捷评语]--吃水不忘打井人,给个评分懂感恩! |
cxp521
| |
+ 1 |
+ 1 |
偶然间看到,好贴啊 |
爆脾气
| |
+ 1 |
+ 1 |
[快捷评语] - 吃水不忘打井人,给个评分懂感恩! |
曲水有情
| |
+ 1 |
|
[快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品! |
李沉舟
| |
+ 6 |
+ 1 |
[快捷评语] - 2018,狗年发发发,狗年旺旺旺! |
CwithW
| |
+ 1 |
+ 1 |
[快捷评语] - 2018,狗年发发发,狗年旺旺旺! |
Shark恒
| + 1 |
+ 100 |
+ 1 |
[快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品! |
查看全部评分
|