Привіт і ласкаво просимо назад.
У цьому уроці ми продовжимо розгляд угод про виклик, але цього разу ми розглянемо,
як викликати функції і передавати параметри через стек.
І, як завжди, ми скористаємося цією проблемою.
Отже, давайте подивимось на приклад коду, що описує виклик стеку та передачу параметрів через
стек.
Тепер, припустимо, що ми будемо використовувати три регістри -, -, і -, а також стек.
І як ми вже вивчали в одному з попередніх уроків, коли ви передаєте параметри у функцію, вам
потрібно виштовхувати їх у стек у правильному порядку, в якому функція буде споживати ці значення.
Отже, в даному випадку нам потрібно проходити в правильному порядку.
Нам потрібно пройти три, десять і п'ять.
Ось чому ми спочатку натискаємо три.
Отже, коли ми натискаємо три, спочатку вказівник стека вказує на нижню частину стека, а коли
ви натискаєте три, вказівник - переміститься вгору на чотири байти або на DWORD, і тоді ви натиснете значення
три тут.
Далі, коли ви натиснете десять, - знову виділить місце, пересунувшись ще на чотири байти вгору, а потім десять
буде скопійовано до стеку ось сюди.
Коли ви знову натиснете п'ять, буде виділено місце для іншого слова.
Отже - знову підніметься на чотири байти вгору, знову на DWORD, а потім виштовхне в стек значення
п'ять.
Отже, на цей момент ви вже підготували свої регістри зі значеннями, які потрібно використовувати
у функції, наведеній нижче.
І наступне, що ви робите, це викликаєте функцію.
Отже, коли ви викликаєте функцію, інструкція виклику виштовхне адресу повернення на вершину стеку.
Тож - переїдемо сюди.
Тепер ви перейдете до адреси функції, яка знаходиться тут.
І ось так функція використовує параметри, які вже поміщені у стек.
Він використовує вказівникову нотацію, вказівник означає адресну нотацію.
Отже, він розіменовує адресу тут, а потім отримує значення звідти і переміщує його до-.
Тож як вилучити посилання на адресу?
Ви ставите квадратну дужку і використовуєте DWORD, щоб вказати, що це значення DWORD.
Отже, ось ця адреса - плюс чотири. Чому плюс чотири? Тому що - тепер знаходиться на вершині стека
і вказує на зворотну адресу.
Але ви хочете отримати доступ до п'яти, тож вам доведеться додати чотири.
Тому тебе плюс чотири.
Отже, коли ви додасте чотири до -, воно вкаже на це значення тут.
І коли ви розіменовуєте цю адресу, ви отримуєте це значення five і копіюєте його в -.
Тепер те саме відбувається в наступному рядку.
Ви також скасовуєте посилання на цю адресу. Цього разу ви додасте вісім, так що це буде вісім, вісім
байт або два DWORD, від одного до двох DWORD, вісім байт, і ви отримаєте цю адресу тут і значення, що зберігається там,
яке дорівнює десяти, а потім скопіюєте його до -. Далі, ти отримаєш доступ до третьої.
Але щоб дістатися до трьох, вам потрібно розіменовувати три слова DWORD.
Один, два, три.
Кожне слово DWORD складається з чотирьох байт.
Отже, чотири помножити на три - це 12.
Тому тобі плюс 12.
Отже, коли ви це зробили, ви берете три з них звідси і копіюєте їх до реєстру. Отже, в цей момент часу ваші три
регістри -, -, і - вже мають значення, які вам потрібні.
Отже, коли ви копіюєте п'ять, вони будуть скопійовані сюди.
Коли ви скопіюєте десять, воно скопіює його на -.
Коли ви скопіюєте три, він скопіює їх на -.
Ось що означають ці три рядки.
MOV - плюс чотири - означає переміщення цієї п'ятірки на -. MOV - плюс вісім означає, що ви переміщуєте цю десятку на -. MOV - плюс 12 означає,
що ви переміщуєте три на -.
Отже, тепер у вас є п'ять, десять і три в трьох регістрах.
Тепер ви можете використовувати ці значення як зазвичай.
Отже, ви множите - на - і зберігаєте результат назад у -.
Потім ви додаєте - до результату в -, після чого повертаєтесь.
Отже, коли ви викликаєте return тут, це значення тут буде
витягнуто зі стеку, тому воно повернеться назад у регістр -, так що потік функції повернеться за адресою
після виклику, яка знаходиться тут.
Ось що означає червона стрілка.
Це означає, що ви рухаєтесь, виймаючи це значення зі стека.
Отже, сенс поп-музики в тому, що ти рухаєшся - вниз, ось так.
Тож ця вже не діє, хоча вона є, але її ігнорують.
Тепер - вказує на нову вершину стека, яка вказує на п'ять.
Тож коли ти повертаєшся, ось що відбувається.
Він вискакує це значення, і - опускається вниз на чотири байти або DWORD.
Потім ви повернетеся сюди, за адресою після дзвінка.
А тут треба почистити стопку.
Отже, сенс очищення полягає в тому, що ви повинні скасувати всі ці поштовхи, які ви зробили.
Для того, щоб очистити стек, вам потрібно перемістити - на те
місце, де він знаходився до виклику, до того, як було зроблено будь-яке з цих натискань.
Ви повинні повернути - назад у початкове
положення, яке насправді знаходиться тут, але для цього вам потрібно додати 12 до -.
Чому 12?
Тому що кожен з цих DWORD складається з чотирьох байт.
Отже, оскільки ти маєш три СЛОВА, то чотири рази по три буде 12.
Отже, коли ви додаєте 12, - тепер йде ось сюди.
Отже, зараз - це вказівка на вершину стопки, нову вершину стопки.
Тому все це ігнорується.
Ось у чому сенс очищення стеку.
Тому очищення стеку важливе щоразу, коли ви переміщуєте щось до стеку для використання функції.
Пізніше, коли ви повернетеся з виклику, вам потрібно буде почистити стопку.
Отже, якщо у вас є три аргументи, три параметри, ви раз,
ви плюс 12 до стека, ви плюс 12 до -, ви повинні, то ви плюс вісім.
Якщо у вас є один, то вас плюс чотири.
Ось так ви чистите стопку.
Отже, давайте подивимося, як ви можете запустити це у вашому x64dbg.
Отже, я вже створив новий файл під назвою 72-Stack-Calling-Convention-X,
і закликаю вас зробити те ж саме.
Тож просто введіть весь цей код тут.
А потім у печері коду я також ввів цю функцію сюди.
Тож зробіть те саме, а потім можете продовжувати.
Тож давайте повернемося назад і поставимо крапку зупинки, повернемося до нашого основного файлу і поставимо крапку зупинки тут.
Тоді біжимо.
Отже, тепер ми збираємося відкласти три карти в стопку.
Тож натисніть три і подивіться, що станеться зі стеком.
Переступаємо, і ось уже три на стопці.
Потім ми штовхаємо десять, переступаємо, і тепер десять лежить на стопці.
Потім ми натискаємо п'ять, і тепер п'ять у стопці.
Отже, ми маємо всі три значення в стеку.
Тепер ви викличете цю функцію, перейшовши за цією адресою в печері коду.
Зверніть увагу, що відбувається, коли ви телефонуєте.
Дивіться, дивіться, що відбувається зі стеком.
Отже, ви входите в цей виклик, входите в нього, і бачите, що він підштовхує зворотну адресу.
Зворотна адреса - це адреса після дзвінка.
Тож давайте піднімемося нагору і подивимося на це ще раз.
Зворотною адресою є цей рядок, а адресою - 40153.
Отже, це зворотна адреса, і вона виштовхується до стеку.
Ось ця адреса, відсунута до стеку, так само, як і та, що ми бачили раніше.
Зворотна адреса виштовхується до стеку.
Тепер давайте продовжимо з того місця, де ми знаходимося.
Тож тепер воно буде розіменоване - плюс чотири. Плюс чотири -
ось це значення:
п'ять.
Отже, він натискає п'ять, копіює п'ять в - і дивиться на -.
Отже, ми переступаємо, а потім п'ять копіюється на -.
Тепер він розіменовує це - плюс
вісім. - плюс вісім
- ось цей.
A. Тож це змістить його на -.
Тож переступайте, а тепер - маєте десять.
Далі він розіменовує цю адресу - плюс 12. C - шістнадцяткове значення для 12.
Отже, воно розіменовує посилання 12.
Отже, плюс 12 -
це значення тут: три. Тож давайте переступимо, і вона пересунеться на три до -. Переступаємо, і тепер три на "-".
Тепер він виконає множення.
Давайте помножимо і додамо, і воно додасться, а тепер воно повернеться.
Отже, коли він повернеться, він витягне це значення зі стеку, тому що це адреса повернення.
Отже, це буде вискочити в -.
Отже, дивіться -, - тепер отримали
зворотну адресу, і ми повертаємося до адреси тут, зворотної адреси, а потім переступаємо.
Зараз він почистить стік.
Тож давайте переступимо через це і дозволимо йому додати C до -.
- все ще вказує на вершину стека, -, яка
все ще вказує сюди, що дорівнює п'яти, що неправильно.
Верхня частина стопки має бути ось тут, тому що ми вже закінчили зі стопкою. Він нам
більше не потрібен.
Тож ми повинні почистити стос.
Тож ми додаємо 12,
щоб воно могло повернутися сюди, і дивимося -, - тепер зміниться на цю адресу ось тут.
Тож переступайте, а тепер - вказує на цю адресу тут.
Тож ми повернулися до того, з чого починали, до того, як були зроблені всі ці поштовхи.
Ось як це працює в x64dbg, і переконайтеся,
що ви зберегли цей файл як 72-Stack-Calling- Convention.
Так, це все для цього відео.
Дякуємо за перегляд.