重定位本进程的标准输出(非子进程)

PS:标准输入/标准错误 ,参考这个来弄吧。

 

环境:Win7(32位/64位),VC6

 

1、

 1 int main()
 2 {
 3     printf("*stdin : %x\n", *stdin);
 4     printf("*stdout : %x\n", *stdout);
 5     printf("*stderr : %x\n", *stderr);
 6 
 7     printf("stdin : %x\n", stdin);
 8     printf("stdout : %x\n", stdout);
 9     printf("stderr : %x\n", stderr);
10 
11     printf("GetStdHandle(STD_INPUT_HANDLE) return : %x\n", GetStdHandle(STD_INPUT_HANDLE));
12     printf("GetStdHandle(STD_OUTPUT_HANDLE) return : %x\n", GetStdHandle(STD_OUTPUT_HANDLE));
13     printf("GetStdHandle(STD_ERROR_HANDLE) return : %x\n", GetStdHandle(STD_ERROR_HANDLE));
14 
15     return 0;
16 }

 

 

 

得到的结果为:

*stdin : 429620
*stdout : 0
*stderr : 0
stdin : 425a30
stdout : 425a50
stderr : 425a70
GetStdHandle(STD_INPUT_HANDLE) return : 3
GetStdHandle(STD_OUTPUT_HANDLE) return : 7
GetStdHandle(STD_ERROR_HANDLE) return : b

 

2、

http://bbs3.driverdevelop.com/read.php?tid-98473-page-e.html 中 五楼说到:

SetStdHandle 仅仅是对 Peb->ProcessParameters里的 StandardInput 、StandardOutput 、StandardError 3个变量的赋值而已。

printf内部实现类似于
  sprintf(buf,format,arglist)
  fwrite(stdout,buf);

其中stdout为CRT内部变量,在初始化时已经被设置为 stdout=GetStdHandle(STD_OUTPUT_HANDLE);
(具体看CRT代码,ioinit()),所以,即使你在程序里改变了Peb->ProcessParameters里的 StandardOutput ,stdout没有变化

想重定向PRINTF之类标准库函数,想办法改变stdout吧

2.1、

我看了 _ioinit() 里面条用了 宏stdhndl,确实 在_ioinit()中,有 “GetStdHandle(STD_INPUT_HANDLE);”、“GetStdHandle(STD_OUTPUT_HANDLE);”、“GetStdHandle(STD_ERROR_HANDLE);”,但是 是如何 赋值给 stdin、stdout、stderr 的  这个没看出来...

 

2.2、

printf 

 

2.3、

关于上面说到的 “Peb->ProcessParameters里的 StandardInput 、StandardOutput 、StandardError”,可以使用 WinDBG查看相关结构中的相关属性值,但是暂时还未自己亲手查看验证过...

 

 3、

 

 

 

PS:测试代码:

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 #include <io.h>
 5 #include <Fcntl.h>
 6 
 7 int main()
 8 {
 9     printf("*stdin : %x\n", *stdin);
10     printf("*stdout : %x\n", *stdout);
11     printf("*stderr : %x\n", *stderr);
12     printf("\n");
13 
14     printf("GetStdHandle(STD_INPUT_HANDLE) return : %x\n", GetStdHandle(STD_INPUT_HANDLE));
15     printf("GetStdHandle(STD_OUTPUT_HANDLE) return : %x\n", GetStdHandle(STD_OUTPUT_HANDLE));
16     printf("GetStdHandle(STD_ERROR_HANDLE) return : %x\n", GetStdHandle(STD_ERROR_HANDLE));
17     printf("\n");
18 
19     STARTUPINFO si = {0};
20     si.cb = sizeof(STARTUPINFO);
21 
22         GetStartupInfo(&si);
23         printf("si.hStdOutput(1) : %x\n", si.hStdOutput);
24 
25         SetStdHandle(STD_OUTPUT_HANDLE, (void*)100);
26 
27         GetStartupInfo(&si);
28         printf("si.hStdOutput(2) : %x\n", si.hStdOutput);
29 
30 
31     printf("\n");
32 
33     printf("*stdin : %x\n", *stdin);
34     printf("*stdout : %x\n", *stdout);
35     printf("*stderr : %x\n", *stderr);
36     printf("\n");
37 
38     printf("GetStdHandle(STD_INPUT_HANDLE) return : %x\n", GetStdHandle(STD_INPUT_HANDLE));
39     printf("GetStdHandle(STD_OUTPUT_HANDLE) return : %x\n", GetStdHandle(STD_OUTPUT_HANDLE));
40     printf("GetStdHandle(STD_ERROR_HANDLE) return : %x\n", GetStdHandle(STD_ERROR_HANDLE));
41 
42     return 0;
43 }

控制台输出:

 1 *stdin : 4285e0
 2 *stdout : 0
 3 *stderr : 0
 4 
 5 GetStdHandle(STD_INPUT_HANDLE) return : 3
 6 GetStdHandle(STD_OUTPUT_HANDLE) return : 7
 7 GetStdHandle(STD_ERROR_HANDLE) return : b
 8 
 9 si.hStdOutput(1) : ffffffff
10 si.hStdOutput(2) : ffffffff
11 
12 *stdin : 4285e0
13 *stdout : 0  // ZC: 这个值不改变的话,本进程的 标准输出流 是没有被重定向的。
14 *stderr : 0
15 
16 GetStdHandle(STD_INPUT_HANDLE) return : 3
17 GetStdHandle(STD_OUTPUT_HANDLE) return : 64  // ZC: 只有这个值 改变了
18 GetStdHandle(STD_ERROR_HANDLE) return : b
19 Press any key to continue

 

 

 

 

A

 

posted @ 2015-11-09 10:56  CodeSkill  阅读(588)  评论(0编辑  收藏  举报