idiotc4t's blog
搜索文档…
编写简单远控

简介

通常在使用cmd控制台中执行命令,本质上是执行windows目录下的system32&syswow64内的可执行文件,通常此类操作可以通过winexec,system等函数进行模拟cmd下命令的执行,但是此类命令往往没有回显,这对我们查看命令执行结果造成一些麻烦。
好在windows提供了一种在进程间共享数据的机制,我们称其为管道(pipe),在windows中其实质是一段共享内存,windows为这段内存设计使用数据流I/O的方式来进行访问。
管道具体又分为匿名管道和命名管道,匿名管道只能用于父子进程之间的数据通信,不能在网络中通信,同时数据传输时单项的,只能一端读,一端写。命名管道则可以在任意进程和网络间通信,且数据是双向的,但同一时间只能一端读一端写。
在windows操作系统提供的createprocess函数可以可以指定程序运行结果存储的缓冲区,如果我们把这个缓冲区指定成匿名管道的写入端,那么我们就能在父进程内进行对执行结果的读取。

流程

  1. 1.
    创建匿名管道
  2. 2.
    创建STARTUPINFO结构体
  3. 3.
    创建进程
  4. 4.
    等待执行结束
  5. 5.
    读取缓冲区

代码实现

1
#include<Windows.h>
2
#include<stdio.h>
3
4
int main() {
5
6
SECURITY_ATTRIBUTES se = { 0 };
7
se.bInheritHandle = TRUE;//描述的对象可以被继承
8
se.nLength = sizeof(se);
9
se.lpSecurityDescriptor = NULL;
10
11
12
HANDLE hWPipe=NULL;
13
HANDLE hRPipe=NULL;
14
15
CreatePipe(&hRPipe, &hWPipe, &se, NULL);
16
17
18
STARTUPINFOA si = { 0 };
19
si.cb = sizeof(si);
20
si.hStdError = hWPipe;
21
si.hStdOutput = hWPipe;
22
si.wShowWindow = SW_HIDE;//隐藏窗口
23
24
si.dwFlags = STARTF_USESHOWWINDOW //启用wShowWindow成员
25
| STARTF_USESTDHANDLES;//启用hStdOutput,hStdError和hStdInput成员
26
27
PROCESS_INFORMATION pi = { 0 };
28
29
CreateProcessA(NULL, (LPSTR)"systeminfo", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
30
31
WaitForSingleObject(pi.hProcess, INFINITE);
32
WaitForSingleObject(pi.hThread,INFINITE);
33
34
LPVOID lpBuffer[4096] = { 0 };
35
36
ReadFile(hRPipe, lpBuffer, 4096, NULL, NULL);
37
38
39
printf("%s", lpBuffer);
40
41
CloseHandle(pi.hProcess);
42
CloseHandle(pi.hThread);
43
CloseHandle(hWPipe);
44
CloseHandle(hRPipe);
45
46
return 0;
47
48
}
Copied!

LINKS

开发人员工具、技术文档和代码示例
docsmsft
最近更新 1yr ago