Получить адрес последней выполненной инструкции в WinDBG

Я переворачиваю приложение win32.

Вопросы:

При отладке проги. я обнаружил, что счетчик один раз перескакивает на адрес 0x0043D4A0. (Это точка входа в функцию).

  0043D4A0   51               PUSH ECX
  0043D4A1   8B51 04          MOV EDX,DWORD PTR DS:[ECX+4]
  0043D4A4   8B4424 0C        MOV EAX,DWORD PTR SS:[ESP+C]
  0043D4A8   3BC2             CMP EAX,EDX
  0043D4AA   890C24           MOV DWORD PTR SS:[ESP],ECX
  0043D4AD   7D 06            JGE SHORT PEiD.0043D4B5
  0043D4AF   32C0             XOR AL,AL
  0043D4B1   59               POP ECX

Теперь я хочу знать, как я могу получить адрес предыдущей инструкции, выполненной до перехода к этой точке 0x0043D4A0 с помощью windbg. ТАК, что я могу отследить, откуда вызывается эта функция.

Заранее спасибо,


person Dev.K.    schedule 07.06.2013    source источник


Ответы (2)


Всякий раз, когда выполняется инструкция вызова, адрес возврата помещается в стек непосредственно перед передачей управления вызываемой функции. Адрес возврата — это 4 байта в регистре ESP. Запустите команду dd для @ESP, затем запустите команду ub для значения в @ESP. Это приведет к деассемблированию в обратном направлении от обратного адреса, что даст вам последовательность инструкций, которые имели место непосредственно перед вызовом и включая его.

person Steve Johnson    schedule 09.06.2013
comment
Предполагая, что используется инструкция CALL, адрес возврата помещается в стек и выполняется переход к цели. Таким образом, чтобы увидеть обратный адрес в отладчике, вам нужно сбросить ESP, а не ESP-4. Обратите внимание, что не все изменения потока управления являются CALL, поэтому адрес возврата в стеке может не совпадать с местом вызова функции. Вы часто видите это на x64, поскольку компилятор любит использовать оптимизацию хвостового вызова (т.е. заменять, возвращать Foo() с помощью jmp Foo вместо вызова Foo). - person snoone; 10.06.2013
comment
Спасибо за это. Ты прав. Я на самом деле хотел сказать +4 в любом случае, но вы правы. - person Steve Johnson; 11.06.2013

Использовать этот:

? $previp

Указатель инструкции во время предыдущего события. (Взлом в отладчик считается событием.)

См. это. другие псевдорегистры

person EdChum    schedule 07.06.2013
comment
На самом деле я хочу отследить, откуда эта функция вызывается, поэтому я поставил BP @ 0043D4A0. Когда отладчик приостановил @BP я вошел? $ previp n Я получил 0x7c810856 Оценить выражение: 2088831062 = 7C810856 Так когда я сделал это, я нашел нет звонка / прыгать на адрес: 0043d4a0 0: 001> U 7C810856 Kernel32! BaseThreadStarttherk: 7C810856 33ED XOR EBP, EBP 7C810858 53 Push EBX 7C810858 50 push eax 7c81085a 6a00 push 0 7c81085c e973acffff jmp kernel32!BaseThreadStart (7c80b4d4) Что может быть причиной этого? Спасибо, - person Dev.K.; 07.06.2013
comment
$ea показывает эффективный адрес последней выполненной инструкции. Если эта инструкция не имеет эффективного адреса, отладчик выдает ошибку Bad register. Я получаю ошибку Bad register.. :( - person Dev.K.; 08.06.2013
comment
Что показывает окно дизассемблирования или окно стека вызовов? Если вы видите «нет предыдущего адреса» в окне дизассемблирования, вы можете вручную попытаться обновить смещение по байтам за раз, пока окно дизассемблирования не сможет сгенерировать более глубокий стек вызовов для предыдущих инструкций, см. analyze-v.com/?p=31 также можно просканировать этот адрес с помощью скрипта: blogs.msdn.com/b/debuggingtoolbox /архив/20.07.2007/ - person EdChum; 08.06.2013