Android主流HOOK框架介绍与应用--游戏破解游戏外挂的必杀技
概述
XPOSED
findAndHookMethod("com.tencent.mm.sdk.platformtools.be", lpparam.classLoader, "tx", int.class, new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param) {int gameType = ((Integer) param.args[0]).intValue();switch (gameType) {case 5:
//投骰子游戏,强制返回最大点数,基数为0,所以返回5param.setResult(5);default:}}
});
frida
package com.wepie.snake.module.game;private void initEntity()
{GameConfig.factor = 1.0F;SnakeSurfaceView.access$102(SnakeSurfaceView.this, SnakeFactory.creatSnakeSelf(LoginHelper.getLoginUser().nickname, 5, null));SnakeSurfaceView.access$1102(SnakeSurfaceView.this, new AiManager(SnakeSurfaceView.this.snakeInfo));SnakeSurfaceView.this.allSnakes.clear();SnakeSurfaceView.this.allSnakes.add(SnakeSurfaceView.this.snakeInfo);SnakeSurfaceView.this.allSnakes.addAll(SnakeSurfaceView.this.aiManager.snakeAis);initUtils();
}
public static SnakeInfo creatSnakeSelf(String paramString, int paramInt, MultiNode paramMultiNode)
{int i = SkinConfig.getInUserSkinId();SkinInfo localSkinInfo = SkinManager.getInstance().getSkin(i);paramString = new SnakeInfo(paramString, localSkinInfo, paramMultiNode);Log.i("999", "----->creatSnakeSelf skin_id=" + localSkinInfo.skin_id);paramString.bodyInfo.initBodyPoints(getBodyPoints(paramString, 0.0F, 0.0F, paramInt));return paramString;
}
private void doSnakeDie(final SnakeInfo snakeInfo, final SnakeInfo snakeInfo2) {if (snakeInfo.snakeStatus.superFrameCount <= 0 && (snakeInfo2 == null || snakeInfo2.snakeStatus.superFrameCount <= 0)) {this.extraFactory.addWrecks(snakeInfo);if (!snakeInfo.isSnakeAi) {((SnakeSurfaceView.GameStatusCallback)this.gameStatusCallback).onGameOver();}else if (snakeInfo2 != null) {snakeInfo2.addKillNum();if (!snakeInfo2.isSnakeAi) {((SnakeSurfaceView.GameStatusCallback)this.gameStatusCallback).onKillAi();}}snakeInfo.doDie();return;}
}
#coding:utf-8import frida, sysdef on_message(message, data):if message['type'] == 'send':print("[*] {0}".format(message['payload']))else:print(message)jscode = """
Java.perform(function () {var curSnake = null;// Function to hook is defined herevar SnakeFactory = Java.use('com.wepie.snake.module.game.snake.SnakeFactory');// Whenever creatSnakeSelf is calledSnakeFactory.creatSnakeSelf.implementation = function (name, len, multiNode) {// Show a message to know that the function got calledsend('creatSnakeSelf');len = 50;// Call the original creatSnakeSelfcurSnake = this.creatSnakeSelf(name, len, multiNode);// Log to the console that it's doneconsole.log('Done: init snake len: ' + JSON.stringify(len) + " name: " + name+ " my snake: " + curSnake.toString() + ' isSnakeAi: ' + curSnake.isSnakeAi.value);return curSnake;};var CollisionUtil = Java.use('com.wepie.snake.module.game.snake.CollisionUtil');CollisionUtil.doSnakeDie.implementation = function (snake1, snake2) {// Show a message to know that the function got calledif (snake1.equals(curSnake) || snake1.isSnakeAi.value == false){console.log('snake1 isSnakeAi: ' + snake1.isSnakeAi.value + " snake1: " + snake1.toString());// Log to the console that it's doneconsole.log('Done: my snake will not die!');return;}else{// Call the original doSnakeDiereturn this.doSnakeDie(snake1, snake2);}};});
"""process = frida.get_usb_device().attach('com.wepie.snake')
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read()
substrate
static void OnCallback_ClassOnCreate(JNIEnv *jni, jobject activity, jobject bundle)
{string strName;strName = getObjectClassName(jni, activity);LOGD("[%s] begin: %s::OnCreate", __FUNCTION__, strName.c_str());(*old_onCreate)(jni, activity, bundle);LOGD("[%s] dynamic load plug apk: %s", __FUNCTION__, g_cfg.strPlugApkPath.c_str());……//调用插件的静态函数init,原型:public static void init(Activity activity, String soPath)jmethodID plugUIinit = jni->GetStaticMethodID(plugClass, "init", "(Landroid/app/Activity;Ljava/lang/String;)V");if ( plugUIinit==NULL ) {LOGE("[%s] not found \"init\" in plug activity: public static void init(Activity activity, String soPath)", __FUNCTION__);}else{LOGD("[%s] invoke %s::init", __FUNCTION__, g_cfg.strPlugActivity.c_str());jstring soPath = jni->NewStringUTF(g_cfg.strPlugSoPath.c_str());jni->CallStaticVoidMethod(plugClass, plugUIinit, activity, soPath);}LOGD("[%s] end", __FUNCTION__);
}
但是C++写起来开发效率比较低,出错了也不容易排查。上面的JNI代码用java代码写起来就非常轻松:
String dexOutputDir = "/data/data/" + targetPackageName + "/cache";
DexClassLoader dexClassLoader = new DexClassLoader(plugApkPath, dexOutputDir, null, ClassLoader.getSystemClassLoader());
java.lang.Class<?> plugClass = dexClassLoader.loadClass(plugInitClass);
Method mInit = plugClass.getDeclaredMethod(Constant.METHOD_NAME_plug_init, Activity.class, String.class);
mInit.invoke(null, param.thisObject, plugSoPath);
但是并不是意味着就不用写JNI代码了,有时候是必须在SO底层做HOOK的。这个应用场景主要在破解逆向分析、脱壳上比较有用,前期的JNI代码写的很是痛苦,编译一次手机需要重启,而且一旦出错并不是那么容易排查,但是框架搭建好后,以后再需要只要HOOK对应的NDK层函数即可。
总结
Android主流HOOK框架介绍与应用--游戏破解游戏外挂的必杀技相关推荐
- 2018年android常用的框架介绍
转载地址:http://blog.csdn.net/RuingMan/article/details/73546718 http://www.cnblogs.com/jincheng-yangchao ...
- 如何写一个Android inline hook框架
Android_Inline_Hook https://github.com/GToad/Android_Inline_Hook_ARM64 有32和64的实现,但是是分离的,要用的话还要自己把两份代 ...
- 主流webgis框架介绍与对比
概述 想写本文,主要是源于前两天有个老师找到我说让我录一个大概半个小时的视频,跟大家分享一下各webgis框架之间的区别以及在应用的过程中应该如何选择.其实之前也有学员问过类似的问题,当时只是针对他们 ...
- 【Unity游戏破解】外挂原理分析
文章目录 认识unity 打包目录结构 游戏逆向流程 Unity游戏攻击面 可被攻击原因 mono的打包 建议方案 锁血 飞天 无限金币 攻击力翻倍 以上统称内存挂 透视 自瞄 压枪 瞬移 内购破解 ...
- Android GUI系统框架介绍
这个又是内部技术分享时准备的PPT,Android GUI框架是一个非常庞大的系统,也是Android最重要的系统之一,其决定了一个Android界面究竟如何显示出来,显示效果/效率怎样,也一直是An ...
- Android显示系统设计框架介绍
1. Linux内核提供了统一的framebuffer显示驱动,设备节点/dev/graphics/fb*或者/dev/fb*,以fb0表示第一个显示屏,当前实现中只用到了一个显示屏. 2. Andr ...
- android主流技术框架,android开发现在流行什么IDE和开发框架?
慕仙森 idea, AS (android studio), adt, 其中 AS 是google 非常推荐的.看官网就知道了. 框架的话: xutils , andbase , volley等等,还 ...
- Android系统Audio框架介绍(一)
原址 音频基础知识 声音有哪些重要属性呢? 响度(Loudness) 响度就是人类可以感知到的各种声音的大小,也就是音量.响度与声波的振幅有直接关系. 音调(Pitch) 音调与声音的频率有关系,当声 ...
- Android系统Audio框架介绍
音频基础知识 声音有哪些重要属性呢? 响度(Loudness) 响度就是人类可以感知到的各种声音的大小,也就是音量.响度与声波的振幅有直接关系. 音调(Pitch) 音调与声音的频率有关系,当声音的频 ...
最新文章
- Java并发编程的艺术(二)——重排序
- JavaScript学习记录总结(四)——js函数的特殊性
- Help:立体图绘制以及根据X,Y,Z三坐标值,在图上描点
- Hadoop下如何执行脚本
- html 替换反斜杠,在URL直接替换反斜杠反斜杠
- C++ std::vector 自定义排序
- java标点符号用什么意思_标点符号的使用我说他说XX说后面在什么情况下加逗号、冒号、冒号双引号、双引号或者逗号双引号等的区分问题请详细说明谢谢...
- 编译错误:invalid types ‘int[int]‘ for array subscrip-markdown编辑器
- Photoshop技术学习有感
- js页面跳转 URL含中文造成乱码
- 基于滴滴云搭建安全稳定的 Memcached 服务器
- 新网站如何提升排名?网站排名提升的优化技巧分享
- iOS 组件中设置文件支持MRC
- codeup之沙漏图形
- Windows 10下视频播放器泛黄,颜色太暖、太亮
- 拆t420s屏轴,T430S T420S 拆机详解LED改高分IPS 1920*1080,拆机注意事项,机友福利
- 圆形标定板_一种圆阵列标定板特征点提取方法与流程
- #即时通讯#实现消息已读回执功能的思路与实现
- Kepware的完美替代者
- yum 安装mysql 5.7
热门文章
- getopt()函数
- java 读取zip文件_JAVA实现zip文件内容读取及解压
- [0x7FFE1E17E050] ANOMALY: meaningless REX prefix used cmd窗口activate报错
- MATLAB App Designer入门实战(一)
- 【实时语音转文本】PC端实时语音转文本(麦克风外音系统内部音源)
- 铁通计算机网络,【计算机网络技术】常见宽带错误代码及处理办法(使用移动宽带【铁通】、部分电信宽带故障、联通宽带故...
- 建网站如何选择空间?
- windows防火墙是干什么的_请教个人防火墙是做什么用的,
- 使用Matlab工具箱(procamcalib)进行投影仪标定---超详细过程
- iview表格中,鼠标滑过单元格展示提示信息