【re】[CISCN 2022 东北]easycpp --ida动态调试,循环异或

拿到程序,我们先查一下有没有加壳,发现没有加壳,并且是64位程序,拖进ida分析其代码逻辑

int __cdecl main(int argc, const char **argv, const char **envp)
{
  void **v3; // rcx
  __int64 v4; // r8
  size_t v5; // r10
  void **v6; // rax
  void **v7; // r8
  void **v8; // rax
  void **v9; // r8
  void **v10; // rax
  void **v11; // r8
  void **v12; // rdx
  int v13; // eax
  const char *v14; // rdx

  sub_7FF6E3862410(*(__int64 *)&argc, (__int64)"Input:", (__int64)envp);
  sub_7FF6E3862B60((__int64)&qword_7FF6E3897590);
  if ( Size != 38 )
    goto LABEL_22;
  v5 = 0i64;
  v3 = &Src;
  do
  {
    v6 = &Src;
    v7 = &Src;
    if ( (unsigned __int64)qword_7FF6E3896C68 >= 0x10 )
      v6 = (void **)Src;
    if ( (unsigned __int64)qword_7FF6E3896C68 >= 0x10 )
      v7 = (void **)Src;
    *((_BYTE *)v7 + v5) ^= *((_BYTE *)v6 + v5 + 1);
// flag[i]^=flag[i+1]
    v8 = &Src;
    v9 = &Src;
    if ( (unsigned __int64)qword_7FF6E3896C68 >= 0x10 )
      v8 = (void **)Src;
    if ( (unsigned __int64)qword_7FF6E3896C68 >= 0x10 )
      v9 = (void **)Src;
    *((_BYTE *)v9 + v5 + 1) ^= *((_BYTE *)v8 + v5 + 2);
    v10 = &Src;
    v11 = &Src;
    if ( (unsigned __int64)qword_7FF6E3896C68 >= 0x10 )
      v10 = (void **)Src;
    if ( (unsigned __int64)qword_7FF6E3896C68 >= 0x10 )
      v11 = (void **)Src;
    *((_BYTE *)v11 + v5 + 2) ^= *((_BYTE *)v10 + v5 + 3);
    ++v5;
    v4 = Size;
  }
  while ( v5 < Size - 3 );                      // 35
  v12 = &Buf2;
  if ( (unsigned __int64)qword_7FF6E3896C48 >= 0x10 )
    v12 = (void **)Buf2;
  if ( (unsigned __int64)qword_7FF6E3896C68 >= 0x10 )
    v3 = (void **)Src;
  if ( Size != qword_7FF6E3896C40 || (v13 = memcmp(v3, v12, Size), v14 = "Right!", v13) )
LABEL_22:
    v14 = "Wrong!";
  sub_7FF6E3862410((__int64)v3, (__int64)v14, v4);
  return 0;
}

虽然代码很长,其实我们只需要关注主要逻辑就行,首先输入字符串长度是38,然后就是四位一组不断循环异或下去,逆向时只需要从最后一个字符,根据上面的代码逆着写回去就行,不需要去特别注意ida的代码实现,其实很冗杂,知道代码在干嘛就行,但是这里有个问题,就是判断数据在那里?看这个代码v13 = memcmp(v3, v12, Size),这个v12是是前面buf2的地址v3是加密过后的字符串,所以buf应该就是判断数据,ida点进去,发现没有数据

那应该是程序运行时才生成的数据了,我们在判断这里下个断点,在ida进行动态调试,这里调试模式选择window remote debug,然后把ida文件夹对应的程序打开

然后远程调试地址选择127.0.0.1(本机回环地址),进行debug

可以得到buf2的内容,故exp如下:

data=[ 0x0A, 0x0B, 0x7D, 0x2F, 0x7F, 0x67, 0x65, 0x30, 0x63, 0x60,

  0x37, 0x3F, 0x3C, 0x3F, 0x33, 0x3A, 0x3C, 0x3B, 0x35, 0x3C,

  0x3E, 0x6C, 0x64, 0x31, 0x64, 0x6C, 0x3B, 0x68, 0x61, 0x62,

  0x65, 0x36, 0x33, 0x60, 0x62, 0x36, 0x1C, 0x7D]

print(len(data))

for i in range(34,-1,-1):

    data[i+2]^=data[i+3]

    data[i+1]^=data[i+2]

    data[i]^=data[i+1]

for i in range(len(data)):

    print(chr(data[i]),end="")    

flag{37c1b0258164803691d1d193b00ec56a}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IDA(Interactive Disassembler)是一款反汇编工具,版本7.0是其最新版本。动态调试安卓应用程序是使用IDA 7.0进行分析和调试。 首先,我们需要准备一个安卓设备(手机或模拟器)和一台运行IDA 7.0的计算机。 1. 在计算机上安装IDA 7.0,并确保它与安卓设备能够进行通信。可以通过连接设备到计算机,或者使用网络调试器,如Frida或Xposed等。 2. 打开IDA 7.0并创建一个新的分析项目。可以选择从APK文件或已经安装在设备上的应用程序进行分析。 3. 如果选择从APK文件进行分析,可以通过"File"菜单下的"Load File"选项加载APK文件。如果选择从已安装应用程序进行分析,则可以通过"File"菜单下的"Attach to process"选项选择目标应用程序。 4. 一旦应用程序被加载或附加,IDA 7.0会自动进行静态分析,并将汇编代码显示在界面上。 5. 接下来,可以使用IDA 7.0的动态调试功能。通过"Debugger"菜单下的"Debugger options"选项,可以设置断点、单步执行代码、查看和修改寄存器值等。 6. 当应用程序执行到断点处时,IDA 7.0会暂停执行,并显示当前的程序状态。此时,可以查看当前的寄存器、内存内容以及堆栈等信息,以帮助分析程序。 7. 可以通过IDA 7.0的调试功能来逐步执行代码,以便分析应用程序的行为和逻辑。可以在特定的代码位置设置断点,并观察寄存器和内存的变化。 8. 在动态调试过程中,可以使用IDA 7.0的其他功能,如动态数据流分析、函数调用图等来深入分析应用程序。 9. 最后,可以通过"Debugger"菜单下的"Detach"选项或关闭IDA 7.0来结束动态调试。 总之,使用IDA 7.0动态调试安卓应用程序可以帮助我们深入分析程序的执行过程和逻辑,从而更好地理解和修改应用程序的行为。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值