通过 x86 程序集从 argv 读取文件名

发布于 2024-12-11 09:39:15 字数 497 浏览 0 评论 0原文

我正在尝试读取传递给我的可执行文件的文件名并使用程序集写入该文件。编译没有错误,但执行时失败。我的代码到底有什么问题?

BITS 32
segment .data
text db "text"

segment .text

global main

main:
pop ebx 
pop ebx
pop ebx    ; pop pointer to filename into ebx
mov eax,0x5  ;syscall open
mov ecx,0x2   ;flag read/write
int 0x80   ;call kernel
mov ebx,eax   ;save returned file descriptor
mov eax,0x4 ; write syscall
mov ecx,text ;mov pointer to text into ecx
mov edx,0x4 ;string length
int 0x80  ;exit syscall
mov eax,0x1
int 0x80

I'm and trying to read a filename passed to my executable and write to that file using assembly. It compiles without error but fails when executed. What is wrong with my code exactly?

BITS 32
segment .data
text db "text"

segment .text

global main

main:
pop ebx 
pop ebx
pop ebx    ; pop pointer to filename into ebx
mov eax,0x5  ;syscall open
mov ecx,0x2   ;flag read/write
int 0x80   ;call kernel
mov ebx,eax   ;save returned file descriptor
mov eax,0x4 ; write syscall
mov ecx,text ;mov pointer to text into ecx
mov edx,0x4 ;string length
int 0x80  ;exit syscall
mov eax,0x1
int 0x80

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃兔兔 2024-12-18 09:39:15

由于您是从 libc 调用的,因此您还必须记住您有返回地址,以便您可以返回那里。这与如果您只有一个简单的汇编程序(如很多教程!)所得到的结果不同。记住这一点:

pop ebx    ;; pops return address to libc caller (_start usually)
pop ebx    ;; pops argc
pop ebx    ;; pops argv !!WAS!!: ; pop pointer to filename into ebx

以下是打印第一个参数的方法。您应该可以从那里开始(注意:我可能犯了错误):

    BITS 32

    section .text
    global main
    extern strlen

main:
    pop ecx ; Return address
    pop ecx ; argc
    pop ecx ; argv 
    mov ecx, [ecx+4] ; argv[1]

    push ecx
    call strlen
    mov edx, eax ; count
    pop ecx ; buf

    mov eax, 4 ; sys_write
    mov ebx, 1 ; stdout
    int 0x80

    mov eax, 1 ; sys_exit
    mov ebx, 0 ; status
    int 0x80

Since you're being called from libc you also have to recall that you have return address so you could return there. This is unlike what you get if you just have a bare-bones assembly program (like a lot of tutorials!). With that in mind:

pop ebx    ;; pops return address to libc caller (_start usually)
pop ebx    ;; pops argc
pop ebx    ;; pops argv !!WAS!!: ; pop pointer to filename into ebx

Here's how you can print the first argument. You should be able to go from there (beware: I might have made mistakes):

    BITS 32

    section .text
    global main
    extern strlen

main:
    pop ecx ; Return address
    pop ecx ; argc
    pop ecx ; argv 
    mov ecx, [ecx+4] ; argv[1]

    push ecx
    call strlen
    mov edx, eax ; count
    pop ecx ; buf

    mov eax, 4 ; sys_write
    mov ebx, 1 ; stdout
    int 0x80

    mov eax, 1 ; sys_exit
    mov ebx, 0 ; status
    int 0x80
无声情话 2024-12-18 09:39:15

进入 main 时:堆栈具有以下内容:

...
*envp[]
*argv[]
argc
return address

当您三次 pop ebx 时,您最终会访问 argv而不是 argv[ 1]

argv 是一个指向以 NULL 结尾的 char * 数组的指针,因此您必须遵循间接寻址,如 @user786653 所示。

On entry to main: the stack has the following:

...
*envp[]
*argv[]
argc
return address

When you pop ebx thrice, you end up accesing argv, not argv[1].

argv is a pointer to a NULL-terminated array of char *, so you have to follow the indirection, as @user786653 shows.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文