Привіт і ласкаво просимо.
У цій вправі я хочу, щоб ви спробували написати програму, яка може запитати у користувача
його ім'я, прізвище, а потім вивести повідомлення:
"Привіт,
ім'я, прізвище.
Приклад
виводу: Під час запуску
програми з'явиться запит "Введіть ім'я", і ви введете своє ім'я, а потім з'явиться
запит "Введіть прізвище", і ви введете своє прізвище.
Після кожного введення імені слід натискати клавішу Enter. Після того, як ви введете своє прізвище, з'явиться
рядкове повідомлення: "Привіт, а
потім ім'я, прізвище.
Тому,
будь ласка, поставте відео на паузу і спробуйте, перш ніж продовжити.
Щасти тобі.
Сподіваюся, ви спробували.
Тож ось як я її вирішуватиму.
Отже, відкриваємо шаблон, шаблон один.
Тепер вам потрібно виділити місце у пам'яті
для ваших рядків і специфікатора формату.
Тому вам потрібно мати підказку для імені.
Це означає, що ви повинні поставити printf
"Введіть ім'я. І тоді вам потрібно
мати сканворд, на якому буде прочитано
ім'я.
Отже, перше ім'я - це рядок.
Отже, ви використовуєте %s, а потім вам потрібно перейти на новий рядок.
Після зчитування рядка, тому що коли ви натискаєте Enter тут, він повинен перейти на новий рядок,
а потім він прочитає його в рядок вашого імені.
Після цього буде надруковано повідомлення з проханням ввести прізвище.
А потім знову відсканує і прочитає ваше прізвище.
%s, тому що це рядок.
А потім ваша змінна для прізвища.
І, нарешті, видайте printf "Hello",
кома, а потім тут потрібно поставити
%s для імені, ще один %s для прізвища,
а потім перейти на новий рядок.
Отже, це те, що ви напишете у програмі на C.
Printf "Введіть ім'я. Вона прочитає ім'я,
збереже його у рядку імені, а потім виведеf "Введіть
прізвище. Ви зчитуєте прізвище
і зберігаєте його у своєму рядку прізвищ.
Потім виведіть рядок "Hello," і об'єднайте та введіть рядок first name,
last name.
І тут я забув ввести змінні:
ім'я, прізвище.
Тож, по суті, це і є план.
Це план вирішення проблеми.
Отже, тепер ви бачите, що нам потрібно створити
кілька рядків: цей рядок, цей рядок, цей рядок, цей рядок, цей рядок і цей рядок.
Отже, скільки у вас струн?
Одна струна, дві струни, три
струни.
Четверта струна така ж, як і друга.
Тож нам не доведеться робити це знову.
Отже, четверта струна має бути - ось ці чотири струни.
Отже, запам'ятайте: перша струна, друга струна, третя струна і чотири струни.
Отже, нам потрібно перейти до карти пам'яті, розділу даних, і створити ці рядки тут.
Отже, першим рядком буде - виберемо це місце і помістимо туди наш рядок "Введіть ім'я. Клацаємо тут правою кнопкою миші, бінарне редагування,
і в полі вводимо "Введіть ім'я", а потім двокрапку.
Гаразд.
Новий рядок не потрібен, оскільки ви хочете, щоб користувач залишався на тому ж рядку, коли вводить
своє ім'я.
Тому не потрібно ставити тут 0A.
Натисни ОК.
А потім наступний.
Отже, ти отримав це.
Тож ми можемо переписати цю адресу.
І покладіть його сюди.
Далі йде специфікатор формату, %s і новий рядок.
Тож ми можемо поставити його тут.
Ми можемо все це вибрати.
А потім клацніть правою кнопкою миші.
Гаразд.
Тут треба бути обережним.
Бачите, після останньої двокрапки 3A має бути нульовий термінатор.
Цей нульовий термінатор повинен бути частиною цього рядка.
Тому ми не можемо використати його для створення нового рядка.
Треба йти до наступного.
Отже, виберіть це, клацніть правою кнопкою миші тут і бінарно відредагуйте та введіть свої %s.
Ваші %s, %s і кінець
нового рядка - 0A.
Потім натисніть "ОК".
Перевірте, чи все правильно.
%s, а потім новий термінатор рядка.
А потім символ нового рядка, за яким слідує ще один термінатор.
Наступним буде "Введіть прізвище. Тому ми хочемо пропустити один
рядок, щоб зберегти послідовність.
Так що ось.
Гаразд, але перед цим давайте скопіюємо цю адресу для рядка, скопіюємо адресу і вставимо її сюди.
Далі - "Введіть прізвище. Отже, ми пропускаємо один рядок,
спускаємося вниз, виділяємо все це, а потім ось тут натискаємо правою кнопкою миші, бінарне редагування,
а потім тут вводимо "Введіть прізвище:"
двокрапку.
А ось тут, може, поставити пробіл, 20.
Я забув поставити пробіл.
Тож натисніть
"ОК".
Тож ми повернемося сюди.
Ми також ставимо пробіл, тому ми редагуємо це, двійкове редагування, і ми хочемо поставити пробіл тут.
Тож ми поставили пробіл.
Отже, ми добираємося до 20 і натискаємо ОК, і тепер у нас є дві 20-ки.
Гаразд. Отже, наступним ми хочемо ввести цей рядок, ось цей.
Це буде четверта струна.
Тож пропустіть один рядок, спустіться сюди, виберіть все це.
Клацніть правою кнопкою миші, бінарне редагування.
А тут в тексті ASCII ми говоримо "Hello", кома, потім перший специфікатор формату, другий специфікатор формату,
а потім тут ми хочемо перейти
на новий рядок.
Отже, тут ми ставимо 0A. Натисни ОК.
Тепер перевірте, чи все правильно.
Після останніх %s з'являється новий рядок.
Тож ми копіюємо ось це. Двійковий - вибачте, скопіюйте
адресу та вставте її сюди.
Гаразд.
Ми забули роздрукувати цю адресу для прізвища.
Тож ми повертаємося сюди і отримуємо цю адресу.
Скопіюйте адресу та вставте її сюди.
Тож у нас є все необхідне.
Цей і цей
- один і той
самий: 00403070.
Тож ми просто копіюємо і розміщуємо його тут.
Отже, ми отримали адреси всіх наших рядків.
Тепер ми готові до кодування.
Перед цим нам потрібні змінні.
Дві змінні для зберігання імені та прізвища.
Ми можемо використати секцію BSS, тому ми переходимо до дампу два і переходимо до BSS, і ми можемо вибрати цю секцію для першого рядка, щоб
зберігати перше ім'я, яке вводить користувач.
Отже, ми можемо скопіювати цю адресу, скопіювати адресу, а тут поставити кому, другу адресу.
Друга адреса посилається на цю змінну, а далі те ж саме.
Нам потрібна ще одна змінна для прізвища, щоб ми могли пропустити один рядок і перейти
до наступного, і ми копіюємо цю адресу, копіюємо адресу, спускаємося сюди, ставимо кому і вставляємо її сюди.
Отже, ця друга адреса призначена для цієї змінної.
Тож у нас є все необхідне.
Цей - у сегменті передачі даних.
Це сегмент BSS.
Тепер ми можемо почати кодування, тож скористаємося печерою коду.
Тому давайте спробуємо зробити це в code cave, тому що якщо ми не використаємо code cave, ви побачите, що цієї
області в пам'яті недостатньо. Цього недостатньо для вашого кодування.
У вас не вистачить місця, щоб все це помістити, чи не так?
Отже, ми можемо розмістити частину коду тут, а частину коду в печері коду.
Отже, спочатку ми спробуємо написати наш код тут.
Потім, коли у нас закінчиться місце, ми підемо в печеру коду.
Гаразд. Тож давайте спробуємо це зараз.
Тож ми почнемо з цього, а потім зробимо поштовх для цієї, цієї струни.
Отже, ми вводимо push, а потім копіюємо цю адресу.
І вже після цього ми викличемо функцію printf.
Отже, ми йдемо і викликаємо функцію printf
звичайним способом ось тут.
Скопіюй цю адресу.
І я думаю, що ми можемо також додати сюди адресу функції printf.
Адреса Printf є цією адресою.
Отже, тепер ми можемо перейти сюди і викликати нашу функцію printf.
Переконайтеся, що ви взяли зелений.
Отже, зараз ми не будемо перескакувати, щоб видалити цей коментар, натисніть крапку з комою і пробіл,
щоб видалити коментар.
Отже, "Введіть ім'я" і printf.
Далі ми збираємось сканфувати.
Отже, для сканування у нас є два параметри: ім'я та цей рядок.
Отже, нам потрібно спочатку натиснути це, а потім виштовхнути це до стеку.
Отже, щоб натиснути ім'я, нам потрібно натиснути цю адресу.
Тож скопіюй цю адресу.
І натисніть на рядок
з ім'ям.
Потім нам потрібно натиснути специфікатор формату, яким є ця адреса.
Тож ви приїжджаєте сюди, і ми збираємо поштовх.
Зрозумів?
Далі нам потрібно викликати scanf.
Тож давайте підемо і візьмемо скафандри зі столу для стрибків.
Прокрутіть вгору і ви побачите тут, скопіюйте цю адресу, і ми можемо розмістити її тут.
Адреса сканфайлу тут.
Поверніться до покажчика інструкцій і зберіть виклик сканфа тут.
Гаразд. Зрозумів.
Тому ми пропонуємо користувачеві ввести ім'я та надрукувати його.
Потім ми скануємо і зберігаємо його за цією адресою.
Далі потрібно повторити те ж саме для прізвища.
Отже, для прізвища ми можемо
просто
скопіювати цю адресу для рядка.
Нам потрібно відправити це до стеку.
Як і прізвище.
Тепер нам потрібно викликати функцію printf, щоб ми могли просто скопіювати звідси.
Упс.
Вибач.
Ctrl+C для копіювання або клацніть правою кнопкою миші, скопіюйте, а потім перейдіть сюди і вставте.
Таким чином, буде надруковано цей запит для прізвища.
Потім вам потрібно зробити сканф, тому ваш сканф буде виглядати так.
Вам потрібно виштовхнути в стек другий параметр, який є вашим прізвищем.
Скопіюйте та натисніть на другий параметр.
А потім ось так.
Потім вам потрібно натиснути цей перший параметр, який є специфікатором формату.
Тож ми копіюємо це.
Це ваш специфікатор формату.
Тоді нам потрібно викликати сканф.
Отже, сканування дзвінків відбувається за цією адресою.
Зрозумів.
А потім ми збираємо ось такий заклик.
Натисни ОК.
Отже, ви бачите, що у нас є сканворд, і тепер ви помічаєте, що у нас закінчується пам'ять.
Отже, ми не можемо продовжувати писати код тут, тому що нам буде недостатньо натиснути цей, цей і цей рядок, а потім викликати
printf, цього буде недостатньо.
Отже, нам потрібно зробити це всередині кодової печери.
Для цього нам потрібно перейти до печери коду звідси, а потім написати цей код у печері коду.
Тож давайте з'ясуємо, де ж наша печера коду?
Здається, у нас є точка зупинки, встановлена раніше, тож ми просто переходимо туди, і це наша печера коду.
Отже, ось наша печера коду.
Клацніть правою кнопкою
миші, скопіюйте цю адресу.
Повертайся нагору.
І давайте перейдемо до нашої кодової печери.
Тож зберіть стрибок тут за адресою кодової печери.
А тепер двічі клацніть тут, щоб перейти до нашої кодової печери.
І тут ми продовжуємо цю останню функцію.
Отже, нам потрібно передати цей параметр, цей параметр і цей рядок з наступним викликом printf.
Отже, у нас є одна, дві, три струни і один дзвінок.
Отже, перший рядок - це прізвище.
Отже, прізвище - ось ця адреса.
Це прізвище.
Отже, ми копіюємо це і тут натискаємо прізвище.
Потім ми натискаємо на ім'я - або навпаки.
Вибачте, ми повинні натиснути на прізвище.
Це прізвище, це.
Дозвольте мені зробити поправку. Зрозумів.
Підійдіть сюди і перейдіть на прізвище.
Гаразд.
Прізвище закінчується на 5030.
Гаразд.
Далі ми натискаємо ім'я.
Ім'я - ця адреса.
Тож ми копіюємо це.
І ми приходимо сюди і натискаємо перше
ім'я.
Потім нам потрібно натиснути на цей формат рядка.
Отже, цей формат рядка є цією адресою.
Отже, ми копіюємо цю адресу, заходимо сюди, натискаємо і вставляємо цю адресу.
І, нарешті, ми викликаємо функцію printf, яка і є цією адресою.
Підійдіть сюди і викличте цю функцію printf.
Нарешті, коли ми закінчимо, нам потрібно повернутися до точки входу.
Вибачте, нам потрібно повернутися до адреси після точки переходу.
Тож давайте повернемося сюди, і це наша точка переходу.
Нам потрібно повернутися до адреси після точки переходу, якою є ця адреса.
Отже, ми копіюємо цю адресу, копіюємо цю адресу, а потім переходимо до переходу і ставимо перехід назад до адреси, вказаної
вище.
Мені дуже шкода.
Не той.
Ось цей.
Ми повертаємося до адреси після точки переходу.
Тож ми просто двічі клацаємо тут, щоб перевірити, чи все правильно.
Двічі клацни.
І ось ми знову тут, після точки переходу.
Отже, ми маємо рацію.
Гаразд.
Тож тепер ми готові це перевірити.
Ми можемо поставити тут точку зупинки, що я вже зробив.
Гаразд.
Я десь помилився.
Перш ніж запускати програму, давайте зробимо поправку.
Тут якась помилка.
Ніколи не додавайте сюди свого нового персонажа.
Тож це слід видалити.
І цей теж.
Видаліть символ нового рядка.
Причина в тому, що коли ви натискаєте Enter після введення імені, символ нового рядка вже вставляється
автоматично.
Отже, якщо ви додасте сюди ще один символ нового рядка, це заплутає функцію scanf.
Отже, виймаємо нового персонажа лінії.
Отже, щоб вилучити новий символ рядка, ви повинні піти і відредагувати пам'ять, куди було вставлено
новий символ рядка.
Це означає, що ви повинні видалити цей 0A і замінити його нульовим термінатором.
Тож просто виберіть це, двійкове редагування, а тут просто змініть значення на 00 і натисніть OK.
Це все.
І тепер ви можете це врятувати.
Тож перш ніж щось робити, просто натисніть на файл і збережіть його у форматі 24- отримати-ім'я-прізвище.
Я вже це зробив.
Я зберіг проект під назвою
24-get-ім'я-прізвище. exe, і я знову відкрив цю програму всередині x64dbg.
Зараз я поставлю тут брейк-поінт.
Я вже зробив це і збираюся запустити програму.
Давайте подивимося на консоль, покладемо її праворуч і переступимо через неї.
Він виштовхне рядок "Введіть
ім'я" до стеку.
Давай переступимо.
Рядок знаходиться у стеку і готовий до використання командою printf.
Отже, це параметр для printf.
Переступимо через printf.
Отже, printf запущено, і він показує рядок "Введіть
ім'я. Тепер він буде натискати
на параметри, які буде використовувати сканфайл.
Отже, це другий параметр, а це перший параметр.
Другий параметр - зберегти рядок, який користувач введе за цією адресою.
І перший параметр - це специфікатор формату для вхідних даних.
Тож давайте переступимо через них.
Другий параметр виштовхується до стеку.
Перейдіть, і наш перший параметр також опиниться у стеку.
Тепер ми готові викликати scanf, і scanf буде використовувати перший і другий параметр.
Отже, другий параметр - це місце, куди буде збережено рядок.
Тож давайте переступимо через скандал і подивимося, що відбувається з державою, яка зараз перебуває на паузі.
Давай переступимо.
І зараз він знаходиться в запущеному стані.
Scanf запущено, і він чекає на введення даних від користувача.
Отже, нам потрібно натиснути сюди, і з'явиться миготливий курсор.
Давайте введемо ім'я.
Я введу своє ім'я і натисну клавішу Enter.
І одразу ж повертається до стану паузи.
І тепер цей рядок зберігається за адресою 405010, тобто за цією адресою тут.
Як бачите, там є моє ім'я, і давайте перевіримо його на звалищі.
Тож ця адреса знаходиться в розділі BSS.
Отже, переходимо до карти пам'яті.
Натисніть на розділ BSS.
А ось тут, за цією адресою, 405010, ви можете побачити,
що моє ім'я вже зберігається там.
Далі буде виконано printf і він надрукує.
Це виштовхне параметр для printf до стеку.
Тож це параметр.
Давайте переступимо через це.
І тепер цей рядок знаходиться у стеку і чекає, коли printf використає цей параметр.
Переступимо через printf.
А printf надрукувала вивід на консоль.
Тепер він виштовхне ці два параметри до стеку для сканування.
Тож давай переступимо.
Отже, це другий параметр у стеку.
Тепер давайте переступимо через це.
І це перший параметр для scanf.
Отже, scanf готовий до запуску.
Він буде використовувати ці два параметри.
Перший параметр - це специфікатор формату рядка.
Отже, що б користувач не ввів зараз, буде збережено всередині цієї адреси за адресою 405030, яка знаходиться ось тут.
Незабаром ми побачимо тут наше прізвище.
Тож наразі він перебуває у стані паузи.
Давайте переступимо через сканф і подивимося, що з цього вийде.
Отже, зараз він перейшов у стан виконання, а це означає, що він чекає на вхідні дані.
Отже, нам потрібно натиснути сюди, і ми бачимо, що курсор блимає, чекаючи на введення.
Дозвольте мені ввести своє ім'я, прізвище та натиснути Enter.
А зараз стан знову змінився на призупинений.
І якщо ми зараз подивимося на цю адресу, 405030, то побачимо, що там
є моє прізвище.
І ви можете побачити тут, на звалищі.
А ця адреса, 405030, це
моє прізвище.
Тож зараз він зробить цей стрибок.
Оскільки нам не вистачає місця в пам'яті, ми створили стрибок, який дозволяє перейти
до печери коду і продовжити роботу з рештою програми.
Тож давайте переступимо через цей трамплін і потрапимо до печери коду.
Ми приземлилися у нашій печері коду, і тепер він буде передавати ці три параметри для printf.
Отже, ці три параметри - прізвище, ім'я та специфікатор формату: "Привіт,
ім'я, прізвище.
І
ось нарешті дзвінок.
Тож давайте відкладемо це до стеку.
Ми переступаємо через них.
І ось тепер третій параметр, прізвище,
у стеку.
Давай переступимо через це.
А тепер другий параметр, тобто ім'я, також знаходиться у стеку.
А тепер виштовхнемо перший параметр у стек.
Отже, тепер перший параметр, який є специфікатором формату
рядка, "Hello, %s %s" і новий рядок, також знаходиться у стеку.
Тепер ці три параметри готові.
Отже, ці три параметри мають бути використані цією командою printf.
Отже, давайте переступимо через printf і побачимо, що printf спричинив виведення:
"Привіт, ім'я,
прізвище.
Привіт,
Полсон.
Отже, і тепер він повернеться до адреси після точки переходу.
Тож давайте зробимо це зараз.
Давай переступимо через це.
І ми знову тут, за адресою після точки переходу.
Тож це точка переходу.
Ми пішли до кодової печери.
Тепер ми повернулися з кодової печери.
Печера.
Тож давайте переступимо через це, поки воно не закінчиться.
Ось і все.
Отже, ось як можна вирішити
цю програму.
Розв'язати задачу, вправу, можна за допомогою кодових печер.
На цьому відео все.
Дякуємо за перегляд.