HTB Challenges GamePwn Nostalgia
主站 分类 云安全 AI安全 开发安全 2025-11-11 13:23:7 Author: www.freebuf.com(查看原文) 阅读量:1 收藏

freeBuf

主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

1.下载文件发现是.gba格式的

在mGBA中打开得到

1762862267_691324bbc09674ff117f6.png!small

txt文件中提示要输入正确的作弊码

2.对文件反编译

我这里用的是Ghidra10.1版本https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_10.1_build/ghidra_10.1_PUBLIC_20211210.zip

加GhidraGBA插件https://github.com/SiD3W4y/GhidraGBA/releases/download/10.1/ghidra_10.1_PUBLIC_20211213_GhidraGBA.zip

将插件压缩包直接放到Ghidra的Extensions\Ghidra\目录下

1762861959_691323878ea657204b84a.png!small

然后打开Ghidra在File->Install Extensions勾选GhidraGBA

重新打开Ghidra并导入.gba文件

3.在左侧Symbol Tree->Functions寻找关键函数

在FUN_080015a8找到

void FUN_080015a8(void)

{
  ushort uVar1;
  undefined4 uVar2;
  undefined4 uVar3;
  ushort uVar4;
  int iVar5;
  ushort *puVar6;
  undefined *local_2c;
  
  DISPCNT = 0x1140;
  FUN_08000a74();
  FUN_08000ce4(1);
  DISPCNT = 0x404;
  FUN_08000dd0(&DAT_02009584,0x6000000,&DAT_030000dc);
  FUN_08000354(&DAT_030000dc,0x3c);
  uVar4 = DAT_030004d8;
  do {
    DAT_030004da = uVar4;
    DAT_030004d8 = KEYINPUT | 0xfc00;
    puVar6 = &DAT_0200b03c;
    uVar4 = DAT_030004d8;
    do {
      uVar2 = DAT_030004dc;
      uVar1 = *puVar6;
      if ((uVar1 & DAT_030004da & ~uVar4) != 0) {
        if (uVar1 == 4) {
          DAT_030000d4 = 0;
          uVar3 = FUN_08001c24(DAT_030004dc);
          FUN_08001868(uVar2,0,uVar3);
          DAT_05000000 = 0x1483;
          FUN_08001844(&DAT_0200ba18);
          FUN_08001844(&DAT_0200ba20,&DAT_0200ba40);
          DAT_030000d8 = 0;
          uVar4 = DAT_030004d8;
        }
        else if (uVar1 == 8) {
          if (DAT_030000d8 == 0xf3) {
            DISPCNT = 0x404;
            FUN_08000dd0(&DAT_02008aac,0x6000000,&DAT_030000dc);
            FUN_08000354(&DAT_030000dc,0x3c);
            uVar4 = DAT_030004d8;
          }
        }
        else if (DAT_030000d4 < 8) {
          DAT_030000d4 = DAT_030000d4 + 1;
          FUN_08000864();
          if (uVar1 == 0x10) {
            DAT_030000d8 = DAT_030000d8 + 0x3a;
LAB_08001742:
            local_2c = &DAT_0200ba0c;
          }
          else if (uVar1 < 0x11) {
            if (uVar1 == 1) {
              DAT_030000d8 = DAT_030000d8 + 3;
LAB_08001766:
              local_2c = &DAT_0200b9f8;
            }
            else {
              iVar5 = 0xe;
              if (uVar1 != 2) {
LAB_0800168a:
                iVar5 = 0;
              }
              DAT_030000d8 = iVar5 + DAT_030000d8;
              if (uVar1 == 0x20) {
LAB_080016ea:
                local_2c = &DAT_0200ba08;
              }
              else if (uVar1 < 0x21) {
                if (uVar1 == 2) {
                  local_2c = &DAT_0200b9fc;
                }
                else {
                  if (uVar1 == 0x10) goto LAB_08001742;
                  if (uVar1 == 1) goto LAB_08001766;
                }
              }
              else {
                if (uVar1 == 0x80) goto LAB_08001754;
                if (uVar1 < 0x81) {
                  if (uVar1 == 0x40) goto LAB_08001778;
                }
                else if (uVar1 == 0x100) {
                  local_2c = &DAT_0200ba04;
                }
                else if (uVar1 == 0x200) {
                  local_2c = &DAT_0200ba00;
                }
              }
            }
          }
          else if (uVar1 == 0x40) {
            DAT_030000d8 = DAT_030000d8 + 0x28;
LAB_08001778:
            local_2c = &DAT_0200ba10;
          }
          else {
            if (uVar1 != 0x80) {
              if (uVar1 != 0x20) goto LAB_0800168a;
              DAT_030000d8 = DAT_030000d8 + 0x6e;
              goto LAB_080016ea;
            }
            DAT_030000d8 = DAT_030000d8 + 0xc;
LAB_08001754:
            local_2c = &DAT_0200ba14;
          }
          uVar2 = FUN_08001bc4(DAT_030004dc,local_2c);
          DAT_05000000 = 0x1483;
          DAT_030004dc = uVar2;
          FUN_08001844(&DAT_0200ba18);
          FUN_08001844(&DAT_0200ba20,uVar2);
          uVar4 = DAT_030004d8;
        }
      }
      puVar6 = puVar6 + 1;
    } while (puVar6 != (ushort *)&UNK_0200b050);
  } while( true );
}

4.分析一下代码

do {
    DAT_030004da = uVar4;
    DAT_030004d8 = KEYINPUT | 0xfc00;

这是一个无限循环

DAT_030004da = uVar4;:保存上一帧的按键状态。

DAT_030004d8 = KEYINPUT | 0xfc00;

KEYINPUT是 GBA 按键寄存器。

| 0xfc00:屏蔽高 6 位,只保留低 10 位按键(A, B, L, R, Start, Select, 上下左右)。

结果存入DAT_030004d8表示当前按键状态。

puVar6 = &DAT_0200b03c;
uVar4 = DAT_030004d8;
do {
    uVar2 = DAT_030004dc;
    uVar1 = *puVar6;

puVar6指向按键掩码数组:

每个元素对应一个按键的 bit 掩码。

按键bit 位掩码(十六进制)掩码(十进制)
A00x00011
B10x00022
Select20x00044
Start30x00088
Right40x001016
Left50x002032
Up60x004064
Down70x0080128
R80x0100256
L90x0200512

uVar2 = DAT_030004dc:保存当前游戏状态,供函数调用使用。

uVar1 = *puVar6:当前遍历的按键掩码。

if ((uVar1 & DAT_030004da & ~uVar4) != 0)

这里是防止按键持续按下多次触发

if (uVar1 == 4) {
    DAT_030000d4 = 0;
    uVar3 = FUN_08001c24(DAT_030004dc);
    FUN_08001868(uVar2,0,uVar3);
    DAT_05000000 = 0x1483;
    FUN_08001844(&DAT_0200ba18);
    FUN_08001844(&DAT_0200ba20,&DAT_0200ba40);
    DAT_030000d8 = 0;
    uVar4 = DAT_030004d8;
}

select键重置

else if (uVar1 == 8) {
    if (DAT_030000d8 == 0xf3) {
    DISPCNT = 0x404;
    FUN_08000dd0(&DAT_02008aac,0x6000000,&DAT_030000dc);
    FUN_08000354(&DAT_030000dc,0x3c);
    uVar4 = DAT_030004d8;
    }
 }

start键

当DAT_030000d8 == 0xf3时会刷新显示模式,可能是通关条件

else if (DAT_030000d4 < 8) {
    DAT_030000d4 = DAT_030000d4 + 1;
    FUN_08000864();

这里限制了按键的次数小于8

if (uVar1 == 0x10) {
    DAT_030000d8 = DAT_030000d8 + 0x3a;
LAB_08001742:
    local_2c = &DAT_0200ba0c;
}

→按键会使DAT_030000d8增加0x3a

后面省略一些于是我们可以得到

按键掩码增加值
0x10+0x3a
1+3
2+0xe
0x20+0x6e
0x40+0x28
0x80+0xc
0x100+0
0x200+0

5.最后我们可以得到这样一张表

按键掩码按键DAT_030000d8 增加值
1A+3
2B+0x0e (14)
4Select0(无增加值,重置)
8Start条件触发(0xf3时触发其他动作,其他情况无增加值)
0x10 (16)Right+0x3a (58)
0x20 (32)Left+0x6e (110)
0x40 (64)Up+0x28 (40)
0x80 (128)Down+0x0c (12)
0x100 (256)R+0(未修改)
0x200 (512)L+0(未修改)

结合上面DAT_030000d8== 0xf3(243)的条件

我们得到以下组合

组合序号按键及次数
1A ×1, Up ×6
2A ×1, B ×1, Right ×2, Left ×1
3A ×1, B ×1, Down ×1, Up ×1, Right ×3
4A ×1, B ×1, Down ×3, Up ×2, Left ×1
5A ×3, B ×1, Left ×2
6A ×3, B ×1, Down ×1, Up ×1, Right ×1, Left ×1

6.在mGBA->工具->设置->键盘可以看到对应按键

1762866987_6913372b2a70d81f52f65.png!small

7.敲下其中一种组合

1762866906_691336da69934c694c964.png!small

按下回车得到flag

1762867022_6913374e5e6ac7d432f95.png!small

已在FreeBuf发表 0 篇文章

本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)


文章来源: https://www.freebuf.com/articles/game/456654.html
如有侵权请联系:admin#unsafe.sh