[Assembler, Отладка, C, Реверс-инжиниринг] Дизассемблируем код на Си — switch() { case assembler: disass(); }
Автор
Сообщение
news_bot ®
Стаж: 6 лет 4 месяца
Сообщений: 27286
Доброго времени суток.Сегодня мы будем смотреть дизассемблированный код инструкций if, for, while, swich, которые написаны на языке Си.![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/4ab221aef2a97c8a558a6c6df0a858f8.jpg)
1605795529033.pngИнcтрукция ifДанную инструкцию довольно просто отличить в дизассемблированном виде от других инструкций. Её отличительное свойство - одиночные инструкции условного перехода je, jne и другие команды jump.![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/cce09185ed1149d96ddb0503a8c4465d.jpg)
1605790962062.png![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/7cfb5e25b7a3618f08dc9d42ae45bc3f.jpg)
1605790989407.pngНапишем небольшую программу на языке Си и дизассемблируем её с помощью radare2. Разницы между IDA PRO и radare2 при дизассемблировании этих программ не было обнаружено, поэтому я воспользуюсь radare2. Вы можете использовать IDA PRO.IDA PRO![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/9e48ef83b5b94ef035fdbe9fa4ba0729.png)
2020-11-17_08-22.png![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/183a80ee4a5ce49f0fd1654d84dd752b.png)
2020-11-17_08-23.pngradare2![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/6e93394e8d8827a6a9119c81999d3975.png)
1605792900362.pngКод на Си
#include <stdio.h>
void main() {
int x = 1;
int y = 2;
if(x == y) {
printf("x = y\n");
}
else{
printf("x != y\n");
}
}
Компилируем при помощи gcc. Команда gcc -m32 prog_if.c -o prog_if. -m32 озночает, что компилироваться код будет под архитектуру x86.Чтобы посмотреть на код в radare2, напишем команду r2 prog_if. Далее прописываем aaa для анализа кода и переходим к функции main s main. Посмотрим на код с помощью команды pdf.Дизассемблированный вариант в radare2![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/19f956569692ac5f602b487657f03775.png)
1605792900362.pngПервым делом в программе происходит объявление переменных ( int x; int y ), а затем значение 1 перемещается в varch (это переменная x) и значение 2 в var10h (это переменная y). Далее идёт сравнение (cmp) 1 и 2 (cmp edx, dword [var_10h]). Эти значения не равны. Значит jne ( jump if noe equal) перейдёт по адресу 0x000011e1. Проще всего инструкцию if запомнить и опрелелить в режиме графов (команда VV для для radare2 или клавиша пробел для IDA).Режим графов![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/6a17e782f689a17c227346c9c0f028b2.png)
1605792914861.pngНемного усложним задачу. Добавим вложенные инструкции. Попробуйте проанализировать этот код.Код на Си
#include <stdio.h>
void main() {
int x = 0;
int y = 1;
int z = 2;
if(x == y) {
if(z == 0) {
printf("z = 0; x = y\n");
}
else{
printf("z = 0; x != y\n");
}
}
else {
if(z == 0) {
printf("z = zero and x != y.\n");
} else {
printf("z non-zero and x != y.\n");
}
}
}
Дизассемблированный вариант в radare2![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/3011d9feeedaa9a7ccb2d398b447473e.png)
1605792935104.pngРежим графов![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/7f7e396057f69983e0e8f31ca2c6f915.png)
1605792950680.pngВ режиме графов это воспринимать намного проще.
Инструкция forЦиклы for всегда состоят из четырех этапов: инициализации, сравнения, выполнения инструкций и инкремента/декремента. По этим четырём этапом мы будем распозновать for в ассемблерном коде.Код на Си
#include <stdio.h>
void main() {
int x;
for(x = 0; x < 100; x++) {
printf("x = %d", x);
}
}
Дизассемблированный вариант в radare2![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/47d5f69fe35ea5076c6d0027111a0e62.png)
1605792973718.png1 - инициализации переменной var_ch (x = 0)
2 - сравнение, а затем jle. ( пока x не будет меньше или равен 2, выполнять цикл.)
3 - выполнения инструкций (printf)
4 - инкрмент переменной var_ch (++x)Режим графов![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/83a33d29da6a10947a709135d4e69316.png)
1605792987678.pngИнструкция whileЦикл while часто используется при ожидании, пока не будет выполнено какое-то условие, например получение команды или пакета. В ассемблере циклы while похожи на for, но их легче понять. В ассемблере это выражение похоже на цикл for, но инкремента может и не быть.Код на Си
#include <stdio.h>
int func_1(int x);
int change_status();
int main() {
int status = 0;
while(status == 0) {
printf("int e = %d", func_1(5) );
status = change_status();
}
return 0;
}
int change_status() {
return 1;
}
int func_1(int x) {
int c;
int e;
int l;
c = 1 + 2;
e = x / 5;
l = 4 - 2;
return e;
}
Дизассемблированный вариант в radare2![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/df22be4dcdc140746315afa8fde377a6.png)
1605793002542.png1 - инициализации переменной var_4h (status = 0)
2 - сравнение, а затем je. ( пока x равен 0, выполнять цикл.)
3 - выполнения инструкций (func1, printf, change_status)Режим графов![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/18f7ca37a1d80c4976d4b6e4bafe7c10.png)
1605793019409.pngИнструкция switchКонструкция switch обычно компилируется двумя способами: по примеру условного выражения или как таблица переходов.Компиляция по примеру условного выраженияКод на Си
#include <stdio.h>
int main() {
int i = 3;
switch(i) {
case 1:
printf("CASE_1 i = %d", i+4);
break;
case 2:
printf("CASE_2 i = %d", i+9);
break;
case 3:
printf("CASE_3 i = %d", i+14);
break;
}
return 0;
}
Дизассемблированный вариант в radare2![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/3128c4f806d97e4836eca28b28c3338a.png)
1605793045836.png1 - инициализации переменной var_4h (i = 3)
2 - выполнения инструкций (add, printf)Чтобы понять какой "case" выбран, происходит сравниение (cmp, а затем je, jne) переменной i с значением case.Режим графов![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/ec572108b2a6b26c6f1634a105605f8a.png)
1605793347813.png![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/7cdf08712d7febccfc7e6f5f3d1d4508.png)
screen13.png![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/6b9228b097a94eb5ab5c3cb097f84483.png)
screen_13_2.pngГлядя на этот код, сложно (если вообще возможно) сказать, что представлял собой оригинальный исходный текст — конструкцию switch или последовательность выражений if . В обоих случаях код выглядит одинаково, поскольку оба выражения используют множество инструкций cmp и je или jne.
Таблица переходовСледующий пример ассемблерного кода часто можно встретить в больших смежных выражениях switch. Мы добавим case 4 и инструкцию по умолчанию.Код на Си
#include <stdio.h>
int main() {
int i = 3;
switch(i) {
case 1:
printf("CASE_1 i = %d", i+4);
break;
case 2:
printf("CASE_2 i = %d", i+9);
break;
case 3:
printf("CASE_3 i = %d", i+14);
break;
case 4:
printf("CASE_3 i = %d", i+19);
break;
default:
break;
}
return 0;
}
Дизассемблированный вариант в radare2![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/db53b73ea424be110cae18bdf6b50193.png)
1605793648917.png![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/4c8e56d59104829bba303257edc0bb07.png)
1605793656018.png1 - инициализации переменной var_4h (i = 3)
2 - выполнения инструкций (add, printf)Вот этот дизасcемблированный код довольно сложно быстро отличить от if и вообще понять что и как тут. В режиме графов всё будет более понятно.
Режим графов![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/26c54dae5518c84a2b7eac82dd1977a4.png)
1605793750977.png![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/b5fb4c99fcf41f125c4a67fb02f4af5a.png)
1605793673414.png![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/714e4307e548f298e993306165135c30.png)
1605793684884.png![Клик для увеличения](https://linkme.ufanet.ru/box/200x100/0aeaf1e30ef319dbfb8a448d4bad63b7.png)
1605793691266.pngРежим графов - ваш друг в дизасcемблировании :)На этом всё. Рекомендую попробовать самому написать программы на Си, скомпилировать и изучить дизасcемблированный код. Практика и ещё раз практика! Спасибо за внимание. Не болейте.
===========
Источник:
habr.com
===========
Похожие новости:
- [Финансы в IT, Криптовалюты] Майнить нельзя посадить: крипторегулирование в России
- [Научно-популярное, Здоровье] Тентакли животного мира
- [] Самое яркое технологическое событие года в области AgroTech
- [Здоровье] Amazon запускает сервис доставки лекарств
- [Развитие стартапа, Научно-популярное, DIY или Сделай сам, Транспорт] Стартап в Y Combinator: сверхзвуковой самолет будущего (перевод)
- [Google App Engine, Облачные вычисления, Google Cloud Platform] Обзор на курс специализации от Coursera — Cloud Architecture with Google Cloud
- [.NET, Управление разработкой, Управление персоналом] Как быть тимлидом и продолжать программировать
- [Схемотехника, Производство и разработка электроники, DIY или Сделай сам, Электроника для начинающих] Active Termination Drivers
- [Информационная безопасность] Страх перед автоматизацией работы и другие тренды в мировой и российской кибербезопасности
- [Сетевые технологии, Беспроводные технологии, Космонавтика, Интернет вещей] Starlink — Спутниковый интернет от Илона Маска: Разбор
Теги для поиска: #_assembler, #_otladka (Отладка), #_c, #_reversinzhiniring (Реверс-инжиниринг), #_assembler (ассемблер), #_radare2, #_assembler, #_reverseengineering, #_reversinzhiniring (реверс-инжиниринг), #_tsikly (циклы), #_otladka (отладка), #_informatsionnaja_bezopasnost (информационная безопасность), #_assembler, #_otladka (
Отладка
), #_c, #_reversinzhiniring (
Реверс-инжиниринг
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 07-Июл 15:28
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 4 месяца |
|
Доброго времени суток.Сегодня мы будем смотреть дизассемблированный код инструкций if, for, while, swich, которые написаны на языке Си. ![]() 1605795529033.pngИнcтрукция ifДанную инструкцию довольно просто отличить в дизассемблированном виде от других инструкций. Её отличительное свойство - одиночные инструкции условного перехода je, jne и другие команды jump. ![]() 1605790962062.png ![]() 1605790989407.pngНапишем небольшую программу на языке Си и дизассемблируем её с помощью radare2. Разницы между IDA PRO и radare2 при дизассемблировании этих программ не было обнаружено, поэтому я воспользуюсь radare2. Вы можете использовать IDA PRO.IDA PRO ![]() 2020-11-17_08-22.png ![]() 2020-11-17_08-23.pngradare2 ![]() 1605792900362.pngКод на Си #include <stdio.h>
void main() { int x = 1; int y = 2; if(x == y) { printf("x = y\n"); } else{ printf("x != y\n"); } } ![]() 1605792900362.pngПервым делом в программе происходит объявление переменных ( int x; int y ), а затем значение 1 перемещается в varch (это переменная x) и значение 2 в var10h (это переменная y). Далее идёт сравнение (cmp) 1 и 2 (cmp edx, dword [var_10h]). Эти значения не равны. Значит jne ( jump if noe equal) перейдёт по адресу 0x000011e1. Проще всего инструкцию if запомнить и опрелелить в режиме графов (команда VV для для radare2 или клавиша пробел для IDA).Режим графов ![]() 1605792914861.pngНемного усложним задачу. Добавим вложенные инструкции. Попробуйте проанализировать этот код.Код на Си #include <stdio.h>
void main() { int x = 0; int y = 1; int z = 2; if(x == y) { if(z == 0) { printf("z = 0; x = y\n"); } else{ printf("z = 0; x != y\n"); } } else { if(z == 0) { printf("z = zero and x != y.\n"); } else { printf("z non-zero and x != y.\n"); } } } ![]() 1605792935104.pngРежим графов ![]() 1605792950680.pngВ режиме графов это воспринимать намного проще. Инструкция forЦиклы for всегда состоят из четырех этапов: инициализации, сравнения, выполнения инструкций и инкремента/декремента. По этим четырём этапом мы будем распозновать for в ассемблерном коде.Код на Си #include <stdio.h>
void main() { int x; for(x = 0; x < 100; x++) { printf("x = %d", x); } } ![]() 1605792973718.png1 - инициализации переменной var_ch (x = 0) 2 - сравнение, а затем jle. ( пока x не будет меньше или равен 2, выполнять цикл.) 3 - выполнения инструкций (printf) 4 - инкрмент переменной var_ch (++x)Режим графов ![]() 1605792987678.pngИнструкция whileЦикл while часто используется при ожидании, пока не будет выполнено какое-то условие, например получение команды или пакета. В ассемблере циклы while похожи на for, но их легче понять. В ассемблере это выражение похоже на цикл for, но инкремента может и не быть.Код на Си #include <stdio.h>
int func_1(int x); int change_status(); int main() { int status = 0; while(status == 0) { printf("int e = %d", func_1(5) ); status = change_status(); } return 0; } int change_status() { return 1; } int func_1(int x) { int c; int e; int l; c = 1 + 2; e = x / 5; l = 4 - 2; return e; } ![]() 1605793002542.png1 - инициализации переменной var_4h (status = 0) 2 - сравнение, а затем je. ( пока x равен 0, выполнять цикл.) 3 - выполнения инструкций (func1, printf, change_status)Режим графов ![]() 1605793019409.pngИнструкция switchКонструкция switch обычно компилируется двумя способами: по примеру условного выражения или как таблица переходов.Компиляция по примеру условного выраженияКод на Си #include <stdio.h>
int main() { int i = 3; switch(i) { case 1: printf("CASE_1 i = %d", i+4); break; case 2: printf("CASE_2 i = %d", i+9); break; case 3: printf("CASE_3 i = %d", i+14); break; } return 0; } ![]() 1605793045836.png1 - инициализации переменной var_4h (i = 3) 2 - выполнения инструкций (add, printf)Чтобы понять какой "case" выбран, происходит сравниение (cmp, а затем je, jne) переменной i с значением case.Режим графов ![]() 1605793347813.png ![]() screen13.png ![]() screen_13_2.pngГлядя на этот код, сложно (если вообще возможно) сказать, что представлял собой оригинальный исходный текст — конструкцию switch или последовательность выражений if . В обоих случаях код выглядит одинаково, поскольку оба выражения используют множество инструкций cmp и je или jne. Таблица переходовСледующий пример ассемблерного кода часто можно встретить в больших смежных выражениях switch. Мы добавим case 4 и инструкцию по умолчанию.Код на Си #include <stdio.h>
int main() { int i = 3; switch(i) { case 1: printf("CASE_1 i = %d", i+4); break; case 2: printf("CASE_2 i = %d", i+9); break; case 3: printf("CASE_3 i = %d", i+14); break; case 4: printf("CASE_3 i = %d", i+19); break; default: break; } return 0; } ![]() 1605793648917.png ![]() 1605793656018.png1 - инициализации переменной var_4h (i = 3) 2 - выполнения инструкций (add, printf)Вот этот дизасcемблированный код довольно сложно быстро отличить от if и вообще понять что и как тут. В режиме графов всё будет более понятно. Режим графов ![]() 1605793750977.png ![]() 1605793673414.png ![]() 1605793684884.png ![]() 1605793691266.pngРежим графов - ваш друг в дизасcемблировании :)На этом всё. Рекомендую попробовать самому написать программы на Си, скомпилировать и изучить дизасcемблированный код. Практика и ещё раз практика! Спасибо за внимание. Не болейте. =========== Источник: habr.com =========== Похожие новости:
Отладка ), #_c, #_reversinzhiniring ( Реверс-инжиниринг ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 07-Июл 15:28
Часовой пояс: UTC + 5