Я играл с примером шеллкода и помещал некоторый код в стек. Вот соответствующий фрагмент из него, как видно в представлении памяти VS2013:
Memory view:
0x0018FEB4 90 90 90 83 ec 28 eb 0b e8 66 2a 1a 75 50 e8 9d 80 18 75
Теперь, когда я вижу тот же код в представлении дизассемблирования, интерпретированном на машинном языке x86, все идет так, как ожидалось, за исключением адресов (с прямым порядком байтов), которые я вижу для инструкций вызова (код операции E8):
Disassembly view:
0018FEB4 nop
0018FEB5 nop
0018FEB6 nop
0018FEB7 sub esp,28h
0018FEBA jmp 0018FEC7
0018FEBC call 75332927
0018FEC1 push eax
0018FEC2 call 75317F64
Если я изменю представление на дизассемблирование с помощью байтов кода, я получу тот же тип дельты между адресом, который я записал в память, и адресом, который вызывается:
Disassembly view, with code bytes as well:
0018FEBC E8 66 2A 1A 75 call 75332927
Я думаю, что мне может не хватать какого-то важного теоретического факта, но может ли кто-нибудь объяснить это мне? Адреса, которые я хотел вызвать, являются конкретными адресами функций из kernel32.dll, но мне пришлось произвести над ними некоторые арифметические действия, чтобы код действительно выполнялся и вызывал правильные адреса.