0x004012d0 <main+0>: push %ebp 0x004012d1 <main+1>: mov %esp,%ebp 0x004012d3 <main+3>: sub $0x28,%esp
Если адрес недоступен , можем ли мы рассчитать его сами?
Я имею в виду, у нас есть только это:
push %ebp mov %esp,%ebp sub $0x28,%esp
количество байтов - это разница адресов между соседними инструкциями:
0x004012d0 <main+0>: push %ebp ;1 byte 0x004012d1 <main+1>: mov %esp,%ebp ;2 bytes 0x004012d3 <main+3>: sub $0x28,%esp
если у вас есть только текст, перейдите сюда: http://www.swansontec.com/sintel.html и здесь: http://faydoc.tripod.com/cpu/conventions.htm и рассчитайте для каждой инструкции, префикса и операнда
Вы не можете определить размер инструкции по мнемонике. Вот несколько особых случаев:
если вы находитесь в 16-битном сегменте, mov eax, 0 требует префикса 0x66, а в 32-битном сегменте - нет. Вам нужно знать размер сегмента.
mov eax, 0
0x66
в 32-битном или 16-битном режиме вы можете кодировать add eax, 1 как 0x40 (inc eax) или 0x83 0xc0 0x01 (add eax, 1). То есть есть некоторые мнемоники, которые можно кодировать несколькими способами.
add eax, 1
0x40
inc eax
0x83 0xc0 0x01
Операнд памяти [eax] может кодировать eax как базу или индекс. Если это индекс, у вас будет дополнительный байт SIB после MOD / RM.
[eax]
eax
в 64-битном режиме вы можете использовать префикс REX 0x4x для кодирования регистров r8 - r15. Тем не менее, вы можете использовать 0x40 как своего рода нулевой REX-байт, который добавит еще один байт к вашей инструкции.
0x4x
r8
r15
могут использоваться переопределения сегментов, даже если явный сегмент совпадает с неявным.
Существует много других способов кодирования инструкции с использованием более или менее байтов. Хороший ассемблер должен, вероятно, всегда использовать самый короткий, но это определенно не требуется архитектурой. Хорошо, что если вы изучите том 2 Руководства разработчика программного обеспечения Intel IA-32, вы сможете сами его решить.
Первая инструкция находится в [main + 0], а вторая в [main + 1], поэтому первая инструкция составляет 1 байт. Третья инструкция находится в [main + 3], поэтому вторая инструкция составляет два байта. Из списка нельзя определить, какова третья инструкция, поскольку в ней не указан адрес инструкции 4.
Если возможно, пусть ассемблер сгенерирует листинг. Это покажет ваш исходный код, а рядом с ним будет двоичное представление инструкций, и все, что вам нужно сделать, это подсчитать, сколько есть байтов, и тогда вы получите размер.
Если у вас есть код ассемблера в тексте, вы должны будете использовать процедуру ассемблера, чтобы получить двоичное представление и, следовательно, размер инструкции. Конечно, это зависит от оборудования.
Например, вот 80x86 32-битный Ассемблер открытый исходный код ( OllyDbg v1.10 ).