首先的解题思路是假设 argv[1]="1";
argv[2]="2";
argv[3]="3";
argv[4]="4";
第一个目的是解出 key1 key2 。
通过题目中的提示,“realize that the function process_keys12
must be somehow changing the value of the dummy
variable. This must be so, because the variables start
and stride
control the extraction of the message, and they are calculated from the value of dummy
.”
不难看出 dummy的真实值 就是由key1 key2 解出。
源代码中有有一条语句是:
void process_keys12 (int * key1, int * key2) {
*((int *) (key1 + *key1)) = *key2;
}
这个方法的目的在于 通过对程序内存地址的数据变化,来间接的改变dummy的值。
((int *) (key1 + *key1)) 表示的就是dummy的地址 。而将key2 的值赋值给dummy的内存地址中 。
所以通过这个方法之后,dummy的真实值已经悄悄的变为了 key2 的值 。
所以程序中dummy的地址与key1的内存地址的偏移量就是 key1的值
Key1 =3 是可以确定的了。
但是dummy的值变为多少? 我们现在是不知道的,只是知道了 dummy=key2.
假设dummy的值是 513 。
在内存中的表示就是:00000000
00000000
00000001
00000010
程序是通过语句: start = (int)(*(((char *) &dummy)));
stride = (int)(*(((char *) &dummy) + 1));
得到start 和 stride 的值。 显而易见, start就是 00000010 stride就是00000001 。
所以start 和 stride 的值决定 key2的值。
而在持续中 start 和 stride 联合控制这一关于输出的循环程序。
char * extract_message1(int start, int stride) {
int i, j, k;
int done = 0;
for (i = 0, j = start + 1; ! done; j++) {
for (k = 1; k < stride; k++, j++, i++) {
if (*(((char *) data) + j) == '/0') {
done = 1;
break;
}
message[i] = *(((char *) data) + j);
}
}
message[i] = '/0';
return message;
}
而题目中说道,这个循环程序的输出的开头是From 。
让我们查查 ASC码表 :F:46 r:72 o: 6F m:6D
而这个循环的特点是 开始点由start 决定 连续读的字符个数由 stride决定 。
所以不难看出 要想输出From 经过推算 start就是9 (00001001) stride就是3(00000011)
所以dummy就是 00000000
00000000
00000011
00001001
是777 。
所以key2 就是777.
第二个目的是解出 key3 key4 。