Реверс-инженеру на заметку: дизассемблирование указателей | OTUS

Реверс-инженеру на заметку: дизассемблирование указателей

Revers_Deep_7.4-5020-d53e4b.png

В одной из предыдущих статей мы рассматривали, как применяются и выглядят в машинном коде массивы. Пришло время поговорить про указатели. Как и прежде, будем использовать для дизассемблирования 64-битную версию IDA Pro и язык программирования «Си».

Итак, исходный код указателей:

int Pointers() {
    int num = 10;

    // указатель на целочисленную переменную
    // включает адрес этой переменной
    int *pointer;

    // &<переменная> вернёт адрес указанной переменной
    pointer = #

    printf("num: %d\n", num);
    printf("*pointer: %d\n", *pointer);
    printf("Address of num: %p\n", &num);
    printf("Address of num using pointer: %p\n", pointer);
    printf("Address of pointer: %p\n", &pointer);

    return 0;
}

Что же, на первый взгляд ничего сложно нет. Но давайте разбираться в машинном коде. Сначала присваиваем переменной num значение 10 (int num = 10).

reverse_dev_pic_11_1-20219-864d5c.jpeg

Идём дальше. Следующий этап — присваивание указателю pointer адреса переменной num (pointer = &num).

reverse_dev_pic_12_1-20219-59b760.jpeg

Продолжаем. Судя по машинному коду, мы выводим переменную num на экран.

reverse_dev_pic_13_1-20219-06525b.jpeg

Также нам потребуется вывести на экран и переменную pointer. Вот, как это выглядит в машинном коде:

reverse_dev_pic_14_1-20219-d5c8a6.jpeg

Теперь выводим адрес переменной num. Это осуществляется посредством инструкции lea (речь идёт о загрузке результирующего адреса) вместо mov:

reverse_dev_pic_15_1-20219-b2f1cd.jpeg

Теперь выводим адрес num через указатель pointer. Машинный код:

reverse_dev_pic_16_1-20219-05a563.jpeg

Останется вывести адрес pointer, что происходит посредством инструкции lea вместо mov. Машинный код:

reverse_dev_pic_17_1-20219-8b9d03.jpeg

Вот и всё, что можно сказать про работу указателей и их отображение в машинном коде. Впрочем, вам также необходимо знать особенности дизассемблирования при реализации таких продвинутых концепций, как динамическое распределение памяти, многопоточность и программирование сокетов. Понимание этих аспектов поможет вам продвинуться в освоении реверс-инжиниринга. Но об этом — в следующий раз.

Источник

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто