Привіт і ласкаво просимо назад.
У цій новій темі ми будемо вивчати виклики функцій, і в цій лекції я познайомлю вас з
нею.
Вступ до функціональних викликів.
Отже, у x64dbg ви побачите виклики функцій, які трапляються дуже часто.
Тож давайте розглянемо приклад.
Наприклад, припустимо, я відкриваю існуючу програму на C.
Отже, це приклад програми на C.
Це виклик функції.
Все це виклики функцій.
Кожного разу, коли ви бачите слово call, це означає, що воно викликає функцію.
У цьому полягає сенс викликів функцій.
А потім у програмі C можна переглянути приклади викликів функцій.
Наприклад, у програмі на C є функція printf, яка називається printf.
Ось як це виглядає: printf, а потім параметр.
Отже, приклад тут: функція printf.
А далі це параметри для функції printf: перший параметр, другий параметр, третій параметр і так
далі.
Може бути один параметр, два параметри або три параметри.
Отже, якщо вам потрібно більше інформації про функцію printf або програмування на C загалом, ви можете зайти на Tutorials
Point і прочитати все про будь-яку тему з програмування на C. Все тут.
Ви можете почитати про це.
Повернімося до нашого слайду.
Існує так звана угода про виклик x86.
x86 - це термін для позначення 32-бітних програм.
Отже, прикладом буде функція, за якою слідує параметр.
Це синтаксис мови C.
Кожна функція має ім'я, за яким слідує параметр і крапка з комою, що позначає
кінець виразу. І асемблер, якщо ми хочемо
перетворити це на мову асемблера, ми повинні виштовхнути параметр у стек, а потім викликати
функцію.
Отже, якщо є тільки один параметр, буде тільки один поштовх.
Отже, це приклад відбитка.
Привіт, світе.
У цьому прикладі ми використовуємо функцію printf, але вона має лише один параметр: рядок Hello
World.
Отже, якщо ми перетворимо його у збірку, то спочатку виштовхнемо цей рядок до стеку.
І ми зробимо це, натиснувши на адресу пам'яті, яка містить рядок.
Отже, ми натискаємо адресу, а потім викликаємо printf, який виведе на екран
рядок Hello World.
Тепер ми можемо спробувати це зараз.
Давайте спробуємо запустити наш відладчик і відкриємо наш шаблон.
Перейдемо до Reverse Engineering Projects, File, Template One. А тут ми прокрутимо вниз, а потім тут шукатимемо
місце в пам'яті, де ми зможемо зберегти наш рядок.
Наш рядок - "Hello World".
Так.
Отже, нам потрібно створити місце на карті пам'яті.
Перейдіть до сегмента даних і прокрутіть вниз до порожньої області пам'яті.
І тут ми можемо вибрати всі ці ключові слова.
Перший: це ключове слово тут, інше ключове слово тут, ще одне ключове слово тут, ще одне ключове слово тут, ще одне ключове слово тут.
Отже, цього має бути достатньо для зберігання нашого рядка Hello
World.
І все, що нам потрібно зробити, це клацнути правою кнопкою миші і вибрати "Двійкові", "Виділити", "Редагувати". А потім під ASCII просто вводимо
наш рядок: Hello World, Hello World.
А потім переконайтеся, що тут позначено: Зберігати розмір. А потім натисни "ОК".
І тут ми бачимо наш рядок: Hello
World.
А ззаду є наш нульовий термінатор, який позначає кінець рядка.
Отже, тепер у нас є ця адреса, тому ми повинні скопіювати цю адресу.
Клацніть правою кнопкою
миші, скопіюйте цю адресу.
Отже, ця адреса є адресою початку рядка, який фактично є першим символом
рядка.
І тепер ми можемо прийти сюди і почати проштовхувати цю нитку до стопки.
Отже, клацніть на цьому рядку, натисніть пробіл і введіть push, поставте шістнадцятковий префікс, поставте шістнадцятковий префікс, а потім вставте адресу
рядка в пам'яті, який, власне, і є цим рядком. Натисни
ОК. Тепер у нас є поштовх.
Отже, наступне, що потрібно зробити, це викликати функцію printf.
Тож де шукати функцію printf?
Ви можете прокручувати і шукати будь-які існуючі виклики.
Наприклад, прокрутіть вниз.
Ви бачите, що тут є два дзвінки.
Отже, ви можете перейти до таблиці функцій, двічі клацнувши будь-яку з цих функцій.
Тож просто двічі клацніть
на ньому, наприклад, putchar. І ви потрапите до таблиць переходів для всіх викликів функцій.
Отже, це таблиці переходів, які містять всі існуючі виклики функцій, що вже були імпортовані
у цю програму.
Отже, тут ви можете побачити адресу, де знаходиться функція.
Ось адреси для кожної з цих функцій.
Наприклад, printf: адреса printf - 402614.
Це те, що ми хочемо.
Отже, все, що нам потрібно зробити, це просто клацнути правою кнопкою миші, скопіювати цю адресу, а потім повернутися до нашої
програми, натиснувши на -.
- є вказівником інструкцій і вказує на місце, де наша програма зараз зупинена.
Отже, це адреса, за якою ми зараз знаходимося.
Тож ми просто двічі клацнемо на ньому, і ми повернемося до цього місця, до початку програми.
Тож просто прокрутіть вниз і поверніться сюди. Отже, тепер ми можемо продовжити цей рядок і зібрати
виклик нашої функції printf.
Зверніть увагу, що ми вже скопіювали адресу функції printf.
Отже, тепер ми просто натискаємо пробіл і вводимо call, вводимо шістнадцятковий префікс, а потім вставляємо адресу виклику або
функцію printf.
Тепер натискаємо ОК. І ось, будь ласка.
Тепер у нас є функція printf, тож ми можемо запустити нашу програму і протестувати її.
Тож просто натисніть на кнопку "Виконати".
Переконайтеся, що перед запуском ви поставили тут точку зупинки.
І ось ми досягли точки зупинки, і ви бачите, що наша програма працює.
Давай переступимо.
Там працює наша програма.
Тож відійди. Тепер він проштовхне цю нитку до стеку.
А це адреса рядка.
Тож слідкуйте за стеком. Відійди.
І тепер вона штовхнула цю нитку до стопки.
Отже, тепер це параметр для printf.
Отже, коли ви збираєтеся викликати функцію printf, функція printf використовуватиме цей параметр,
який вже знаходиться у стеку. Це базується на нашому форматі.
Будь-який параметр, який буде використовуватися функцією, повинен бути спочатку виштовхнутий у стек.
Потім ви викликаєте функцію.
Функція автоматично знатиме, де шукати.
Він одразу перейде до стеку, щоб знайти свій параметр.
Отже, тепер ми можемо викликати функцію printf і переглянути вивід для нашого виклику
функції у цьому виводі.
Тож давайте переступимо цю межу і подивимося, як це відбувається.
І ви бачите, що Hello World виводиться на екран.
Як і на нашому слайді, на виході ми отримуємо "Hello World".
Ось як можна зробити виклик функції, що використовує один параметр.
Тому ми зупинимося на цьому. У наступному уроці ми продовжимо
розглядати виклики функцій, які використовують два параметри.
Тож до наступної зустрічі.
Тим часом, якщо бажаєте, ви можете зберегти цей файл: Patch і натиснути кнопку Patch File. А потім приходьте сюди і дайте йому
ім'я.
Назвемо його 14_функція _один
_латок.
exe.
Натисніть "Зберегти".
Отже, function_one означає виклик функції з одним параметром.
Натисни
ОК.
Ось і все.
До зустрічі в наступному відео.
Дякуємо за перегляд.