У меня есть книга, которую мне нужно прочитать в школе, и есть упражнение по созданию программы в Visual Studio на языке C, которая печатает «Hello!» и вставьте его в IDA. Затем вам нужно найти, где находится строка «Привет!» то, что было определено в программе, было сохранено, и я думаю, что нашел. Затем он говорит:
Внутри нашего main мы сосредоточимся на двух строках. Первое,
aHello offset push
. Эта строка помещает в стек адрес памяти строки Hello. Если мы нажмем aHello, мы будем перенаправлены на адрес строки в памяти», однако я не могу найти ни эту строку, ни ключевое слово «aHello» нигде в IDA.
После этого идет фото-пример и следующий текст:
Видно, что строка определена по адресу 416B94 и после нее определен символ 0Ah (как помнится из исследований по сборке, перенос строки), за которым следует символ 0 (как вы помните, обозначает конец строки для функций вывода).
Я пытался перейти к этой линии, но не смог ее найти. Мне было интересно, смогу ли я получить некоторые знания о IDA.
Код, который я использовал в программе:
#include <stdio.h>
int main() {
printf("Hello!");
return 0;
}
Извините, если я выразился что-то неправильно. Книга не на английском языке, и я новичок в IDA и языке C.
Кажется, вы описываете здесь то, что, по словам вашей книги, вы должны видеть, но что вы видите на самом деле?
@interjay Я тоже не могу найти эту строчку. Обычно я не могу найти слово aHello ни в одном сегменте данных.
Вы это показали на скриншоте. Или вы зачем-то выложили скриншот из книги?
@500-Внутренняя ошибка сервера. Есть ли способ как-нибудь загрузить весь файл IDA? Я не знаю, какую часть мне следует разместить.
Картинка из книги @interjay
Ну, у меня нет установленного банкомата IDA, и я давно им не пользовался, но видите ли вы что-нибудь «главное» на экране IDA? (я думаю, вам следует это сделать, если ваша программа была построена с использованием отладочной информации)
@500-InternalServerError Вопрос касается строкового литерала, который, вероятно, находится в другом сегменте, чем функция main()
.
@500-Внутренняя ошибка сервера, насколько я видел, она есть. Хотя я там ничего не вижу. Я добавил это к вопросу о теле.
Ах, это прямо посередине вашего снимка экрана: 1400118ac: lea rcx, _Format ; "Привет!". Это загружает адрес «Hello!» строку (с именем «Формат») в ecx
. Книга, вероятно, была основана на версии компилятора, отличной от той, которую вы используете, возможно, на 32-битной — здесь у вас 64-битный код.
@500-Внутренняя ошибка сервера. Думаю, именно там она и сохраняется. Тем не менее, я до сих пор не могу найти строку push offset aHello
. Он еще нужен или он мне теперь не нужен?
Похоже, в вашей книге описан 32-битный пример, в котором перед вызовом printf помещается указатель на строку формата (автоматически называемую aHello
) в стек.
Ваш двоичный файл является 64-битным с другим соглашением о вызовах, где регистр rcx
используется для хранения указателя на строку формата (автоматически называемую _Format
) вместо стека (поэтому инструкция push не требуется).
Если вы перейдете туда, где определен _Format
(возможно, воспользуетесь функцией XREF, чтобы найти его), вы найдете байты, составляющие вашу строку.
(Похоже, ваша версия IDA использует имя аргумента функции для генерации имени, а версия книги использовала содержимое строки для генерации имени.)
Я нажал «Привет» на строке _Format
, и это привело меня к строке _Format db 'Hello!',0 ; DATA XREF: main+1C↑o
, которая не должна вести меня к SEG данных? Например, когда вы используете сборку и отлаживаете ее в DOSBox, где все записано в шестнадцатеричном формате? И заменяет ли это строку push offset aHello
?
@yarden Я предполагаю, что это, вероятно, сегмент данных, доступный только для чтения, хотя я не могу проверить то, что вы вставили. В этом соглашении о вызовах вместо стека используется регистр, поэтому не будет инструкции push, а будет только назначение регистра.
Это привело вас к сегменту rdata (поскольку строковые литералы C неизменяемы, компилятор помещает их в данные, доступные только для чтения). Слева от этой копии будет что-то вроде .rdata:....
, как в том примере, который вы привели в вопросе.
Инструкция должна быть
push offset aHello
, а неaHello offset push
. Возможно, в IDA он написан по-другому или сгенерирован вашим компилятором по-другому — проследите за XREF в строкеaHello
, чтобы увидеть, где он используется.