• [HNCTF 2022 WEEK2]e@sy_flower


    花指令分析
    如果没接触过花指令,先看这个博客,大致了解一下花指令

    https://www.cnblogs.com/Here-is-SG/p/15802040.html

    点击此处下载附件

    查壳

    32位,无壳
    image.png

    去除花指令

    用32位ida打开,就看到红色字体的XREF(非自然程序流程,可以用它对程序流进行跟踪和控制,估计以后有的学了),这时候F5反编译,发现没有反应,再联系题目,推测有花指令(也就是红色字体的XREF)影响ida进行编译。
    image.png
    又看到它附近有jz和jnz
    image.png
    我们找到地址loc_4010D4,然后按u
    可以发现loc_4010D4+1的+1没了,变成函数unk_4010D5
    image.png
    然后从有XREF的这一行选中下面所有数据,按c,选择Analyze
    image.png
    按完后,就变成正常的汇编代码了
    image.png
    然后需要把db 0E9h进行nop处理,使数据变成90,再按c,变成汇编代码
    image.png
    image.png
    再在上面翻,找到主函数并在此处按p,解析成函数,即可F5了
    image.png
    image.png
    F5,查看伪代码
    image.png

    分析代码

    int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
    {
      signed int v3; // kr00_4
      int i; // edx
      char v5; // cl
      unsigned int j; // edx
      int v7; // eax
      char v8; // [esp+0h] [ebp-44h]
      char v9; // [esp+0h] [ebp-44h]
      char Arglist[48]; // [esp+10h] [ebp-34h] BYREF
    
      sub_401020("please input flag\n", v8);
      sub_401050("%s", (char)Arglist);
      v3 = strlen(Arglist);
      for ( i = 0; i < v3 / 2; ++i )
      {
        v5 = Arglist[2 * i];
        Arglist[2 * i] = Arglist[2 * i + 1];
        Arglist[2 * i + 1] = v5;
      }
      for ( j = 0; j < strlen(Arglist); ++j )
        Arglist[j] ^= 0x30u;
      v7 = strcmp(Arglist, "c~scvdzKCEoDEZ[^roDICUMC");
      if ( v7 )
        v7 = v7 < 0 ? -1 : 1;
      if ( !v7 )
      {
        sub_401020("yes", v9);
        exit(0);
      }
      sub_401020("error", v9);
      exit(0);
    }
    

    这段代码的意思是将flag先后经过两次for循环加密,最后得到字符串c~scvdzKCEoDEZ[^roDICUMC

    写脚本

    flag = [0] * 24
    tmp = 'c~scvdzKCEoDEZ[^roDICUMC'
    
    for i in range(0,24):
        flag[i] = chr(ord(tmp[i]) ^ 48)
    
    for i in range(0,12):
        v5 = flag[2 * i]
        flag[2 * i] = flag[2 * i + 1]
        flag[2 * i + 1] = v5
    
    print("".join(flag))
    

    写这个脚本遇到的困难:

    • 不知道字符串怎么和数字进行异或

    解决:
    第一步:将flag初始化为固定长度的列表:flag = [0] * 24。

    在Python中,[0] * 24表示创建一个包含24个0的列表。这种语法可以用来快速创建指定长度的列表,并将其初始化为相同的值。在这个例子中,我们创建了一个长度为24的列表,并将其初始化为0。这个列表在后续的代码中被用来存储计算结果。

    第二步:先将tmp字符串转换成整数,即加个ord()函数,然后与数字进行异或,异或完之后再转换成字符,即加个chr()函数。

    ord()函数主要用于将字符转换为整数,即获取ASCII给定字符的值;返回的结果是对应字符的ASCII码
    chr()函数是ord()函数的配对函数,主要用一个范围内的整数作参数,返回的结果是对应的字符,可以用十进制或者十六进制。

    • 最后如果直接输出flag,是个序列形式,不方便

    image.png
    解决:
    使用Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
    image.png
    这样就好多了
    flag:**NSSCTF{Just_junk_Bytess}**

  • 相关阅读:
    docker命令介绍,镜像制作,容器启动,进入容器操作等
    C++的运算符重载介绍
    《昇思25天学习打卡营第18天|热门LLM及其他AI应用-基于MindNLP+基于MindSpore的红酒分类实验》
    大数据技术原理与应用
    重新认识 IP地址
    windows安装redis
    以太网 TCP协议(TCP交互过程中出现丢包时的解决机制-列举部分)
    java计算机毕业设计桔子酒店客房管理系统源程序+mysql+系统+lw文档+远程调试
    输出调节求解跟踪问题(二阶线性系统)
    itextpdf代码生成pdf直接下载
  • 原文地址:https://www.cnblogs.com/Zer0o/p/17726235.html