简介
手游市场的发展增大,用户增多,寻求外挂的玩家用户增大,外挂市场也意识到外挂开发者在大量的涌进,绝大多数开发者有着编程的基础,都能够写点脚本开发外挂,那么商人们就开始着手底层,通过找寻到的“专业人士”开发底层框架,提供接口供上层开发者调用,把逻辑的实现交给他们。
遇到了一个框架类定制的外挂,外挂作者通过该框架实现了一套自动化点击的脚本,完全无需人工进行操作。这类方式的实现,将底层深入的原理实现进行了封装,最后以API的形式提供给玩家,玩家仅需要一定的编程基础便可以掌握进行二次开发。
原理分析
深入分析该框架类软件,发现它使用ROOT权限启动了一个疑似输入的可执行文件,从该路径下提取该可执行文件进行分析,从中找到了它使用app_process命令执行了一个名为input.jar的文件。
以下为IDA解析出来的伪代码,作为参考。
int sub_80DC()
{
const char *v0; // r0
int v2; // [sp+0h] [bp-28h]
char v3; // [sp+8h] [bp-20h]
char v4; // [sp+10h] [bp-18h]
char v5; // [sp+18h] [bp-10h]
sub_7FC0();
sub_2EB6(&v2);
sub_2EB6(&v3);
sub_2EB6(&v4);
sub_2E6C((int)&v3, "export CLASSPATH=/sdcard/input.jar;");
sub_2E6C((int)&v4, "app_process /sdcard com.android.commands.input.Input $@ ");
sub_3234((int)&v5, &v3, &v4);
sub_2DD8(&v2, &v5);
sub_2C50(&v5);
v0 = (const char *)sub_2D9A(&v2, 0);
system(v0);
sub_2C50(&v4);
sub_2C50(&v3);
sub_2C50(&v2);
return 0;
}
使用工具打开jar包查看,代码没有混淆,很轻易的就找到了关键的实现函数(具体实现原理可以参考https://blog.csdn.net/u011247544/article/details/77449412,这里提到过同样实现的方法):
private void injectMotionEvent(int arg28, int arg29, long arg30) {
int v7 = 0;
int v19;
for(v19 = 0; v19 < 5; ++v19) {
String v26 = Input.readObject("/sdcard/gginput.txt", v19 + "");
if(v26.indexOf(",") != -1) {
String[] v23 = v26.split(",");
float v24 = Float.parseFloat(v23[0]);
float v25 = Float.parseFloat(v23[1]);
MotionEvent$PointerProperties v22 = new MotionEvent$PointerProperties();
v22.id = v7;
v22.toolType = 0;
this.properties[v7] = v22;
MotionEvent$PointerCoords v21 = new MotionEvent$PointerCoords();
v21.x = v24;
v21.y = v25;
v21.pressure = 1f;
v21.size = 1f;
this.pointerCoords[v7] = v21;
++v7;
}
}
if(v7 >= 1) {
try {
MotionEvent v18 = MotionEvent.obtain(arg30, arg30, arg29, v7, this.properties, this.pointerCoords, 0, 0, 1f, 1f, 0, 0, arg28, 0);
System.out.println("injectMotionEvent: " + v18);
InputManager.getInstance().injectInputEvent(v18, 2);//关键点
}
catch(Throwable v20) {
System.out.println("injectMotionEvent err ...");
}
}
}
通过jar包实现了模拟点击,与上层使用socket和其他进程进行通信,用户通过lua脚本控制代码逻辑,整个框架流程大致如此。