题目

CSDN免积分下载

文件

先查壳,有壳脱壳,没壳拖入IDA
gcc编译的32位无壳ELF
image.png

IDA

image.png

答案

9447{you_are_an_international_mystery}

解题

查看Writeup

运行报错

image.png
代码里没有什么特殊处理,搜索报的字符串,推测应该是gcc编译器的问题😅
image.png

代码逻辑

main函数里面4个函数,前面的两个明显是初始化和提示性字符串,不是很重要。但是可以通过提示性字符串,查看打印字符串的交叉引用处(“X”键),发现被调用次数不多,选择相对而言稍微靠后一点的位置,继而定位flag的输出处:
image.png

打印Flag的函数

s2是内置的密文动态解密(decrypt函数)返回的字符串,与输入的字符串相同时,打印提示成功的字符串。
所以s2就是Flag:
image.png

解题方式

1️⃣动态调试

在解密函数decrypt下一行下断后运行,或者在这行按F4。返回值EAX就是s2,在Hex窗口右击,选择Synchronize with-EAX:
image.png
复制Flag时注意堆地址不要错(不要从“1”开始复制):
image.png

2️⃣静态分析算法

decrypt

解密的运算为减法运算,减数和被减数(两个参数)都为wchar类型:
image.png
在IDA View窗口中将其定义为数组后,发现这两个参数的值很有规律:
image.png
数据为:

  1. #减数
  2. Minus = [ 0x143A, 0x1436, 0x1437, 0x143B, 0x1480, 0x147A, 0x1471, 0x1478, 0x1463, 0x1466, 0x1473, 0x1467, 0x1462, 0x1465, 0x1473, 0x1460, 0x146B, 0x1471, 0x1478, 0x146A, 0x1473, 0x1470, 0x1464, 0x1478, 0x146E, 0x1470, 0x1470, 0x1464, 0x1470, 0x1464, 0x146E, 0x147B, 0x1476, 0x1478, 0x146A, 0x1473, 0x147B, 0x1480 ][ 0x143A, 0x1436, 0x1437, 0x143B, 0x1480, 0x147A, 0x1471, 0x1478, 0x1463, 0x1466, 0x1473, 0x1467, 0x1462, 0x1465, 0x1473, 0x1460, 0x146B, 0x1471, 0x1478, 0x146A, 0x1473, 0x1470, 0x1464, 0x1478, 0x146E, 0x1470, 0x1464, 0x1470, 0x1464, 0x146E, 0x147B, 0x1476, 0x1478, 0x146A, 0x1473, 0x147B, 0x1480 ]
  3. #被减数
  4. Minute = [ 0x1401, 0x1402, 0x1403, 0x1404, 0x1405 ]

还原算法

逻辑很简单,就是将两个数组相减的差值以字符串类型输出

🐍Python代码🐍

  1. #减数
  2. listMinus = [ 0x143A, 0x1436, 0x1437, 0x143B, 0x1480, 0x147A, 0x1471, 0x1478, 0x1463, 0x1466, 0x1473, 0x1467, 0x1462, 0x1465, 0x1473, 0x1460, 0x146B, 0x1471, 0x1478, 0x146A, 0x1473, 0x1470, 0x1464, 0x1478, 0x146E, 0x1470, 0x1470, 0x1464, 0x1470, 0x1464, 0x146E, 0x147B, 0x1476, 0x1478, 0x146A, 0x1473, 0x147B, 0x1480 ]
  3. lenMinus = len(listMinus)
  4. #被减数
  5. listMinute = [0x1401, 0x1402, 0x1403, 0x1404, 0x1405]
  6. lenMinute = len(listMinute)
  7. flag = ''
  8. #减数下标
  9. indexMinus = 0
  10. while indexMinus<lenMinus:
  11. #被减数下标
  12. indexMinute = 0
  13. while indexMinute<lenMinute and indexMinus<lenMinus:
  14. listMinus[indexMinus] -= listMinute[indexMinute]
  15. flag += chr(listMinus[indexMinus])
  16. indexMinus += 1
  17. indexMinute += 1
  18. print(flag)

image.png

⚠数据显示问题之显示格式⚠

一开始的Python代码写好后却数据出错:
image.png
打印出的错误字符串长度为37,检查了一下减数列表,长度也为37,按道理来说应该是没错的。(错了,实际正确答案的长度是38
接着检查While条件,依旧没错。
打印出现乱码的字符串处(print(hex(listMinus[25]))),值为0x1470,也是符合这个题目数据的范围的。
最后确认一下数据,发现原来是IDA将“0x1470, 0x1470”显示为“dup(1470h)”:
image.png
导致进行运算的列表从正确的38个元素,被处理为37个元素,从下标25处偏差了一位。
IDA的显示的雷点有点多😣

😎解决方案 - 导出数据😎

IDA经常出现数据的各种识别和显示问题,在此题中,数据中有相邻的重复项,被处理为dup(数据)。
比较安全保险的方式为从内存中复制:
image.png
但是还会复制多余的数据。
IDA自带一个功能——导出数据,Shift+E,可直接将选中的数据以多种格式导出:
image.png
但是没有符合我已经写好的Python的数据格式😥

👍解决方案 - Convert to array👍

发现原来“dup”是可以取消的:
image.png
取消后显示如下:
image.png