Форум: "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