首先,我是汇编新手,但在 C++ 方面有不错的背景。我的问题源于我使用 assembly关注命令行参数的教程。
当程序运行时,它会根据教程执行它应该做的一切,即显示程序输入列表:
./asm1 arg1 arg2 arg3
问题是当您提供星号作为参数时:
./asm1 *
它有效地在 CWD 上执行/usr/bin/ls。
我的问题是如何防止这种情况发生,以及有关实施该计划的更好方法的任何建议。
替换:
; the loop
cmp ecx, eax ; if ecx not equal to eax
jne begin_for_loop ; jmp to loop, else exit
Run Code Online (Sandbox Code Playgroud)
和:
; the loop
cmp ecx, eax ; if ecx not equal to eax
jmp begin_for_loop ; jmp to loop, else exit
Run Code Online (Sandbox Code Playgroud)
我发现了一个更大的问题,即程序将 ENV 变量打印到屏幕上。
; FOR LOOP: Print commandline arguments> an equivalent program to
this in assembly
SECTION .data
argv db "Arguments = %s",10,0
argc db "Argument Count = %d",10,0
SECTION .text
; allow access to printf
extern printf
; make main_function available externally
global main
main: ; int main (int argc, char* argv[])
push ebp
mov ebp,esp
sub esp, 10
mov eax, DWORD [ebp + 8] ; points to argc
mov ebx, DWORD [ebp + 12] ; points to argv
mov ecx, 0 ; mov ZERO to count register
begin_for_loop:
; always preserve values prior to external function calls
; external function calls may modify values you placed in registers
push ebx ; preserve ebx; holds argument address
push eax ; preserve eax; holds number of arguments
push ecx ; preserve ecx; holds the counter
; call printf
push DWORD [ebx]
push argv
call printf
add esp, 8 ; clean up the stack
; always restore in backwards order
pop ecx ; restore counter
pop eax ; restore number of arguments
pop ebx ; restore argument address
inc ecx ; increase our counter by 1
add ebx, 4 ; move to next argument in the array
; the loop
cmp ecx, eax ; if ecx not equal to eax
jne begin_for_loop ; jmp to loop, else exit
mov esp,ebp
pop ebp
ret
Run Code Online (Sandbox Code Playgroud)
预期输出:
$ ./asm5 me you them us
Arguments = ./asm5
Arguments = me
Arguments = you
Arguments = them
Arguments = us
Run Code Online (Sandbox Code Playgroud)
有问题的输出:
$ ./asm5 me you them us *
Arguments = ./asm5
Arguments = me
Arguments = you
Arguments = them
Arguments = us
Arguments = asm1
Arguments = asm1.asm
Arguments = asm1.o
Arguments = asm2
Arguments = asm2.asm
Arguments = asm3
Arguments = asm3.asm
Arguments = asm4
Arguments = asm4.asm
Arguments = asm5
Arguments = asm5.asm
Arguments = asm-template.asm
Arguments = compile-asm.sh
Arguments = cpp_libs
Run Code Online (Sandbox Code Playgroud)
在 POSIX 系统上,如果你从 shell 启动一个程序,shell将执行所谓的 globbing,扩展*并用匹配的文件替换它;结果将用作调用程序的参数。
你不能做任何事情来阻止它出现在你的程序中,你看到的参数确实是从 shell 获得的参数(IOW,它们是传递给 的参数exec)。
如果要在*从 shell 启动程序时将文字传递给程序,则必须引用它。
./asm5 me you them us "*"
Run Code Online (Sandbox Code Playgroud)
当然,如果其他程序启动您的程序将参数直接传递给exec,而没有外壳妨碍,则这一切都不会发生。
替换:
Run Code Online (Sandbox Code Playgroud); the loop cmp ecx, eax ; if ecx not equal to eax jne begin_for_loop ; jmp to loop, else exit和:
Run Code Online (Sandbox Code Playgroud); the loop cmp ecx, eax ; if ecx not equal to eax jmp begin_for_loop ; jmp to loop, else exit我发现了一个更大的问题,即程序将 ENV 变量打印到屏幕上。
这是因为您忽略了终止argv参数列表的 NULL ,并且您继续阅读接下来的内容;在您的情况下,这恰好是环境内存块。