申请会员ID:shaoyue【申请通过】
1.申请ID:shaoyue2.个人邮箱:1103768754@qq.com
3.原创技术文章:《android的逆向另类破解》
开始:
相信大家都玩过2048这款小游戏,2048曾经可是风靡一时,现在我们通过破解2048来进行对Android逆向的了解。先看一下修改后的图与原图。(由于特殊原因不能用电脑 我就用手机来进行破解教程。)
工具:mt管理器,2048游戏安装包一个
需要基础:android;java ;smali
首先进入用mt管理器apk的AndroidManifest.xml文件进行反编译,得到apk的基本信息,部分代码如下:
<application
android:theme="@style/AppTheme"
android:label="@string/app_name"
android:icon="@drawable/icon"
android:allowBackup="true"
android:supportsRtl="true">
<activity
android:name="com.game2048.puzzle.plus2048.activity.GuideActivity">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.game2048.puzzle.plus2048.activity.GameActivity" />
<meta-data
......
不难看出首先进入的activity是com.game2048.puzzle.plus2048.activity.GuideActivit,这是一个教程activity,然后进入dex找到GuideActivit开始修改(建议反编译为Java,但是samli够硬的话也不强求)。GuideActivit的部分代码如下
private void isShowButton() {
if (this.currentIndex == 0) {
this.buttonView.setVisibility(8);
this.contentView.setTextSize(30.0f);
this.contentView.setText(getString(0x7f070032));
return;
}
this.buttonView.setVisibility(0);
this.contentView.setTextSize(20.0f);
this.contentView.setText(getString(0x7f070033));
}
这串代码就是控制TextView的文本,就是用来提示用户的,我们先对它入手,代码显示文本的ID序号为0x7f070032和0x7f070033。用mt管理器打开arsc搜索ID,可以显示如下的字样。(我只粘贴了0033的字样)
When two tiles with the same number touch,they merge into one!
然后把它修改为我们想要的字样,我修改成了“破解内容:点击“吾”会添加一个128方块,点击“爱”会添加一个512方块”的字样。效果图:
只是修改文字就太low了,下面我们来了修改的重点:①自定义的添加添加按钮。②修改按钮的图标。③实现点击按钮会添加一个小方块的功能
接着看GuideActivity的代码,会发现教程结束后会进入GameActivity,也就是正式的游戏Activity了。以下是GameActivity中onCreate()的部分代码
this.view = new GameView(this);
this.view.hasSaveState = ShareFileUtils.getBoolean("save_state", false);
if (bundle != null && bundle.getBoolean("hasState")) {
load();
}
this.clickListener = new 1(this);
startAppAd = new StartAppAd(this);
StartAppSDK.init(this, "204430908", true);
setContentView(this.view);
由此看出开发者并没有使用layout作为view,而是自定义了一个view,即GameView,这就为我们添加按钮提供了很大的帮助。由import路径可以得出GameView的路径,现在让我们杀到GameView。GameView的部分方法如下
void drawShareButton()
void drawScoreText()
void drawHighText()
.......
啧啧,看看这些方法的名字,分工明确啊,既然这样,我们就再接着开发者的思路继续写吧。
先在类中添加一个int变量负责储存按钮的x坐标,mt管理器可以帮你不用些任何代码来完成定义变量这一步,当然变量定义完之后的赋值需要自己用smali来编写了,我把赋值代码写在了getLayout()之中(我定义的变量为sWuai,吾爱的拼音哦):
iget v13 v0 Lcom/game2048/puzzle/plus2048/view/GameView;->iconPaddingSize:I
sub-int/2addr v12 v13
move-object/from16 v0 v18
iput v12 v0 Lcom/game2048/puzzle/plus2048/view/GameView;->sWuai:I
只串smali代码还涉及apk的自带变量,就不一一介绍了。
定义完变量后再来定义一个方法,同样mt管理器可以完成。我定义了一个名为“drawWuaiButton()”的方法,修饰符:private,返回值:void,参数:无
定义其内容:
iget-object v2 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->backgroundRectangle:Landroid/graphics/drawable/Drawable;
iget v3 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->sWuai:I
iget v4 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->sYIcons:I
iget v0 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->sWuai:I
iget v1 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->iconSize:I
add-int v5 v0 v1
iget v0 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->sYIcons:I
iget v1 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->iconSize:I
add-int v6 v0 v1
move-object v0 v7
move-object v1 v8
invoke-direct/range {v0..v6} Lcom/game2048/puzzle/plus2048/view/GameView;->drawDrawable(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
invoke-virtual {v7} Lcom/game2048/puzzle/plus2048/view/GameView;->getResources()Landroid/content/res/Resources;
move-result-object v0
const v1 0x7f020080
invoke-virtual {v0,v1} Landroid/content/res/Resources;->getDrawable(I)Landroid/graphics/drawable/Drawable;
move-result-object v2
iget v0 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->sWuai:I
iget v1 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->iconPaddingSize:I
add-int v3 v0 v1
iget v0 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->sYIcons:I
iget v1 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->iconPaddingSize:I
add-int v4 v0 v1
iget v0 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->sWuai:I
iget v1 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->iconSize:I
add-int/2addr v0 v1
iget v1 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->iconPaddingSize:I
sub-int v5 v0 v1
iget v0 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->sYIcons:I
iget v1 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->iconSize:I
add-int/2addr v0 v1
iget v1 v7 Lcom/game2048/puzzle/plus2048/view/GameView;->iconPaddingSize:I
sub-int v6 v0 v1
move-object v0 v7
move-object v1 v8
invoke-direct/range {v0..v6} Lcom/game2048/puzzle/plus2048/view/GameView;->drawDrawable(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
return-void
方法定义完了,那么我们去调用它吧。在createBackgroundBitmap()中来调用:
invoke-direct {v2,v0} Lcom/game2048/puzzle/plus2048/view/GameView;->drawWuaiButton(Landroid/graphics/Canvas;)V。
现在可以打包,签名,安装,运行一下,你会惊奇的发现在分享按钮旁边又多了一个按钮。你可以点击一下,但是没有反应。
ヽ(`д′)ノ,呀呀,这不是白搭了吗?不要紧 ,我们可以发GameView紧紧的绑于一个名为InputListener的类,这就是我们的点击了事件了。进入InputListener,加入一下代码(
if-eqz v3 :label_622
iget-object v3 v11 Lcom/game2048/puzzle/plus2048/listener/InputListener;->gameView:Lcom/game2048/puzzle/plus2048/view/GameView;
iget-object v3 v3 Lcom/game2048/puzzle/plus2048/view/GameView;->gameActivity:Lcom/game2048/puzzle/plus2048/activity/GameActivity;
invoke-virtual {v3} Lcom/game2048/puzzle/plus2048/activity/GameActivity;->showWuaiState()V
goto/16 :label_14
label_622:
invoke-direct {v11,v8} Lcom/game2048/puzzle/plus2048/listener/InputListener;->isTap(I)Z
move-result v3
由于该方法中含有if ,else if语句,结构较为复杂,可以花点时间耐心看看
现在有了按钮,有了点击监听,那么事件呢?事件一定存在于GameActivity之中,我们GameActivity中加入一个方法来储存事件,我定义了一个名为showWuaiState()的方法,修饰符:public,返回值:void,参数:无。
并写入smali来定义事件。
等等,我们不要忘了要定义的事件是什么:点击按钮,生成一个小方块。
即然事件已经定了,那么我们找一个符合事件的接口。就是在GameActivity中频繁出现的GameMain类了,打开GameMain会发现一个方法:addRandomTile()。有木有莫名的兴奋?我们的事件接口找到了,接着在GameMain中定义一个public方法,名字随便起吧。
内部模仿addRandomTile()来进行编写。
iget-object v2 v6 Lcom/game2048/puzzle/plus2048/domain/MainGame;->grid:Lcom/game2048/puzzle/plus2048/domain/Grid;
invoke-virtual {v2} Lcom/game2048/puzzle/plus2048/domain/Grid;->isCellsAvailable()Z
move-result v2
if-eqz v2 :label_29
const/16 v1 0x80
new-instance v0 Lcom/game2048/puzzle/plus2048/domain/Tile;
iget-object v2 v6 Lcom/game2048/puzzle/plus2048/domain/MainGame;->grid:Lcom/game2048/puzzle/plus2048/domain/Grid;
invoke-virtual {v2} Lcom/game2048/puzzle/plus2048/domain/Grid;->randomAvailableCell()Lcom/game2048/puzzle/plus2048/domain/Cell;
move-result-object v2
invoke-direct {v0,v2,v1} Lcom/game2048/puzzle/plus2048/domain/Tile;-><init>(Lcom/game2048/puzzle/plus2048/domain/Cell;I)V
invoke-direct {v6,v0} Lcom/game2048/puzzle/plus2048/domain/MainGame;->spawnTile(Lcom/game2048/puzzle/plus2048/domain/Tile;)V
iget-object v2 v6 Lcom/game2048/puzzle/plus2048/domain/MainGame;->mView:Lcom/game2048/puzzle/plus2048/view/GameView;
invoke-virtual {v2} Lcom/game2048/puzzle/plus2048/view/GameView;->invalidate()V
label_29:
return-void
这是随机生成一个128方块的代码,我们和showWuaiState()连接起来,在showWuaiState()中编写:
iget-object v0 v1 Lcom/game2048/puzzle/plus2048/activity/GameActivity;->view:Lcom/game2048/puzzle/plus2048/view/GameView;
iget-object v0 v0 Lcom/game2048/puzzle/plus2048/view/GameView;->mainGame:Lcom/game2048/puzzle/plus2048/domain/MainGame;
invoke-virtual {v0} Lcom/game2048/puzzle/plus2048/domain/MainGame;->addSuper2Tile()V
return-void
现在打包,签名,安装,运行。点击那个我们添加的按钮,你会发现自动随机的增加一个128小方块。
同样的原理可以修改分享按钮的事件来添加512方块。
下面的的图片替换教程就很简单了,自己制作两张图片(我制作了“吾”,“爱”两张图片)现在去drawable中重命名再替换。记得在arsc中添加ID,再在GameView中修改ID。
大家有兴趣可以修改一下得分什么的。
成品链:https://pan.baidu.com/s/14GFa00PBdUrfE4MalRsJtw 密码:lp00
原版链接:https://pan.baidu.com/s/1n4dB8a9zXBXYcTqaOz_Jjg 密码:j759
纯手打,不易,望通过
I D:shaoyue
邮箱:1103768754@qq.com
申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。
ps:登录后可以把文章整理到移动安全分析区。 已经注册了,现在来报道,谢谢通过 Hmily 发表于 2018-4-2 11:11
I D:shaoyue
邮箱:
为什么还是显示未报到,管理没看到?
再来报道一次,顺便再感谢一次管理的审核通过
页:
[1]