Привіт і ласкаво просимо назад.
У цьому новому розділі ми вивчатимемо масиви пам'яті.
Отже, ми почнемо зі знайомства з масивами пам'яті.
Що таке спогади?
Отже, давайте подивимось на цю схему розташування оперативної пам'яті.
Як ви можете бачити у лівому стовпчику, це адреса пам'яті.
Так, наприклад, для простого прикладу, припустимо,
що ми знаходимося за цією адресою пам'яті, позначеною цією шістнадцятковою адресою, 403040 і так далі.
А адреса пам'яті, як відомо, збільшується на слово. Це означає, що від однієї адреси пам'яті до
іншої адреси пам'яті ми зазвичай адресуємо їх як приріст у чотири байти або DWORD.
Отже, тут ми маємо 3040.
Отже, додаємо до цього чотири, отримуємо 3044. Додаємо до цього чотири, отримуємо 3048 і так далі.
Тепер, припустимо, що ми хочемо зберегти числа в пам'яті, у нас є три числа: один, два
і три.
Найпростіший і звичайний спосіб зберегти їх у пам'яті - це зберегти їх у пам'яті послідовно.
Отже, перше число, яке є номером один, буде збережено за цією адресою пам'яті, наприклад, 3040.
І тоді поруч з ним може бути збережено число два, значення 2, 3044.
А третій, номер три, буде врятований у 3048 році.
Тепер, як ви можете бачити, коли ці числа зберігаються в пам'яті, вони зберігаються як DWORD, тобто
чотири байти.
Отже, він займає чотири байти, як ви можете порахувати тут: один байт, два байти, три байти, чотири байти.
Отже, оскільки вони займають тут чотири байти, наступна адреса пам'яті для наступного числа
буде 3044 і так далі.
Ось чому, коли ми звертаємося до адрес пам'яті, ми отримуємо доступ до них з кроком DWORD.
DWORD плюс 3040 плюс DWORD, отримуємо
ось це. Плюс DWORD, ви отримуєте це і так далі.
Це і є концепція зберігання чисел у масивах.
Отже, коли ми маємо серію даних, які зберігаються ось так, пліч-о-пліч, безперервно, тобто
пліч-о-пліч, ми називаємо це масивом.
Оскільки він використовує пам'ять, ми називаємо його масивом пам'яті.
Тепер у x64dbg, ось як це виглядає, представлення масиву пам'яті. Як ви можете бачити, тут у лівій колонці
вказана адреса.
Ми починаємо з базової адреси 403040 і зберігаємо його там.
А потім у наступному DWORD ми отримуємо 403044, яке знаходиться тут, і зберігаємо цифру два там.
А за наступною адресою пам'яті ми отримаємо 403048, і там ми
зберігаємо число три.
Тепер зверніть увагу, що у пам'яті числа зберігаються у малому кінці, тобто у зворотному
порядку.
Тож коли ви прочитаєте цей номер, це буде 00000001 у зворотному порядку.
Тож тут, як ви бачите, коли ми візуалізуємо це, ми спрощуємо.
Але коли він фактично зберігається в апаратній адресі пам'яті, він зберігається у зворотному порядку.
Отже, тут перше місце, перша клітинка, 03040 відповідає цій комірці.
І ось вже наступний,
3044.
Якщо ви наведете на них мишку, то зможете побачити їх пізніше в практичній частині.
Я вам все це продемонструю.
Отже, тепер у нас є розуміння того, як зберігаються масиви, як дані зберігаються
у вигляді масиву в пам'яті. Як ми можемо отримати доступ до цих даних або навіть записати їх чи прочитати з локацій?
Погляньте на цю діаграму.
Тому на цій діаграмі я додав ще один стовпчик.
Таким чином, кожен масив буде мати індекс.
Перший елемент масиву, індекс якого дорівнює нулю.
Другим елементом буде
індекс один. Третій елемент буде з індексом два і так далі.
Отже, якби у нас було три числа або три елементи в масиві, то перший індекс був би нульовим, другий - одиничним,
а третій - двозначним.
Отже, якщо ми хочемо отримати доступ до всього цього через
програму,
то нам потрібно мати дві речі.
По-перше, нам потрібен регістр ітератора,
наприклад, -. Ви можете використовувати інші реєстри.
І тоді нам знадобиться лічильник та індексний трекер.
Отже, це був би реєстр, -. Отже, ми будемо відслідковувати індекс,
який елемент ви маєте на увазі?
А ще він діє як лічильник того, скільки разів ви прокручуєте сторінку, щоб прочитати кожен елемент.
То для чого ж потрібен знак -?
Це - фактично зберігати дані, які витягуються або зчитуються.
Так, наприклад, якщо ми намагаємося отримати доступ до першого індексу, то мені потрібно отримати доступ до цієї адреси.
Потім, коли ми захочемо прочитати наступний елемент або наступне значення з наступної
адреси, мені потрібно буде звернутися до наступної адреси і так далі.
Тому нам потрібно мати спосіб обчислення адреси.
Отже, щоб обчислити адресу, нам потрібно додати чотири до першої адреси.
Тож коли ви додасте чотири, тоді я перейду до наступної адреси.
Знову додаєш чотири.
- потім перейде до наступної адреси і так далі.
Тож, щоб додати до цього чотири, нам потрібно зробити невелику арифметику.
Базова арифметика така.
Ми беремо базову адресу, якою є ця адреса 403040, додаємо до неї чотири рази -.
- це індекс.
Якщо - дорівнює нулю, то чотири рази помножити на нуль дасть нуль.
І коли ви додаєте нуль до базової адреси, ви все одно отримуєте назад це число, цю адресу.
Отже - зможе потім отримати це значення, цей елемент.
Потім, коли ви переходите до наступного індексу, який є індексом один, - це вже одиниця. Чотири рази по одному - це чотири.
Отже, ви берете чотири, додаєте базову адресу і отримуєте 3044.
Зараз я отримаю доступ до цієї адреси, і ми зможемо отримати значення, яке там зберігається.
Далі, коли індекс збільшується до двох, то ми маємо чотири помножити на два дорівнює вісім. Вісім плюс базова адреса буде такою: 3040
плюс вісім дасть вам 3048.
Тепер - буде посилатися на третю адресу, і ми
зможемо отримати третє значення, що зберігається там.
Ось чому нам потрібно
мати два компоненти: регістр ітератора для зберігання адреси та - регістр для зберігання індексу та лічильника, а також для відстеження того, скільки разів ми проходимо цикл.
Отже, простий спосіб реалізувати це в коді наступний:
циклічний перебір масиву.
Тому я просто розміщу цей код
тут, збоку, праворуч, щоб ми могли посилатися на нього, коли будемо намагатися пройти крок за кроком.
Отже, дивлячись на діаграму, коли програма
вперше запускається, нам потрібно перемістити нуль в - тому що це буде перший індекс.
Далі ми перейдемо до - тому що - потрібно використовувати для обчислення адреси.
Після цього множимо на чотири. SHL - два означає помножити на чотири.
Як ви пам'ятаєте, ми вивчали це раніше у попередніх уроках,
де, коли ви хотіли щось помножити, вам потрібно було зсунутись вліво на кількість бітів.
Отже, тут нам потрібно помножити на чотири, щоб отримати адресу зміщення. А потім, на наступному кроці, додається адреса зсуву,
яка в цьому випадку дорівнює нулю, оскільки перший індекс - -. Воля дорівнює
нулю.
Отже, коли ви множите щось на нуль, ви все одно отримаєте нуль.
І коли ви додасте нуль до базової адреси, ви все одно отримаєте 403040.
Далі ви розіменовуєте адресу -, щоб отримати значення, яке там зберігається.
Ось чому ми використовуємо - в дужках для того, щоб відмінити посилання на адресу.
І як тільки ми отримаємо адресу, ми отримаємо DWORD, що зберігається
за цією адресою, а потім збережемо його в -.
Отже - тепер будемо зберігати значення 1.
Отже, якщо ви хочете виконати інші інструкції, цей рядок
тут буде замінено вашим власним кодом або будь-якою кількістю рядків, щоб виконати обчислення на ваш власний вибір.
Отже, в цьому простому прикладі ми просто хочемо зберігати в -. Після цього нам потрібно збільшити лічильник на одиницю, щоб
перейти до наступного індексу.
Отже, коли ви збільшуєте -, - тепер стає одиницею. Потім він порівняє, чи - досягло трьох,
тому що у нас тут три значення.
Якщо вона не дорівнює трьом,
то програма повернеться до верхньої адреси і виконає ще один цикл.
Тепер він перемістить нове значення -, яке дорівнює одиниці, у -.
Тоді ми помножимо на чотири.
Тепер чотири помножити на один - вийде чотири.
Отже, ви додаєте чотири до базової адреси, і тепер ваша базова адреса зміниться на 3044.
Тепер ви розіменовуєте посилання 3044, отримуєте значення, рівне двом, і зберігаєте його в -.
Потім ви збільшуєте - знову.
- тепер стає два.
Отже, тепер ви отримаєте доступ до індексу номер два, тобто до третього значення.
Потім ви порівнюєте, чи досягло - трьох.
Ні. Якщо вона ще не досягла трьох, ви повертаєтесь назад і виконуєте ще один цикл, і переходите від - до -.
- вже два, пам'ятаєш?
Отже - це теж два.
Отже, ми множимо два на чотири, отримуємо вісім і додаємо вісім до базової адреси.
Отже, коли ви додасте вісім до базової адреси тут, ви отримаєте 3048.
Отже, якщо - дорівнює 3048, а отже, ви можете отримати доступ
до значення, що зберігається в ньому, розіменовуючи посилання на -, ви отримаєте три і збережете його в -, отже, - тепер має значення три. Потім ви збільшуєте - знову.
- тепер стає трьома.
Тож коли ви зараз порівняєте - з трьома, це буде правдою.
Тому, оскільки це правда, цей стрибок не відбудеться.
Ти вийдеш із циклу.
Отже, це один із способів циклічного перегляду масиву.
На цьому відео все.
У наступній статті ми займемося практичною реалізацією цього коду.
Дякуємо за перегляд.
Побачимося.