ling林 发表于 2013-11-12 00:47

windows下替换cmd记录执行的命令

1. 测试环境:
windows xp sp3中文版
注意: 在sp3中要替换cmd.exe,需要替换2个地方,一个是c:\windows\system32\cmd.exe,另一个是c:\windows\system32\dllcache\cmd.exe(dllcache默认是隐藏的)。

2. 功能实现概述
   在我们的程序中,创建cmd.exe进程,获取用户命令行输入,将命令记录到文件中,然后传给cmd.exe,让其运行,并获取cmd.exe的返回结果显示到控制台界面上,详细代码见附件。

3. 程序关键点分析:

3.1 匿名管道的使用
BOOL WINAPI CreateProcess(
__in          LPCTSTR lpApplicationName,
__in_out      LPTSTR lpCommandLine,
__in          LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in          LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in          BOOL bInheritHandles,
__in          DWORD dwCreationFlags,
__in          LPVOID lpEnvironment,
__in          LPCTSTR lpCurrentDirectory,
__in          LPSTARTUPINFO lpStartupInfo,
__out         LPPROCESS_INFORMATION lpProcessInformation
);
其中倒数第二个参数的结构体类型如下:
typedef struct _STARTUPINFO {
      DWORD cb;
      LPTSTR lpReserved;
      LPTSTR lpDesktop;
      LPTSTR lpTitle;
      DWORD dwX;
      DWORD dwY;
      DWORD dwXSize;
      DWORD dwYSize;
      DWORD dwXCountChars;
      DWORD dwYCountChars;
      DWORD dwFillAttribute;
      DWORD dwFlags;//
      WORD wShowWindow;
      WORD cbReserved2;
      LPBYTE lpReserved2;
      HANDLE hStdInput;//程序的标准输入句柄
      HANDLE hStdOutput;//程序的标准输出句柄
      HANDLE hStdError;//程序的错误输出句柄
} STARTUPINFO,*LPSTARTUPINFO;


其中当dwFlags被设置成STARTF_USESTDHANDLES,则hStdInput、hStdOutput、hStdError将分别作为对应的句柄。

通过CreatePipe创建管道,就可以通过管道传递命令给cmd,并且获取到cmd程序的输出结果。
3.2 运行批处理程序
    当我们双击一个bat的批处理文件(如 c:\a.bat)时,运行的程序的命令行参数为 cmd.exe /c "c:\a.bat"(其中/c表示 bat文件运行完后自动关闭cmd.exe), 当用我们的程序去替换掉cmd时,我们的程序也要能够处理这种情况。
    当判断到程序运行时是带参数,且参数为/c时,直接创建cmd进程时,也传递同样的参数给cmd(即CreateProcess的第二个参数lpCommandLine)。同时创建一个线程,用WaitForSingleObject等待创建的进程结束,如果结束,则整个程序退出。
3.3 采用多线程
    程序的读和写是相对独立的过程,所以通过创建线程,将读和写分开,使得程序不会只获取到一半cmd输出后,就进入到等待用户输入,导致cmd的后半输出不能及时显示到界面上。


4 程序替换后,将真正的cmd.exe 重命名为 realcmd.exe, 然后记录的命令将在cmdlog.log中记录


页: [1]
查看完整版本: windows下替换cmd记录执行的命令