实例程序

1.主函数:

一个64位的linux程序,ida查看函数逻辑:
flag被分成两半进行验证,前半段的验证函数为left_check,后半段函数使用了SMC,这里分析一下具体操作:
  1. 首先调用mmap函数开辟一段内存空间
    1. mmap函数用法分析
      参数介绍:
      1. addr:指定映射的起始地址,通常设为NULL,由内核来分配
      1. length:代表将文件中映射到内存的部分的长度。
      1. prot:映射区域的保护方式。可以为以下几种方式的组合:
        1. PROT_EXEC 映射区域可被执行
        2. PROT_READ 映射区域可被读取
        3. PROT_WRITE 映射区域可被写入
        4. PROT_NONE 映射区域不能存取
      1. flags:映射区的特性标志位,常用的两个选项是:
        1. MAP_SHARD:写入映射区的数据会复制回文件,且运行其他映射文件的进程共享
        2. MAP_PRIVATE:对映射区的写入操作会产生一个映射区的复制,对此区域的修改不会写会原文件
      1. fd:要映射到内存中的文件描述符,有open函数打开文件时返回的值。
      1. offset:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。
      函数返回值:实际分配的内存的起始地址。
  1. cipher()函数先对函数代码解密。
  1. memcpy()函数将解密的代码放入之前开辟的空间
  1. 将后半段flag传入刚刚自解密出来的函数,这里应该是对后半段flag进行加密。
  1. 最后调用right_check()函数对加密后的后半段flag进行验证。

2.前半段Flag解密:

看到wasd判断这可能是个迷宫问题,跟踪数组aAB,其值以放在了注释中,将它手工改成一个二维地图:
notion image
从A点出发到达B点,*号为墙壁,而且看地图可知只有一条路可走:ssddddwddddsss
但是这里还需要注意的是长度要求为15,在后面随便再补一个字符即可ssddddwddddsss
接着是flag的后半段。

3.后半段flag解密:

先看一下自解密函数:
第一个循环中byte_404080处的数据异或上byte_404360处的数据解密出程序代码。在第二个循环解密了一串字符串,这里动调直接看一下解密后的函数与字符串:
notion image
上图就是自解密后的函数可以发现是常规的base64编码,然后查看cipher()函数查看解密后的那64位字符串:
notion image
这个字符串大概率就是当base64的码表来用了,接着查看right_check()函数:
看到这里思路大概就明朗了,后半段的flag做了一次换了码表的base64编码,得出来的结果若为r60ihyZ/m4lseHt+m4t+mIkc则表示后半段flag输入正确,用脚本快速解密:
notion image
至此flag就解出来了:ssddddwddddsss-J1aR@j1w@nch1sh3m3