0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: реверс-инжиниринг, машинный код, дизассемблирование, указатели</p>
1
<p>Теги: реверс-инжиниринг, машинный код, дизассемблирование, указатели</p>
2
<p>В одной из<a>предыдущих статей</a>мы рассматривали, как применяются и выглядят в машинном коде массивы. Пришло время поговорить про<strong>указатели</strong>. Как и прежде, будем использовать для дизассемблирования 64-битную версию IDA Pro и язык программирования "Си".</p>
2
<p>В одной из<a>предыдущих статей</a>мы рассматривали, как применяются и выглядят в машинном коде массивы. Пришло время поговорить про<strong>указатели</strong>. Как и прежде, будем использовать для дизассемблирования 64-битную версию IDA Pro и язык программирования "Си".</p>
3
<p>Итак, исходный код указателей:</p>
3
<p>Итак, исходный код указателей:</p>
4
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; }<p>Что же, на первый взгляд ничего сложно нет. Но давайте разбираться в машинном коде. Сначала присваиваем переменной num значение 10 (int num = 10).</p>
4
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; }<p>Что же, на первый взгляд ничего сложно нет. Но давайте разбираться в машинном коде. Сначала присваиваем переменной num значение 10 (int num = 10).</p>
5
<p>Идём дальше. Следующий этап - присваивание указателю pointer адреса переменной num (pointer = &num).</p>
5
<p>Идём дальше. Следующий этап - присваивание указателю pointer адреса переменной num (pointer = &num).</p>
6
<p>Продолжаем. Судя по машинному коду, мы выводим переменную num на экран.</p>
6
<p>Продолжаем. Судя по машинному коду, мы выводим переменную num на экран.</p>
7
<p>Также нам потребуется вывести на экран и переменную pointer. Вот, как это выглядит в машинном коде:</p>
7
<p>Также нам потребуется вывести на экран и переменную pointer. Вот, как это выглядит в машинном коде:</p>
8
<p>Теперь выводим адрес переменной num. Это осуществляется посредством инструкции lea (речь идёт о загрузке результирующего адреса) вместо mov:</p>
8
<p>Теперь выводим адрес переменной num. Это осуществляется посредством инструкции lea (речь идёт о загрузке результирующего адреса) вместо mov:</p>
9
<p>Теперь выводим адрес num через указатель pointer. Машинный код:</p>
9
<p>Теперь выводим адрес num через указатель pointer. Машинный код:</p>
10
<p>Останется вывести адрес pointer, что происходит посредством инструкции lea вместо mov. Машинный код:</p>
10
<p>Останется вывести адрес pointer, что происходит посредством инструкции lea вместо mov. Машинный код:</p>
11
<p>Вот и всё, что можно сказать про работу указателей и их отображение в машинном коде. Впрочем, вам также необходимо знать особенности дизассемблирования при реализации таких продвинутых концепций, как динамическое распределение памяти, многопоточность и программирование сокетов. Понимание этих аспектов поможет вам продвинуться в освоении реверс-инжиниринга. Но об этом - в следующий раз.</p>
11
<p>Вот и всё, что можно сказать про работу указателей и их отображение в машинном коде. Впрочем, вам также необходимо знать особенности дизассемблирования при реализации таких продвинутых концепций, как динамическое распределение памяти, многопоточность и программирование сокетов. Понимание этих аспектов поможет вам продвинуться в освоении реверс-инжиниринга. Но об этом - в следующий раз.</p>
12
<p><a>Источник</a></p>
12
<p><a>Источник</a></p>
13
13