首先的解题思路是假设 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 。
解析内存操作与输出控制
本文解析了一个涉及内存地址操作及输出控制的程序问题。通过分析关键函数process_keys12的作用,确定了key1和key2的具体数值,并进一步探讨了start和stride变量如何影响输出循环,最终解出key3和key4。
5633

被折叠的 条评论
为什么被折叠?



