Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2009.10.25;
Скачать: [xml.tar.bz2];

Вниз

Выгрузка WinApi перехватчика   Найти похожие ветки 

 
evvcom ©   (2008-09-03 13:54) [160]

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


 
KygECHuK ©   (2008-09-03 15:11) [161]


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


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


 
Anatoly Podgoretsky ©   (2008-09-03 20:14) [162]

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

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


 
evvcom ©   (2008-09-04 23:27) [163]

// На вход передаем 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;


 
evvcom ©   (2008-09-05 08:27) [164]


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

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


 
KygECHuK ©   (2008-09-05 09:53) [165]


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


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


 
evvcom ©   (2008-09-05 10:34) [166]

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


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


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

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


 
evvcom ©   (2008-09-05 12:07) [168]

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


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


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


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

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

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

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


 
evvcom ©   (2008-09-05 13:13) [170]

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


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


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


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


 
evvcom ©   (2008-09-05 14:10) [172]

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

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

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

цикл:
push ebx

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

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

условие N:
call FreeLibrary

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


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


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


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


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

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

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


 
KygECHuK ©   (2008-09-05 15:20) [174]


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


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


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


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


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

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

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

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


 
KygECHuK ©   (2008-09-05 15:44) [176]


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


Автор:

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


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



Страницы: 1 2 3 4 5 вся ветка

Форум: "WinAPI";
Текущий архив: 2009.10.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.76 MB
Время: 0.051 c
2-1251275225
TarenoKostanay
2009-08-26 12:27
2009.10.25
Task Bar


2-1251642682
tonich
2009-08-30 18:31
2009.10.25
Блокировка потоков


15-1251444756
TarenoKostanay
2009-08-28 11:32
2009.10.25
ОС


2-1251711555
Franzy
2009-08-31 13:39
2009.10.25
Как передать в dll адрес процедуры?..


2-1251778934
Phoenix
2009-09-01 08:22
2009.10.25
Обратная связь





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский