FridaHook框架学习(2)

前言

学习过程参考https://bbs.pediy.com/thread-227233.htm。

逆向分析

安装并运行例子程序,可以看到这个例子是一个验证注册码的程序。

使用jadx解析这个APK。

通过类名以及AndroidManifest可以猜测以及知道LauncherActivity是这个程序的启动类。先看看LauncherActivity的代码。

public class LauncherActivity extends AppCompatActivity {
/* access modifiers changed from: protected */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView((int) R.layout.activity_launcher);
} public void verifyClick(View v) {
try {
InputStream in = new URL("http://broken.license.server.com/query?license=" + ((EditText) findViewById(R.id.text_license)).getText().toString()).openConnection().getInputStream();
StringBuilder responseBuilder = new StringBuilder();
byte[] b = new byte[0];
while (in.read(b) > 0) {
responseBuilder.append(b);
}
String response = responseBuilder.toString();
if (response.equals("LICENSEKEYOK")) {
String activatedKey = new String(MainActivity.xor(getMac().getBytes(), response.getBytes()));
SharedPreferences.Editor editor = getApplicationContext().getSharedPreferences("preferences", 0).edit();
editor.putString("KEY", activatedKey);
editor.commit();
new AlertDialog.Builder(this).setTitle((CharSequence) "Activation successful").setMessage((CharSequence) "Activation successful").setIcon(17301543).show();
return;
}
new AlertDialog.Builder(this).setTitle((CharSequence) "Invalid license!").setMessage((CharSequence) "Invalid license!").setIcon(17301543).show();
} catch (Exception e) {
new AlertDialog.Builder(this).setTitle((CharSequence) "Error occured").setMessage((CharSequence) "Server unreachable").setNeutralButton((CharSequence) "OK", (DialogInterface.OnClickListener) null).setIcon(17301543).show();
}
} private String getKey() {
return getApplicationContext().getSharedPreferences("preferences", 0).getString("KEY", "");
} private String getMac() {
try {
return ((WifiManager) getApplicationContext().getSystemService("wifi")).getConnectionInfo().getMacAddress();
} catch (Exception e) {
return "";
}
} public void showPremium(View view) {
Intent i = new Intent(this, MainActivity.class);
i.putExtra("MAC", getMac());
i.putExtra("KEY", getKey());
startActivity(i);
}
}

可以通过方法名猜测verifyClick方法应该就是VERIFY按钮的点击事件,showPremium应该就是另一个按钮的点击事件。可以看到程序的逻辑大概为通过网络验证license的正确性,若正确就调用MainActivity的xor方法通过MAC和response生成密钥并保存在本地的preference中。

其中InputStream是Java一个用于读取流的类。SharedPreferences是一个类似Python中字典的一种数据结构。

再来看看MainActivity的代码

public class MainActivity extends AppCompatActivity {
public native String stringFromJNI(String str, String str2); public static byte[] xor(byte[] val, byte[] key) {
byte[] o = new byte[val.length];
for (int i = 0; i < val.length; i++) {
o[i] = (byte) (val[i] ^ key[i % key.length]);
}
return o;
} public void onCreate(Bundle savedInstanceState) {
String key = getIntent().getStringExtra("KEY");
String mac = getIntent().getStringExtra("MAC");
if (key == "" || mac == "") {
key = "";
mac = "";
}
super.onCreate(savedInstanceState);
setContentView((int) R.layout.activity_main);
((TextView) findViewById(R.id.sample_text)).setText(stringFromJNI(key, mac));
} static {
System.loadLibrary("native-lib");
}
}

可以看到显示flag的函数写在了So中,通过密钥KEY和MAC生成。

可以得到Hook思路:Hook getKey方法直接使用MAC和LICENSEOK构造密钥并返回,之后点击PREMIUMCONTENT按钮即可

Hook代码编写

import frida
import sys jscode = """
Java.perform(function(){ function stringToBytes(str){
var javaString = Java.use('java.lang.String');
var bytes = [];
bytes = javaString.$new(str).getBytes();
return bytes;
} function bytesToString(bytes){
var javaString = Java.use('java.lang.String');
return javaString.$new(bytes);
} var launcheractivity = Java.use('de.fraunhofer.sit.premiumapp.LauncherActivity');
var main = Java.use('de.fraunhofer.sit.premiumapp.MainActivity');
var license = "LICENSEKEYOK";
launcheractivity.getKey.implementation = function() {
var mac = this.getMac(); var macbyte = stringToBytes(mac);
var licensebyte = stringToBytes(license); var xor = main.xor(macbyte,licensebyte);
send(xor)
var key = bytesToString(xor);
send(key.toString());
return key;
} launcheractivity.verifyClick.implementation = function(v) {
this.showPremium(v);
}
});
""" def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message) process = frida.get_usb_device().attach('de.fraunhofer.sit.premiumapp')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()

运行结果

总结

编写js代码的时候是真的累,因为要写在字符串里,没法自动补全,有些变量名就打错了,还全部都是绿绿的很难看出来,终于也看懂了一点js的报错才找出来了。Js中可以通过Java.use使用Java中的一些基类用于灵活转换类型。

FridaHook框架学习(2)的更多相关文章

  1. FridaHook框架学习(1)

    FridaHook框架学习(1) 前言 本次学习过程参考https://bbs.pediy.com/thread-227232.htm Frida安装与使用 Windows端安装 pip instal ...

  2. IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API

    IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习之保护API. 使用IdentityServer4 来实现使用客户端凭据保护ASP.N ...

  3. Hadoop学习笔记—18.Sqoop框架学习

    一.Sqoop基础:连接关系型数据库与Hadoop的桥梁 1.1 Sqoop的基本概念 Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据移植过去并不容易.Apache Sqoop正在加 ...

  4. Spring框架学习一

    Spring框架学习,转自http://blog.csdn.net/lishuangzhe7047/article/details/20740209 Spring框架学习(一) 1.什么是Spring ...

  5. EF框架学习手记

    转载: [ASP.NET MVC]: - EF框架学习手记 1.EF(Entity Framework)实体框架EF是ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架 ...

  6. web框架学习列表

    转载自鲁塔弗的博客,原文网址:http://lutaf.com/148.htm web framework层出不穷,特别是ruby/python,各有10+个,php/java也是一大堆 根据我自己的 ...

  7. 2013 最新的 play web framework 版本 1.2.3 框架学习文档整理

    Play framework框架学习文档 Play framework框架学习文档 1 一.什么是Playframework 3 二.playframework框架的优点 4 三.Play Frame ...

  8. SSH 框架学习之初识Java中的Action、Dao、Service、Model-收藏

    SSH 框架学习之初识Java中的Action.Dao.Service.Model-----------------------------学到就要查,自己动手动脑!!!   基础知识目前不够,有感性 ...

  9. 各种demo——CI框架学习

    各种demo——CI框架学习   寒假学习一下CI框架,请各位多多指教! 一.CI的HelloWorld! 注意:CI禁止直接通过文件目录来访问控制器. ./application/controlle ...

随机推荐

  1. [LeetCode]690. Employee Importance员工重要信息

    哈希表存id和员工数据结构 递归获取信息 public int getImportance(List<Employee> employees, int id) { Map<Integ ...

  2. 5.汇编实现裸机LED

    首先:操作LED就要操作GPIO  alpha的芯片是NXP的IMX6ULL  其GPIO和STM32的命名有所区别 可以看到IMX6ULL的GPIO以其功能进行命名,对应上图中PAD之后的部分 即G ...

  3. ThreadX应用笔记:内核初始化和任务调度

    作者:zzssdd2 E-mail:zzssdd2@foxmail.com 一.前言 了解ThreadX的初始化流程有助于移植使用,掌握任务的的调度有助于更加得心应手地运用该实时操作系统. 二.初始化 ...

  4. Spring Boot 计划任务中的一个“坑”

    计划任务功能在应用程序及其常见,使用Spring Boot的@Scheduled 注解可以很方便的定义一个计划任务.然而在实际开发过程当中还应该注意它的计划任务默认是放在容量为1个线程的线程池中执行, ...

  5. 为什么.NET Standard 仍然有意义?

    .NET Standard 是.NET 官方的API规范,可在许多.NET环境中使用.之所以存在,面向.NET Standard 2.0的库提供了最大可能的覆盖范围,并启用了几乎所有现代的.NET功能 ...

  6. Laya 踩坑日记-人物模型穿模,模型显示不正常

    最近做游戏,人物要跑到很远的位置,z轴距离大概有20000个单位,然后就发现一个bug,到远处人物模型穿了,而且没办法改,这就尴尬了 Z轴对应值    0    100000 100000 当距离零点 ...

  7. 【剑指 Offer】08.二叉树的下一个节点

    题目描述 给定一颗二叉树和其中的一个节点,找出中序遍历序列的下一个节点.树中的节点除了有两个分别指向左右节点的指针,还有一个指向父节点的指针. Java public class Solution08 ...

  8. 【Flutter】功能型组件之跨组件状态共享

    前言   在Flutter开发中,状态管理是一个永恒的话题.   一般的原则是:如果状态是组件私有的,则应该由组件自己管理:如果状态要跨组件共享,则该状态应该由各个组件共同的父元素来管理.   对于组 ...

  9. 【Linux】centos7中 root家目录中perl5文件夹无法删除问题解决

    由于新项目上线,安装了一些perl的一些包 但是发现,在/root下有一个perl5/的文件夹,删除后,重新登录又会出现,很是烦人,而且他还没有内容,就是一个空文件 那么着手搞掉他 环境:centos ...

  10. Leetcode53. 最大子序列和

    问题 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 代码 贪心算法 核心思想就是检查之前 i-1 的元素和,如果小于零就舍弃--对应下面第六行 ...