2015-05-17 71 views
0

我正在使用AT & T语法。我写了代码,它从c调用函数mmap2。汇编 - mmap2从c调用

这是我的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 $0x80 
    mov %ebp,%esp 
    pop %ebp 

    ret 

我的问题是 - 我怎么能检查,如果这个代码是好?我想这个答案是在eax寄存器中,但是 - 我怎样才能访问这个值?在这种情况下,我不知道如何使用gdb。

回答

1

第一次检查应该看看返回的值是否是一个小的负数。接下来,你可以尝试使用它,因为你通过了旗帜。最简单的方法是尝试读取第一个字节。此外,在gdb中断后停止时,可以将eax中的值与使用info proc mappings可访问的进程内存映射进行比较(或直接在单独的终端中检查/proc)以查看它是否指向适当区域的开始。您也可以使用straceltrace查看有关执行的系统调用的详细信息。

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

  • 你把你的代码到.data部分,这是行不通的。您 应该将其更改为.text
  • 您的#define常量与asm版本冲突,保留一个或另一个为 。它甚至不按原样组装。
  • fd可以忽略不计,但最好将其设置为-1
  • 一个MAP_SHAREDMAP_PRIVATE必须设置
  • C调用约定的任务,你保存一些寄存器,包括ebxesi,但你消灭他们。在系统调用之后,您应该使用pushpop将它们保存在 堆栈中。
+0

对那些#define进行了注释,因为'#'在AT&T语法中开始注释,所以不应该是错误的。我只是提醒一下。 – DzikiChrzan

+0

而我的问题是 - 如何使用此文件运行gdb?编译后,我有f.e.名为exec的文件。我使用命令./exec运行这个命令 - 但是当我在gdb(“gdb ./exec”)中运行这个命令时,我不能只是傻乎乎地把断点放在一些像。当我使用命令'文件'它说,没有文件加载。 – DzikiChrzan

+0

'gdb。/ exec'应该可以工作,并且您应该可以放置断点。 – Jester