为什么 CreateProcess 不能在 Windows 中的汇编中工作?
Why won't CreateProcess work in assembly in Windows?
我这里有一个调用 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。
我也有这段代码,通过 MinGW 编译器套件用 GAS 汇编编写,用于 Windows...
.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 , %esp
movl %esp, %eax
#STARTUPINFO...
subl , %esp
movl , (%esp)
movl %esp, %ebx
#Application name with path : C:\WINDOWS\system32\cmd.exe...
subl , %esp
xor %edx, %edx
movb %dx, 27(%esp)
movb [=12=]x65, 26(%esp)
movw [=12=]x7856, 24(%esp)
movl [=12=]x2e646d63, 20(%esp)
movl [=12=]x5c32336d, 16(%esp)
movl [=12=]x65747379, 12(%esp)
movl [=12=]x735c5357, 8(%esp)
movl [=12=]x4f444e49, 4(%esp)
movl [=12=]x575c3a43, (%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 或标签。另请注意,我已经尝试在汇编程序的字符串中使用转义斜杠 (\\) 无济于事,如果使用转义斜杠,它实际上会崩溃。
关于编程风格
你应该忘记与 ESP
.
混在一起
这样做的方法是在例程开始时设置堆栈帧,并使用 EBP
来寻址由此创建的 space。
你的路径有错字
您将 "c1\win...."
作为路径传递。那是行不通的。
您应该根据 ascii-table 仔细检查代码,或者检查调试器中进行 API 调用的参数..
我也不知道为什么你需要 29 个字节来存储字符串。据我所知,它适合 28 个字符。
使用栈帧的工作代码
这是使用堆栈框架按预期方式工作的代码。
//Set up stack frame.
00418200 55 push ebp
00418201 8BEC mov ebp,esp
00418203 83C490 add esp,-
//Zero StartupInfoA
00418206 57 push edi
00418207 8D45A0 lea eax,[ebp-]
0041820A 8BF8 mov edi,eax
0041820C 33C0 xor eax,eax
0041820E B911000000 mov ecx,[=10=]000011
00418213 F3AB rep stosd
//st.cb = SizeOf(st)
00418215 C745A044000000 mov [ebp-],[=10=]000044
//Set the string: path = 'c:\windows\system32\cmd.exe'; 28 chars including trailing 0.
0041821C C745E4433A5C77 mov [ebp-c],5c3a43 //c:\w
00418223 C745E8696E646F mov [ebp-],f646e69 //indo
0041822A C745EC77735C73 mov [ebp-],5c7377 //ws\s
00418231 C745F079737465 mov [ebp-],747379 //yste
00418238 C745F46D33325C mov [ebp-[=10=]c],c32336d //m32\
0041823F C745F8636D642E mov [ebp-],e646d63 //cmd.
00418246 C745FC65786500 mov [ebp-],[=10=]657865 //exe-
//Set up parameters for call
0041824D 8D4590 lea eax,[ebp-] //ProcessInfo
00418250 50 push eax
00418251 8D45A0 lea eax,[ebp-] //StartupInfoA
00418254 50 push eax
00418255 6A00 push [=10=]
00418257 6A00 push [=10=]
00418259 6A00 push [=10=]
0041825B 6A00 push [=10=]
0041825D 6A00 push [=10=]
0041825F 6A00 push [=10=]
00418261 6A00 push [=10=]
00418263 8D45E4 lea eax,[ebp-c] //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 设置为未对齐的地址,则会严重降低性能。
@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 , %esp
movl %esp, %eax
#STARTUPINFO...
subl , %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 , (%esp)
movl %esp, %ebx
#Application name (C:\WINDOWS\system32\cmd.exe)...
subl , %esp
movb %dl, 27(%esp)
movb [=10=]x65, 26(%esp)
movw [=10=]x7865, 24(%esp)
movl [=10=]x2e646d63, 20(%esp)
movl [=10=]x5c32336d, 16(%esp)
movl [=10=]x65747379, 12(%esp)
movl [=10=]x735c5357, 8(%esp)
movl [=10=]x4f444e49, 4(%esp)
movl [=10=]x575c3a43, (%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
我这里有一个调用 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。
我也有这段代码,通过 MinGW 编译器套件用 GAS 汇编编写,用于 Windows...
.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 , %esp
movl %esp, %eax
#STARTUPINFO...
subl , %esp
movl , (%esp)
movl %esp, %ebx
#Application name with path : C:\WINDOWS\system32\cmd.exe...
subl , %esp
xor %edx, %edx
movb %dx, 27(%esp)
movb [=12=]x65, 26(%esp)
movw [=12=]x7856, 24(%esp)
movl [=12=]x2e646d63, 20(%esp)
movl [=12=]x5c32336d, 16(%esp)
movl [=12=]x65747379, 12(%esp)
movl [=12=]x735c5357, 8(%esp)
movl [=12=]x4f444e49, 4(%esp)
movl [=12=]x575c3a43, (%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 或标签。另请注意,我已经尝试在汇编程序的字符串中使用转义斜杠 (\\) 无济于事,如果使用转义斜杠,它实际上会崩溃。
关于编程风格
你应该忘记与 ESP
.
混在一起
这样做的方法是在例程开始时设置堆栈帧,并使用 EBP
来寻址由此创建的 space。
你的路径有错字
您将 "c1\win...."
作为路径传递。那是行不通的。
您应该根据 ascii-table 仔细检查代码,或者检查调试器中进行 API 调用的参数..
我也不知道为什么你需要 29 个字节来存储字符串。据我所知,它适合 28 个字符。
使用栈帧的工作代码
这是使用堆栈框架按预期方式工作的代码。
//Set up stack frame.
00418200 55 push ebp
00418201 8BEC mov ebp,esp
00418203 83C490 add esp,-
//Zero StartupInfoA
00418206 57 push edi
00418207 8D45A0 lea eax,[ebp-]
0041820A 8BF8 mov edi,eax
0041820C 33C0 xor eax,eax
0041820E B911000000 mov ecx,[=10=]000011
00418213 F3AB rep stosd
//st.cb = SizeOf(st)
00418215 C745A044000000 mov [ebp-],[=10=]000044
//Set the string: path = 'c:\windows\system32\cmd.exe'; 28 chars including trailing 0.
0041821C C745E4433A5C77 mov [ebp-c],5c3a43 //c:\w
00418223 C745E8696E646F mov [ebp-],f646e69 //indo
0041822A C745EC77735C73 mov [ebp-],5c7377 //ws\s
00418231 C745F079737465 mov [ebp-],747379 //yste
00418238 C745F46D33325C mov [ebp-[=10=]c],c32336d //m32\
0041823F C745F8636D642E mov [ebp-],e646d63 //cmd.
00418246 C745FC65786500 mov [ebp-],[=10=]657865 //exe-
//Set up parameters for call
0041824D 8D4590 lea eax,[ebp-] //ProcessInfo
00418250 50 push eax
00418251 8D45A0 lea eax,[ebp-] //StartupInfoA
00418254 50 push eax
00418255 6A00 push [=10=]
00418257 6A00 push [=10=]
00418259 6A00 push [=10=]
0041825B 6A00 push [=10=]
0041825D 6A00 push [=10=]
0041825F 6A00 push [=10=]
00418261 6A00 push [=10=]
00418263 8D45E4 lea eax,[ebp-c] //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 设置为未对齐的地址,则会严重降低性能。
@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 , %esp
movl %esp, %eax
#STARTUPINFO...
subl , %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 , (%esp)
movl %esp, %ebx
#Application name (C:\WINDOWS\system32\cmd.exe)...
subl , %esp
movb %dl, 27(%esp)
movb [=10=]x65, 26(%esp)
movw [=10=]x7865, 24(%esp)
movl [=10=]x2e646d63, 20(%esp)
movl [=10=]x5c32336d, 16(%esp)
movl [=10=]x65747379, 12(%esp)
movl [=10=]x735c5357, 8(%esp)
movl [=10=]x4f444e49, 4(%esp)
movl [=10=]x575c3a43, (%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