程序集 - 从 c 调用的 mmap2

Assembly - mmap2 called from c

我使用的是 AT&T 语法。我写了代码,它从 c.

调用函数 mmap2

这是我的 C 文件:

#include <stdio.h>
int* callloc(int length);
int main(){
int *adres = callloc(1000);
printf("%u\n",adres);
return 0;
}

这是我的汇编函数:

#define PROT_READ       0x1             /* Page can be read.  */
#define PROT_WRITE      0x2             /* Page can be written.  */
#define PROT_EXEC       0x4             /* Page can be executed.  */
#define PROT_NONE       0x0             /* Page can not be accessed.  */

#define __NR_mmap                90
#define __NR_munmap              91
#define __NR_mmap2              192


.data
MMAP2 = 192
MUNMAP = 91
PROT_READ = 0x1
MAP_ANONYMOUS = 0x20

.global callloc
callloc:
    #mmap2 function takes 6 arguments when called
    #void *addr - it must be equal 0
    #sieze_t length - this is variable from call in C
    #int prot - access level, I guess it should be equal 0x1
    #int flags - map_anonymous, then fd i offset are ignored
    #int fd, off_t offset - those parameters are ignored

    push %ebp
    mov %esp,%ebp       #esp has address of beginning of function
    xor %ebx,%ebx
    mov 8(%ebp),%ecx    #length of memory to allocate is kept in stack since 8 byte 
    mov $PROT_READ,%edx
    mov $MAP_ANONYMOUS,%esi

    mov $MMAP2,%eax
    int [=11=]x80
    mov %ebp,%esp
    pop %ebp

    ret

我的问题是 - 我如何检查这段代码是否正确?我想答案在 eax 寄存器中,但是 - 我如何访问这个值?我不知道在这种情况下如何使用 gdb。

首先检查返回值是否为小的负数。接下来,您当然可以根据传入的标志尝试使用它。最简单的方法是尝试读取第一个字节。此外,在中断后停止的 gdb 中,您可以将 eax 中的值与使用 info proc mappings 可访问的进程内存映射进行比较(或在单独的终端中直接检查 /proc )以查看是否它指向适当区域的开始。您还可以使用 straceltrace 查看有关已执行系统调用的详细信息。

请注意,您的代码存在各种问题:

  • 您将您的代码放入 .data 部分,但这将不起作用。你 应该将其更改为 .text.
  • 你的#define常量与asm版本冲突,保留一个或 另一个。它甚至没有 assemble 原样。
  • fd可以忽略,但最好设置为-1
  • 必须设置MAP_SHAREDMAP_PRIVATE之一
  • C 调用约定要求您保留一些寄存器,包括 ebxesi 但您会销毁它们。你应该把它们保存在 在系统调用后使用 pushpop 将它们堆叠起来。