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]