Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Выгрузка WinApi перехватчика [D7, WinXP]


Страницы:   1 2 3 4 5 6 7 8 9

KygECHuK ©   (2008-08-26 10:33:00) 

занимаюсь автоматизированным тестированием, оформил плагин для перехвата отрисовки текста. он подменяет адресса к функциям в таблице импорта, в моём случае это textOut в GDI32.dll. Всё работает хорошо, вот только что при выгрузке перхватчика с некоторойй вероятностью появлятся ошибка доступа к памяти...

Возможно кто нибудь занимался подомной проблематикой и может что нибудь посоветовать...


KygECHuK   (2008-09-05 15:44:00) [1]


> Тебе-т он зачем ? Явно же не твой же случай ..


Автор:

Для того, чтобы его понять нужна всего-лишь капля мозгов (не больше).


по минимальным требованиям, вроде подхожу... :)
Учиться никогда не поздно, хотя часто бесполезно ....


Сергей М.   (2008-09-05 15:29:00) [2]


> KygECHuK ©   (05.09.08 15:20) [174]


"Шурик, это же не наш метод !" (С)

Тебе-т он зачем ? Явно же не твой же случай ..

Или "Надо, Федя, надо"  ?)

http://www.wasm.ru/article.php?article=apihook_1


KygECHuK   (2008-09-05 15:20:00) [3]


> здесь на сцену выходит метод сплайсинга.


Что за зверь, где о нём можно раздобыть инфу?


Сергей М.   (2008-09-05 14:33:00) [4]


> evvcom ©   (05.09.08 14:10) [172]


А, ты вон о чем ..

Ч.г., я не вник в [141], а ты там завел речь о частном случае (довольно редкий он и заведомо не случай автора, потому я и не рассматривал его) ..

Ну что тут сказать ?
Для случаев, подобных твоему, метод перехвата путем модификации IAT/EAT не годится, здесь на сцену выходит метод сплайсинга.


evvcom   (2008-09-05 14:10:00) [5]

Сергей, ты в [141] читал ситуацию?

> И более никогда не будут обращаться к этому АП, потому что
> оригинальная IAT восстановлена перед началом проверки.

Разве обращаться к функции можно только каждый раз проверяя IAT? Еще раз поясню ситуацию. Процесс загрузил мою dll, dll изменила IAT, процесс считал адрес (это уже адрес в моей dll) и сохранил его в ebx, далее

цикл:
push ebx

условие 1:
call ebx // перехваченная функция

... прочие условия

условие N:
call FreeLibrary

pop ebx
cmp ...
jmp nz, цикл


Вот такая вот реальная ситуация была и происходило это в однопоточном приложении.


Сергей М.   (2008-09-05 13:40:00) [6]


> нет никакой гарантии, что не схватим AV после Resume потоков


Гарантия есть, потому что тек.контексты и стеки потоков отныне ни прямо ни косвенно не ссылаются ни на один из адресов в АП модуля-перехватчика, что как раз и покажет проверка. И более никогда не будут обращаться к этому АП, потому что оригинальная IAT восстановлена перед началом проверки.


evvcom   (2008-09-05 13:13:00) [7]

Согласен :)
Я не все здесь описал, что задумал. Даже если в настоящий момент код не выполняется, и мы определим это из контекстов, стеков и прочих ухищрений, нет никакой гарантии, что не схватим AV после Resume потоков. Я столкнулся с этим в первой же своей подобной задаче, о чем упомянул в [141]. Гораздо проще, имхо, и надежнее сделать нечто типа MakeObjectInstance, которая конструировала бы в куче что-то типа вызова перехваченной функции или оригинала по условию в зависимости от взведенного флага и соответственно перед выполнением кода "ловушки" inc счетчика, после dec. Естественно все это надежно защитить, например, крит. секцией. Детали я еще не реализовывал, потому по ходу будут грабли, обязательно будут.


Сергей М.   (2008-09-05 12:24:00) [8]


> evvcom ©   (05.09.08 12:07) [168]


А грабли как были , так и остались, не смотря на все эти хитромудрые телодвижения)

Ведь выгрузку модуля-перехватчика нельзя делать пор, пока хотя бы в одном из потоков процесса-жертвы исполняется код, принадлежащий АП модуля-перехватчика..

Первое что напрашивается для устранения засады - в ходе деинициализации перехватчика вернуть на место оригинальные IAT/EAT-элементы и в цикле (опасно, но куда деваться ?) проверять, не ссылается ли контекст каждого из существующих потоков жертвы на код в АП перехватчика или не фигурирует ли в стеках потоков адреса возвратов, указывающие на АП перехватчика.

Это отдельный геморрой, но он, видимо, того стОит ..


evvcom   (2008-09-05 12:07:00) [9]

аааа.... Ты вот о чем. Идея такова. После того, как случился внедреж :), dll в жертве (далее просто жертва) начинает общаться с сервисом, вариантов реализации этого общения - масса, каждый выбирает, что ему по вкусу, поэтому не буду на этом останавливаться. Жертва запрашивает у сервиса, что приготовлено для данного процесса, какую dll надо загрузить, после чего выполняет LoadLibrary уже штатно. Далее останавливаются все потоки процесса кроме текущего (или это лучше сделать самым первым делом после внедрения), из загруженной dll вытягивается инфа, что должно быть перехвачено, вычисляются адреса и данные, которые должны быть по ним записаны, и все это сообщается сервису, который успешно производит подмены адресов. Сообщение жертве "все готово", та запускает потоки и завершает свой стартовый код DLL_PROCESS_ATTACH. Ну вот типа такого.


KygECHuK   (2008-09-05 10:41:00) [10]


> Этим и достигается синхронизация.

Все это хоршо, я это понял из предыдущего поста. мения интеризуют не конкретно используемые объекты синхронизации Windows, а "синхронизация" потока, исправляющего адреса с другими потоками процесса жертвы


evvcom   (2008-09-05 10:34:00) [11]

Действия, которые производит библиотека при отключении, выполняются в DLL_PROCESS_DETACH (в АП жертвы). Пока они не выполнятся, поток не завершит свою работу. А сервис (у меня сервис), т.е. процесс, который занимается внедрением/изъятием dll в/из АП жертвы, ждет завершения удаленного потока WaitForSingleObject(l_hThread, INFINITE);Этим и достигается синхронизация.


KygECHuK   (2008-09-05 09:53:00) [12]


> Из кода видно, что выполняется ожидание завершения потока
> до закрытия хэндла. Или ты под задержкой/синхронизацией
> имел ввиду что-то другое?


Я имел ввиду действия, которые производит библиотека при отключении жертвы от неё.


evvcom   (2008-09-05 08:27:00) [13]


> Ты её делаешь сразу без условий или с какими то либо задержками
> или синхронизацией?

Из кода видно, что выполняется ожидание завершения потока до закрытия хэндла. Или ты под задержкой/синхронизацией имел ввиду что-то другое?


evvcom   (2008-09-04 23:27:00) [14]

// На вход передаем dwProcessId - идентификатор процесса,
// в который требуется внедрить dll с именем lpModName
function InjectLibByRemoteThread(dwProcessId: DWORD; lpModName: PChar): Boolean;
var
 l_hProcess: THandle;
 l_hThread: THandle;
 l_ThreadFunc: TFNThreadStartRoutine;
 l_ThreadId: DWORD;
 l_iLength: Cardinal;
 l_pBuffer: PChar;
 l_NumberOfBytesWritten: DWORD;
begin
 Result := False;
 l_hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or
   PROCESS_VM_WRITE, False, dwProcessId);
 if l_hProcess = 0 then Exit;
 try
   l_ThreadFunc := GetProcAddress(GetModuleHandle(kernel32), 'LoadLibraryA');
   if not Assigned(l_ThreadFunc) then Exit;
   l_iLength := Length(lpModName);
   l_pBuffer := VirtualAllocEx(l_hProcess, nil, l_iLength + 1,
     MEM_COMMIT, PAGE_READWRITE);
   if not Assigned(l_pBuffer) then Exit;
   try
     if not WriteProcessMemory(l_hProcess, l_pBuffer, lpModName, l_iLength,
       l_NumberOfBytesWritten)
     then Exit;
     l_hThread := CreateRemoteThread(l_hProcess, nil, 0, l_ThreadFunc,
       l_pBuffer, 0, l_ThreadId);
     Result := l_hThread <> 0;
     if Result then begin
       WaitForSingleObject(l_hThread, INFINITE);
       CloseHandle(l_hThread);
     end;
   finally
     VirtualFreeEx(l_hProcess, l_pBuffer, 0, MEM_RELEASE);
   end;
 finally
   CloseHandle(l_hProcess);
 end;
end;

// На вход передаем dwProcessId - идентификатор процесса,
// из которого требуется выгрузить dll с именем lpModName
function WithdrawLibByRemoteThread(dwProcessId: DWORD; lpModName: PChar): Boolean;
var
 l_hProcess: THandle;
 l_hThread: THandle;
 l_ThreadFunc: TFNThreadStartRoutine;
 l_ToolHelp: TToolHelp;
 l_me: TModuleEntry32;
 l_ThreadId: DWORD;
begin
 Result := False;
 l_hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or
   PROCESS_VM_WRITE, False, dwProcessId);
 if l_hProcess = 0 then Exit;
 try
   l_ThreadFunc := GetProcAddress(GetModuleHandle(kernel32), 'FreeLibrary');
   if not Assigned(l_ThreadFunc) then Exit;
   // Найдем внедренную библиотеку в целевом процессе
   l_ToolHelp := TToolHelp.Create(TH32CS_SNAPMODULE, dwProcessId);
   try
     l_me.dwSize := SizeOf(TModuleEntry32);
     if not l_ToolHelp.ModuleByNameFind(lpModName, l_me) then Exit;
     l_hThread := CreateRemoteThread(l_hProcess, nil, 0, l_ThreadFunc,
       Pointer(l_me.hModule), 0, l_ThreadId);
     Result := l_hThread <> 0;
     if Result then begin
       WaitForSingleObject(l_hThread, INFINITE);
       CloseHandle(l_hThread);
     end;
   finally
     l_ToolHelp.Free;
   end;
 finally
   CloseHandle(l_hProcess);
 end;
end;


Anatoly Podgoretsky   (2008-09-03 20:14:00) [15]

> KygECHuK  (03.09.2008 10:34:39)  [159]

Есть и на русском и на английском. Четвертое издание.


KygECHuK   (2008-09-03 15:11:00) [16]


>  сишного примера Рихтера на паскаль


я то же с чьегото сишного примера делал


evvcom   (2008-09-03 13:54:00) [17]

честно говоря, такую деталь не помню. Писал давно, да и по сути делал перевод с сишного примера Рихтера на паскаль, а под рукой сейчас исходника нет. Вечером посмотрю, если не забуду :)


KygECHuK   (2008-09-03 10:34:00) [18]


> Джефри Рихтер. Windows для профессионалов.Если не путаю,
>  у Анатолия Подгорецкого на сайте есть.

Спасибо посмотрю

> выгрузка CreatRemoteThread FreeLibrary


Ты её делаешь сразу без условий или с какими то либо задержками или синхронизацией?


evvcom   (2008-09-03 08:17:00) [19]


> это веть книга? )

Джефри Рихтер. Windows для профессионалов.
Если не путаю, у Анатолия Подгорецкого на сайте есть.


KygECHuK   (2008-09-02 21:08:00) [20]


> Да и, похоже, ни о чем она была - как был у тебя вопрос
> про AV неразрешенным, так он таким и остался.


нет, все получилось, я использовал ваш совет и AV больше нет.
Ище раз спасибо.


Страницы:   1 2 3 4 5 6 7 8 9

Наверх

Титульная страница Поиск, карта сайта Написать письмо