поиск адресов возврата в стеке

Тема в разделе "WASM.WIN32", создана пользователем kropalik, 22 мар 2006.

  1. kropalik

    kropalik New Member

    Публикаций:
    0
    Регистрация:
    27 апр 2005
    Сообщения:
    155
    Адрес:
    msk
    какие есть способы анализа стека

    (текущий поток, ring3, перехваченый

    вызов ntdll.dll). хочу найти способ

    более подходящий чем использование

    stackwalk из dbghelp.dll. информацию

    искал - пришел к выводу что в моем

    случае достаточно только найти адреса

    возврата (вернее адреса соответствующих

    инструкций call) параметры и всякие ebp

    не нужны. пока пытаюсь разобраться как

    это сделано в wine. хотелось бы найти

    документацию . просто в wine много

    ненужного (в моем случае) и все равно

    придется большую часть переделывать.
     
  2. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    Если так вопрос ставишь, то это очень просто, вытаскиваешь потихоньку дворды из стека и используешь их как указатели, смотриш по ним, не являются ли байты выше по коду инструкцией call на точку входа твоей функции, ну и дальше делаешь чо нада. ну а затем разницу считаешь стековую. Всё просто, немного головой подумать.
     
  3. kropalik

    kropalik New Member

    Публикаций:
    0
    Регистрация:
    27 апр 2005
    Сообщения:
    155
    Адрес:
    msk
    может я действительно что-то не понимаю,

    но таким образом можно получить только

    первый адрес возврата (который и так известен

    потому что мы знаем какую функцию перехватили

    и сколько у нее аргументов). по этому адресу

    естественно находится следующая инструкция

    после той call которой была вызвана наша функция.

    вопрос в том как получить следующий адрес -

    ведь неизвестно количество аргументов и

    локальных переменных у той функции которая

    вызвала нашу. если я правильно понял в

    stackwalk используется предположние что

    функции сохраняют ebp в стеке, и зная текущий

    можно найти остальные. вот как stackwalk

    работает если функции не используют ebp как обычно

    я так и не понял.

    >вытаскиваешь потихоньку дворды из стека и

    >используешь их как указатели

    там необязательно указатели... придется

    их все проверять через IsBadCodePtr() ?
     
  4. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    да просканируй стек не только вверх но и вниз
     
  5. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    в винде направление роста стекового сегмента задано вниз. Сканируй и проверяй по аналогичному принципу что я выше написал.
     
  6. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    CARDINAL

    колл может быть и на джамп
     
  7. kropalik

    kropalik New Member

    Публикаций:
    0
    Регистрация:
    27 апр 2005
    Сообщения:
    155
    Адрес:
    msk
    попробовал тест написать такой -

    несколько проблем остается.

    1. многие данные на стеке не являются

    указателями. проверять их через IsBadCodePtr()

    плохая идея. я перехватываю вызовы ntdll.dll

    а сама IsBadCodePrt() сводится к вызову

    NtQueryVirtualMemory(). будет нехорошо если

    мне как раз ее вздумается тоже перехватывать.

    по этой же причине я решил не юзать dbghelp.dll.

    2. проверять весь стек таким образом потребует

    много времени.

    3. не все указатели на секции кода являются

    адресами возврата и к тому же код не обязан

    находиться внутри загруженной DLL (а мне интересны

    в первую очередь такие случаи)



    может задача вообще не имеет правильного решения?

    если бы оно было - его реализовали бы в отладчиках.

    а например OllyDbg не всегда call stack полностью

    показывает.
     
  8. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    1 просканируй память и запомни все секции кода

    2 смотри указатели которые указывают в секции кода

    3 юзай сэх.



    таким образом ты отфильтруеш указатели и не будеш юзать из бад птр. так пони что рет - 6 может указывать на колл который на джамп или вообще вызов может быть нестандартным
     
  9. kropalik

    kropalik New Member

    Публикаций:
    0
    Регистрация:
    27 апр 2005
    Сообщения:
    155
    Адрес:
    msk
    1. это уже и так реализовано.

    2. код может быть в стеке или в памяти

    выделенной VirtualAlloc. как раз такой

    пример у меня есть - длл загружается

    без вызова LoadLibrary() загрузчик

    выделяет память читает файл, настраивает

    импорт и релоки.

    то есть метод вполне ясен, только мне не

    удалось найти нормальный критерий что данный

    кусок памяти является секцией кода.

    именно поэтому хочется какой нибудь независимый

    способ это проверить. собственно вопрос

    в том как отличить адрес возврата от указателеля

    на секцию кода ? пока пробовал сделать проверку

    на наличие в ожидаемом месте разных видов call

    но получается слишком медленно. (может замена

    IsBadCodePtr на SEH поможет ?)

    3. имеется в виду проверять указатель на

    доступность с помощью test eax,eax если

    исключения не будет - то оно доступно для

    чтения ? попробую...
     
  10. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    - длл загружается

    без вызова LoadLibrary()



    а ты пореверси лоад либрари =)
     
  11. kropalik

    kropalik New Member

    Публикаций:
    0
    Регистрация:
    27 апр 2005
    Сообщения:
    155
    Адрес:
    msk
    >а ты пореверси лоад либрари

    зачем ? у меня от той тулзы исходники есть.

    там юзается VirtualAllocEx (из другого процесса),

    и WriteProcessMemory. естественно методы нахождения

    DLL типа CreateToolHelp32Snapshot обламываются.
     
  12. doctor_Ice

    doctor_Ice New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2005
    Сообщения:
    845
    Адрес:
    Russia
    а виртула куери? странички то все равно кодовые... вот по атрибуту страниц и смотри какие код какие данные.
     
  13. kropalik

    kropalik New Member

    Публикаций:
    0
    Регистрация:
    27 апр 2005
    Сообщения:
    155
    Адрес:
    msk
    да наверно так и придется делать.

    то есть типа заранее создавать карту

    памяти через VirtualQuery() а потом ее

    юзать при сканировании стека.

    если еще какой нибудь пакости не случиться...

    кстати может у кого есть идеи насчет

    какие еще проблемы при этом будут ?
     
  14. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow


    я думаю нет смысла расписывать все комбинации, сам догадаеца