Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2011.07.10;
Скачать: [xml.tar.bz2];

Вниз

Стек вызовов   Найти похожие ветки 

 
Unknown user ©   (2009-06-02 13:37) [0]

Скажите, есть ли возможность получить стек вызовов (call stack) для другого процесса (основной поток). Если этот процесс запущен с флагом отладки и находится в остановленном состоянии?

Нашел в JEDI Code Library функции для работы со стеком. но они похоже работают лишь внутри вызывающего процесса.


 
Игорь Шевченко ©   (2009-06-02 14:59) [1]

Есть. Руссинович в Process Explorer получает, но детали мне неизвестны


 
Rouse_ ©   (2009-06-02 16:28) [2]

Разворачивать стек нужно через контекст нити из которой вытаскивай указатель на фрейм стека EBP, текущий указатель на вершину стека ESP и собственно адрес некущей инструкции, где мы остановили нить EIP (на нее можно ориентироваться в случае трассирования кода с целью поиска инструкций, манипулирующих с ESP). Соответственно разбирай фреймы, выбирая из них адреса возврата.
Вот эта статья может помочь: http://www.codeproject.com/KB/threads/StackWalker.aspx


 
Unknown user ©   (2009-06-03 11:25) [3]

>Rouse_

Спасибо за идею. Функция StackWalk работает, навигация по стеку вызовов происходит. Но есть 2 проблемы:

1. Функция StackWalk для стека вызовов больше 3-х фреймов пропускает тот, что на вершине стека. Выдает адрес возврата для предыдущей функции не для текущей. При этом работает верно если задать текущий адрес не из EIP, а указать 0. Однако для других случаев 0 не срабатывает.

2. Функция StackWalk64 в ImageHlp.pas не объявлена, хотя в статье рекомендуется использовать именно ее. Объявил сам аналогично StackWalk параметры судя по MSDN правильны (хотя там не нашел даже упоминания про StackWalk, описана лишь StackWalk64) однако объявленная мною функция вызывает исключение.

Вобщем, путаница со StackWalk и StackWalk64. Еще непонятно зачем эти 2 функции экспортируются и в dbghelp.dll и в imagehlp.dll.


 
Rouse_ ©   (2009-06-03 13:06) [4]

Ты используй именно StackWalk64, т.к. StackWalk устарела, просто указывай IMAGE_FILE_MACHINE_I386 для 32-битных платформ.
Почему декларация в двух библиотеках: imagehlp - устаревшая библиотека и присутствует только в целях совместимости со старым ПО, это просто врапер на dbghelp - которая повяилась начиная с W2K.

Вот тебе декларация, проверь со своей:

type
 HANDLE = THandle;
 PVOID = Pointer;
 DWORD64 = Int64;

 ADDRESS_MODE = (
   AddrMode1616,
   AddrMode1632,
   AddrModeReal,
   AddrModeFlat);
 TAddressMode = ADDRESS_MODE;

 LPADDRESS64 = ^ADDRESS64;
 _tagADDRESS64 = record
   Offset: DWORD64;
   Segment: WORD;
   Mode: ADDRESS_MODE;
 end;
 ADDRESS64 = _tagADDRESS64;
 TAddress64 = ADDRESS64;
 PAddress64 = LPADDRESS64;

 PKDHELP64 = ^KDHELP64;
 _KDHELP64 = record
   //
   // address of kernel thread object, as provided in the
   // WAIT_STATE_CHANGE packet.
   //
   Thread: DWORD64;
   //
   // offset in thread object to pointer to the current callback frame
   // in kernel stack.
   //
   ThCallbackStack: DWORD;
   //
   // offset in thread object to pointer to the current callback backing
   // store frame in kernel stack.
   //
   ThCallbackBStore: DWORD;
   //
   // offsets to values in frame:
   //
   // address of next callback frame
   NextCallback: DWORD;
   // address of saved frame pointer (if applicable)
   FramePointer: DWORD;
   //
   // Address of the kernel function that calls out to user mode
   //
   KiCallUserMode: DWORD64;
   //
   // Address of the user mode dispatcher function
   //
   KeUserCallbackDispatcher: DWORD64;
   //
   // Lowest kernel mode address
   //
   SystemRangeStart: DWORD64;
   Reserved: array [0..7] of DWORD64;
 end;
 KDHELP64 = _KDHELP64;
 TKdHelp64 = KDHELP64;

 LPSTACKFRAME64 = ^STACKFRAME64;
 _tagSTACKFRAME64 = record
   AddrPC: ADDRESS64; // program counter
   AddrReturn: ADDRESS64; // return address
   AddrFrame: ADDRESS64; // frame pointer
   AddrStack: ADDRESS64; // stack pointer
   AddrBStore: ADDRESS64; // backing store pointer
   FuncTableEntry: PVOID; // pointer to pdata/fpo or NULL
   Params: array [0..3] of DWORD64; // possible arguments to the function
   Far: BOOL; // WOW far call
   Virtual: BOOL; // is this a virtual frame?
   Reserved: array [0..2] of DWORD64;
   KdHelp: KDHELP64;
 end;
 STACKFRAME64 = _tagSTACKFRAME64;
 TStackFrame64 = STACKFRAME64;
 PStackFrame64 = LPSTACKFRAME64;

 PREAD_PROCESS_MEMORY_ROUTINE64 = function (hProcess: HANDLE; qwBaseAddress: DWORD64;
   lpBuffer: PVOID; nSize: DWORD; var lpNumberOfBytesRead: DWORD): BOOL; stdcall;
 PReadProcessMemoryRoutine64 = PREAD_PROCESS_MEMORY_ROUTINE64;

 PFUNCTION_TABLE_ACCESS_ROUTINE64 = function (hProcess: HANDLE;
   AddrBase: DWORD64): PVOID; stdcall;
 PFunctionTableAccessRoutine64 = PFUNCTION_TABLE_ACCESS_ROUTINE64;

 PGET_MODULE_BASE_ROUTINE64 = function (hProcess: HANDLE;
   Address: DWORD64): DWORD64; stdcall;
 PGetModuleBaseRoutine64 = PGET_MODULE_BASE_ROUTINE64;

 PTRANSLATE_ADDRESS_ROUTINE64 = function (hProcess: HANDLE; hThread: HANDLE;
   const lpaddr: ADDRESS64): DWORD64; stdcall;
 PTranslateAddressRoutine64 = PTRANSLATE_ADDRESS_ROUTINE64;

function StackWalk64(MachineType: DWORD; hProcess: HANDLE; hThread: HANDLE;
 var StackFrame: STACKFRAME64; ContextRecord: PVOID;
 ReadMemoryRoutine: PREAD_PROCESS_MEMORY_ROUTINE64;
 FunctionTableAccessRoutine: PFUNCTION_TABLE_ACCESS_ROUTINE64;
 GetModuleBaseRoutine: PGET_MODULE_BASE_ROUTINE64;
 TranslateAddress: PTRANSLATE_ADDRESS_ROUTINE64): BOOL; stdcall;
 external "dbghelp.dll"


 
Unknown user ©   (2009-06-03 16:25) [5]

Спасибо за код, теперь функция исключения не вызывает. Но все равно не работает. Хотя возвращает TRUE. Однако Винда говорит об ошибке 203 - системе не удается найти указанный параметр среды.  Привожу код.

function ReadProcMem64(hProcess: HANDLE; qwBaseAddress: DWORD64;
  lpBuffer: PVOID; nSize: DWORD; var lpNumberOfBytesRead: DWORD): BOOL; stdcall;
begin
 Result := ReadProcessMemory(hProcess, Pointer(qwBaseAddress),
   lpBuffer, nSize, lpNumberOfBytesRead);
end;

function GetImgBase64(hProcess: HANDLE; Address: DWORD64): DWORD64; stdcall;
begin
 Result := $400000; //эта функция не вызывается
end;

begin
...
   FillChar(StackFrame64, SizeOf(StackFrame64), 0);
   StackFrame64.AddrPC.Offset := FLastBreakAddr;
   StackFrame64.AddrPC.Mode := DbgHelp.AddrModeFlat;
   StackFrame64.AddrFrame.Offset := Context.Ebp;
   StackFrame64.AddrFrame.Mode := DbgHelp.AddrModeFlat;
   StackFrame64.AddrStack.Offset := Context.Esp;
   StackFrame64.AddrStack.Mode := DbgHelp.AddrModeFlat;

   res := StackWalk64(IMAGE_FILE_MACHINE_I386, FProcInfo.hProcess, FProcInfo.hThread,
             @StackFrame64, @Context, ReadProcMem64, nil, GetImgBase64, nil);


В StackFrame64.AddrReturn.Offset после вызова функции записано значение StackFrame64.AddrPC.Offset.

Ты использовал StackWalk64 в своих проектах?


 
Rouse_ ©   (2009-06-03 18:20) [6]

Как то у тебя параметры отличаются от тех которые я привел, во вторых предпоследним параметром должен идти адресу функции SymGetModuleBase64, которую экспортирует dbghelp, прочти еще раз внимательней справку по StackWalk64.
В догонку вот тебе самый простейший шаблон: http://www.rsdn.ru/forum/src/1342099.1.aspx


 
Unknown user ©   (2009-06-04 19:12) [7]

Rouse_ спасибо за помощь.


 
DeedeledFlank   (2009-07-27 23:44) [8]

Удалено модератором



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2011.07.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.003 c
2-1301675364
Gu
2011-04-01 20:29
2011.07.10
PhysicalDrive


15-1301344197
Юрий
2011-03-29 00:29
2011.07.10
С днем рождения ! 29 марта 2011 вторник


15-1300947227
И. Павел
2011-03-24 09:13
2011.07.10
Печать нескольких RAV-проектов на одной странице


8-1212730666
DJ Kondakov
2008-06-06 09:37
2011.07.10
Проигрывание AVI


15-1300913792
Handbrake
2011-03-23 23:56
2011.07.10
Динамическая пакетная архитектура и БД





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский