【发布时间】:2016-08-28 21:17:17
【问题描述】:
我这里有一个调用 CreateProcess 的 C 程序...
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(int argc, char *argv[])
{
STARTUPINFO st;
ZeroMemory(%st, sizeof(STARTUPINFO));
st.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi;
CreateProcessA("C:\\WINDOWS\\system32\\cmd.exe",0,0,0,0,0,0,0,&st,&pi);
return 0;
}
运行良好,在外壳中创建外壳。
我也有这段代码,通过适用于 Windows 的 MinGW 编译器套件以 GAS 程序集编写...
.extern _CreateProcessA@40
.def _CreateProcessA@40; .scl 2; .type 32; .endef
.extern _ExitProcess@4
.def _ExitProcess@4; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
push %ebp
movl %esp, %ebp
#PROCESS_INFORMATION...
subl $16, %esp
movl %esp, %eax
#STARTUPINFO...
subl $68, %esp
movl $68, (%esp)
movl %esp, %ebx
#Application name with path : C:\WINDOWS\system32\cmd.exe...
subl $29, %esp
xor %edx, %edx
movb %dx, 27(%esp)
movb $0x65, 26(%esp)
movw $0x7856, 24(%esp)
movl $0x2e646d63, 20(%esp)
movl $0x5c32336d, 16(%esp)
movl $0x65747379, 12(%esp)
movl $0x735c5357, 8(%esp)
movl $0x4f444e49, 4(%esp)
movl $0x575c3a43, (%esp)
movl %esp, %ecx
push %eax
push %ebx
push %edx
push %edx
push %edx
push %edx
push %edx
push %edx
push %edx
push %ecx
call _CreateProcessA@40
movl %ebp, %esp
pop %ebp
push %edx
call _ExitProcess@4
它可以很好地编译和链接;
as createProc.s -o createProc.o
ld createProc.o -o createProc.exe -lkernel32
当它运行时,它确实运行了,它执行时不会在命令行的 shell 中启动第二个 shell。有什么问题?
注意:我输入带有 movl 指令的字符串是有原因的,所以请不要建议我应该使用 .data、.bss 或标签。另请注意,我已经尝试在汇编程序中的字符串中使用转义斜杠(\\)无济于事,如果使用转义斜杠,它实际上会崩溃。
【问题讨论】:
-
您的代码甚至没有汇编。你确定你能运行它吗?
-
Cmd.exe 是命令解释器。 Explorer.exe 是外壳。请修正您的术语。
-
可能有错字,但代码在我端运行完美,只是没有从 cmd.exe 创建新进程。亲爱的 IInspectable;如果你运行我的 C 程序,你会看到它在一个 shell 中创建了第二个 shell,Explorer.exe 就是 GUI。
-
最明显的区别是 C 代码将
STARTUPINFO结构归零,除非我遗漏了什么,否则汇编代码不会。如果这不能解决问题(或者即使解决了!),您应该添加错误检查 - 检查 CreateProcess 的返回值,如果它为零,则调用 GetLastError 并将结果返回给用户。 (如果你还没有这样的机制,最简单的方法是让它成为你的应用程序的退出代码。) -
请再次阅读我的评论。我从来没有声称,你的代码应该启动一个 GUI 进程。这是关于术语的,在 Windows 中,cmd.exe 被称为“命令处理器”,而不是“shell”,正如您坚持的那样。请修正您的术语以及误导性标签。