吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 14588|回复: 80

[Android 原创] 《魔法密码》详细分析

  [复制链接]
lzc090 发表于 2019-1-11 21:57
本帖最后由 lzc090 于 2019-5-2 08:23 编辑

前提U3D游戏,请优先看懂这个贴子
U3D游戏《东方新世界》Il2Cpp破解详细教程
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一.货币修改
public uint get_money(); // 0xA9BA5C

[Asm] 纯文本查看 复制代码
text:00A9BA5C sub_A9BA5C ; CODE XREF: .text:00A44198↑p
.text:00A9BA5C  0C 00 D0 E5                 LDRB            R0, [R0,#0xC]
.text:00A9BA60  1E FF 2F E1                 BX              LR


修改成:

[Asm] 纯文本查看 复制代码
text:00A9BA5C             sub_A9BA5C                              
.text:00A9BA5C  0F 02 E0 E3              MOV             R0, #0xFFFFFFF
.text:00A9BA60  1E FF 2F E1               BX                LR




--------------------------------------------------------------------------------------------------------------------------------------------------------
二.等级修改

public uint get_level(); // 0xA8D7D0

[Asm] 纯文本查看 复制代码
.text:00A8D7D0             sub_A8D7D0                             
.text:00A8D7D0 14 00 90 E5                 LDR             R0, [R0,#0x14]
.text:00A8D7D4 1E FF 2F E1                 BX              LR


修改方式和货币一样,不过!!!!有个问题是,等级有了,但属性值可能没加上去,只是等级好看而已,没任何用处。因此我会介绍比较有用的经验修改

三.经验修改

经验修改1:
public uint get_exp(); // RVA: 0xA9BBE4 Offset: 0xA9BBE4

[Asm] 纯文本查看 复制代码
.text:00A9BBE4             sub_A9BBE4                         
.text:00A9BBE4 18 00 90 E5                 LDR             R0, [R0,#0x18]
.text:00A9BBE8 1E FF 2F E1                 BX              LR 


修改方式和金币一样,不过这个可能是获得的总经验

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

经验修改2:

public uint get_requiredExpToNextLevel(); // RVA: 0xA9BC1C-----------升级所需的必须经验

11.PNG

当看到  
[Asm] 纯文本查看 复制代码
.text:00A9BC4C 14 10 94 E5                 LDR             R1, [R4,#20]---假设:当前等级
.text:00A9BC50 01 20 A0 E3                 MOV             R2, #1
.text:00A9BC54 63 30 A0 E3                 MOV             R3, #99
.text:00A9BC58 00 50 8D E5                 STR             R5, [SP]
.text:00A9BC5C 01 10 81 E2                 ADD             R1, R1, #1
.text:00A9BC60 9A FE 01 EB                 BL              sub_B1B6D0 


我就联想起dump文件里面的下列2个函数

public const uint minLevel = 1; // 0x0

public const uint maxLevel = 99; // 0x0

那么将
[Asm] 纯文本查看 复制代码
.text:00A9BC4C 14 10 94 E5                 LDR             R1, [R4,#20]


修改成

[Asm] 纯文本查看 复制代码
.text:00A9BC4C 14 10 94 E5                MOV             R1,  99      当前等级不就变成了99了?


经过修改后发现,这个函数其实是每个等级需要的经验数,那么我们将修改的99换成1,每一级升级只需要等级1的经验也是100左右,我现在29级,还是只需要100.

11.PNG
------------------------------------------------------------------------------------------------------------------------------------------------------------

经验值修改3:

public uint get_restExpToNextLevel(); // RVA: 0xA8EBE4-----------------------这个是剩余升级的经验,就是经验条灰色部分。

.text:00A8EBE4             sub_A8EBE4   
.text:00A8EBE4 10 4C 2D E9                 STMFD           SP!, {R4,R10,R11,LR}
.text:00A8EBE8 08 B0 8D E2                 ADD             R11, SP, #8
.text:00A8EBEC 00 40 A0 E1                 MOV             R4, R0  ;
.text:00A8EBF0 09 34 00 EB                 BL              sub_A9BC1C ;        
.text:00A8EBF4 18 10 94 E5                 LDR             R1, [R4,#0x18]       ------------  获得的经验
.text:00A8EBF8 01 00 50 E0                 SUBS            R0, R0, R1              需求的经验-获得的经验  ,
.text:00A8EBFC 00 00 A0 93                 MOVLS           R0, #0                  结果≤0那么,结果就等于0   (  result = 0;)
.text:00A8EC00 10 8C BD E8                 LDMFD           SP!, {R4,R10,R11,PC}   如果是大于0,结果R0-R1(需求的经验-获得的经验)(  result = v2 - v3;)==剩余升级经验(图片灰色部分)

11.PNG

伪代码:
unsigned int __fastcall sub_A8EBE4(int a1)
{
  int v1; // r4
  unsigned int v2; // r0
  unsigned int v3; // r1
  bool v4; // cf
  unsigned int result; // r0
---------------------------------------------------------------------
  v1 = a1;
  v2 = sub_A9BC1C(a1);                               v1 = sub_A9BC1C(a1);
  v3 = *(v1 + 24);
  v4 = v2 >= v3;                         修改后       v2 = v1 >= v1 - 1;     
  result = v2 - v3;                                         result = 1;
  if ( result == 0 || !v4 )                                if ( !v2 )
    result = 0;                                               result = 0;
  return result;                                             return result;
}

那么我们只需要将结果都改成1,

[Asm] 纯文本查看 复制代码
.text:00A8EBF4 18 10 94 E5                 LDR             R1, [R4,#0x18] 


修改成:
[Asm] 纯文本查看 复制代码
.text:00A8EBF4 01 10 40 E2                 SUB             R1, R0, #1 ; 


说明下:
.text:00A8EBF0 09 34 00 EB                 BL              sub_A9BC1C ;                  
.text:00A8EBF4 01 10 40 E2                 SUB             R1, R0, #1 ;        ------------  获得的经验=需求经验-1
.text:00A8EBF8 01 00 50 E0                 SUBS            R0, R0, R1         ---------     需求的经验-获得的经验 =1 ,(v2 - v3)
.text:00A8EBFC 00 00 A0 93                 MOVLS           R0, #0             ------     因为值=1不会<0,跳过
.text:00A8EC00 10 8C BD E8                 LDMFD           SP!, {R4,R10,R11,PC}     值大于0,那么结果就是R0-R1的值(  result = v2 - v3;)

比如需求经验100 ,(SUB      R1, R0, #1 ;)100-1=99, 获得的经验就是99,    result = v2(100) - v3(99);   代码就变成了这个   result = 1;

修改测试并没有任何变化,可能有其他原因限制,因此这个修改为理论!
-----------------------------------------------------------------------------------------------------------------------------------------------------------
三.HP修改
public uint get_maxHp(); // RVA: 0xA9BC78 Offset: 0xA9BC78       ----------本函数在IDA对应的是loc_A9BC78

这是不能F5,所以就需要慢慢去查看了

找到关键的跳转:

11.PNG

[Asm] 纯文本查看 复制代码
.text:00A9BD34 AA 1C 02 EA                 B               loc_B22FE4


跳转后找到的关键点:

11.PNG

.text:00B230D4 00 10 A0 E1                 MOV             R1, R0            ------------当前血量
.text:00B230D8 00 00 A0 E3                 MOV             R0, #0
.text:00B230DC 01 20 A0 E3                 MOV             R2, #1         --------------- MINHP
.text:00B230E0 0F 37 02 E3                 MOV             R3, #9999 ;------------------MAXHP
.text:00B230E4 00 40 8D E5                 STR             R4, [SP]


看到加粗的地方是不是又熟悉了,dump文件里面的函数

public const uint maxHp = 9999; // 0x0

只需要将

[Asm] 纯文本查看 复制代码
.text:00B230D4 00 10 A0 E1                 MOV             R1, R0            ------------当前血量


修改成
[Asm] 纯文本查看 复制代码
.text:00B230D4 00 10 A0 E1                 MOV             R1, 9999            ------------当前血量


11.PNG
----------------------------------------------------------------------------------------------------------------------------------------------------------

四.MP修改
看到MP和HP的汇编语言差不多因此尝试和HP一样的修改方式

public uint get_maxMp(); // RVA: 0xA9BD64 Offset: 0xA9BD64   ---------本函数在IDA对应的是loc_A9BD64
找到MP的相关代码

11.PNG

进入跳转.text:00A9BE20 FA 1C 02 EA                 B               loc_B23210

找到关键位置

11.PNG

[Asm] 纯文本查看 复制代码
text:00B23318 0C 20 90 E5                 LDR             R2, [R0,#0xC]            -----------当前MP
.text:00B2331C 00 00 A0 E3                 MOV             R0, #0
.text:00B23320 E7 13 00 E3                 MOV             R1, #999
.text:00B23324 00 30 A0 E3                 MOV             R3, #0
.text:00B23328 63 A7 F4 EB                 BL              sub_84D0BC ; 


看到这里是不是又熟悉了,dump文件里面的函数

public const uint maxMp = 999; // 0x0


[Asm] 纯文本查看 复制代码
text:00B23318 0C 20 90 E5                 LDR             R2, [R0,#0xC]            -----------当前MP


修改成
[Asm] 纯文本查看 复制代码
text:00B23318 0C 20 90 E5                 MOV             R2, 999            -----------当前MP


发现没任何作用,那么函数就不是我们上面猜测的

我们分析下整体,找到了相关的点,所以就没吧所有的都贴出来了

11.PNG

.text:00B232E0             loc_B232E0                              ; CODE XREF: .text:00B232CC↑j
.text:00B232E0 00 30 90 E5                 LDR             R3, [R0]
.text:00B232E4 08 10 A0 E1                 MOV             R1, R8
.text:00B232E8 04 20 90 E5                 LDR             R2, [R0,#4]
.text:00B232EC 05 00 A0 E1                 MOV             R0, R5
.text:00B232F0 33 FF 2F E1                 BLX             R3
.text:00B232F4 00 10 A0 E1                 MOV             R1, R0
.text:00B232F8 00 00 A0 E3                 MOV             R0, #0
.text:00B232FC 00 20 A0 E3                 MOV             R2, #0
.text:00B23300 00 60 A0 E3                 MOV             R6, #0
.text:00B23304 06 9D FD EB                 BL              sub_A8A724
.text:00B23308 00 50 A0 E1                 MOV             R5, R0
.text:00B2330C 08 00 94 E5                 LDR             R0, [R4,#8]
.text:00B23310 00 00 50 E3                 CMP             R0, #0
.text:00B23314 0C 00 00 0A                 BEQ             loc_B2334C
.text:00B23318 0C 20 90 E5                 LDR             R2, [R0,#0xC]  --我们之前改的是这个,但没用       unsigned int __fastcall sub_84D0BC {
.text:00B2331C 00 00 A0 E3                 MOV             R0, #0                                                                      if ( a2 < a3 )   ----R2<999
.text:00B23320 E7 13 00 E3                 MOV             R1, #999                                                                   a3 = a2;        
.text:00B23324 00 30 A0 E3                 MOV             R3, #0                                                                      return a3;}
.text:00B23328 63 A7 F4 EB                 BL              sub_84D0BC   --刚好是sub,我们看下代码            这代码是求MP ,设当前MP:72/80,求这个80
.text:00B2332C 00 30 A0 E1                 MOV             R3, R0       (R1, R0)               这就是上面的80  也是MAXMP                                                  
.text:00B23330 00 00 A0 E3                 MOV             R0, #0       (R0, #0)                                                                          
.text:00B23334 05 10 A0 E1                 MOV             R1, R5       (R2, #1)               当前MP                                                   
.text:00B23338 00 20 A0 E3                 MOV             R2, #0       (R3, #9999)          MIXMP                                                            
.text:00B2333C 00 60 8D E5                 STR             R6, [SP]                                                                                                  
                                                                     

有没发现蓝色这一段和上面HP的蓝色是同一个函数()里面的是HP的,不过位置变动了


位置调换一下

[Asm] 纯文本查看 复制代码
.text:00B23334 05 10 A0 E1                 MOV             R1, R5      (R1, R0) 
.text:00B23330 00 00 A0 E3                 MOV             R0, #0       (R0, #0)
.text:00B23338 00 20 A0 E3                 MOV             R2, #0       (R2, #1)
.text:00B2332C 00 30 A0 E1                 MOV             R3, R0       (R3, #9999)


这样我们就知道要修改哪了


[Asm] 纯文本查看 复制代码
.text:00B23334 05 10 A0 E1                 MOV             R1, R5
      


修改成:
[Asm] 纯文本查看 复制代码
.text:00B23334 05 10 A0 E1                 MOV             R1, 999




[Asm] 纯文本查看 复制代码
.text:00B2332C 00 30 A0 E1                 MOV             R3, R0 

      
修改成
[Asm] 纯文本查看 复制代码
.text:00B2332C 00 30 A0 E1                 MOV             R3, 999


11.PNG

----------------------------------------------------------------------------------------------------------------------------------------------------
五.无限体力

游戏回复体力的方式看广告或者是等待时间回复

无限体力1(跳过广告):

public bool get_skipAds(); // RVA: 0xA9D88C Offset: 0xA9D88C     IDA对应的是loc_A9D88C,

同样无法看伪代码,不过查看过程中发现了这个关键点(代码很长就不全部贴出来了

11.PNG

[Asm] 纯文本查看 复制代码
.text:00A9DB78             loc_A9DB78   
.text:00A9DB74 00 60 A0 E3                 MOV             R6, #0
.text:00A9DB78
.text:00A9DB78             loc_A9DB78                             
.text:00A9DB78 06 00 A0 E1                 MOV             R0, R6
.text:00A9DB7C F0 8B BD E8                 LDMFD           SP!, {R4-R9,R11,PC}



[Asm] 纯文本查看 复制代码
.text:00A9DB78 06 00 A0 E1                 MOV             R0, R6


修改成
[Asm] 纯文本查看 复制代码
.text:00A9DB78 06 00 A0 E1                 MOV             R0, 1



同时抽取塔罗牌也是跳过广告的

MuMu20190111223440.png MuMu20190111223932.png

修改体力2:

public uint get_motivation(); // RVA: 0xA8E98C Offset: 0xA8E98C

代码太长,提取关键地方
11.PNG

从伪代码可以开到,最后的结果是return (loc_A9C08C)(v1, HIDWORD(v7), v4, v3, v5, v6); 对应的就是loc_A9C08C,那么进去loc_A9C08C差看下

关键处:
11.PNG

前面的代码好像是计算时间的,不过我不确定就不在这里说了

.text:00A9C1B8 2F 69 DB EB                 BL              j___udivsi3                  ---F5  return a1 / a2       血力格式    R5/R0
.text:00A9C1BC 05 50 80 E0                 ADD             R5, R0, R5                    ------- 当前体力         
.text:00A9C1C0 04 00 A0 E1                 MOV             R0, R4
.text:00A9C1C4 70 FC FF EB                 BL              loc_A9B38C                     -------这个是上限MAX体力,后面会分析到
.text:00A9C1C8 00 00 55 E1                 CMP             R5, R0                                 ---  判断当前体力是不是满                 
.text:00A9C1CC 05 00 A0 91                 MOVLS           R0, R5                          --   R5<=R0,体力不满,当前体力为R5
                                                                                                                                 当体力满时 ,当前体力=MAX体力 =R0
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

关键MAX体力跳转

[Asm] 纯文本查看 复制代码
.text:00A9C1C4 70 FC FF EB                 BL              loc_A9B38C 
  

11.PNG

关键跳转
[Asm] 纯文本查看 复制代码
.text:00A9B448 66 20 02 EA                 B               loc_B235E8


关键点:
11.PNG

看到是不是有是熟悉的感觉

[Asm] 纯文本查看 复制代码
.text:00B236E0 00 10 A0 E1                 MOV             R1, R0  ;                          当前体力MAX
.text:00B236E4 00 00 A0 E3                 MOV             R0, #0
.text:00B236E8 01 20 A0 E3                 MOV             R2, #1                          体力限制MIN
.text:00B236EC E7 33 00 E3                 MOV             R3, #999                       体力现在MAX
.text:00B236F0 00 40 8D E5                 STR             R4, [SP] 


[Asm] 纯文本查看 复制代码
.text:00B236E0 00 10 A0 E1                 MOV             R1, R0 


修改成
[Asm] 纯文本查看 复制代码
.text:00B236E0 E7 13 00 E3                 MOV             R1, #999 


11.PNG


六.跳过战斗画面

public bool get_skipBattle(); // RVA: 0xA9DBC8 Offset: 0xA9DBC8

同样的跳过战斗过程修改和去广告也是一样的修改方式

11.PNG

MuMu20190111224517.png

七.修改角色属性

1.敏捷/防御(其实是同一个东西)

public uint get_agility(); // RVA: 0xA9BF3C Offset: 0xA9BF3C-------IDA对应的是loc_A9BE50  

public uint get_defence(); // RVA: 0xA9BE50 Offset: 0xA9BE50

关键代码

11.PNG

同样我们会再底部看到一个跳转

[Asm] 纯文本查看 复制代码
.text:2B 1D 02 EA                 B               loc_B234AC ;


进去后看到一个关键的地方

11.PNG

是不是和HP的一样,敏捷取值范围1<=敏捷<=99

[Asm] 纯文本查看 复制代码
.text:00B23468 00 10 A0 E1                 MOV             R1, R0


改成
[Asm] 纯文本查看 复制代码
.text:00B23468 00 10 A0 E1                 MOV             R1, 99


11.PNG

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

七.秒杀


秒杀修改方式有2种

1.修改主角本身的攻击力

2.修改怪物的血量为1

本游戏是主角挨打,伙伴攻击因此方式1的修改并不存在,我们修改方式2.

public uint get_hp(); // RVA: 0xB1141C Offset: 0xB1141C

[Asm] 纯文本查看 复制代码
.text:00B1141C             sub_B1141C                              
.text:00B1141C 1C 00 90 E5                 LDR             R0, [R0,#0x1C]
.text:00B11420 1E FF 2F E1                 BX              LR


修改为
[Asm] 纯文本查看 复制代码
.text:00B1141C             sub_B1141C                              
.text:00B1141C 1C 00 90 E5                 mov            R0, 1
.text:00B11420 1E FF 2F E1                 BX              LR


很多参数(暴击、闪避、无敌等)修改方式和上面介绍的差不多,多去看dump文件里面的参数就知道了,就不一一罗列出来了。
希望大家喜欢!




MuMu20190111165754.png

点评

做的好仔细。幸苦了。  发表于 2019-2-24 12:10
好详细的教程 支持  发表于 2019-2-20 21:36
很详细的教程,点个赞!  发表于 2019-1-23 10:23

免费评分

参与人数 28吾爱币 +29 热心值 +25 收起 理由
YunsChou + 1 我很赞同!
onihot + 1 + 1 跟着大神的教程提升自己
天空藍 + 1 + 1 谢谢@Thanks!
大山猫 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
GaaraZL + 1 + 1 谢谢@Thanks!
下个月再说 + 1 + 1 热心回复!
传说。 + 1 + 1 感谢分享
sunnylds7 + 1 + 1 热心回复!
youhen233 + 1 + 1 谢谢@Thanks!
饭没吃 + 1 + 1 热心回复!
yyy1867 + 1 + 1 热心回复!
f4cku + 1 + 1 谢谢@Thanks!
jnez112358 + 1 + 1 谢谢@Thanks!
z19980331 + 1 + 1 谢谢@Thanks!
dongmie + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lookerJ + 1 谢谢@Thanks!
lds114 + 1 我很赞同!
IT_K + 1 + 1 谢谢@Thanks!
suoyt + 1 + 1 我很赞同!
天涯星客 + 1 + 1 谢谢@Thanks!
Re.delight + 1 + 1 谢谢@Thanks!
cxp521 + 1 + 1 牛逼,光整理都要N久
stars-one + 1 + 1 我很赞同!
静一静 + 1 + 1 谢谢@Thanks!
CrazyNut + 3 + 1 膜拜大佬半夜发教程贴
飞天蜗牛 + 1 + 1 谢谢@Thanks!
吾爱支持 + 1 谢谢@Thanks!
joneqm + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| lzc090 发表于 2019-1-16 20:46
本帖最后由 lzc090 于 2019-1-16 20:51 编辑
878510 发表于 2019-1-16 20:25
..
在C之前是不是应该有更基础的东西
我啥都不懂呢

U3D打包模式有2种:
momo打包的游戏,源码是直接可以看到的,论坛也有很多入门的教程。
IL2是吧源码放到了so文件,反编译出来变成ARM语言的。需要再把ARM语言自己专为C#,所以难度会更大点,因此需要C#语言也需要ARM语言。
所以建议你从momo开始认识,这个帖子你就直接跳过,先去看MOMO的游戏教程
 楼主| lzc090 发表于 2019-1-16 21:26
878510 发表于 2019-1-16 21:04

照着做都搞不定

去移动板块,查看那些无限金币帖子开始一步一步跟着做。
https://www.52pojie.cn/thread-846577-1-2.html
这个帖子就很适合入门学习,也写的非常清楚。如果看不懂,就需要多花点时间,记得是动手跟着做才有用。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
878510 + 1 + 1 谢谢@Thanks!

查看全部评分

吾爱支持 发表于 2019-1-11 23:00
支持原创……感谢楼主分享……。
最后一个小分分送上,请笑纳
fq645122 发表于 2019-1-11 23:01
看着可以哦
565266718 发表于 2019-1-11 23:06
支持了。。。。
飞天蜗牛 发表于 2019-1-11 23:24
好教程,感谢楼主分享,学习下
CrazyNut 发表于 2019-1-12 02:44
精华帖预定
逐梦网络科技 发表于 2019-1-12 05:45
感谢楼主的分享。支持原创
wisoft 发表于 2019-1-12 10:01
膜拜,感谢分享
无上归一 发表于 2019-1-12 20:14
楼主牛逼,66666666666。就服你
Dimi520 发表于 2019-1-13 00:53
好教程,楼主牛逼
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:禁止回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2019-8-21 02:30

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表