Получение кол-стека

Тема в разделе "WASM.WIN32", создана пользователем _DEN_, 2 фев 2008.

  1. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Пытаюсь заполучить кол-стек через StackWalk64 и сотоварищи. Как не бйус апстену, а все что я получаю, это только:

    KiFastSystemCallRet
    SymFunctionTableAccess64

    И все :dntknw: Может чего-то нехватает? Какой-то дополнительной инициализации чего-нибудь еще?
     
  2. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код где?

     
  3. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Почти разобрался. Осталась последняя проблема...

    Код (Text):
    1. SymInitialize(GetCurrentProcess(), 0, TRUE);
    2. SymSetOptions(SYMOPT_LOAD_LINES);
    3. CONTEXT context = CONTEXT();
    4. RtlCaptureContext(&context);
    5. IMAGEHLP_MODULE64 module = IMAGEHLP_MODULE64();
    6. module.SizeOfStruct = sizeof(module);
    7. SymGetModuleInfo64(GetCurrentProcess(), context.Eip, &module); // Возвращает FALSE :'-(
    Почему-то не удается получить инфу о модуле по виртуальному адресу в нем :dntknw: В чем может быть дело?
     
  4. Songoku

    Songoku Эдгар

    Публикаций:
    0
    Регистрация:
    1 мар 2003
    Сообщения:
    68
    Адрес:
    Belarus
    1. а ты уверен что context.Eip 64 бита?
    Код (Text):
    1. BOOL WINAPI SymGetModuleInfo64(
    2.   __in   HANDLE hProcess,
    3.   __in   [b]DWORD64[/b] dwAddr,
    4.   __out  PIMAGEHLP_MODULE64 ModuleInfo
    5. );
    2. попробуй обнулить IMAGEHLP_MODULE64.
    3. в msdn о SymInitialize написанно:
     
  5. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Songoku

    1. Не понял? Там же все функции 64.

    2. IMAGEHLP_MODULE64 module = IMAGEHLP_MODULE64(); // Это и есть обнуление module.

    3. Не работает при обычном запуске, не под дебагом.
     
  6. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    1. А шо говорит GetLastError() ?
    2. А context.Eip вообще содержит валидный адрес? (я-то понимаю, что должен, но всякое бывает :))
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Ursus

    1. ERROR_INVALID_PARAMETER = 87 = The parameter is incorrect.

    2. Нужно пологать что валидный, поскольку вся остальная инфа (имя функции, строка и т.д.) по нему резолвится корректно.
     
  8. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Сейчас вопрос вот в чем.

    Если для получения контекста потока делать RtlCaptureContext, то все работает, стек прекрасно снимается. Если же контекст получать через GetThreadContext, то ничего не работает :-( В чем же разница? Весь отстой в том, что RtlCaptureContext работает только для вызывающего потока, а мне надо научиться получать стек произвольного потока, на который есть права.

    PS. SuspendThread / ResumeThread делаю.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Какую ошибку возвращает GetThreadContext ?
    CONTEXT.ContextFlags не забыл установить ?
     
  10. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Clerk

    GetThreadContext-то отрабатывает нормально! Просто StackWalk64 не раскручивает стек по этим данным. Вот код:

    Код (Text):
    1.     HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION, 0, process_id);
    2.     HANDLE thread = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT, 0, thread_id);
    3.  
    4.     SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
    5.     SymInitialize(process, 0, TRUE);
    6.  
    7.     CONTEXT context = {0};
    8.     context.ContextFlags = CONTEXT_FULL;
    9.     GetThreadContext(thread, &context);
    10.  
    11.     STACKFRAME64 stackFrame = {0};
    12.  
    13.     stackFrame.AddrPC.Offset    = context.Eip;
    14.     stackFrame.AddrPC.Mode      = AddrModeFlat;
    15.     stackFrame.AddrStack.Offset = context.Esp;
    16.     stackFrame.AddrStack.Mode   = AddrModeFlat;
    17.     stackFrame.AddrFrame.Offset = context.Ebp;
    18.     stackFrame.AddrFrame.Mode   = AddrModeFlat;
    19.  
    20.     StackWalk64(IMAGE_FILE_MACHINE_I386, process, thread, &stackFrame, 0, 0, SymFunctionTableAccess64, SymGetModuleBase64, 0);
    21.  
    22.     SymGetModuleInfo64(process, stackFrame.AddrPC.Offset, &module); // Вот тут уже лажа,
    23.     // а повторный StackWalk64 скажет что мол все, стек закончился.
    24.     // Если же взять RtlCaptureContext, то все раскручивается нормально.
    25.     // Но мне нужен сторонний поток, а не вызывающий :-(
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    А не проще будет из TEB получить ?
    У тебя какойто черезжопный способ..
     
  12. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Clerk

    Как это сделать?
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    TEB.Tib.StackBase
    TEB.Tib.StackLimit
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    получи и так и так и сравни результаты в CONTEXT. напишешь чем отличается
     
  15. Ra_

    Ra_ New Member

    Публикаций:
    0
    Регистрация:
    4 мар 2007
    Сообщения:
    289
  16. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    гы) нет
     
  17. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Clerk

    Как их получить средствами WinAPI и C++ (без кернелмода и ассемблера)?


    Great

    esp и ebp они отличаются, поэтому и StackWalk64 себя по-разному ведет. А почему они отличаются, я не понимаю. Кроме того, GetThreadContext на вызывающем потоке вроде как нельзя юзать, потому что для получения контекста нужно предварительно заюзать SuspendThread, что, очевидно, для вызывающего потока не канает. Видимо поэтому и есть RtlCaptureContext.
     
  18. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Сравнил контексты. Т.к. нас интересуют только eip, ebp и esp, то сравнивать остальное нет смысла.

    Код (Text):
    1. CONTEXT context = {0};
    2. context.ContextFlags = CONTEXT_FULL;
    3. GetThreadContext(thread, &context);
    4. RtlCaptureContext(&context);
    5.  
    6. // ........................................
    7.  
    8.      GetThreadContext   RtlCaptureContext
    9.  
    10. Eip: 0x7c90eb94         0x004120f6
    11. Esp: 0x0012ee9c         0x0012fddc
    12. Ebp: 0x0012eeac         0x0012ff68
    Объясните пожалуйста, откуда берется такая разница?
     
  19. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Да RtlCaptureContext выполняет примитивную инициализация структуры CONTEXT и всё.
    Вот как определяется Eip:
    mov eax,dword ptr ss:[ebp+4], причём сама функция регистр Ebp не изменяет.
    Ну уж если ты память средствами WinAPI и C++ прочитать не можешь, то что говорить..
     
  20. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Clerk

    Я не верю, что получение кол-стека не возможно без ассемблерных вставок.


    Я умею "читать память средствами WinAPI и C++". Дело вот в чем.

    MSDN:

    Такими вещами я никогда не пользуюсь. Если уж без нее никак, то просто подскажи откуда мне эту TEB можно вынуть.