如何获取到cmd.exe中的消息?



------
请问如何获取到cmd.exe中的消息?比如点击鼠标右键弹出菜单的消息,我用spy++无法获取到cmd窗口,请高手帮忙谢谢
------
还真不能用 sp++ 找 cmd窗口,估计是没有消息循环的缘故


可以用钩子 稍后给你代码
------
所谓钩子是王道,等着楼上的代码吧!
------
根本不是靠注入。
------
study
------
学习了...
------
dir c:\ >c:\1.txt

在读取c:\1.txt 可以吗??
是不是很弱智。。。
------
学习ing
------
学习学习,多谢~
------
学无止境~
------
mark
这个真不知道
------
study
------
学习
------
SPY++只能查找GUI程序,貌似只能重定向和钩子了
------
拜读,学习
------
8楼最正确!C:\Documents and Settings\Administrator\桌面>asdfsfa >1.txt 2>&1
这样错误的信息也会输出到1.txt,就是输出文件后加2>&1
------
引用 4 楼 tr0j4n 的回复:
DOS程序通过一个名为Winoldap的控制台程序来运行,而这个程序则是在32位Windows控制台窗口中运行。原理上,Winoldap利用x86的"Virtual86"模式来虚拟实模式。
创建控制台时,操作系统自动创建三个"标准"文件句柄。在高级控制台编程中,用两个API函数控制这些句柄

GetStdHandle和SetStdHandle

控制台使用的不是我们常见的Win32消息队列,而是事件队列。
事件队列和Windows消息队列差不多,不过是接收输入事件,而非消息。所以Spy++当然得不到消息

ReadConsoleInput可以用来获得控制台的输入,参考

MSDN给出了一个创建标准信息队列的例子

C/C++ code
#include<windows.h>
#include<stdio.h>

VOID ErrorExit(LPSTR);
VOID KeyEventProc(KEY_EVENT_RECORD); 
VOID MouseEventProc(MOUSE_EVENT_RECORD); 
VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);int main(VOID) 

  HANDLE hStdin; 
  DWORD cNumRead, fdwMode, fdwSaveOldMode, i; 
  INPUT_RECORD irInBuf[128];int counter=0;// Get the standard input handle. 
  hStdin= GetStdHandle(STD_INPUT_HANDLE);if (hStdin== INVALID_HANDLE_VALUE) 
  ErrorExit("GetStdHandle");// Save the current input mode, to be restored on exit.if (! GetConsoleMode(hStdin,&fdwSaveOldMode) ) 
  ErrorExit("GetConsoleMode");// Enable the window and mouse input events. 
  fdwMode= ENABLE_WINDOW_INPUT| ENABLE_MOUSE_INPUT;if (! SetConsoleMode(hStdin, fdwMode) ) 
  ErrorExit("SetConsoleMode");// Loop to read and handle the input events.while (counter++<=100) 
  {// Wait for the events.if (! ReadConsoleInput( 
  hStdin,// input buffer handle irInBuf,// buffer to read into128,// size of read buffer&cNumRead) )// number of records read ErrorExit("ReadConsoleInput");// Dispatch the events to the appropriate handler.for (i=0; i< cNumRead; i++) 
  {switch(irInBuf[i].EventType) 
  {case KEY_EVENT:// keyboard input KeyEventProc(irInBuf[i].Event.KeyEvent);break;case MOUSE_EVENT:// mouse input MouseEventProc(irInBuf[i].Event.MouseEvent);break;case WINDOW_BUFFER_SIZE_EVENT:// scrn buf. resizing ResizeEventProc( 
  irInBuf[i].Event.WindowBufferSizeEvent);break;case FOCUS_EVENT:// disregard focus eventscase MENU_EVENT:// disregard menu eventsbreak;default: 
  ErrorExit("Unknown event type");break; 
  } 
  }
  }return0; 
}

VOID ErrorExit (LPSTR lpszMessage) 

  fprintf(stderr,"%s\n", lpszMessage); 
  ExitProcess(0); 
}

VOID KeyEventProc(KEY_EVENT_RECORD ker)
{
  printf("Key event:");if(ker.bKeyDown)
  printf("key pressed\n");else printf("key released\n");
}

VOID MouseEventProc(MOUSE_EVENT_RECORD mer)
{
#ifndef MOUSE_HWHEELED#define MOUSE_HWHEELED 0x0008#endif
  printf("Mouse event:");switch(mer.dwEventFlags)
  {case0:
  printf("button press\n");break;case DOUBLE_CLICK:
  printf("double click\n");break;case MOUSE_HWHEELED:
  printf("horizontal mouse wheel\n");break;case MOUSE_MOVED:
  printf("mouse moved\n");break;case MOUSE_WHEELED:
  printf("vertical mouse wheel\n");break;default:
  printf("unknown\n");break;
  }
}

VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr)
{
  printf("Resize event\n");
}
我就花点事件给你解释下
WINDOW_BUFFER_SIZE_EVENT 屏幕大小改变时发出
MENU_EVENT 用户使用控制台菜单或工具栏时发出
FOCUS_EVENT 控制台得到输入焦点时发出


这是内部实现,当然我们外部也可以获得。利用管道,然后GetStdHandle(STD_INPUT_HANDLE);

然后即可读取Console窗口的事件。

好久没见到这么值得我回,详细解释的帖子。希望对后面看帖的朋友有帮助




------
操作控制台程序得用管道。
------
收藏一下
------
好好学习下
------
浏览一下
------
引用 8 楼 xxbd123 的回复:
dir c:\ >c:\1.txt

在读取c:\1.txt 可以吗??
是不是很弱智。。。

------
dingdddddddddddddddd
------
确实应该学习下了...
------
gz
------
学习学习
------
学习
------
又看一下
------
真的是好东东
------
真的是好的学习!
------
不是吧?楼主问的是窗口消息啊,又不是输入输出
------
DDDDDDDDDDDDDDDD
------
都是高手啊
------
学习了~
------
1 dos 事件序列,学习了
------
学习一下

------
ding
------
。。。
------
学习一下。
------
引用 35 楼 phhawk 的回复:
学习了~

------
sd
------
不行了,收藏了!
------
建立进程,从管道读出
------
看看
------
这个贴子的几个回复确实相当不错,要好好学习一下
------
Console程序是没有窗口消息的
估计楼主是问怎么得到cmd.exe里的文字~
------
这个回复还可以。

引用 2 楼 yxwsbobo 的回复:
C/C++ code
#include<stdio.h>

#include<windows.h>
HHOOK g_ms_hook=0;
HHOOK g_kb_hook=0;


LRESULT CALLBACK kb_proc (int code, WPARAM w, LPARAM l)
{
printf((w==WM_KEYDOWN)?"按下%c\n":"抬起%c\n",((PKBDLLHOOKSTRUCT)l)->vkCode);return CallNextHookEx (g_kb_hook, code, w, l);
}
LRESULT CALLBACK ms_proc (int code, WPARAM w, LPARAM l)
{if(w== WM_LBUTTONDOWN)
printf("按下左键\n");elseif(w== WM_LBUTTONUP)
printf("抬起左键\n");else
printf("x:%d\ty:%d\n",((PMSLLHOOKSTRUCT)l)->pt.x,((PMSLLHOOKSTRUCT)l)->pt.y);return CallNextHookEx (g_ms_hook, code, w, l);
}int main (void)
{
g_kb_hook= SetWindowsHookEx (WH_KEYBOARD_LL,kb_proc,GetModuleHandle (NULL),0);
g_ms_hook= SetWindowsHookEx (WH_MOUSE_LL, ms_proc,GetModuleHandle(NULL),0);if (g_kb_hook== NULL|| g_ms_hook== NULL)
{
printf("安装钩子出错\n");return0;
};
MSG msg;while (GetMessage (&msg, NULL,0,0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
};
UnhookWindowsHookEx (g_kb_hook);return0;
};

------
发错了,是这个回复好。

引用 4 楼 tr0j4n 的回复:
DOS程序通过一个名为Winoldap的控制台程序来运行,而这个程序则是在32位Windows控制台窗口中运行。原理上,Winoldap利用x86的"Virtual86"模式来虚拟实模式。
 创建控制台时,操作系统自动创建三个"标准"文件句柄。在高级控制台编程中,用两个API函数控制这些句柄

 GetStdHandle和SetStdHandle

 控制台使用的不是我们常见的Win32消息队列,而是事件队列。
 事件队列和Windows消息队列差不多,不过是接收输入事件,而非消息。所以Spy++当然得不到消息

 ReadConsoleInput可以用来获得控制台的输入,参考

 MSDN给出了一个创建标准信息队列的例子

C/C++ code
#include<windows.h>
#include<stdio.h>

VOID ErrorExit(LPSTR);
VOID KeyEventProc(KEY_EVENT_RECORD); 
VOID MouseEventProc(MOUSE_EVENT_RECORD); 
VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);int main(VOID) 

  HANDLE hStdin; 
  DWORD cNumRead, fdwMode, fdwSaveOldMode, i; 
  INPUT_RECORD irInBuf[128];int counter=0;// Get the standard input handle. 
  hStdin= GetStdHandle(STD_INPUT_HANDLE);if (hStdin== INVALID_HANDLE_VALUE) 
  ErrorExit("GetStdHandle");// Save the current input mode, to be restored on exit.if (! GetConsoleMode(hStdin,&fdwSaveOldMode) ) 
  ErrorExit("GetConsoleMode");// Enable the window and mouse input events. 
  fdwMode= ENABLE_WINDOW_INPUT| ENABLE_MOUSE_INPUT;if (! SetConsoleMode(hStdin, fdwMode) ) 
  ErrorExit("SetConsoleMode");// Loop to read and handle the input events.while (counter++<=100) 
  {// Wait for the events.if (! ReadConsoleInput( 
  hStdin,// input buffer handle irInBuf,// buffer to read into128,// size of read buffer&cNumRead) )// number of records read ErrorExit("ReadConsoleInput");// Dispatch the events to the appropriate handler.for (i=0; i< cNumRead; i++) 
  {switch(irInBuf[i].EventType) 
  {case KEY_EVENT:// keyboard input KeyEventProc(irInBuf[i].Event.KeyEvent);break;case MOUSE_EVENT:// mouse input MouseEventProc(irInBuf[i].Event.MouseEvent);break;case WINDOW_BUFFER_SIZE_EVENT:// scrn buf. resizing ResizeEventProc( 
  irInBuf[i].Event.WindowBufferSizeEvent);break;case FOCUS_EVENT:// disregard focus eventscase MENU_EVENT:// disregard menu eventsbreak;default: 
  ErrorExit("Unknown event type");break; 
  } 
  }
  }return0; 
}

VOID ErrorExit (LPSTR lpszMessage) 

  fprintf(stderr,"%s\n", lpszMessage); 
  ExitProcess(0); 
}

VOID KeyEventProc(KEY_EVENT_RECORD ker)
{
  printf("Key event:");if(ker.bKeyDown)
  printf("key pressed\n");else printf("key released\n");
}

VOID MouseEventProc(MOUSE_EVENT_RECORD mer)
{
#ifndef MOUSE_HWHEELED#define MOUSE_HWHEELED 0x0008#endif
  printf("Mouse event:");switch(mer.dwEventFlags)
  {case0:
  printf("button press\n");break;case DOUBLE_CLICK:
  printf("double click\n");break;case MOUSE_HWHEELED:
  printf("horizontal mouse wheel\n");break;case MOUSE_MOVED:
  printf("mouse moved\n");break;case MOUSE_WHEELED:
  printf("vertical mouse wheel\n");break;default:
  printf("unknown\n");break;
  }
}

VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr)
{
  printf("Resize event\n");
}
 我就花点事件给你解释下
 WINDOW_BUFFER_SIZE_EVENT 屏幕大小改变时发出
 MENU_EVENT 用户使用控制台菜单或工具栏时发出
 FOCUS_EVENT 控制台得到输入焦点时发出


 这是内部实现,当然我们外部也可以获得。利用管道,然后GetStdHandle(STD_INPUT_HANDLE);

 然后即可读取Console窗口的事件。

 好久没见到这么值得我回,详细解释的帖子。希望对后面看帖的朋友有帮助




------
可以用钩子
------
路过.
------
可以使用Process.Start("*.exe")来启动进程,使用Process.StandardOutput来获取输出值。
------
Mark!
------
学习,拜读
------
study.
------
学习
------
learning~!!!
------
路过帮顶了
------
楼主问的是如何从cmd获得拷贝的数据啊!
------
sf


------
这里是高手如云,真不知从何看起。
------
study
------
Tr0j4n,真乃牛人哪
------
牛人啊。。。
------
学习
------
楼主的问题我都看不懂
------
看到了新的东西,有趣。
------
这个问题...很难...
楼主的问题很模糊.
回答很多.
结果很失望..
在下也无解.
不知道在问啥.
------
嗯 学习了
------
cmd >>1.txt
type cmd >>2.txt
------
太深奥了,不明白。。。
------
不错,学习下
------
引用 4 楼 tr0j4n 的回复:
DOS程序通过一个名为Winoldap的控制台程序来运行,而这个程序则是在32位Windows控制台窗口中运行。原理上,Winoldap利用x86的"Virtual86"模式来虚拟实模式。
创建控制台时,操作系统自动创建三个"标准"文件句柄。在高级控制台编程中,用两个API函数控制这些句柄

GetStdHandle和SetStdHandle

控制台使用的不是我们常见的Win32消息队列,而是事件队列。
事件队列和Windows消息队列差不多,不过是接收输入事件,而非消息。所以Spy++当然得不到消息

ReadConsoleInput可以用来获得控制台的输入,参考

MSDN给出了一个创建标准信息队列的例子

C/C++ code
#include<windows.h>
#include<stdio.h>

VOID ErrorExit(LPSTR);
VOID KeyEventProc(KEY_EVENT_RECORD); 
VOID MouseEventProc(MOUSE_EVENT_RECORD); 
VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);int main(VOID) 

  HANDLE hStdin; 
  DWORD cNumRead, fdwMode, fdwSaveOldMode, i; 
  INPUT_RECORD irInBuf[128];int counter=0;// Get the standard input handle. 
  hStdin= GetStdHandle(STD_INPUT_HANDLE);if (hStdin== INVALID_HANDLE_VALUE) 
  ErrorExit("GetStdHandle");// Save the current input mode, to be restored on exit.if (! GetConsoleMode(hStdin,&fdwSaveOldMode) ) 
  ErrorExit("GetConsoleMode");// Enable the window and mouse input events. 
  fdwMode= ENABLE_WINDOW_INPUT| ENABLE_MOUSE_INPUT;if (! SetConsoleMode(hStdin, fdwMode) ) 
  ErrorExit("SetConsoleMode");// Loop to read and handle the input events.while (counter++<=100) 
  {// Wait for the events.if (! ReadConsoleInput( 
  hStdin,// input buffer handle irInBuf,// buffer to read into128,// size of read buffer&cNumRead) )// number of records read ErrorExit("ReadConsoleInput");// Dispatch the events to the appropriate handler.for (i=0; i< cNumRead; i++) 
  {switch(irInBuf[i].EventType) 
  {case KEY_EVENT:// keyboard input KeyEventProc(irInBuf[i].Event.KeyEvent);break;case MOUSE_EVENT:// mouse input MouseEventProc(irInBuf[i].Event.MouseEvent);break;case WINDOW_BUFFER_SIZE_EVENT:// scrn buf. resizing ResizeEventProc( 
  irInBuf[i].Event.WindowBufferSizeEvent);break;case FOCUS_EVENT:// disregard focus eventscase MENU_EVENT:// disregard menu eventsbreak;default: 
  ErrorExit("Unknown event type");break; 
  } 
  }
  }return0; 
}

VOID ErrorExit (LPSTR lpszMessage) 

  fprintf(stderr,"%s\n", lpszMessage); 
  ExitProcess(0); 
}

VOID KeyEventProc(KEY_EVENT_RECORD ker)
{
  printf("Key event:");if(ker.bKeyDown)
  printf("key pressed\n");else printf("key released\n");
}

VOID MouseEventProc(MOUSE_EVENT_RECORD mer)
{
#ifndef MOUSE_HWHEELED#define MOUSE_HWHEELED 0x0008#endif
  printf("Mouse event:");switch(mer.dwEventFlags)
  {case0:
  printf("button press\n");break;case DOUBLE_CLICK:
  printf("double click\n");break;case MOUSE_HWHEELED:
  printf("horizontal mouse wheel\n");break;case MOUSE_MOVED:
  printf("mouse moved\n");break;case MOUSE_WHEELED:
  printf("vertical mouse wheel\n");break;default:
  printf("unknown\n");break;
  }
}

VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr)
{
  printf("Resize event\n");
}
我就花点事件给你解释下
WINDOW_BUFFER_SIZE_EVENT 屏幕大小改变时发出
MENU_EVENT 用户使用控制台菜单或工具栏时发出
FOCUS_EVENT 控制台得到输入焦点时发出


这是内部实现,当然我们外部也可以获得。利用管道,然后GetStdHandle(STD_INPUT_HANDLE);

然后即可读取Console窗口的事件。

好久没见到这么值得我回,详细解释的帖子。希望对后面看帖的朋友有帮助




------
我弄了 没整出来。555
------
啥都别弄了.孙鑫的视频里面的一个视频就有讲这个的.至于哪个我也不知道.但是我确实看过.你自己找找吧
------
学着也没弄明白~~~~~~~
------
学习中
------
没研究过,先收藏~~
------
mark
------
学习
------
也想不出来。
------
唉,真是孤陋寡闻啊,要继续学习
------
继续学习
------
学习,学习
------
mark!
------
学习了啊
------
重定向输出
------
very good, thanks a lot
------
学习了 仍需努力啊
------
我学到了,谢谢
------
太有学问了
------
通过匿名管道,不过卡巴斯基会阻止所有连接向CMD的通信。
------
谢谢斑竹的详细解释,也谢谢各位支持,帮助很大,谢谢大家
------
学习下···
------
學習了﹗﹗
------
不错。。。
------
还是不明白啊?kankan
------
ding
桂ICP备07017180号