很久没有总结过关于逆向编程的文章了,来写一篇实践分享给大家。主要来说说如何通过逆向修改APK来实现游戏进入后直接获得胜利领取奖励。为了学习发展就不分享游戏名称了。下面我们开始吧:
AndroidKiller / IDE 3.1.0.0 (用来反汇编APK)
.NET Reflector 9.0 (用来查找修改)
首先通过AndroidKiller将游戏APK安装包反汇编出来,使用.NET Reflector 打开目录下的Assembly-CSharp.dll文件。
F3(调查查询界面) → ctrl + m(查询方法类型) → win(查询关键字) → 选择精准匹配(如下图所示)。
我们锁定(上图中倒数第四个)Menber = win,Declaring Type = BattleState(战斗状态)这行,双击进去,顺便看看BattleState这个类都有些什么相关的信息。
(单词含义不太确定的可以百度翻译,平时多记多查点滴积累。)
AllEnemiesDead() : Boolean 批注:(所有敌人死亡)Boolean在这里叫做布尔值,代表返回的数据类型:True 或为 False
AllHeroDead() : Boolean (所有英雄死亡)
EndBattle() : Void 批注:(结束战斗)Void 当看到这个类型时要明白方法返回值为空 或 不返回值
这里我们把直接胜利,比喻成我们想添加的toast,想让toast在启动的时候显示,就要找到主启动的activity添加进去。
在Win() : Void → 右键Analyze / ctrl + r (进入分析器界面) →双击 展开列表 → 展开 Used By 。如下图:
批注:Depends On:执行Win()方法时所需要内容。 Used By : Win()方法 被哪些过程使用
BattleState.Win() : Void
Depends On
Used By
BattleState.Update() : Void
PlayerCmder.Reconnect(FullPlayerWrap) : Void
批注:我在这里看出 Win()方法 与 Update() 是属于BattleState类下的方法也可以说Reconnect()方法属于 PlayerCmder类
分析来看:发现游戏在运行 有查看 战斗状态(BattleState)的过程,而游戏在执行这个过程中会用到 胜利(Win()) 和 刷新(Update())的命令。 所以在这里只要我们把胜利的命令放在刷新命令的第一行,让玩家进入游戏时,系统就会查看战斗状态-刷新-玩家胜利。这就是代码之后执行的逻辑。
下面我们接着操作:
先来看看Update() : Void
对于代码看不明白的可以直接看下方文字即可:
public override void Update()
{
base.Update();
if ((this.m_status == Status.Init) && (BattleApp.aBattle != null))
{
this.m_status = Status.Runing;
}
if (BattleApp.aBattle != null)
{
if (this.m_status == Status.BattleEndTutorial)
{
if (Singleton<TutorialManager>.Get().IsTutorialFinishOp(this.m_battleEndTutorial))
{
if (this.m_result == BattleResult.Win)
{
this.Win();
}
else if (this.m_result == BattleResult.Lose)
{
this.Loss();
}
}
}
else
{
if (!this.m_bTriggerStartEvent && (this.ElapseTime > 0x9c4L))
{
this.m_bTriggerStartEvent = true;
Singleton<TutorialManager>.Get().SendEvent(new BattleStart());
}
if (!this.m_bTrriggerWaveStartEvent && (this.ElapseTime > 0x9c4L))
{
this.m_bTrriggerWaveStartEvent = true;
Singleton<TutorialManager>.Get().SendEvent(new WaveStart(this._curWave));
}
bool flag = false;
if (!this.PauseTime && !this.WaveCleared)
{
this.RemainTime -= App.Clock.DeltaMillis;
if ((this.RemainTime <= 0L) || this.AllHeroDead())
{
flag = true;
this.m_result = BattleResult.Lose;
}
if (this.AllEnemiesDead())
{
this._waveCleared = true;
if (this.CurWave == this.MaxWave)
{
flag = true;
this.m_result = BattleResult.Win;
}
else
{
this.ClearWave();
}
}
if (flag)
{
this.OnBattleEnd();
if (this.m_status != Status.BattleEndTutorial)
{
if (this.m_result == BattleResult.Win)
{
this.Win();
}
else if (this.m_result == BattleResult.Lose)
{
this.Loss();
}
}
}
if ((this.m_helpAddEpDataList != null) && (this.m_helpAddEpDataList.Count > 0))
{
HelpAddEpData data = this.m_helpAddEpDataList[0];
if ((data.Tick * 1000f) < this.ElapseTime)
{
this.m_helpAddEpDataList.RemoveAt(0);
BevUnit bevUnitByHeroID = BattleApp.aBattle.GetBevUnitByHeroID(data.HeroID);
if (bevUnitByHeroID != null)
{
bevUnitByHeroID.aUnitAttribute.aUnitProp.CurEP = UnitProp.MAX_EP;
}
}
}
}
}
}
}
通过分析代码可以看到胜利、失败、所有敌人死亡、所有英雄死亡。
想让游戏直接胜利,就在第一行Update() : Void上面调用Win() : Void方法。
在菜单Tools → Reflexil v1.6 →如下面两张图。
修改后:
这样程序就能达到直接胜利的效果了,之后通过回编译、签名游戏、打包就可以把游戏安装到手机了。希望可以帮到对此技术好奇的你们,荣幸与您分享~
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。