какие есть способы анализа стека (текущий поток, ring3, перехваченый вызов ntdll.dll). хочу найти способ более подходящий чем использование stackwalk из dbghelp.dll. информацию искал - пришел к выводу что в моем случае достаточно только найти адреса возврата (вернее адреса соответствующих инструкций call) параметры и всякие ebp не нужны. пока пытаюсь разобраться как это сделано в wine. хотелось бы найти документацию . просто в wine много ненужного (в моем случае) и все равно придется большую часть переделывать.
Если так вопрос ставишь, то это очень просто, вытаскиваешь потихоньку дворды из стека и используешь их как указатели, смотриш по ним, не являются ли байты выше по коду инструкцией call на точку входа твоей функции, ну и дальше делаешь чо нада. ну а затем разницу считаешь стековую. Всё просто, немного головой подумать.
может я действительно что-то не понимаю, но таким образом можно получить только первый адрес возврата (который и так известен потому что мы знаем какую функцию перехватили и сколько у нее аргументов). по этому адресу естественно находится следующая инструкция после той call которой была вызвана наша функция. вопрос в том как получить следующий адрес - ведь неизвестно количество аргументов и локальных переменных у той функции которая вызвала нашу. если я правильно понял в stackwalk используется предположние что функции сохраняют ebp в стеке, и зная текущий можно найти остальные. вот как stackwalk работает если функции не используют ebp как обычно я так и не понял. >вытаскиваешь потихоньку дворды из стека и >используешь их как указатели там необязательно указатели... придется их все проверять через IsBadCodePtr() ?
в винде направление роста стекового сегмента задано вниз. Сканируй и проверяй по аналогичному принципу что я выше написал.
попробовал тест написать такой - несколько проблем остается. 1. многие данные на стеке не являются указателями. проверять их через IsBadCodePtr() плохая идея. я перехватываю вызовы ntdll.dll а сама IsBadCodePrt() сводится к вызову NtQueryVirtualMemory(). будет нехорошо если мне как раз ее вздумается тоже перехватывать. по этой же причине я решил не юзать dbghelp.dll. 2. проверять весь стек таким образом потребует много времени. 3. не все указатели на секции кода являются адресами возврата и к тому же код не обязан находиться внутри загруженной DLL (а мне интересны в первую очередь такие случаи) может задача вообще не имеет правильного решения? если бы оно было - его реализовали бы в отладчиках. а например OllyDbg не всегда call stack полностью показывает.
1 просканируй память и запомни все секции кода 2 смотри указатели которые указывают в секции кода 3 юзай сэх. таким образом ты отфильтруеш указатели и не будеш юзать из бад птр. так пони что рет - 6 может указывать на колл который на джамп или вообще вызов может быть нестандартным
1. это уже и так реализовано. 2. код может быть в стеке или в памяти выделенной VirtualAlloc. как раз такой пример у меня есть - длл загружается без вызова LoadLibrary() загрузчик выделяет память читает файл, настраивает импорт и релоки. то есть метод вполне ясен, только мне не удалось найти нормальный критерий что данный кусок памяти является секцией кода. именно поэтому хочется какой нибудь независимый способ это проверить. собственно вопрос в том как отличить адрес возврата от указателеля на секцию кода ? пока пробовал сделать проверку на наличие в ожидаемом месте разных видов call но получается слишком медленно. (может замена IsBadCodePtr на SEH поможет ?) 3. имеется в виду проверять указатель на доступность с помощью test eax,eax если исключения не будет - то оно доступно для чтения ? попробую...
>а ты пореверси лоад либрари зачем ? у меня от той тулзы исходники есть. там юзается VirtualAllocEx (из другого процесса), и WriteProcessMemory. естественно методы нахождения DLL типа CreateToolHelp32Snapshot обламываются.
а виртула куери? странички то все равно кодовые... вот по атрибуту страниц и смотри какие код какие данные.
да наверно так и придется делать. то есть типа заранее создавать карту памяти через VirtualQuery() а потом ее юзать при сканировании стека. если еще какой нибудь пакости не случиться... кстати может у кого есть идеи насчет какие еще проблемы при этом будут ?