为什么CreateProcess在Windows中的汇编中不起作用?

时间:2016-08-28 21:17:18

标签: windows assembly mingw

我这里有一个调用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;
}

哪个运行正常,在shell中创建一个shell。

我也有这个代码,通过适用于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或lables。另请注意,我已经尝试在汇编程序的字符串中使用转义斜杠(\\)无效,如果使用了转义斜杠,它实际上会崩溃。

2 个答案:

答案 0 :(得分:2)

关于编程风格
你应该忘记与ESP混在一起 这样做的方法是在例程开始时设置堆栈帧,并使用EBP来解决由此创建的空间。

您的路径中有拼写错误
您将"c1\win...."作为路径传递。这不会起作用。
您应该针对ascii-table仔细检查代码,或者在调试器中查看参数进行API调用。
另外我不知道为什么你需要29个字节来存储字符串。据我所知,它适合28个字符。

使用堆栈框架的工作代码
这里的代码按照应该完成的方式使用堆栈帧。

//Set up stack frame.
00418200 55               push ebp
00418201 8BEC             mov ebp,esp
00418203 83C490           add esp,-$70
//Zero StartupInfoA
00418206 57               push edi
00418207 8D45A0           lea eax,[ebp-$60]
0041820A 8BF8             mov edi,eax
0041820C 33C0             xor eax,eax
0041820E B911000000       mov ecx,$00000011
00418213 F3AB             rep stosd 
//st.cb = SizeOf(st)
00418215 C745A044000000   mov [ebp-$60],$00000044
//Set the string: path = 'c:\windows\system32\cmd.exe'; 28 chars including trailing 0.
0041821C C745E4433A5C77   mov [ebp-$1c],$775c3a43  //c:\w
00418223 C745E8696E646F   mov [ebp-$18],$6f646e69  //indo
0041822A C745EC77735C73   mov [ebp-$14],$735c7377  //ws\s
00418231 C745F079737465   mov [ebp-$10],$65747379  //yste
00418238 C745F46D33325C   mov [ebp-$0c],$5c32336d  //m32\
0041823F C745F8636D642E   mov [ebp-$08],$2e646d63  //cmd.
00418246 C745FC65786500   mov [ebp-$04],$00657865  //exe- 
//Set up parameters for call
0041824D 8D4590           lea eax,[ebp-$70]        //ProcessInfo
00418250 50               push eax                 
00418251 8D45A0           lea eax,[ebp-$60]        //StartupInfoA
00418254 50               push eax
00418255 6A00             push $00
00418257 6A00             push $00
00418259 6A00             push $00
0041825B 6A00             push $00
0041825D 6A00             push $00
0041825F 6A00             push $00
00418261 6A00             push $00
00418263 8D45E4           lea eax,[ebp-$1c]      //Path
00418266 50               push eax
//Call 
00418267 E80823FFFF       call CreateProcessA
//Clean up the stackframe
0041826C 5F               pop edi
0041826D 8BE5             mov esp,ebp
0041826F 5D               pop ebp

关于搞乱ESP
如果将ESP设置为未对齐的地址,则会严重降低性能。

答案 1 :(得分:0)

@HarryJohnson认为,所需要的只是将STARTUPINFO结构归零,

.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 %ebp, %esp

       xor %edx, %edx

       #PROCESS_INFORMATION...
       subl $16, %esp
       movl %esp, %eax

       #STARTUPINFO...
       subl $68, %esp
       movl %edx, 64(%esp)
       movl %edx, 60(%esp)
       movl %edx, 56(%esp)
       movl %edx, 52(%esp)
       movl %edx, 48(%esp)
       movl %edx, 44(%esp)
       movl %edx, 40(%esp)
       movl %edx, 36(%esp)
       movl %edx, 32(%esp)
       movl %edx, 28(%esp)
       movl %edx, 24(%esp)
       movl %edx, 20(%esp)
       movl %edx, 16(%esp)
       movl %edx, 12(%esp)
       movl %edx, 8(%esp)
       movl %edx, 4(%esp)
       movl %edx, (%esp)
       movb $68, (%esp)
       movl %esp, %ebx

       #Application name (C:\WINDOWS\system32\cmd.exe)...
       subl $28, %esp
       movb %dl, 27(%esp)
       movb $0x65, 26(%esp)
       movw $0x7865, 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

       mov %ebp, %esp
       pop %ebp

       push %edx
       call _ExitProcess@4