Почему нет соответствующего вызова подпрограммы в дампе машинного кода при вызове strcpy ()? - PullRequest
2 голосов
/ 22 января 2012

Я работаю над книгой Джона Эриксона «Взлом: искусство эксплуатации».

В одной части книги он дает код на C, а затем просматривает соответствующую сборку, используя gdb, объясняя инструкции и действия с памятью.

Я работаю вместе в Mac OS X, поэтому все немного отличается от того, что он представляет в книге (он использует Linux).

В любом случае, у меня есть эта программа на C:

1 #include <stdio.h>
2 #include <string.h>
3 
4 int main()
5 {
6         char str_a[20];
7 
8         strcpy(str_a, "Hello, world!\n");
9         printf(str_a);
10 }

Вот соответствующий дамп объекта otool (я только что включил main):

_main:
0000000100000ea0    pushq   %rbp
0000000100000ea1    movq    %rsp,%rbp
0000000100000ea4    subq    $0x30,%rsp
0000000100000ea8    movq    0x00000189(%rip),%rax
0000000100000eaf    movq    (%rax),%rax
0000000100000eb2    movq    %rax,0xf8(%rbp)
0000000100000eb6    leaq    0xd4(%rbp),%rax
0000000100000eba    movq    %rax,%rcx
0000000100000ebd    movq    $0x77202c6f6c6c6548,%rdx
0000000100000ec7    movq    %rdx,(%rcx)
0000000100000eca    movb    $0x00,0x0e(%rcx)
0000000100000ece    movw    $0x0a21,0x0c(%rcx)
0000000100000ed4    movl    $0x646c726f,0x08(%rcx)
0000000100000edb    movq    %rcx,0xe8(%rbp)
0000000100000edf    xorb    %cl,%cl
0000000100000ee1    movq    %rax,%rdi
0000000100000ee4    movb    %cl,%al
0000000100000ee6    callq   0x100000f1e ; symbol stub for: _printf
0000000100000eeb    movl    0xf4(%rbp),%eax
0000000100000eee    movq    0x00000143(%rip),%rcx
0000000100000ef5    movq    (%rcx),%rcx
0000000100000ef8    movq    0xf8(%rbp),%rdx
0000000100000efc    cmpq    %rdx,%rcx
0000000100000eff    movl    %eax,0xd0(%rbp)
0000000100000f02    jne 0x100000f0d
0000000100000f04    movl    0xd0(%rbp),%eax
0000000100000f07    addq    $0x30,%rsp
0000000100000f0b    popq    %rbp
0000000100000f0c    ret
0000000100000f0d    callq   0x100000f12 ; symbol stub for: ___stack_chk_fail

OK. Вы заметите вызов подпрограммы для printf ():

0000000100000ee6    callq   0x100000f1e ; symbol stub for: _printf

Но где же вызов strcpy ()?

Есть еще две аномалии. Прежде всего, если я установлю точку останова в gdp для strcpy ():

break strcpy

Программа выполняет выполнение без остановки. Кажется, что strcpy () на самом деле не вызывается.

Во-вторых, когда я скомпилировал код:

gcc -g -o char_array2 char_array2.c

Я получил предупреждение:

char_array2.c: In function ‘main’:
char_array2.c:9: warning: format not a string literal and no format arguments
char_array2.c:9: warning: format not a string literal and no format arguments

Я не уверен, связано ли это с отсутствующим вызовом подпрограммы, но я подумал, что все равно включу его в качестве точки данных.

Мне кажется, что компилятор решил, что strcpy () не нужен, и оптимизировал код для работы без него. Программа работает как положено, печатая «Привет, мир!» к стандартному выводу, но этот пропущенный вызов strcpy () заставляет меня задуматься, что именно происходит.

В примере Эриксона в книге - это вызов strcpy (), так что, возможно, есть разница в том, как работает его компилятор и мой компилятор. Я на LLVM:

i686-яблоко-darwin11-LLVM-GCC-4,2

Любые идеи будут с благодарностью приняты!

Заранее спасибо, и я надеюсь, что вы найдете этот интересным.

Tom

1 Ответ

9 голосов
/ 22 января 2012

Это прямо здесь:

0000000100000ebd    movq    $0x77202c6f6c6c6548,%rdx
0000000100000ec7    movq    %rdx,(%rcx)
0000000100000eca    movb    $0x00,0x0e(%rcx)
0000000100000ece    movw    $0x0a21,0x0c(%rcx)
0000000100000ed4    movl    $0x646c726f,0x08(%rcx)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...