2015-05-17 7 views
0

Я использую AT & T синтаксис. Я написал код, который вызывает функцию mmap2 с c.Сборка - 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 непосредственно в отдельном терминале), чтобы увидеть, указывает ли оно на начало соответствующего региона. Вы также можете использовать strace или ltrace, чтобы узнать подробности о выполненном системном вызове.

Обратите внимание, что ваш код имеет различные вопросы:

  • Вы помещаете свой код в секцию .data и что не будет работать. Вы должны изменить это на .text.
  • Ваш #define постоянные конфликты с версиями asm, сохранить один или другой. Он даже не собирается как есть.
  • fd могут быть проигнорированы, но это лучше, чтобы установить его на -1
  • Один из MAP_SHARED или MAP_PRIVATE должен быть установлен
  • С призванием Конвенция предусматривает вам сохранить некоторые регистры, включая ebx и esi, но вы их уничтожить. Вы должны сохранить их в стеке , используя push и pop их обратно после системного вызова.
+0

Те, что #define комментируются, как «#» начинают комментарий в синтаксисе AT & T, это не должно быть неправильно. Я добавил это как напоминание. – DzikiChrzan

+0

И моя проблема - как запустить gdb с этими файлами? После компиляции я получил f.e. файл с именем exec. Я запускаю это с помощью команды ./exec - но когда я запускаю это в gdb («gdb ./exec»), я не могу просто просто поставить точку останова на некоторые подобные. И когда я использую команду «файл», она говорит, что нет загруженного файла. – DzikiChrzan

+0

'gdb./Exec' должен работать, и вы должны иметь возможность разместить точки останова. – Jester