Как проанализировать ассемблерный код для стековых фреймов? - PullRequest
1 голос
/ 31 декабря 2010

У меня есть следующий код:

Func5() { ShowStackTrace();}
Func4() { Func5();}

Вот трассировка стека, которую я имею -

**Frame for Func5**
EIP : 403899
Function name : Func5
EBP : 12ff0c
ESP : 12fed0
Return address : 4038c8
CS : 23
DS : 9998
ESI : 0
EDI : 0

**Frame for Func4**
Function name : Func4
EBP : 12ff14
ESP : 12ff14
CS : 23
DS : 9998
ESI : 0
EDI : 0

Теперь, используя адрес возврата Func5, я получил первые 5 байтов над ним

ff ff ff 88 E8

Наличие E8 здесь означает, что это оператор вызова (рядом), и следующие 4 байта должны использоваться для вычисления адреса.Таким образом, EIP, когда мы будем читать CALL Func5, будет 4038c3.Как рассчитать начальный адрес Func5 по этим данным?Пожалуйста, скажите, если вам нужны какие-либо другие данные.Кроме того, как выполняется вычисление, если это дальний вызов (код операции - FF)?

Ответы [ 2 ]

3 голосов
/ 31 декабря 2010

Вы печатаете байты в обратном порядке.Правильный порядок:

E8 88 ff ff ff 

, где E8 - это код операции для "jump относительный imm32"

Это будет означать jump relative 0xFFFFFF88, или -0x78, потому что x86 использует немного порядка байтов1009 *

РЕДАКТИРОВАТЬ: это относительно следующего байта после инструкции вызова.Например,

0x100: E8 10 00 00 00 ;// call relative, will call 0x115 (0x105 + 0x10)
                      ;// and will leave 0x105 on the stack as return address
0x105: 90             ;// next instruction
1 голос
/ 31 декабря 2010

Это зависит от формы пластины. На большинстве UNICES dladdr предоставляет ближайший символ к адресу.

В Windows все сложнее: посмотрите на API dbghelp.dll и msapi.dll. Я не помню точно, но это не далеко.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...