程序集 - 从 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
)以查看是否它指向适当区域的开始。您还可以使用 strace
或 ltrace
查看有关已执行系统调用的详细信息。
请注意,您的代码存在各种问题:
- 您将您的代码放入
.data
部分,但这将不起作用。你
应该将其更改为 .text
.
- 你的
#define
常量与asm版本冲突,保留一个或
另一个。它甚至没有 assemble 原样。
fd
可以忽略,但最好设置为-1
- 必须设置
MAP_SHARED
或MAP_PRIVATE
之一
- C 调用约定要求您保留一些寄存器,包括
ebx
和 esi
但您会销毁它们。你应该把它们保存在
在系统调用后使用 push
和 pop
将它们堆叠起来。
我使用的是 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
)以查看是否它指向适当区域的开始。您还可以使用 strace
或 ltrace
查看有关已执行系统调用的详细信息。
请注意,您的代码存在各种问题:
- 您将您的代码放入
.data
部分,但这将不起作用。你 应该将其更改为.text
. - 你的
#define
常量与asm版本冲突,保留一个或 另一个。它甚至没有 assemble 原样。 fd
可以忽略,但最好设置为-1
- 必须设置
MAP_SHARED
或MAP_PRIVATE
之一 - C 调用约定要求您保留一些寄存器,包括
ebx
和esi
但您会销毁它们。你应该把它们保存在 在系统调用后使用push
和pop
将它们堆叠起来。