пытаюсь скрыть процесс под Windows Vista SP1... делаю это сплайсингом функции ZwQuerySystemInformation из ntdll.dll в процессе taskmgr.exe.... свой обработчик подгружается в dll удаленным потоком... во время выполнения возникает ошибка "Access violation reading location"... мои изыскания показали, что внедрение dll, сплайсинг проходят нормально, то есть мой обработчик вызывается вместо ZwQuerySystemInformation, причем вызывается несколько раз, потом возникает ошибка... вообще такое впечатление, что вся система со сплайсингом зациклилась, и таскмэнеджер просто с ума сходит при определенной итерации... подскажите пожалуйста, в чем может быть ошибка... наверняка глупая ошибка где-то закралась, у меня мало опыта в этом, по-этому приходится спрашивать((((( код моего обработчика из подгружаемой dll'ки: Код (Text): typedef NTSTATUS (WINAPI* PZQSI)(UINT, PVOID, ULONG, PULONG); PZQSI pZwQuerySystemInformation = (PZQSI)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "ZwQuerySystemInformation"); // Получаем "указатель" на функцию CSplice* Splice = new CSplice(); // Мой класс, реализующий сплайсинг и ещё много чего // СВОЙ ОБРАБОТЧИК ZwQuerySystemInformation NTSTATUS My_ZwQuerySystemInformation(UINT SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength) { Splice->Splice_SimpleFree(pZwQuerySystemInformation); // Снимаю сплайсинг NTSTATUS ret = pZwQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength); // Вызываю оригинал функции Splice->Splice_SimpleSet(pZwQuerySystemInformation, My_ZwQuerySystemInformation); // Восстанавливаю сплайсинг if(ret != STATUS_SUCCESS) { return ret; } //Если все прошло нормально здесь проводятся манипуляции с результатом return ret; } Заранее спасибо!
помимо зацикливания (по сути дела бесконечного реккурсивного запуска моего обработчика) возможно ещё, что сама функция ZwQuerySystemInformation (оригинал) в моем обработчике (My_ZwQuerySystemInformation) возвращает через указатели SystemInformation и ReturnLength не то, что нужно... в смысле не верный ReturnLength, в следствии чего бедный таскмэнеджер пытается считать белеберду и из-за этого обижается на меня и не работает.... но причину этого я тож понять не могу((((((
1. Сплайсинг стуба нубский способ. Уже мильон раз обсуждалось. 2. Сплайсинг в хэндлере не снимают, а копируют инструкции в буфер, где их исполняют. 3. Выполнить атомарно, но для тм не важно. Увидеть бы приложение, всё бы прояснилось, а так хз.
Rel Нужно делать мост к оригинальной функции. С помощью дизасма длин сохранять целое число команд. Можно изменить таблицу импорта в той библиотеке, которая вызывает ZwQuerySystemInformation (ToolHelp или чем там таскменеджер пользуется). А клерка не слушай, он тебе счас предложот перехвотовоть sysenter как минимум...
K10 Ну в юзермоде ведь хук. Вот тут подробно рассмотрено было http://www.wasm.ru/forum/viewtopic.php?id=29558
А вобще кривая реализация. Я сделол бы иначе. Известно что поток один и тотже получает слепок и Dr часть контекста поток не сбрасывает. Это позволяет поставить хардварный бряк на сервис. Тоесть мы делоем так: > Выделяем память(в идеале хип, но не столь важно) и записываем туда хэндлеры исключений и сервиса. > Устанавливаем векторный хэндлер исключений, тот который ставит RtlAddVectoredExceptionHandler(), вручную(там просто связанный список). > Суспендим поток/потоки и устанавливаем в их контексте/-тах Dr-часть так, чтобы останов происходил по исполнению ZwQuerySystemInformation, тут вариантов множество, например есчо можно на KiFastSystemCall брякнутсо. > При срабатывании точки останова управление первым получит наш хэндлер исключений(VEH исполняетсо раньше чем SEH), далее обрабатываетсо просто. Простому юзеру это будет обнаружить сложнее, чем просто сплайсинг.
спасибо всем за ответы! к сожалению (а может быть и к счастью, зная мою нубость в этом вопросе) передо мной стоит задача разрешить все это именно сплайсингом функции, именно в юзермоде, да и не особо палясь каверкая память другого процесса (поэтому использую избитый метод подгрузки своей dll)... вчера ещё немного помучал свой "проэкт", снял более подробные логи... и так, что именно происходит... мой алгоритм верно отрабатывается 2 вызова таскменеджера (с входным параметром SystemInformationClass = 0 и 2) и возвращает то, что и должен, а имеено ничего... на третьем вызове (SystemInformationClass = 5), когда по адресу буффера, передаваемого через параметр SystemInformation, нужно было бы записать данные о весьма приличном количестве работающих в системе процессов и собсна происходит сбой... а через параметр ReturnLength возвращается, что процессов 77 с чем то тысяч, что мне кажется совершенно невозможной цифрой... сегодня ещё покапаюсь в этом всем... наверное придется так и сделать, если не пойму в чем тут дело... хотя по логике вещей, от того чтобы снимать сплайсинг, вызывать оригинал, восстанавливать сплайсинг, ничего плохо произойти не должно... хотя у меня очень мало опыта в этом... да, я думал об этом (даж немного покапался в детурсе)... но потом пришел к выводу, что код с получившейся битой командой будет недосягаем, может канеш я что-то и недопонимаю...
вот кстати немного оффтопный вопрос... найти адрес экспортируемой из библиотеки функции проще простого (с помощью GetProcAddress), а существует ли способ нахождения адреса неэкспортируемой функции (кроме дизассемблирования)? в смысле функции с кодом в самом теле программы, допустим, зная имя функции, можно как-то определить адрес?
Да какой дизасм и сплайсинг, они тут не нужны. Этот кодес какойто понос.. как тока можно так извращаться.)
после долгих мук разобрался сам... если кому интересно, в чем была проблема: надо было объявить прототип моей функции, как NTSTATUS WINAPI My_ZwQuerySystemInformation, то есть со словом WINAPI... и так что же это меняет... а меняет это то, что WINAPI эквивалентно __stdcall, я думаю все знают, что это штука значит... из того, что у меня не было этого чудо-слова в прототипе, в стеке происходила анархия, что в итоге и выливалось в ошибку чтения по совершенно чумовому адресу... в общем, всем еще раз спасибо за попытки мне помочь! если кому понадобится мучать беднягу эксплорера, или ещё че-нить сплайсингом делать, отправляйте их ко мне... )))))
Rel Скажи, как ты будешь исполнять перехват сплайсингом например следующего кода. Нормальный пролог: Код (Text): 8BFF mov edi,edi 55 push ebp 8BEC mov ebp,esp [...] Пролог с точкой останова: Код (Text): CD 03 int 3 55 push ebp 8BEC mov ebp,esp [...] В текущем и чужём процессах. Интересно твоё мнение.