как знать местоположение обратного адреса на стеке c/c ++

я читал о функции, которая может перезаписать ее обратный адрес.

void foo(const char* input)
{
    char buf[10];

    //What? No extra arguments supplied to printf?
    //It's a cheap trick to view the stack 8-)
    //We'll see this trick again when we look at format strings.
    printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n% p\n\n"); //%p ie expect pointers

    //Pass the user input straight to secure code public enemy #1.
    strcpy(buf, input);
    printf("%s\n", buf);

    printf("Now the stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
}  

Было предложено, чтобы это было то, как стек был бы похож

Адрес нечто = 00401000

Мой стек похож:
00000000
00000000
7FFDF000
0012FF80
0040108A <-Мы хотим перезаписать обратный адрес для нечто.
00410EDE

Вопрос:
-. Почему автор произвольно выбирал предпоследнее значение в качестве обратного адреса нечто ()?

-. Значения добавляются к стеку от нижней части или от вершины?

  • кроме функционального обратного адреса, каковы другие значения, которые я, по-видимому, вижу на стеке? т.е. почему это не заполнено нулями

Спасибо.

5
задан Alex Budovski 19 April 2010 в 09:54
поделиться

1 ответ

Тот, что над ним, является предыдущим EBP ( 0012FF80 ). Значение выше prev-EBP всегда является адресом возврата.

(Это, очевидно, предполагает двоичную систему, отличную от FPO, и 32-битную Windows) 1 .

Если вы помните, пролог выглядит так:

push ebp      ; back up the previous ebp on the stack
mov ebp, esp  ; set up the new frame pointer

и когда вызывается функция, например

call 0x00401000

Текущий EIP помещается в стек (используется как адрес возврата), поэтому стек после пролога выглядит так:

[ebp+0xc]  ; contains parameter 1, etc
[ebp+0x8]  ; contains parameter 0
[ebp+0x4]  ; contains return address
[ebp]      ; contains prev-EBP

Итак, для каждого % p printf использует следующие 4 байта, начиная с из [ebp + 0xc] (первый параметр % p ). В конце концов, вы попадаете в предыдущее значение EBP, хранящееся в стеке, которое ( 0012FF80 ), а затем следующее - это адрес возврата.

Обратите внимание, что эти адреса должны «иметь смысл», что они здесь явно и имеют (хотя это может быть не «понятным» для всех).

По Q2) Стек растет вниз. Итак, когда вы нажимаете eax , 4 вычитается из esp , затем значение eax перемещается в [esp], что эквивалентно в коде:

push eax
;  <=>
sub esp, 4
mov [esp], eax

  1. Книга Writing Защитный код , да?
3
ответ дан 15 December 2019 в 06:20
поделиться