首页 > 其他分享 >b01lers CTF & WolvCTF 2023 部分Re WriteUp

b01lers CTF & WolvCTF 2023 部分Re WriteUp

时间:2023-03-20 17:22:22浏览次数:35  
标签:b01lers WriteUp Re flag ._ R25R24 ARRAY null byte

这周打了两个比赛,个人感觉 b01lers CTF 偏简单一些,WolvCTF 比前者难一点。

养生型选手,一共做了三个题

b01lers CTF

Safe

一个嵌入式逆向的题目,是逆向 Arduino UNO 一个门锁一样的东西。附件给了固件,效果图,和电路原理图。

image

image

直接把给的固件拖到 ghidra ,因为固件是Intel Hex 格式的并不包含架构信息所以需要我们手动选择一下,这里选择 AVR8 gccArduino UNO 所采用的芯片使用的架构是 AVR8),首先找到入口函数,发现有 Reset 函数如下图

image

所以,被我重命名成 reset_impl 的函数应该就是入口了。

void reset_impl(void)
{
  undefined1 *puVar1;
  
  R1 = 0;
  SREG = 0;
  Ylo = 0xff;
  Yhi = 8;
  R17 = '\x01';
  X = &mem_100;
  Z = &DAT_codebyte_0582;
  while (puVar1 = X, (byte)X != 0x1c || X._1_1_ != (char)(R17 + ((byte)X < 0x1c))) {
    R0 = *Z;
    Z = Z + 1;
    X = X + 1;
    *puVar1 = R0;
  }
  R18 = '\x01';
  X = &DAT_mem_011c;
  while (puVar1 = X, (byte)X != 0x3a || X._1_1_ != (char)(R18 + ((byte)X < 0x3a))) {
    X = X + 1;
    *puVar1 = R1;
  }
  mem_const_7c = 0x7c;
  real_main();
  while_true();
  return;
}

显然就是设置了一堆内存信息,然后调用了两个函数,重点关注被我重命名为 real_main 的函数,while_true 那个就是一个空的死循环,在嵌入式中很常见。

后面了解了一下 Arduino 开发,这个 real_main 函数应该就是 setup 函数

real_main 的实现就比较复杂了,我在参考 Arduino 的标准库源码之后基本还原了所有用到的函数的符号,具体实现如下

void real_main(void)
{
  char cVar1;
  char *pcVar2;
  byte *pbVar3;
  char *pcVar4;
  // 初始化一堆寄存器
  R1 = 0;
  R25R24._0_1_ = TCNT2;
  R25R24._0_1_ = (byte)R25R24 | 2;
  TCNT2 = (byte)R25R24;
  R25R24._0_1_ = TCNT2;
  R25R24._0_1_ = (byte)R25R24 | 1;
  TCNT2 = (byte)R25R24;
  R25R24._0_1_ = TCCR2;
  R25R24._0_1_ = (byte)R25R24 | 2;
  TCCR2 = (byte)R25R24;
  R25R24._0_1_ = TCCR2;
  R25R24._0_1_ = (byte)R25R24 | 1;
  TCCR2 = (byte)R25R24;
  R25R24._0_1_ = DAT_mem_006e;
  R25R24._0_1_ = (byte)R25R24 | 1;
  DAT_mem_006e = (byte)R25R24;
  ICR3H = 0;
  R25R24._0_1_ = ICR3H;
  R25R24._0_1_ = (byte)R25R24 | 2;
  ICR3H = (byte)R25R24;
  R25R24._0_1_ = ICR3H;
  R25R24._0_1_ = (byte)R25R24 | 1;
  ICR3H = (byte)R25R24;
  R25R24._0_1_ = ICR3L;
  R25R24._0_1_ = (byte)R25R24 | 1;
  ICR3L = (byte)R25R24;
  R25R24._0_1_ = DAT_mem_00b1;
  R25R24._0_1_ = (byte)R25R24 | 4;
  DAT_mem_00b1 = (byte)R25R24;
  R25R24._0_1_ = DAT_mem_00b0;
  R25R24._0_1_ = (byte)R25R24 | 1;
  DAT_mem_00b0 = (byte)R25R24;
  R25R24._0_1_ = TCCR1C;
  R25R24._0_1_ = (byte)R25R24 | 4;
  TCCR1C = (byte)R25R24;
  R25R24._0_1_ = TCCR1C;
  R25R24._0_1_ = (byte)R25R24 | 2;
  TCCR1C = (byte)R25R24;
  R25R24._0_1_ = TCCR1C;
  R25R24._0_1_ = (byte)R25R24 | 1;
  TCCR1C = (byte)R25R24;
  R25R24._0_1_ = TCCR1C;
  R25R24._0_1_ = (byte)R25R24 | 0x80;
  TCCR1C = (byte)R25R24;
  DAT_mem_00c1 = 0;
  // 设置引脚模式
  pinMode(10,1);
  R25R24 = CONCAT11(R25R24._1_1_,11);
  pinMode(11,1);
  R15R14 = &DAT_mem_0118;
  Y = &DAT_mem_0114;
  do {
    pbVar3 = Y;
    Y = Y + 1;
    R25R24._0_1_ = *pbVar3;
    R25R24 = R25R24 & 0xff00 | (uint)(byte)R25R24;
                    /* pinMode(R24, INPUT_PULLUP) */
    pinMode((byte)R25R24,2);
    Z = R15R14 + 1;
    R17R16._1_1_ = *R15R14;
    R17R16 = (byte *)((uint)R17R16 & 0xff | (uint)R17R16._1_1_ << 8);
    R15R14 = Z;
    R25R24 = R25R24 & 0xff00 | (uint)R17R16._1_1_;
    pinMode(R17R16._1_1_,1);
    R25R24 = R25R24 & 0xff00 | (uint)R17R16 >> 8;
    R25R24._0_1_ = (byte)((uint)R17R16 >> 8);
    digitalWrite((byte)R25R24,'\x01');
    Z = (byte *)CONCAT11(1,(byte)Z);
  } while ((byte)Y != 0x18 || Y._1_1_ != (char)(((byte)Y < 0x18) + '\x01'));
  R10 = '9';
  R11 = 1;
  R17R16 = &DAT_mem_0125;
  R7 = 20;
  R8 = 0;
  R9 = '\0';
LAB_code_0242:
  R25R24 = 0x100;
  // 扫描按键
                    /* 5 4 3 2 */
  R15R14 = &DAT_mem_0118;
  Y._0_1_ = 0;
  do {
    Z = R15R14 + 1;
    R6 = *R15R14;
    R15R14 = Z;
    R25R24 = R25R24 & 0xff00 | (uint)R6;
    digitalWrite(R6,0);
                    /* 9 8 7 6  */
    R13R12 = &DAT_mem_0114;
    Y._1_1_ = 0;
    do {
      Z = R13R12 + 1;
      R5 = *R13R12;
      R13R12 = Z;
      R25R24 = digitalRead(R5);
      R25R24._0_1_ = (byte)R25R24 | R25R24._1_1_;
      R25R24 = R25R24 & 0xff00;
      if ((byte)R25R24 == 0) {
        do {
          R25R24 = digitalRead(R5);
          R25R24._0_1_ = (byte)R25R24 | R25R24._1_1_;
        } while ((byte)R25R24 == 0);
        Z = (byte *)CONCAT11(-((DAT_mem_0139 < 0xdb) + -2),DAT_mem_0139 + 0x25);
        R25R24._0_1_ = DAT_mem_0139;
        *Z = Y._1_1_ + (byte)Y;
        DAT_mem_0139 = (byte)R25R24 + 1;
        R25R24 = FUN_code_0156(0,0x32);
      }
      Y._1_1_ = Y._1_1_ + 1;
    } while (Y._1_1_ != 4);
    R25R24 = R25R24 & 0xff00 | (uint)R6;
    digitalWrite(R6,0x1);
    Y._0_1_ = (byte)Y + 0x4;
  } while ((byte)Y != 16);
  // 判断长度,等于20就对比 
  if (DAT_mem_0139 == 20) {
    Z = &DAT_mem_0125;
    X = &mem_100; // [0x0d, 0x05, 0x0f, 0x04, 0x0c, 0x00, 0x09, 0x07, 0x0d, 0x07, 0x09, 0x04, 0x05, 0x08, 0x06, 0x0d, 0x0e, 0x05, 0x05, 0x0f] maybe
LAB_code_0284:
    pcVar4 = (char *)Z;
    pcVar2 = X;
    Z = (byte *)((char *)Z + 1);
    R25R24._1_1_ = *pcVar4;
    X = X + 1;
    R25R24._0_1_ = *pcVar2;
    if (R25R24._1_1_ == (byte)R25R24) goto LAB_code_02ad;
    cVar1 = 5;
    do {
      R25R24 = CONCAT11(R25R24._1_1_,11);
      digitalWrite(11,1);
      FUN_code_0156(0,0xf4);
      R25R24 = CONCAT11(R25R24._1_1_,11);
      digitalWrite(11,0);
      R25R24._1_1_ = 0;
      FUN_code_0156(0,0xf4);
      cVar1 = cVar1 + -1;
    } while (cVar1 != 0);
    goto LAB_code_029f;
  }
  goto LAB_code_02a6;
LAB_code_02ad:
  if (R10 == (byte)Z && R11 == (char)(Z._1_1_ + (R10 < (byte)Z))) goto code_c0x02b0;
  goto LAB_code_0284;
code_c0x02b0: // 应该是开

标签:b01lers,WriteUp,Re,flag,._,R25R24,ARRAY,null,byte
From: https://www.cnblogs.com/gaoyucan/p/17237028.html

相关文章