сборка 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 3

1 ответ:

В архитектуре x86 каждый адрес состоит из двух частей - сегмента и смещения. Итак, OFFSET означает просто, что смещение адреса некоторой переменной " Hello_Wo.??_C@_0M@KPLPPDAC@H " помещается в стек. Эта директива от синтаксиса ассемблера MASM, где "нажимаем переменную" означает нажимаем значение переменной и "push offset переменная" означает толчок, смещение переменной.

Упоминалось ".данные и ".текст " - это не сегменты, а разделы. Это совсем другое дело. Этот раздел-всего лишь часть. исполняемого файла, который имеет отдельную защиту памяти. Компиляторы C / C++ обычно используют ".текст " для программного кода. Не спрашивайте меня почему.

В современных ОС защищенного режима используется плоская модель памяти. Это означает, что весь код и данные помещаются в один большой сегмент, поэтому вам никогда не придется работать с DS, ES и т. д. сегментный регистр. Их значения управляются ОС.

P.S. начинать изучать язык ассемблера с реверсивными программами HLL-не лучшая стратегия.

Лучше попробуйте прочитать и написать собственный ассемблерный код. Есть много мест в Интернете, где вы можете скачать такие примеры - очень простые и очень сложные, в зависимости от вашего прогресса. Я бы предложил использоватьFASM . Существует доска объявлений, с тоннами полезной информации и людьми, которые могут ответить на ваши вопросы.