user-0 提问: 一道笔试题。。求答案

回复:
user: user-1
content: void  fun(void) { int i = 4; (&i+3) = 100; }

user: user-0
content: 感谢大家，结贴了。。

user: user-2
content: 引用 27 楼 halleyzhang3 的回复:开阔思路的题吧，除了前面说到的结束进程、堆栈溢出方法外，我再给一个： int fun(void) { #define printf } good

user: user-3
content: 引用 58 楼 lunat 的回复:void fun() { #define printf(fmt, a, b) puts("Not 1, 2!") } 引用 45 楼 download_wg 的回复: void fun(void) { 	void** p;  	_asm 	{ 		mov p,ebp 	}  	*((int*)*p-1) = 324523; 	*((int*)*p-2) = 1345; }   char ch = 0; 	char *p = &ch; 	printf("%p\n", p); 	p += 88;//前提需要知道这个偏移量 	*(int *)p = 300; 	*(int *)(p + 4) = 400;  个人觉得嵌入汇编最理想的，直接找到帧地址，向上偏移一定字节数即可，58L，最简洁。

user: user-4
content: //1. void fun(void) {     #define fun() do {\         x = 123;\         y = 456;\     } while (0) }  int main() {     int x = 1;     int y = 2;     fun();     printf("x,y%d %d\n",x,y);          system("pause");     return 0; }   //2. void fun(void) {     /**add begin**/     }     int main()     {         printf("fuck\n");         system("pause");         return 0;     #define main useless     /**add end**/ }  int main() {     int x = 1;     int y = 2;     fun();     printf("x,y%d %d\n",x,y);          system("pause");     return 0; }  //3. 和编译器相关，VC6下应该可以 void fun(void) {     int *shit = *((int **)(&shit + 1));     *--shit = 123;     *--shit = 456; }  int main() {     int x = 1;     int y = 2;     fun();     printf("x,y%d %d\n",x,y);          system("pause");     return 0; }   //4. 和编译器相关，VC6下应该可以 void fun(void) {    __asm    {        mov eax, [ebp]        mov dword ptr [eax - 4], 123        mov dword ptr [eax - 8], 456    } }  int main() {     int x = 1;     int y = 2;     fun();     printf("x,y%d %d\n",x,y);          system("pause");     return 0; }

user: user-5
content: 把字符串常量修改了  #include <stdio.h> void foo() { #pragma comment(linker,"/SECTION:.rdata,RW") 	char* p = "%d, %d\n"; 	p[0] = 0; 	puts("3,4"); }  int main() { 	int x = 1; 	int y = 2; 	foo(); 	printf("%d, %d\n", x , y); }

user: user-5
content: 趁周末有时间，写了一个实现。// 这个示例代码不具有移植性 // #include <stdio.h> //__declspec(noinline)是vc的扩展属性 __declspec(noinline) void   foo() { 	int* vebp; 	//intel 汇编 	__asm mov vebp, ebp 	printf("0x%08x\n", vebp[1]); 	//修改函数返回地址（即ebp[1]),跳过执行printf("%d,%d\n",x, y); 	// printf("%d,%d\n",x, y) 在vc 2013的debug和release分别需要0x1f和0x12个字节 #if _DEBUG 	vebp[1] += 0x1f; #else  	vebp[1] += 0x12; #endif }  int main()  { 	int x = 1; 	int y = 2; 	foo(); 	printf("%d,%d\n",x, y); }

user: user-5
content: 引用 58 楼 lunat 的回复:void fun() { #define printf(fmt, a, b) puts("Not 1, 2!") }  好办法！！

user: user-6
content: void fun() { #define printf(fmt, a, b) puts("Not 1, 2!") }

user: user-5
content: 引用 56 楼 zhan0903 的回复:[quote=引用 54 楼 mujiok2003 的回复:] [quote=引用 53 楼 zhan0903 的回复:] [quote=引用 48 楼 mujiok2003 的回复:] [quote=引用 26 楼 max_min_ 的回复:] [quote=引用 25 楼 zhan0903 的回复:] [quote=引用 24 楼 yulitingfeng 的回复:] #include <stdio.h>  #pragma pack(push)  int fun(void) {         int a=0;         int *p;         p=&a;         while(*p!=1)         {          p++;         }         *p=10; }  int main() {         int x=1;         int y=2;         fun();         printf("%d %d\n",x,y); }  #pragma pack(pop) 遍历下就可以吧  运行确实是可以的，但是，，能不能解释下代码？[/quote] 遍历地址值，通过地址修改内容。。[/quote]  这是不可靠的。  int x=1;         int y=2;         fun();         printf("%d %d\n",x,y);可以完全可以优化成fun();printf("%d %d\n", 1, 2);[/quote]  什么意思？编译器进行的优化？[/quote]  vc 2013 release结果:  0FC0FFC  add         byte ptr [eax],al   00FC0FFE  add         byte ptr [eax],al   --- c:\users\bruce\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp  	int a = 1, b = 2; 	foo(); 	printf("%d %d", a, b); 00FC1000  push        2  //不访问b 00FC1002  push        1  //没有访问a 00FC1004  push        0FC2100h   00FC1009  call        dword ptr ds:[0FC2090h]   00FC100F  add         esp,0Ch   [/quote] push 2 push 1 不就是访问了a和b？ 局部变量入栈？[/quote] 这是常量，在代码段中

user: user-0
content: 引用 54 楼 mujiok2003 的回复:[quote=引用 53 楼 zhan0903 的回复:] [quote=引用 48 楼 mujiok2003 的回复:] [quote=引用 26 楼 max_min_ 的回复:] [quote=引用 25 楼 zhan0903 的回复:] [quote=引用 24 楼 yulitingfeng 的回复:] #include <stdio.h>  #pragma pack(push)  int fun(void) {         int a=0;         int *p;         p=&a;         while(*p!=1)         {          p++;         }         *p=10; }  int main() {         int x=1;         int y=2;         fun();         printf("%d %d\n",x,y); }  #pragma pack(pop) 遍历下就可以吧  运行确实是可以的，但是，，能不能解释下代码？[/quote] 遍历地址值，通过地址修改内容。。[/quote]  这是不可靠的。  int x=1;         int y=2;         fun();         printf("%d %d\n",x,y);可以完全可以优化成fun();printf("%d %d\n", 1, 2);[/quote]  什么意思？编译器进行的优化？[/quote]  vc 2013 release结果:  0FC0FFC  add         byte ptr [eax],al   00FC0FFE  add         byte ptr [eax],al   --- c:\users\bruce\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp  	int a = 1, b = 2; 	foo(); 	printf("%d %d", a, b); 00FC1000  push        2  //不访问b 00FC1002  push        1  //没有访问a 00FC1004  push        0FC2100h   00FC1009  call        dword ptr ds:[0FC2090h]   00FC100F  add         esp,0Ch   [/quote] push 2 push 1 不就是访问了a和b？ 局部变量入栈？

user: user-5
content: 引用 61 楼 zhan0903 的回复:[quote=引用 57 楼 mujiok2003 的回复:] [quote=引用 56 楼 zhan0903 的回复:] [quote=引用 54 楼 mujiok2003 的回复:] [quote=引用 53 楼 zhan0903 的回复:] [quote=引用 48 楼 mujiok2003 的回复:] [quote=引用 26 楼 max_min_ 的回复:] [quote=引用 25 楼 zhan0903 的回复:] [quote=引用 24 楼 yulitingfeng 的回复:] #include <stdio.h>  #pragma pack(push)  int fun(void) {         int a=0;         int *p;         p=&a;         while(*p!=1)         {          p++;         }         *p=10; }  int main() {         int x=1;         int y=2;         fun();         printf("%d %d\n",x,y); }  #pragma pack(pop) 遍历下就可以吧  运行确实是可以的，但是，，能不能解释下代码？[/quote] 遍历地址值，通过地址修改内容。。[/quote]  这是不可靠的。  int x=1;         int y=2;         fun();         printf("%d %d\n",x,y);可以完全可以优化成fun();printf("%d %d\n", 1, 2);[/quote]  什么意思？编译器进行的优化？[/quote]  vc 2013 release结果:  0FC0FFC  add         byte ptr [eax],al   00FC0FFE  add         byte ptr [eax],al   --- c:\users\bruce\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp  	int a = 1, b = 2; 	foo(); 	printf("%d %d", a, b); 00FC1000  push        2  //不访问b 00FC1002  push        1  //没有访问a 00FC1004  push        0FC2100h   00FC1009  call        dword ptr ds:[0FC2090h]   00FC100F  add         esp,0Ch   [/quote] push 2 push 1 不就是访问了a和b？ 局部变量入栈？[/quote] 这是常量，在代码段中[/quote] 可否详细解释下？这个没有取a和b的值是不是和编译器优化有关？换一种编译器会不会取a和b的值？[/quote]  寻址方式：立即数

user: user-5
content: 引用 61 楼 zhan0903 的回复:[quote=引用 57 楼 mujiok2003 的回复:] [quote=引用 56 楼 zhan0903 的回复:] [quote=引用 54 楼 mujiok2003 的回复:] [quote=引用 53 楼 zhan0903 的回复:] [quote=引用 48 楼 mujiok2003 的回复:] [quote=引用 26 楼 max_min_ 的回复:] [quote=引用 25 楼 zhan0903 的回复:] [quote=引用 24 楼 yulitingfeng 的回复:] #include <stdio.h>  #pragma pack(push)  int fun(void) {         int a=0;         int *p;         p=&a;         while(*p!=1)         {          p++;         }         *p=10; }  int main() {         int x=1;         int y=2;         fun();         printf("%d %d\n",x,y); }  #pragma pack(pop) 遍历下就可以吧  运行确实是可以的，但是，，能不能解释下代码？[/quote] 遍历地址值，通过地址修改内容。。[/quote]  这是不可靠的。  int x=1;         int y=2;         fun();         printf("%d %d\n",x,y);可以完全可以优化成fun();printf("%d %d\n", 1, 2);[/quote]  什么意思？编译器进行的优化？[/quote]  vc 2013 release结果:  0FC0FFC  add         byte ptr [eax],al   00FC0FFE  add         byte ptr [eax],al   --- c:\users\bruce\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp  	int a = 1, b = 2; 	foo(); 	printf("%d %d", a, b); 00FC1000  push        2  //不访问b 00FC1002  push        1  //没有访问a 00FC1004  push        0FC2100h   00FC1009  call        dword ptr ds:[0FC2090h]   00FC100F  add         esp,0Ch   [/quote] push 2 push 1 不就是访问了a和b？ 局部变量入栈？[/quote] 这是常量，在代码段中[/quote] 可否详细解释下？这个没有取a和b的值是不是和编译器优化有关？换一种编译器会不会取a和b的值？[/quote] 跟编译器有关，跟优化有关。

user: user-0
content: 引用 57 楼 mujiok2003 的回复:[quote=引用 56 楼 zhan0903 的回复:] [quote=引用 54 楼 mujiok2003 的回复:] [quote=引用 53 楼 zhan0903 的回复:] [quote=引用 48 楼 mujiok2003 的回复:] [quote=引用 26 楼 max_min_ 的回复:] [quote=引用 25 楼 zhan0903 的回复:] [quote=引用 24 楼 yulitingfeng 的回复:] #include <stdio.h>  #pragma pack(push)  int fun(void) {         int a=0;         int *p;         p=&a;         while(*p!=1)         {          p++;         }         *p=10; }  int main() {         int x=1;         int y=2;         fun();         printf("%d %d\n",x,y); }  #pragma pack(pop) 遍历下就可以吧  运行确实是可以的，但是，，能不能解释下代码？[/quote] 遍历地址值，通过地址修改内容。。[/quote]  这是不可靠的。  int x=1;         int y=2;         fun();         printf("%d %d\n",x,y);可以完全可以优化成fun();printf("%d %d\n", 1, 2);[/quote]  什么意思？编译器进行的优化？[/quote]  vc 2013 release结果:  0FC0FFC  add         byte ptr [eax],al   00FC0FFE  add         byte ptr [eax],al   --- c:\users\bruce\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp  	int a = 1, b = 2; 	foo(); 	printf("%d %d", a, b); 00FC1000  push        2  //不访问b 00FC1002  push        1  //没有访问a 00FC1004  push        0FC2100h   00FC1009  call        dword ptr ds:[0FC2090h]   00FC100F  add         esp,0Ch   [/quote] push 2 push 1 不就是访问了a和b？ 局部变量入栈？[/quote] 这是常量，在代码段中[/quote] 可否详细解释下？这个没有取a和b的值是不是和编译器优化有关？换一种编译器会不会取a和b的值？

user: user-5
content: 引用 53 楼 zhan0903 的回复:[quote=引用 48 楼 mujiok2003 的回复:] [quote=引用 26 楼 max_min_ 的回复:] [quote=引用 25 楼 zhan0903 的回复:] [quote=引用 24 楼 yulitingfeng 的回复:] #include <stdio.h>  #pragma pack(push)  int fun(void) {         int a=0;         int *p;         p=&a;         while(*p!=1)         {          p++;         }         *p=10; }  int main() {         int x=1;         int y=2;         fun();         printf("%d %d\n",x,y); }  #pragma pack(pop) 遍历下就可以吧  运行确实是可以的，但是，，能不能解释下代码？[/quote] 遍历地址值，通过地址修改内容。。[/quote]  这是不可靠的。  int x=1;         int y=2;         fun();         printf("%d %d\n",x,y);可以完全可以优化成fun();printf("%d %d\n", 1, 2);[/quote]  什么意思？编译器进行的优化？[/quote]  vc 2013 release结果:  0FC0FFC  add         byte ptr [eax],al   00FC0FFE  add         byte ptr [eax],al   --- c:\users\bruce\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp  	int a = 1, b = 2; 	foo(); 	printf("%d %d", a, b); 00FC1000  push        2  //不访问b 00FC1002  push        1  //没有访问a 00FC1004  push        0FC2100h   00FC1009  call        dword ptr ds:[0FC2090h]   00FC100F  add         esp,0Ch

user: user-0
content: 引用 48 楼 mujiok2003 的回复:[quote=引用 26 楼 max_min_ 的回复:] [quote=引用 25 楼 zhan0903 的回复:] [quote=引用 24 楼 yulitingfeng 的回复:] #include <stdio.h>  #pragma pack(push)  int fun(void) {         int a=0;         int *p;         p=&a;         while(*p!=1)         {          p++;         }         *p=10; }  int main() {         int x=1;         int y=2;         fun();         printf("%d %d\n",x,y); }  #pragma pack(pop) 遍历下就可以吧  运行确实是可以的，但是，，能不能解释下代码？[/quote] 遍历地址值，通过地址修改内容。。[/quote]  这是不可靠的。  int x=1;         int y=2;         fun();         printf("%d %d\n",x,y);可以完全可以优化成fun();printf("%d %d\n", 1, 2);[/quote]  什么意思？编译器进行的优化？

user: user-7
content: 问，如何实现函数fun，使得最后的结果是下载整个互联网内容到本机？！

user: user-8
content: 引用 50 楼 qq523176585 的回复:[quote=引用 49 楼 download_wg 的回复:] [quote=引用 47 楼 qq523176585 的回复:] [quote=引用 46 楼 download_wg 的回复:] 看了半天才想通 int arr[1] = {0}; int *p = (int *)(arr[1]);   --不报错、或者告警没想通啊  虽然感觉跟下面这个是一样的 void fun(void) {  	int k; 	int* p =&k; 	*((int*)*(p +1) - 1)  = 100; 	*((int*)*(p +1) - 2)  = 200;  	/*void** p;  	_asm 	{ 		mov p,ebp 	}  	*((int*)*p-1) = 324523; 	*((int*)*p-2) = 1345;*/ }   为什么要报错或者警告呢，你觉得哪里不对？[/quote]  我把东西都丢光了，arr[1]不是该越界么[/quote]   C语言不是不检查越界吗？为什么要报错呢[/quote]  这个我不知道，尴尬了

user: user-9
content: 引用 49 楼 download_wg 的回复:[quote=引用 47 楼 qq523176585 的回复:] [quote=引用 46 楼 download_wg 的回复:] 看了半天才想通 int arr[1] = {0}; int *p = (int *)(arr[1]);   --不报错、或者告警没想通啊  虽然感觉跟下面这个是一样的 void fun(void) {  	int k; 	int* p =&k; 	*((int*)*(p +1) - 1)  = 100; 	*((int*)*(p +1) - 2)  = 200;  	/*void** p;  	_asm 	{ 		mov p,ebp 	}  	*((int*)*p-1) = 324523; 	*((int*)*p-2) = 1345;*/ }   为什么要报错或者警告呢，你觉得哪里不对？[/quote]  我把东西都丢光了，arr[1]不是该越界么[/quote]   C语言不是不检查越界吗？为什么要报错呢

user: user-8
content: 引用 47 楼 qq523176585 的回复:[quote=引用 46 楼 download_wg 的回复:] 看了半天才想通 int arr[1] = {0}; int *p = (int *)(arr[1]);   --不报错、或者告警没想通啊  虽然感觉跟下面这个是一样的 void fun(void) {  	int k; 	int* p =&k; 	*((int*)*(p +1) - 1)  = 100; 	*((int*)*(p +1) - 2)  = 200;  	/*void** p;  	_asm 	{ 		mov p,ebp 	}  	*((int*)*p-1) = 324523; 	*((int*)*p-2) = 1345;*/ }   为什么要报错或者警告呢，你觉得哪里不对？[/quote]  我把东西都丢光了，arr[1]不是该越界么