一、前言

  烧饼游戏修改器是一款元老级的游戏修改器,提供了精确搜索、模糊搜索、联合搜索、数据过滤、存储搜索与读取搜索等功能。主要实现搜索手机进程的内存数据并做相应修改。

  本文中分析的版本为2.0.2(34),SDK:8,TargetSDK:17,代码经过混淆,修改器基本使用方法为输入需要修改的数据进行查询,查询结果少则可直接修改,查询结果多则需要返回游戏,使想修改的数据发生变化后再次搜索,最后根据数据变化偏移找到需要修改的地址。输入想要修改成的数据即可修改。

  本程序测试机为LG Nexus 5,版本为Android 4.4,运行程序前需先root手机。

  系统环境:Java 1.8.0_92 ,Android Debug Bridge version 1.0.36

  使用工具:AndroidKiller、JEB、Eclipse、IDA

二、详细分析

2.1 关于smali注入代码的说明

  为了便于分析,本文中涉及向工程中注入smali代码并重新打包运行,对常用的注入代码做如下说明。其中使用到的寄存器vn要根据实际代码使用的寄存器个数来做相应修改。如图2-1中的run()中“.locals 5”申明使用了5个寄存器,即v0~v4,如果我们需要插入一条日志信息,为了不影响原来代码的执行,需要自己增加一个寄存器v5,先将“.locals 5”变成“.locals 6”,再用v5来保存日志信息。

图2-1 Smali代码中对寄存器的说明

2.1.1 log信息输出


const-string vn, "提示语"

invoke-static {vn}, Lcom/android/killer/Log;->LogStr(Ljava/lang/String;)V


图2-2 Log信息输出

2.1.2 打印字符型数据


const-string vn, "string数据"

invoke-static {vn, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I


图2-3 打印字符数据

2.1.3 打印整型数据


const-string vn, "int数据"

invoke-static {v1}, Ljava/lang/Integer;->toString(I)Ljava/lang/String;

move-result-object v(n+1)

invoke-static {vn, v(n+1)},Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I


图2-4 打印整型数据

2.1.4 打印boolean型数据


const-string vx, "boolean数据"

invoke-static {p1}, Ljava/lang/Boolean;->toString(Z)Ljava/lang/String;

move-result-object v(x+1)

invoke-static {vx, v(x+1)}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I


图2-5 打印boolean型数据

2.1.5 栈追踪


new-instance vn, Ljava/lang/Exception;

const-string v(n+1),"这里是 trace"

invoke-direct{vn,v(n+1)},Ljava/lang/Exception;-><init>(Ljava/lang/String;)V

invoke-virtual{v(n+1)},Ljava/lang/Exception;->printStackTrace()V


图2-6 栈追踪

2.1.6 toast输出


const-string v0, "这里是Toast输出"

const/4 v1, 0x1

invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

move-result-object v0

invoke-virtual {v0}, Landroid/widget/Toast;->show()V


图2-7 Toast输出

2.1.7 加载so库


const-string v0, "这里是Toast输出"

const/4 v1, 0x1

invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

move-result-object v0

invoke-virtual {v0}, Landroid/widget/Toast;->show()V


图2-8 加载so库

2.2 Java层代码分析

2.2.1 加载的so文件

  用AndroidKiller打开该apk,得到反编译之后的工程,如图2-9。

图2-9 反编译之后的apk工程目录

  查看AndroidMainfest.xml,如图2-10,可以看到应用程序包名为“org.sbtools.gamehack”,程序主活动为“MainActivity”,还可以看到服务名为“org.sbtools.gamehack.sesrvice.FlowServ”。

图2-10 AndroidMainfest.xml

  找到MainActivity.smali,其中onCreate方法如图2-11,在做一些布局工作后调用了a(),a()方法如图2-12,其主要工作为启用Instrumentation,通过Instrumentation框架,可以在主程序启动之前,创建模拟的系统对象,如Context;控制应用程序的多个生命周期;发送UI事件给应用程序;在执行期间检查程序状态等。从AndroidMainfest.xml中可以知道Instrumentation对应的方法为org.sbtools.gamehack.GameInstrumention。在Instrumentation中启用了服务,如图2-13。

图2-11 MainActivity.onCreate()

图2-12 MainActivity.a()

图2-13 启动服务

  在FlowServ中,发现该方法加载了Libencode.so,而在该方法中我们可以找到decode被声明为native(图2-14),想必能用到这个decode的地方一定是关键之处,于是在工程里搜索decode,发现在/d/i.smali中用到了decode,而decode上面出现了两个可疑文件(图2-15)。在工程中注入代码打印出string v1,打开eclipse, 在DDMS中打印出如图2-16的信息,可知将路径“/data/data/org.sbtools.gamehack/files/hack”和“/data/data/

org.sbtools.gamehack/files/gamehack”作为参数传给了decode(),随后在该类的a方法中运行了hack文件(图2-17),运行之后将该文件删除(图2-15)。

图2-14 Native程序加载

图2-15 调用decode的地方

图2-16 获取的path

图2-17 给hack文件赋予root权限

  这里的gamehack文件笔者未找到,IDA调试程序安装时显示Libdecode.so加载失败,因此按逻辑图2-7中的decode()执行失败,后面的hack文件不能执行,但以附加方式调试代码时候hack文件确实已经执行了,观察smali代码反应JEB翻译的java逻辑没有问题,猜测程序采用了一些反调试的手段,具体原因还待考究。

2.2.2 Socket消息传送

  打开该程序,搜索界面和搜索结果界面如图2-18、图2-19,我们有多种方法来了解执行搜索时候java层的执行逻辑,比如在AndroidKiller中搜索字符串“搜索”,找到其ID,逐层分析其流程,或从搜索结果入手,搜索找到“共搜索到%ld个数值,请选择修改”出现的地方,然后利用再smali代码中添加栈回溯语句来查看栈调用顺序。

图2-18 搜索界面

图2-19 搜索结果页面

  最后我们在ah类中找到程序对搜索消息的的设置(图2-20),最后发送的数据为“s [要搜索的数据] 标志位 0”,其中s表示正在进行搜索操作,当输入的搜索数据合法时,标志位为1。我们在这个方法中注入代码打印出发送的消息,发送的消息如图2-21所示。

图2-20 设置搜索消息

图2-21 发送的消息

  那么现在问题来了,这些消息发送给了谁?又是谁来接收这些搜索指令呢?分析到这里,之前提到的hack文件的功能就可想而知了。

2.3 Hack文件分析

2.3.1 获取hack文件

  那么这个hack文件具体做了些什么呢?为了进一步分析我们需要先提取该hack文件。打开adb shell,进入该文件所在目录,但是ls命令并未查看到,文件显然已经被删掉了。(图2-22)

图2-22 adb shell未查找到文件

  此时我们有两种方法来找到该hack文件:

  方法一:找到删除文件的smali代码,注释掉删除文件的代码,重新打包运行。之后用adb pull /data/data/org.sbtools.gamehack/files/hack D://命令将文件拷贝到本地计算机。注释掉的代码如图2-23、图2-24所示。

图2-23 注释掉的代码1

图2-24 注释掉的代码2

  方法二:linux系统中每一个进程都有一个/proc/[pid]目录,该目录下保存着有关该进程的各类信息,其中有个文件名为exe,这个文件是一个链接指向该进程的实际可执行文件。用命令ps |grep gamehack找到该进程ID为18912(图2-25),执行cd /proc/18912 进入到该进程信息目录,用ls –al会看到我们要找的文件。linux系统删除文件是使用了unlink这个函数,这个函数只会减少某个文件的硬连接数,当某个文件被打开后,并调用unlink删除该文件时,使用ls命令是不能查看到该文件了的,但这个文件实际上还是存在在磁盘上的,当使用该文件的进程结束时或者调用close关闭该文件描述符时,这个文件才真正的从磁盘上消失。因此,只要程序还在运行,该hack文件就不会被真正删除,将该文件拷贝到sdcard,再pull到计算机上(图2-26)。

图2-25 查看进程ID

图2-26 进入进程目录并提取文件

  接下来就可以对该文件进行分析了。

2.3.2 hack文件分析

  IDA加载提取出来的hack文件,查看导出表,只有一个start(),双击进入start(),F5之后如图2-27所示。

图2-27 start()启动函数

  在我重命名为“_HackWhat”的函数中,实现了该程序中最核心的功能。首先建立起socket连接,接收来自远端的数据,并根据第一个数据来决定后续要执行的操作(图2-28)。前面我们已经得出,当执行数据搜索的时候用字母“s”来表示,直接分析case s的代码(图2-29),可以发现在_DataMemory()中对接收到的数据做了一些处理,提取出需要搜索的数值,接着在_SearchData中读取进程内存信息进行搜索。

图2-28 接收socket数据

图2-29 搜索数据

  静态分析搜索部分的代码,可以看到程序首先用ptrace来attatch进程(图2-30),接着打开了进程内存映射信息所在的文件“/proc/[PID]/maps”并读取相关信息进行保存(图2-30)。

图2-30 Ptrace进程

图2-31 读取内存映射信息

  接下来程序读取进程内存信息“/proc/[PID]/mem”并保存。此处用于监测程序的内存映射信息是否发生变化。当在执行搜索操作时,程序实际上执行的为图所示的_SearchData函数,该函数在IDA中的偏移地址为0000A900。

图2-32 读取进程内存

图2-33 执行搜索

  在该函数中,同样先ptrace进程,读取内存信息并和之前保存的做一个比较,校验内存是否发生变化,接着从内存信息中搜索我们要修改的数据(图2-35、图2-36),而此处的具体逻辑还待深究,此处未作进一步描述。

图2-34 读取内存信息

图2-35 搜索数据a

图2-36 搜索数据b

  搜索完数据之后,执行图2-29中的_SendFindResult将搜索结果发送到远端,交给java层代码做接下来的处理。

  如果搜索结果太多,需要我们返回游戏,手动使想要修改的数据发生变化,然后重新搜索(图2-37)。此时发送的消息为“f = [Data]” (图2-38)。Hack程序收到socket信息后会提取变化之后的数字,再次执行图2-33中的_SearchData函数,不过此时会读取刚才搜索数字8之后的内存,检测哪一个内存保存的数值变为了12,据此来锁定想要修改的数据所在的内存。接着执行修改操作。

图2-37 变化数据

图2-38 第二次搜索时向socket发送的数据

  当点击修改之后,hack进程识别标志修改的字母“m”并执行如图2-39所示的操作流程。在对收到搜索命令做一系列提取等操作之后,ptrace注入进程并对相应内存地址的数据进行修改(图2-40),最后将修改结果发送给java层进行处理。

图2-39 修改数据a

图2-40 修改数据b

2.3.3 用IDA进行动态分析

  以上分析结合了静态分析和动态分析,用IDA对进程进行动态分析的步骤如下:

  1)    把IDA\dbgsrv目录下的android_server push到android中,命令:

    adb push  android_server /data/data/sv

  2)    adb shell进入该目录,为android_server赋755权限并以管理员权限运行。

cd /data/data/sv

chmod 755 android_server

su

./android_server

    成功运行之后可以看到监听端口为23946。.

  3)    在windows控制台下转发window到模拟器或手机端口。

    adb forward tcp:23946 tcp:23946

  4)    在IDA中选择android调试,在Debuggger 中的process options 的hostname 填上localhost。

  5)    在Debugger中的attach上选择对应的android程序即可。

  这里由于hack文件运行之后被删除了  因此需要注释掉删除文件的代码,重新编译运行之后才能attach上该进程。附加上该进程之后在IDA右侧的Modules窗格可以看到该文件基址为00008000,从刚才IDA加载的我们导出的hack文件中可以看到start偏移地址为00009010。两个地址相加即为该代码在elf文件中的实际地址,即00011010,我们在IDA中找到这个地址并下断。接着运行程序点击搜索,可以发现程序执行了如图所示的流程,在寄存器窗格中可以查看到存放接收数据的地址,Hex窗格中可以看到该地址下存放的数据。(图2-41)

图2-41 IDA动态加载hack程序——数据处理

  调试到图2-42所示的过程中发现程序在读取内存信息。

图2-42 读取内存

  搜索完数据之后对搜索结果进行处理,将处理之后的数据发送给远端(图2-43)。发送的信息如图2-44,其格式为“[内存地址]=[查找的数据]=[数据类型]”。

图2-43 处理搜索结果

图2-44 发送的数据

三、总结

  本文中分析的烧饼游戏修改器是一款经典的游戏修改器,之后时常出现的很多修改器和外挂都在其基础上衍生,对该游戏修改器进行分析能帮助学者素数掌握修改器和外挂的思路。通过这段时间的学习,收获如下:

  1)    掌握了逆向分析的大致流程和相关工具的使用;

  2)    对java语言有进一步了解;

  3)    熟悉了android框架及一些基础控件的使用;

  4)    熟悉了smali代码语法,能读懂smali代码,通过注入samli代码来调试程序;

  5)    掌握了IDA动态调试进程的方法;

  6)    对Native程序有了初步的认识。

  该apk是笔者分析的第一个android程序,由于没有相关分析经验,以及对工具和相关编程语言不熟悉,导致前期花费了大量时间在android编程学习和java层代码的分析上,没有抓住程序的关键点。针对本文中的游戏修改器的分析,尚有许多待完善之处:

  1)    程序读取完内存之后执行搜索操作的时候用的什么方法或函数来搜索尚不确定;

  2)    本文只对综合搜索进行了分析,对于修改器中提供的其他功能,如模糊搜索、深度搜索、联合搜索、反加密等还未做进一步分析。

  3)    对JNI还需深入学习。

  初次分析,难免有错误、不当和疏漏的地方,如有发现,还请指正,谢谢!

关于烧饼游戏修改器的分析相关推荐

  1. 游戏修改器的基本工作原理

    所谓游戏修改器,主要是通过修改游戏程序的内存数据或存盘文件来修改游戏中的相关数据,使之达到"无敌"等效果. 游戏修改器主要分为两类:单一游戏的修改器和通用游戏修改器.顾名思义,前者 ...

  2. root的游戏修改器,手游root修改器

    有什么好用的游戏修改器? 有<金山游侠>.<梦幻魔盒修改器>.<星云修改器>.<CE游戏修改器>. <金山游侠> 名称:金山游侠修改器下载v ...

  3. 游戏修改器、外挂原理

    修改内存. 通过一款第三方软件金山游侠2002便可以找到那些存储数据的地址,在我们玩游戏的过程中,通过单一变量法来分析某种属性的地址在哪里,比如说玩游戏的过程中生命全满然后保持其他不变将生命值减少然后 ...

  4. 单机游戏修改器——从计算机基础学科出发

     游戏修改器--从计算机基础学科出发 qq:610551883@qq.com 主要针对单机游戏.从操作系统层面对如何做进行了说明. 认识内存  图1所示的为某一代内存条的硬件示意图,任何与CPU打交道 ...

  5. 游戏修改器制作-黑客入门

    工具:SoftICE.金山游侠2002.VC++7.0.PE查看器.SPY++ 测试平台:Window2000 Professional SP2 首先我介绍一下将会用到的工具: 1. SoftICE( ...

  6. 利用cheat engine以及VC编写游戏修改器

    cheat engine的介绍已经完毕了,下面就是怎么使用它的问题,这里写一个稍微有意思一点的,也有实际用途的话题,就是来编写自己的游戏修改器. 这篇文章参考了http://www.pediy.com ...

  7. 打造自己的游戏修改器和内存补丁

    相信很多人打游戏的时候都用修改器,这里我介绍怎样用VB编写修改器. 1.其实修改器原理很简单,一般来说,在游戏运行的时候我们对游戏内存空间中必要的数据进行修改就可以了.举个例子来说,一款拳皇模拟器里游 ...

  8. 基于QT的游戏修改器

    基于QT的游戏修改器 本项目是一个可以修改部分游戏的部分数据的.例如:修改自己做的贪吃蛇的得分. 1.h代码 #pragma once#include <QtWidgets/QMainWindo ...

  9. 为英雄无敌3写个游戏修改器

    我是比较铁杆的英雄无敌3的fans,在网上看到这样的文章:http://game.china.com/zh_cn/play/10002765/20021113/11362720.html 就是让我方英 ...

最新文章

  1. 爬取某一微博用户所有文本文件或者是视频图片文件
  2. 开源oa_圈子哥推荐一款基于 Spring Boot 开发 OA 开源产品,学习/搞外快都是不二选择!...
  3. 零基础学习Java-素数和
  4. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分
  5. 学习Spring Boot前需要了解的Spring基础知识
  6. python pathlib模块_【Python Snippets】Pathlib 模块
  7. XML PUBLISHER输出excel存在科学计数
  8. 软件的一些标号及对应版本
  9. 51单片机开发入门(1)-单片机简介
  10. ICode python 3级训练场判断能量状态第19关
  11. 浏览器保存图片时,将jfif改为jpg格式
  12. Android studio开发Android图灵智能聊天机器人,课程设计报告
  13. [CDQ][最小生成树]2018 [HNOI2010]CITY 城市建设
  14. Altera内部结构(一):Cyclone IV内部资源特点
  15. Nodejs手把手教程
  16. 【LOJ2863】【IOI2018】组合动作(交互)
  17. 文件服务器 excle 变为temp,WPS的excel表格保存之后变成tmp_共享文档无法保存EXCLE 生成TMP...
  18. git 更换仓库地址
  19. 拥有10年编程经验的你,为什么还一直停留在原地
  20. 通过静态LSP、LDP LSP、MPLS TE三种方式实现总部与分支的互通

热门文章

  1. tf神经网络模型预测泰坦尼克号生还
  2. VC中窗口在屏幕中央显示
  3. Google Earth Engine(GEE)——Python干旱严重程度案例分析
  4. PostgreSQL嵌套事务提交流程研究
  5. HTML5期末大作业:动漫人物介绍网站设计——哆啦A梦(5页) HTML+CSS+JavaScript 学生动漫网页设计模板下载 哆啦A大学生HTML网页制作作品 简单漫画网页设计成品...
  6. 四川一度智信|小白卖家不懂选品?
  7. “茶界茅台”竹叶青的数字化营销玩法 | 案例
  8. 相机闪光灯(camera flash)
  9. 计算机win7卡顿如何解决方法,win7电脑玩2D游戏经常发生卡顿六大解决方法
  10. 学计算机要选什么科,计算机要学什么科目