SSD6 Exercise 1: Decoding Lab

来源:互联网 发布:七天天网络 编辑:程序博客网 时间:2024/06/07 00:04

Secret messages:
From: CTE
To: You
Excellent!You got everything!

Secret keys:
key1:1
key2:777
key3:-1
key4:55


系统及所用工具:
Win10
gcc+gdb(MinGW32)


解题步骤:

1.分析extract_message1(start, stride)方法
由于控制台输出的msg1是extract_message1(start, stride)的返回值,故分析extract_message1(start, stride)方法,可得此方法的作用就是把一个int型的数组(data)中的每一个int数值转换为4个字符,最终从得到的char数组中读取部分字符放入数组message中,当读到‘\0’字符时结束。
参数start,stride的作用简言之即,start就是开始位置,stride就是跳跃的距离
显然,extract_message1这个函数的结果由start和stride决定,而代码中start和stride的值又由dummy来决定

2.求解key1
*((int *)(key1 + *key1)) = *key2;,可得该程序主要是通过引用 key1的地址来相对定位 dummy的值, 然后用 key2的值来赋给 dummy。而 key1的位置和 dummy的位置相对距离是固定的,通过debug找出 key1和 dummy的距离(这个距离就是通过 *key1来赋值的)。
(这里key1是main中key1的地址,*key1等于main中的key1),调试信息如下图
这里写图片描述
key1=(0x61ff1c-0x61ff18)/4=1

3.求解参数start和stride
编写代码把data数组转换字符数组显示出来,代码及运行结果如下图,
这里写图片描述
这里写图片描述

观察所输出字符串,为了能得到“From”,易判定start=9,stride=3

4.求解key2

start = (int)(*(((char *)&dummy)));stride = (int)(*(((char *)&dummy) + 1));

由上述代码可得,start等于dummy最低地址那一字节中的数值;stride等于dummy第二低地址那一字节中的数值。即dummy的值后两个字节满足03,09(16进制),显然满足此条件的key2值有777等无穷个。
编写代码输出key2=777时该字符串的值,运行结果如下
这里写图片描述
符合题目文档中的提示,故key2=777

5.求解key3
通过代码及提示,可知应使程序进入并执行 msg2 = extract_message2(start, stride);但是从正常的程序逻辑上看,无法使 msg1为空而顺利进入到if语句块中,因此可知应该在process_keys34中做出调整,猜测修改了函数的返回地址。根据函数调用的堆栈原理,易得下图
这里写图片描述
返回地址就在 key3的下面,只需要在 key3基础上-1(这个-1是在 int下的,实际上在地址层面应该是 -4),又因为

void process_keys34 (int * key3, int * key4) {     *(((int *)&key3) + *key3) += *key4;}

所以key3的值 为-1

6.求解key4
分析易得,key4的值是之前的返回地址和期望程序抵达的返回地址,
(即第一句process_keys34(&key3, &key4);返回地址和第二句process_keys34(&key3, &key4);返回地址的差值)
利用gdb**查看main函数的汇编**,如下图
这里写图片描述
下图为main函数中以下几句代码的汇编,

msg1 = extract_message1(start, stride);if (*msg1 == '\0') {        process_keys34(&key3, &key4);        msg2 = extract_message2(start, stride);

这里写图片描述
观察得,main+300 是之前保存在栈帧中的返回地址,而期望程序返回时直接到达 main+355,故 key4 的值为:355-300=55

7.代入解密
代入以上所求参数(1,777,-1,55),运行源文件解密,获得信息如图
这里写图片描述

原创粉丝点击