为什么系统调用不起作用? [英] Why syscall doesn't work?

查看:63
本文介绍了为什么系统调用不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MAC OSX上,并且尝试通过程序集调用execve syscall.他的操作码是59.在linux中,我必须将操作码设置为eax,然后将参数设置为其他寄存器,但是在这里,我必须将操作码放入eax,并从右向左将参数压入堆栈.

I'm on MAC OSX and I'm trying to call through assembly the execve syscall.. His opcode is 59 . In linux I have to set opcode into eax, then parameters into the others registers, but here I have to put the opcode into eax and push parameters into the stack from right to left.

所以我需要execve("/bin/sh",NULL,NULL),我发现某个地方的程序集为null = 0,所以我将null放入了第二个和第三个参数中.

So I need execve("/bin/sh",NULL,NULL), I found somewhere that with assembly null=0, so I put null into 2nd and 3rd parameters.

global start 
section .text
start:
    jmp string
main: 
    ; 59 opcode
    ; int execve(char *fname, char **argp, char **envp);
    pop ebx             ;stringa
    push 0x0            ;3rd param
    push 0x0            ;2nd param
    push ebx            ;1st param
    add eax,0x3b        ;execve opcode
    int 0x80            ;interupt
    sub eax,0x3a        ; exit opcode
    int 0x80
string:
    call main
    db '/bin/sh',0

当我尝试执行它时,请说:错误的系统调用:12

When I try to execute it say: Bad system call: 12

推荐答案

BSD 上的32位程序(基于OS/X)要求您将额外的4个字节压入堆栈如果您打算直接调用 int 0x80 .在 FreeBSD文档中,您会找到这个:

32-bit programs on BSD (on which OS/X is based) requires you to push an extra 4 bytes onto the stack if you intend to call int 0x80 directly. From the FreeBSD documentation you will find this:

默认情况下,FreeBSD内核使用C调用约定.此外,尽管使用int 80h访问内核,但假定程序将调用发出int 80h的函数,而不是直接发出int 80h.

By default, the FreeBSD kernel uses the C calling convention. Further, although the kernel is accessed using int 80h, it is assumed the program will call a function that issues int 80h, rather than issuing int 80h directly.

[snip]

但是汇编语言程序员喜欢缩短周期.上面的示例需要一个呼叫/重拨组合.我们可以通过添加一个额外的dword来消除它:

But assembly language programmers like to shave off cycles. The above example requires a call/ret combination. We can eliminate it by pushing an extra dword:

open:
push    dword mode
push    dword flags
push    dword path
mov eax, 5
push    eax     ; Or any other dword
int 80h
add esp, byte 16

在调用 int 0x80 时,您需要将堆栈指针调整4.按下任何值都将实现此目的.在示例中,他们只是执行 push eax .在调用 int 0x80 之前,将4个字节压入堆栈.

When calling int 0x80 you need to adjust the stack pointer by 4. Pushing any value will achieve this. In the example they just do a push eax. Before your calls to int 0x80 push 4 bytes onto the stack.

您的另一个问题是,例如, add eax,0x3b 要求 EAX 已经为零,这很可能不是这种情况.要解决此问题,请在代码中添加 xor eax,eax .

Your other problem is that add eax,0x3b for example requires EAX to already be zero which is almost likely not the case. To fix that add an xor eax, eax to the code.

修复程序可能类似于:

global start
section .text
start:
    jmp string
main:
    ; 59 opcode
    ; int execve(char *fname, char **argp, char **envp);
    xor eax, eax        ;zero EAX
    pop ebx             ;stringa
    push 0x0            ;3rd param
    push 0x0            ;2nd param
    push ebx            ;1st param
    add eax,0x3b        ;execve opcode
    push eax            ;Push a 4 byte value after parameters per calling convention
    int 0x80            ;interupt
    sub eax,0x3a        ; exit opcode
    push eax            ;Push a 4 byte value after parameters per calling convention
                        ; in this case though it won't matter since the system call
                        ; won't be returning
    int 0x80
string:
    call main
    db '/bin/sh',0


Shellcode

您的代码实际上称为 JMP/CALL/POP 方法,用于编写漏洞利用程序.您是在编写漏洞利用程序还是只是在网上找到此代码?如果打算用作外壳程序代码,则需要避免在输出字符串中放入0x00字节. push 0x00 将在生成的代码中编码0x00字节.为了避免这种情况,我们可以使用 EAX ,现在将其清零并将其压入堆栈.同样,您将无法NUL终止字符串,因此必须将NUL(0)字符移入字符串.将 EAX 调零并弹出 EBX 后的一种方法是使用 mov [ebx + 7],al .七个是字符串/bin/sh 末尾的索引.您的代码将如下所示:


Shellcode

Your code is actually called the JMP/CALL/POP method and is used for writing exploits. Are you writing an exploit or did you just find this code online? If it is intended to be used as shell code you would need to avoid putting a 0x00 byte in the output string. push 0x00 will encode 0x00 bytes in the generated code. To avoid this we can use EAX which we are now zeroing out and push it on the stack. As well you won't be able to NUL terminate the string so you'd have to move a NUL(0) character into the string. One way after zeroing EAX and popping EBX is to move zero to the end of the string manually with something like mov [ebx+7], al. Seven is the index after the end of the string /bin/sh. Your code would then look like this:

global start
section .text
start:
    jmp string
main:
    ; 59 opcode
    ; int execve(char *fname, char **argp, char **envp);
    xor eax, eax        ;Zero EAX
    pop ebx             ;stringa
    mov [ebx+7], al     ;append a zero onto the end of the string '/bin/sh' 
    push eax            ;3rd param
    push eax            ;2nd param
    push ebx            ;1st param
    add eax,0x3b        ;execve opcode
    push eax
    int 0x80            ;interupt
    sub eax,0x3a        ; exit opcode
    push eax
    int 0x80
string:
    call main
    db '/bin/sh',1

这篇关于为什么系统调用不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆