сборка x86 "push OFFSET ..." и мнемоника?
Я пытаюсь научиться немного сборке, создавая небольшие программы на языке Си в Visual Studio 2012 Express, а затем разбирая их в отладчике иммунитета. Но я, очевидно, столкнулся с чем-то, чего не понимаю:
012A13F0 68 58582A01 PUSH OFFSET Hello_Wo.??_C@_0M@KPLPPDAC@H>; ASCII "Hello World"
012A13F5 FF15 BC922A01 CALL DWORD PTR DS:[<&MSVCR110D.printf>] ; MSVCR110.printf
Меня смущают обе эти инструкции. На самом деле, опкоды имеют для меня больше смысла, чем реальные инструкции, изображенные отладчиком.
Очевидно, что первая инструкция помещает адрес в стек. Когда я иду следом адрес в дампе, он показывает мне область, которая содержит некоторые шестнадцатеричные числа, которые составляют строку Hello World
. Я считаю, что это .data segment
. Я не ошибаюсь?
И также; я думаю, что Hello_Wo.??_C@_0M@...
- это просто визуальное пособие, предоставленное мне отладчиком, чтобы я мог лучше понять, что это такое... Что-то...
Но что означает смещение в этой инструкции push? Я не смог найти ничего в Google по этому поводу.
Я также хотел бы спросить о другом инструкция...
Насколько я понимаю, он пытается вызвать подпрограмму, используя 4-байтовое значение, расположенное по адресу DS:[102A92BC] (&MSVCR110D...)
, как адрес вызова ?
Отладчик говорит мне, что DS:[102A92BC] = 5C0A93A0
. И этот диапазон памяти зарезервирован для MSVCR110 .text segment
.
Не по теме: у меня есть последний вопрос это немного глупо и не по теме, но я надеюсь, вы не возражаете: вы не должны читать сегменты данных как дизассемблированный код, не так ли? сегмент данных импорта привел меня в замешательство в моем поиске 5C0A93A0
.
1 ответ:
В архитектуре x86 каждый адрес состоит из двух частей - сегмента и смещения. Итак, OFFSET означает просто, что смещение адреса некоторой переменной " Hello_Wo.??_C@_0M@KPLPPDAC@H " помещается в стек. Эта директива от синтаксиса ассемблера MASM, где "нажимаем переменную" означает нажимаем значение переменной и "push offset переменная" означает толчок, смещение переменной.
Упоминалось ".данные и ".текст " - это не сегменты, а разделы. Это совсем другое дело. Этот раздел-всего лишь часть. исполняемого файла, который имеет отдельную защиту памяти. Компиляторы C / C++ обычно используют ".текст " для программного кода. Не спрашивайте меня почему.
В современных ОС защищенного режима используется плоская модель памяти. Это означает, что весь код и данные помещаются в один большой сегмент, поэтому вам никогда не придется работать с DS, ES и т. д. сегментный регистр. Их значения управляются ОС.
P.S. начинать изучать язык ассемблера с реверсивными программами HLL-не лучшая стратегия.
Лучше попробуйте прочитать и написать собственный ассемблерный код. Есть много мест в Интернете, где вы можете скачать такие примеры - очень простые и очень сложные, в зависимости от вашего прогресса. Я бы предложил использоватьFASM . Существует доска объявлений, с тоннами полезной информации и людьми, которые могут ответить на ваши вопросы.