Android反编译


Android中Java编写的APK使用apktool反编译并修改smali

今天装了某个游戏,游戏中有“商店”,可以用金币购买相关物品。而获得金币的途径,是用人民币购买(1元100只)或者安装该公司的其他应用(安装3款得一点点)。

这显然不科学啊!

当然,程序在我机子上,我们当然能够用科学的手段来对付不科学的游戏货币商城制度。

1、使用apktool进行反编译,得到smali的字节码

假设游戏安装文件为my_game.apk,我们将把它反编译到mygame目录下。

这里下载apktool和对应的dependencies,把apktool和对应的dependencies加压缩到一起,并将该文件夹添加到path环境变量中。我在使用Windows系统,这时候apktool的解压文件夹有以下内容:

aapt.exe

apktool.bat

apktool.jar

然后对my_game.apk进行反编译,运行命令:

apktool d my_game.apk mygame

可以看到apktool将游戏反编译到mygame文件夹中。其中的smali就是对应的字节码。

2、修改smali字节码

关于smali字节码的寄存器可以参考这里,类型、函数和成员可以参考这里,操作符号可以参考这里

当然,由于程序已经混淆,所以不能从文件名和包名中猜测相关信息。这时候有好几个办法定位到要修改的地方。如调试设断点,在这里有教程。还可以通过资源和字符串定位,这是我现在使用的方法,因为我的调试环境还没搭好……

我注意到,某一个与购买相关的按钮图片的id编号为“0×7f020093”,于是在smali中搜索,最后在某个文件夹,也就对应Java的某个包中找到g.smali,这个文件包含了字符串“0×7f020093”。然后,点击购买时,会提示“金币不足,无法购买”,这是文本信息。也就是说,可以在g.smali中搜索该字符串,或者字符串子串来进行程序上下文的定位。当然,直接搜索中文字符串是一无所获的,因为反编译器将中文以utf8的裸编码格式表现。这时候在g.smali中搜索“\u91d1\u5e01\u4e0d\u8db3,\u65e0\u6cd5\u8d2d\u4e70”,找到详细位置!具体代码片段如下:

sget-object v0, La/f/c;->s:La/a/b/g; 

iget-object v9, v0, La/a/b/g;->j:Ld/a/b; 

iget v10, p2, La/d/n;->f:I 

iget v0, v9, Ld/a/b;->v:I 

if-ge v0, v10, :cond_0 

invoke-static {}, Lcom/gale/manager/f;->a()Lcom/gale/manager/f; 

move-result-object v0 

const-string v1, "\u91d1\u5e01\u4e0d\u8db3,\u65e0\u6cd5\u8d2d\u4e70" 

invoke-virtual {v0, v1}, Lcom/gale/manager/f;->a(Ljava/lang/String;)V 

:goto_0     
return-void 

:cond_0     
neg-int v0, v10 

iput v0, v9, Ld/a/b;->x:I 

需要关注的是“if-ge”这句,意思是如果v0大于等于v10,则跳到cond_0执行,否则显示“金币不足,无法购买”并返回。

我们可以直接将“if-ge”改成“if-le”解决问题,不过这时金币会在购买后变负数,说不定会把游戏crash。所以,更好的修改方法如下:

    sget-object v0, La/f/c;->s:La/a/b/g; 

    iget-object v9, v0, La/a/b/g;->j:Ld/a/b; 

    iget v10, p2, La/d/n;->f:I 

    iget v0, v9, Ld/a/b;->v:I 

    if-ge v0, v10, :cond_0     
    goto/16 :cond_0 

    :goto_0     
    return-void 

    :cond_0     
    move v0, v10 

    iput v0, v9, Ld/a/b;->x:I

意思是,即使当前金币小于购买所需金币,也跳到条件成立的地方执行。另外,执行时会将玩家的金币数加上所需金币的相反数,即“neg-int v0, v10”,将其改为“move v0, v10”就可以每次都把玩家的金币数加上所需金币数。最终效果则是,即使金币不足也可以购买,并且越买钱越多。

3、打包、签名和安装修改后的apk

修改完了,就可以打包回apk了。执行以下命令:

apktool b mygame

在mygame目录下的dist在会看到打包好的apk。

当然,现在一般是无法安装的,因为apk还没有签名。下面就来签名。签名需要keystore文件,我已经有专用的keystore了,如果还没有,请参阅这里进行生成。

执行以下命令为重新编译的my_game.apk签名:

jarsigner -verbose -keystore creke.keystore my_game.apk Alias_name

最后,在安装到手机前,需要把手机中的已有版本先卸载,因为如果签名不同,是不能覆盖安装的,会提示“应用程序未安装”错误。

4、其他

Windows下的aapt似乎不能对非本地磁盘进行读写,比如我原来在内存盘中进行操作,apktool总是提示aapt出错,不能打包apk。后来放到本地磁盘中进行才一切正常。

最后说一句,好的游戏从来不会用奇怪的货币和商城来吸引玩家或者玩家的钱财。

http://www.doc88.com/p-196266186415.html



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值