З поверненням.
Тепер ми розглянемо виклики функцій з двома параметрами.
Отже, у двопараметричних викликах функцій є два параметри, які передаються у функцію.
Коли ви перетворюєте це на збірку, вам потрібно виштовхнути параметри до стеку.
Тепер порядок, в якому ви штовхаєте до стеку, є зворотнім.
Спочатку ви натискаєте другий параметр, потім перший параметр, а потім викликаєте функцію.
Отже, давайте розглянемо приклад виклику функції з двома параметрами.
Тут ми маємо інструкцію print, але цього разу printf має два параметри.
Це: перший параметр.
Далі йде кома і другий параметр.
Перший параметр містить рядок Hello, а також
специфікатор
формату %s, який також виконує роль заповнювача.
Отже, коли цей printf буде викликано, цей заповнювач буде замінено на рядок.
Отже, коли ви викликаєте всю цю функцію, вона
виведе Hello, а потім рядок.
Уявімо, що рядок - це моє ім'я,
моє ім'я Пол.
Отже, коли ця функція друку викликається, рядок замінить специфікатор формату, і ви отримаєте
Hello, Paul.
Отже, це специфікатор формату.
У специфікаторі формату потрібно вказати, який саме формат потрібно вставити. У цьому випадку % s означає, що ви збираєтеся
вставити сюди рядок.
Існують також інші різні специфікатори форматів.
Наприклад, якщо ви хочете вставити число, ви вводите %d, як у наступному прикладі:
%d.
Отже, у цьому випадку, коли ви викликаєте функцію printf, формат буде d. Тому він очікує, що цей другий параметр
буде числом.
Отже, коли ви припускаєте, коли ви, якщо ви припускаєте, що число тут дорівнює 12, то коли ви викликаєте цю
функцію, ви отримаєте на виході: Число: 12.
Отже, у цьому випадку "Number:" походить з першої частини рядка, а 12 - зі специфікатора
формату %d, який замінюється на число у другому параметрі.
Тож якщо ви забули все це, ви можете піти і почитати про специфікатори форматів в Google.
Просто погугліть "специфікатори форматів" і ви зможете прочитати про специфікатори форматів.
Як бачите, існує багато специфікаторів форматів.
Тому для нашого прикладу я покажу лише два з них, а саме %s для рядка
і %d для цілого числа.
А детальніше про те, що таке специфікатори форматів і як вони працюють, ви можете прочитати тут.
Отже, давайте спробуємо зробити це у вашому x64dbg.
Тож ми візьмемо перший, ось цей.
Отже, ми знову відкриваємо наш Шаблон Один.
Зараз ви спробуєте цей приклад.
У цьому прикладі є рядок, а точніше
два рядки. Другий параметр - це рядок, який
містить моє ім'я, а перший параметр - це інший рядок, який містить рядок:
Hello, кому та специфікатор формату.
Отже, нам потрібно знайти дві комірки пам'яті для зберігання цих двох рядків.
Тож давайте перейдемо до нашої Карти пам'яті.
Перейдіть до нашого сегменту даних і прокрутіть вниз, щоб знайти порожні місця для зберігання наших двох рядків.
Ми можемо вибрати це і це.
Ці дві адреси пам'яті порожні.
Ми можемо їх використати.
Отже, для перших 13050 ми будемо використовувати його для зберігання мого імені, Павло.
Тож ми просто вибираємо все це тут.
Ви можете вибрати все, що завгодно, аж до цього місця.
Виберіть кількість слів, достатню для зберігання цього рядка.
Пол - це чотири персонажі.
Тоді вам знадобиться ще один символ для нульового термінатора.
Отже, вам потрібно п'ять символів.
Це означає п'ять байт.
Один символ - один байт.
Отже, тут у вас є чотири байти, а потім ще один байт для нульового термінатора.
Тож моє ім'я буде зберігатися тут:
Павло, за яким стоятиме нульовий термінатор.
Отже, нам потрібно вибрати два слова.
Отже, два слова мають бути достатньо довгими, щоб зберігати моє ім'я,
Пол, і нульовий термінатор.
Отже, тепер ми можемо клацнути тут правою кнопкою миші, перейти до пункту Двійковий і вибрати пункт Редагувати. Потім клацніть на текстовому полі
ASCII і введіть моє ім'я, Пол. Потім натисніть на , переконайтеся, що позначено пункт Зберігати розмір, і натисніть OK.
І тепер у вас є ім'я Пол і нульовий термінатор ззаду.
Пол і нуль-термінатор ззаду.
Тепер ми закінчили з другим
параметром.
Тепер ми збережемо перший параметр за наступною адресою тут.
Отже, за наступною адресою нам потрібно
зберігати цей рядок: Hello, %s.
Тож скільки там персонажів?
Один, два, три, чотири, п'ять, шість, сім, вісім, дев'ять символів: дев'ять байт.
Отже, вам потрібно дев'ять байт.
Отже, двох слів для цього недостатньо.
Вам потрібно щонайменше три слова.
Отже, у вас є 12 байт: тричі по чотири - 12.
Значить, більше дев'яти.
Цього має бути достатньо.
Клацніть правою кнопкою миші, виберіть "Двійкові", "Редагувати", а потім перейдіть сюди і введіть цей рядок.
Hello,
а потім кома, пробіл, %s. А потім переконайтеся, що це перевірено.
Натисни ОК.
Тепер підтвердьте, що це так, це
правильно.
Отже, у вас є Hello, пробіл
- це пробіл, потім %s, а потім нульовий термінатор.
Отже, це зроблено.
Тепер ми готові зіштовхнути все до стеку.
Отже, ми виштовхнемо першу пам'ять, першу адресу до стеку, а саме цю адресу.
Це перший параметр.
Клацніть правою кнопкою миші та скопіюйте цю адресу.
Скопіюй цю адресу.
Перейдіть до цього місця, клацніть на ньому, натисніть пробіл і введіть push, введіть префікс
hex, а потім вставте адресу другого параметра.
ГАРАЗД.
Потім знову штовхають наступну.
ГАРАЗД.
Перед цим скопіюємо адресу першого параметра.
Це другий параметр.
Це перший параметр.
Тож скопіюй цю адресу.
Клацніть правою кнопкою миші, скопіюйте адресу.
Підійдіть сюди, натисніть пробіл, наберіть push.
Поставте префікс hex і вставте туди адресу.
Натисни
ОК.
Отже, тепер ви перевіряєте, щоб підтвердити, що вашим другим параметром є рядок Paul, який є цією адресою.
Перший параметр - Hello %s, тобто ця адреса.
Так що все правильно.
Тепер нам потрібно знайти функцію printf.
Отже, як завжди, нам потрібно перейти до таблиць переходів для функцій.
Щоб перейти до таблиць переходів, просто прокрутіть вниз і знайдіть будь-яку функцію, наприклад,
цю, а потім двічі клацніть її, щоб перейти до таблиць переходів.
Зараз ми знаходимося в таблицях переходів, тому шукайте функцію printf.
функцію printf.
Отже, прокрутіть вниз, і ви побачите функцію printf, а це адреса функції printf.
Клацніть правою кнопкою миші на цій адресі та скопіюйте її.
Потім натисніть на вказівник інструкції, щоб повернутися до того місця, де ви зупинилися.
Прокрутіть вниз, а потім сюди, натисніть на це, натисніть пробіл і введіть виклик.
Введіть шістнадцятковий префікс і вставте туди адресу функції printf.
Натисни
ОК.
І тепер у вас є відбиток. Отже, тепер ви готові до запуску програми.
Тож давайте зробимо це.
Тепер просто поставте тут точку зупинки, як це зробив я, і запустіть програму. Б'є наш брейк-пойнт.
Відійди.
Тепер він виштовхне другий параметр до стеку.
Стеж за стопкою.
Я підходжу і бачу, що моя струна, Пол, вже лежить
у стосі.
Він знаходиться за цією адресою.
Тепер ми виштовхнемо перший параметр до стеку.
Тож давай переступимо.
І тепер мій перший параметр у стеку.
Це другий параметр.
Це перший параметр.
Тепер наша функція printf готова до виклику, оскільки параметри вже знаходяться у стеку і готові до використання
printf.
Тож ми переступаємо.
Тепер ми стежимо за тим, що вийде на виході.
Отже, давайте перейдемо до виводу для цієї програми.
Отже, це вихідні дані.
А тепер ми викличемо функцію. Відійди. І ви бачите результат:
"Привіт, Поле.
Гаразд, отже, "Привіт" йде звідси.
Привіт,
далі кома, пробіл, а %s - це Пол.
Як бачите.
Так само, як і на виході тут.
Hello, і тоді специфікатор
формату буде замінено на рядок, моє ім'я, Павло.
Отже, ви отримуєте
"Привіт, Поле".
Ось так можна написати асемблерний код для виклику функції, передаючи два параметри, виштовхуючи
їх у стек.
На цьому відео все.
Ви можете зберегти його, якщо хочете: Файл виправлення, натисніть на кнопку "Виправлення", а потім тут дайте йому ім'я.
15 _функція_два.
exe.
Function_two означає функцію з двома параметрами.
Тож натисніть "Зберегти", натисніть
"ОК".
Тепер, для наступного прикладу, ми спробуємо ще один приклад з двома параметрами, цього разу %
d.
Я рекомендую вам спробувати це самостійно, перш ніж дивитися наступне відео, тож вперед, спробуйте.
Дякуємо за перегляд.