2010-10-31 3 views

ответ

53

Предполагая, что 32-битный x86, используют следующую функцию:

get_eip: mov eax, [esp] 
     ret 

Затем, чтобы получить значение EIP в EAX, просто:

call get_eip 
+2

Это потрясающе: D – Mehrdad

+0

Мне жаль, что не было возможности сделать это без ярлыков или подсчета байтов – Dmitry

9
call foo 
foo: 
    pop eax ; address of foo 
+8

Этот подход имеет тонкую проблему. Современные процессоры пытаются предсказать обратные адреса - вызов, который не сопряжен с возвратом, искажает предсказание. См. Http://blogs.msdn.com/b/oldnewthing/archive/2004/12/16/317157.aspx – user200783

+0

@Paul Baker обычно это не критическая проблема. Например, 'call @f/db '123', 0/@@:' является обычной практикой – Abyx

+0

call foo, pop eax, push eax, ret –

22

На x86-64 (в отличие от 32 бит x86), есть RIP - относительная адресация (RIP - это 64-разрядный аналог EIP). Таким образом, в 64-битном коде, вы можете просто сделать

lea rax, [rip] 

переместить текущее содержимое RIP в RAX (вы можете использовать lea но не mov для этого).

+0

Отличный комментарий. Я удалил свой неправильный ответ. Комментарии не должны размещаться в качестве ответов. –

+0

Хммм, это не работает в блоке VC++ 2015 '__asm ​​{}'. :(Получить 'ошибка C2415: ошибка неправильного операнда. – Adrian

Смежные вопросы