如何在汇编程序中运行Windows Shell命令,而无需C库?
我正在学习组装,但是我一直在Linux上学习,并且由于我了解C/C ++,它已经与C/C ++交织在一起。
但是,现在,我想在我的Windows计算机上编写一个程序,该程序调用一个运行shell命令的函数,希望不包括任何库,因为我希望此可执行文件能尽可能小 /strong>。 (一个简单的C ++可执行文件,其中包括cstdlib
是32 kb,而我几乎根本不键入任何代码。)
我本质上想编写此程序,但在汇编中:
#include <cstdlib>
int main()
{
system("echo ABCDEFG> msg.txt");
system("type msg.txt");
return 0;
}
到目前为止,我已经安装了NASM和MINGW而且我正在尝试使用它们[编辑:我现在正在尝试使用MASM,而不是Visual Studio],但是没有任何可行我遇到的在线资源已经成功地汇编了我试图做的事情。它似乎也不了解语句extern System
,因此我认为这可能是C/C ++库的事物(来自cstdlib
)。
另外,在某些情况下,我遇到了一个错误,说“角色常数太长”。我认为它是指字符串;在真实程序中,回声的字符串比上面的示例要长得多。
我也对生成的.OBJ文件遇到了一个问题。
因此,基本上,我所需要的只是如何将上述程序变成Windows的组件,以及如何使NASM和MINGW将其转换为可执行文件,而无需给我错误。
编辑:经过几天的研究,我决定不知道自己在做什么错,我无法弄清楚什么是正确的。
我现在尝试了Visual Studio,但是再一次,它不了解Extern System
。
.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode: DWORD
.data
Var db 'dir && pause', 0
.code
extern system
main PROC
push ebp
mov ebp, esp
sub esp, 32
lea ecx, [Var]
call system
xor eax, eax
INVOKE ExitProcess, 0
main ENDP
END main
I'm learning assembly, but I've been learning on Linux, and it's been very interwoven with C/C++ since I understand C/C++.
However, now, I want to write a program in assembly on my Windows computer that makes a call to a function that runs a shell command, and hopefully without including any libraries since I want this executable to be as small as possible. (A simple C++ executable I made which included cstdlib
is 32 KB while I typed barely any code at all.)
I want to essentially write this program but in assembly:
#include <cstdlib>
int main()
{
system("echo ABCDEFG> msg.txt");
system("type msg.txt");
return 0;
}
So far, I have installed NASM and MinGW and I'm trying to use them [Edit: I am now trying to use MASM instead, with Visual Studio], but nothing works and I assume it's because Windows has its own stuff from Microsoft that obviously aren't in Linux, but none of the online resources I've come across have successfully compiled with what I was trying to do. It also doesn't seem to understand the statement extern system
, so I think that this might be a C/C++ library thing (from cstdlib
).
Also, in some cases I encountered an error where it said the "character constant is too long". I assume it's referring to the string; in the real program, the string to echo is much longer than what's in the example above.
I also had an issue apparently with the .obj file that was generated.
So, basically, all I need is how to turn the above program into assembly for Windows, and how to get NASM and MinGW to turn it into an executable without giving me errors.
Edit: After a few days of researching, I have decided I don't know what I'm doing wrong and I can't figure out what is right.
I've tried Visual Studio now, but once again, it doesn't understand extern system
.
.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode: DWORD
.data
Var db 'dir && pause', 0
.code
extern system
main PROC
push ebp
mov ebp, esp
sub esp, 32
lea ecx, [Var]
call system
xor eax, eax
INVOKE ExitProcess, 0
main ENDP
END main
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如我在评论中提到的那样,Windows确实具有系统命令。它位于msvcrt.dll中,因此您需要与msvcrt.lib链接以解决外部参考。
您从“第11行”中遇到的错误是由于错误定义外部的错误,这很奇怪,因为您在ExitProcess(也是外部)中正确地做了相同的操作。
32K听起来可能很大,但是如今Windows可以在4K页面上工作,允许它设置页面保护 bits(只读页面,可执行页等)。可执行代码的一个页面,一个用于数据,一个用于常数,进出口,进出口,调试信息,异常信息等的页面。8页似乎并不是当今标准的那样令人毛骨悚然。
但是正如我也提到的那样,有 hacks 如果有一些令人信服的理由,则可以用来减少可执行文件的大小。所以。该示例(使用
nasm.exe doit.asm -o doit.exe
使用NASM版本2.15.05构建)为1,184字节。当您运行它时,似乎什么都不会发生(没有CMD窗口打开),而且确实很快。但是您会看到foo.xxx会创建并包含来自dir&gt;的输出。 foo.xxx
命令嵌入了代码中。这里的链接器通常为您处理,这里有很多gobbledygook。有趣的位从
开始:
。 CMD定义在代码末尾附近。该代码的隐秘性质与小尺寸相结合,可以使用此代码进行恶作剧。我将假设这不是您的意图。
As I mentioned in the comments, Windows does have a system command. It's located in MSVCRT.dll, so you'll need to link with msvcrt.lib to resolve the external reference.
The error you are getting from "line 11" is due to incorrectly defining the external, which is odd since you're correctly doing the same for ExitProcess (which is also an external) just a few lines before.
32k may sound big, but Windows works in 4k pages these days, allowing it set page protection bits (read-only pages, executable pages, etc). One page for executable code, one for data, one for constants, imports, exports, debug info, exception info, etc. 8 pages doesn't seem that outrageous by today's standards.
But as I also mentioned, there are hacks one can use to reduce the size of the executable if there's some compelling reason to do so. This sample (built with NASM version 2.15.05 using
nasm.exe doit.asm -o doit.exe
) is 1,184 bytes. When you run it, nothing seems to happen (no cmd window opens) and it's really quick. But you'll see that foo.xxx gets created and contains the output from thedir > foo.xxx
command embedded in the code.There's a lot of gobbledygook here that the linker normally handles for you. The interesting bits start at
ENTRY:
. cmd is defined near the end of the code.The stealthy nature of this code combined with the small size opens the possibility of using this code for mischief. I'm going to assume that's not your intent.
您对外部的使用没有任何意义,extern在MASM中表示您调用API函数(例如C中的printf)而不是可执行文件。第一个评论是正确的。在Win32 API中,从Anther过程启动的过程中,您需要CreateProcessa或CreateProcessw函数,并且需要设置Process_Information结构来传递它。我不记得您也必须设置其他结构,如果您将其推向堆栈,或者简单地调用它,然后让汇编器处理它。我建议您获得MASM32的副本,这应该使它变得容易,其中可能已经有一个示例或互联网上的样本。
You usage of extern does not make any sense, extern in masm means you are calling an API function (like printf in c) not a executable file. The first comment is correct. In the win32 api a process launched from anther process you need the CreateProcessA or CreateProcessW function and you need to setup a PROCESS_INFORMATION structure to pass it. You might have to set up other structures too, I don't remember, then you call it if you pushed to arguments to the stack manually or simply invoke it and let the assembler handle that. I would recommend getting a copy of masm32, that should make it easy, there is likely already a sample in it or on the internet.