Форум: "WinAPI";
Текущий архив: 2002.12.23;
Скачать: [xml.tar.bz2];
ВнизВот вопросик для мастеров! Найти похожие ветки
← →
Василий2 (2002-11-04 13:51) [0]Как внедрить свою DLL в чужой процесс? Только внедрять НЕ с помощью ловушек! Знаю, что надо использовать функции OpenProcess, VirtualAllocEx, WriteProcessMemory, CreateRemoteThread...
← →
Digitman (2002-11-04 15:09) [1]
> Знаю, что надо использовать функции
Знаешь - используй ! Какие проблемы ?
← →
Василий2 (2002-11-04 20:36) [2]Проблема в том, что я не понимаю какое кол-во памяти нужно занять (VirtualAllocEx). Вообщем, расскажите, пожалуйста, как всей этой трухой пользоваться.
← →
Ihor Osov'yak (2002-11-04 22:57) [3]Найди книгу Рихтера, там целая глава материала на эту тему.
И вообще, очень полезная книга.
← →
AlteFriz (2002-11-05 09:14) [4]Полное название книги, если можно напишите, тоже хочу почитать.
← →
Digitman (2002-11-05 09:25) [5]>Василий2
Запросить нужно столько памяти, сколько ее требуется для размещения полного образа внедряемого исп.модуля
← →
Digitman (2002-11-05 09:33) [6]Несколько неточно. Имеется ввиду - не модуля самой dll, а бинарного образа исп.кода, который будет стартован в целевом ВАП посредством CreateRemoteThread.
В успешно распределенное таким способом целевое ВАП вызовом WriteProcessMemory() копируется исп.код потока, после чего поток стартуется вызовом CreateRemoteThread(). В ходе исполнения удаленного код.потока, собственно, и происходит загрузка dll в то ВАП, в котором код.поток стартован (если это предусмотрено алгоритмом код.потока)
← →
Василий2 (2002-11-05 12:00) [7]А кого-нибудь есть исходник? На словах это сложно понять.
← →
Digitman (2002-11-05 14:34) [8]
> На словах это сложно понять.
Что сложно ? Конкретно ?
← →
Василий2 (2002-11-06 11:12) [9]Когда видишь пример, тебе становится все ясно. Говорят - учиться надо на реальных примерах, а не только на одной теории.
Как определить бинарный образ исполняемого кода?
← →
Ihor Osov'yak (2002-11-06 11:33) [10]2 AlteFriz © (05.11.02 09:14)
Джеффи Рихтер. Windows для профессионалов. Третье издание.
Изд Русская редакция Microsoft Press
В оригинале Advanced Windows. Third Edition Jeffey Richter.
Уже вышла четвертая редакция, но называется как-то по другому,
что-то типа Programming Application for Microsoft Windows,
люди говорят, что бегает по инету в электронном виде.
2 Василий2 © (06.11.02 11:12) Идите к Рихтеру.
В третьем русском издании страницы 625-646. И все в примерах.
← →
Digitman (2002-11-06 11:33) [11]>Василий2
> Как определить бинарный образ исполняемого кода?
Что под сим подразумевается - не понятно. Прокомментируй
← →
Василий2 (2002-11-06 18:48) [12]Вы говорили:
Несколько неточно. Имеется ввиду - не модуля самой dll, а бинарного образа исп.кода, который будет стартован в целевом ВАП посредством CreateRemoteThread.
← →
Василий2 (2002-11-06 18:49) [13]Ihor Osov"yak -> А где в интернете валяется это книжка?
← →
Ihor Osov'yak (2002-11-07 10:13) [14]2 Василий2 © (06.11.02 18:49)
Ну блин, вы даете.
Ровно две минуты поиска - http://anatolix.naumen.ru/win32books.htm
ЗЫ. Даже не знаю, как Вы со мной рассчитаетесь.
← →
Gandalf (2002-11-07 18:07) [15]Ровно две минуты поиска - http://anatolix.naumen.ru/win32books.htm
Спасибо, но там вроде ссылки битые.
← →
Gandalf (2002-11-07 18:10) [16]Прошу прощения. Все нормально.
← →
Василий2 (2002-11-07 20:35) [17]Единственное плохо - код на C... :(
← →
Xemax (2002-11-08 13:40) [19]
← →
Xemax (2002-11-08 13:41) [20].
← →
Xemax (2002-11-08 13:46) [21]Форум заглючил ;-))
← →
Ketmar (2002-11-08 15:10) [22]ну и что, что Ц? перевести сложно? in a mater of fact, у меня есть, конечно, на эльфах, только я не дам. жадный я. %-) разве если только задача очень срочная и важная...
Satanas Nobiscum! 08-Nov-XXXVII A.S.
← →
Василий2 (2002-11-08 17:51) [23]Если бы мне это было не важно, я бы не писал, а раз тебе жалко, то зачем вообще писать об этом???
← →
Ketmar (2002-11-08 19:06) [24]скажем так: мне очень интересно знать, ЗАЧЕМ это вам. если причины мне покажутся достаточно важными, я пришлю код. это во-первых. во-вторых, код №1 работоспособен только на WinNT, код №2 проверялся только на Win2K и я не знаю, будет ли работать в других системах. короче говоря - welcome в мое мыло. возможно, специально для вас вырежу кусок из Кассандры.
зыж
можно и догадаться, что если написать мне правильное мыло, то будет людям счастье %-))
ззыж
не знаю, правда, как мой код коррелируется с Рихтером (не смотрел я его реализацию)... у меня (Win2K Advanced Server) - работает.
Satanas Nobiscum! 08-Nov-XXXVII A.S.
← →
Василий2 (2002-11-09 13:52) [25]Ketmar -> Скажем так: какая тебе РАЗНИЦА? Ты ведь не спрашиваешь почему я хожу с теми девками, а не с теми. Зачем тебе какие-то причины? Научиться я хочу!
Что касается кода, то мне без разницы пришлешь ты мне его или нет, №1 или №3... В конце концов других попрошу. Умолять я никого не буду. Но если пришлешь, то буду благодарен.
← →
Ketmar (2002-11-09 15:02) [26]2Василий2:
а большая разница. код - МОЙ. и мне интересно, для чего он будет использован. если у вас реальная срочная задача - да. если просто баловство - обойдетесь как-нибудь. у другого попросите, как и предполагали. я понял - баловство. ну и вперед, балуйтесь дальше.
кстати, не мешало бы быть повежливей. это не я к вам пришел, прося взять у меня код, а вы ко мне, за помощью. вот и будьте столь любезны просить ВЕЖЛИВО. comprenez vous?
Satanas Nobiscum! 09-Nov-XXXVII A.S.
← →
Василий2 (2002-11-09 16:05) [27]2Ketmar:
Верно! Я пришел к вам за помощью, только вы помочь не хотите. Или не хотите или не знаете...
О каком баловстве вы говорите??? Внедрение DLL - баловство? Я знаю как внедрять с помощью ловушек, хочу попробовать с помощью потоков. В чем собственно проблема? Как вас еще просить - не понимаю.
← →
paul_shmakov (2002-11-09 16:53) [28]
//
// внедрение dll в чужой процесс с помощью CreateRemoteThread.
// работать будет только там, где эта самая CreateRemoteThread реализована,
// а это nt/w2k/xp
// использовать так:
// loader.exe идентификатор_процесса полный_путь_и_имя_dll
// paul_shmakov@mail.ru
//
program loader;
{$APPTYPE CONSOLE}
uses
Windows, Messages, SysUtils;
function SetDebugPriv: Boolean;
var
Token: THandle;
tkp: TTokenPrivileges;
begin
Result := false;
if OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
begin
if LookupPrivilegeValue(nil, PChar("SeDebugPrivilege"), tkp.Privileges[0].Luid) then
begin
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
Result := AdjustTokenPrivileges(Token, false, tkp, 0, PTokenPrivileges(nil)^, PDWord(nil)^);
end;
end;
end;
function Start(ProcessID: Cardinal; DllFileName: string): Boolean;
var
hProcess, hTh: THandle;
BytesWritten, ThreadID, DllNameLen: Cardinal;
LoadLibraryProc, MemPtr: Pointer;
ExitCode: DWord;
begin
Result := false;
//
// этот вызов нужен только для внедрения в системные процессы
// btw, нужны привилегии администратора
//
SetDebugPriv();
hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE,
true, ProcessID);
if hProcess <> 0 then
begin
DllNameLen := Length(DllFileName) + 1;
MemPtr := VirtualAllocEx(hProcess, nil, DllNameLen, MEM_COMMIT, PAGE_READWRITE);
if MemPtr <> nil then
begin
if WriteProcessMemory(hProcess, MemPtr, PChar(DllFileName), DllNameLen, BytesWritten) then
begin
LoadLibraryProc := GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
hTh := CreateRemoteThread(hProcess, nil, 0, LoadLibraryProc, MemPtr, 0, ThreadID);
if hTh <> 0 then
begin
if (WaitForSingleObject(hTh, INFINITE) = WAIT_OBJECT_0) and
GetExitCodeThread(hTh, ExitCode) then
Result := ExitCode <> 0;
CloseHandle(hTh);
end;
end;
VirtualFreeEx(hProcess, MemPtr, 0, MEM_RELEASE);
end;
CloseHandle(hProcess);
end;
end;
var
ProcessID: Cardinal;
DllName: string;
begin
if ParamCount < 2 then
begin
WriteLn("usage: loader.exe process_id dll_full_path_and_name");
Exit;
end;
ProcessID := StrToInt(ParamStr(1));
WriteLn("process id: " + IntToStr(ProcessID));
DllName := ParamStr(2);
WriteLn("dllname: " + DllName);
if ProcessID <> 0 then
begin
if Start(ProcessID, DllName) then
WriteLn("success")
else
WriteLn("fail");
end;
end.
← →
Ketmar (2002-11-09 17:00) [29]внедрение DLL - баловство. не вижу, для чего бы вы могли это применить. для обыкновенных задач (хотя какие, нафиг, обыкновенные задачи требуют внедрения своего кода в чужой процесс?!) хуков вполне хватает.
если вы учитесь ИЗ ЛЮБОПЫТСТВА - так читайте Рихтера, учите Си и переводите. всяко полезное дело. по дороге еще, возможно, что нибудь интересное узнаете. а если у вас срочная задача (шеф приказал, курсовик горит и ты ды) - тогда другой разговор. тогда я кинусь кодом, а потом уже растолкую, что неясно. потому как горит. поелику у вас не горит, значит - баловство. тон ваш мне не нравится, следовательно - не поделюсь.
зыж
и вообще - давайте сойдемся на том, что я не знаю и не умею этого делать.
Satanas Nobiscum! 09-Nov-XXXVII A.S.
← →
Василий2 (2002-11-09 17:08) [30]paul_shmakov: Спасибо!
← →
paul_shmakov (2002-11-09 17:16) [31]2 Ketmar:
" внедрение DLL - баловство..... хотя какие, нафиг, обыкновенные задачи требуют внедрения своего кода в чужой процесс?!"
ну не скажите, мне, например, необходимо расширять функциональность приложений (чужих, без исходников) для выполнения тех функций, которые в них изначально не были заложены. например, есть задача функционирования некоего приложения в условиях повышенной секретности. необходимо, например, чтобы все файлы, которые удаляет это приложение в процессе работы, удалялись без возможности восстановления, не с помощью обычной DeleteFile, как было заложено изначально разработчиками. и т.п.
при интеграции унаследованных систем с новым программным обеспечением тоже такие задачи часто появляются.
← →
Ketmar (2002-11-09 18:00) [32]2paul_shmakov:
а я и спрашивал, ЗАЧЕМ человеку знать. если "для интересу" - баловство. пусть сам ищет, большему научится. %-)
кстати, вот этот кусочек вызывает у меня сомнения:hTh := CreateRemoteThread(hProcess, nil, 0, LoadLibraryProc, MemPtr, 0, ThreadID);
после того, как LoadLibraryA-таки выполнилась, куда оно вернется? не есть ли более верно потом вызывать ExitThread? в хэлпе написано, что процедура потока "обычно не завершается" (имеется в виду, что не достигает финального end). на всех ли системах корректно предположить, что после завершения оной процедуры будет возврат в туда, куда ExitThread посылает?
и вот этот вот код (подправленный %-) часом не ваш? а то не помню, у кого спионерил %-)
var
PDOSHeader: PImageDosHeader;
PNTHeader: PImageNtHeaders;
PImportDesc: PImageImportDescriptor;
dwProtect: DWORD;
PThunk: PImageThunkData;
dwNewProtect: DWORD;
dwAddressToIntercept: DWORD;
WasProtected, Ok: Boolean;
begin
Result := False;
if IsBadReadPtr(Pointer(ModuleHandle), SizeOf(TImageNtHeaders)) then Exit;
// check for correct DOS header
PDOSHeader := PImageDosHeader(ModuleHandle);
if (PDOSHeader^.e_magic <> IMAGE_DOS_SIGNATURE) then Exit;
// check for correct PE header
PNTHeader := PImageNtHeaders(DWORD(PDOSHeader) + DWORD(PDOSHeader^._lfanew));
if (PNTHeader^.Signature <> IMAGE_NT_SIGNATURE) then Exit;
PImportDesc := PImageImportDescriptor(DWORD(ModuleHandle) +
DWORD(pNTHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
if (DWORD(PImportDesc) = DWORD(PNTHeader)) then Exit;
dwAddressToIntercept := DWORD(HookAddr);
while (PImportDesc^.Name <> 0) do
begin
PThunk := PImageThunkData(DWORD(ModuleHandle) + DWORD(PImportDesc^.FirstThunk));
while (PThunk^.ProcEntry <> nil) do
begin
if (DWORD(pThunk^.ProcEntry) = dwAddressToIntercept) then
begin
WasProtected := IsBadWritePtr(@pThunk^.ProcEntry, SizeOf(DWORD));
if WasProtected then
Ok := VirtualProtect(@PThunk^.ProcEntry, SizeOf(DWORD), PAGE_EXECUTE_READWRITE, dwProtect)
else
Ok := True;
if Ok then
begin
// WriteLn("!");
PThunk^.ProcEntry := OldProc;
Result := True;
end;
if Ok and WasProtected then
begin
dwNewProtect := dwProtect;
VirtualProtect(@pThunk^.ProcEntry, SizeOf(DWORD), dwNewProtect, dwProtect);
end;
end;
Inc(PChar(PThunk), SizeOf(TImageThunkData32));
end;
Inc(PChar(PImportDesc), SizeOf(TImageImportDescriptor));
end;
end;
Satanas Nobiscum! 09-Nov-XXXVII A.S.
← →
paul_shmakov (2002-11-09 18:37) [33]2 Ketmar:
"пусть сам ищет, большему научится. %-)"
вот это правильно, но если человек сам не хочет учиться - можно ему помочь готовым - ему же хуже в будущем ;)
"кстати, вот этот кусочек вызывает у меня сомнения: hTh := CreateRemoteThread(hProcess, nil, 0, LoadLibraryProc, MemPtr, 0, ThreadID);
после того, как LoadLibraryA-таки выполнилась, куда оно вернется? не есть ли более верно потом вызывать ExitThread? в хэлпе написано, что процедура потока "обычно не завершается" (имеется в виду, что не достигает финального end). на всех ли системах корректно предположить, что после завершения оной процедуры будет возврат в туда, куда ExitThread посылает?"
брр... не совсем понял вашу мысль - видать работы в праздники сказывается :)
поэтому изложу так, как я это все вижу. надеюсь отвечу :)
упрощенно последовательность такая:
1) объект ядра "поток" создается посредством вызова CreateThread или CreateRemoteThread. происходит некая инициализация вроде выделения стека, едыб вызовов dllmain с DLL_THREAD_ATTACH у загруженных dll и т.п.
2) начинает выполнятся функция в контексте этого потока, адрес которой был передан в Create(Remote)Thread.
3) как только происходит возврат из этой функции, вызывается ExitThread. т.е. условно код такой:
// действие происходит в далекой галактике, где-то глубоко внутри ядра windows....
void DeepInternalStartThread(...., LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, ....)
{
// .... bla-bla-bla
// .... bla-bla-bla
// .... bla-bla-bla
ExitThread(lpStartAddress(lpParameter));
}
4. все, потока уже почти нет. в процессе выполнения ExitThread выполняется какая-то деинициализация, вроде оповещения dll о DLL_THREAD_DETACH, удаление стека потока и т.д. объект ядра "поток" будет уничтожен когда закроются все ссылки на него.
исходя из этой примерной схемы никаких проблем не видно. да и нет их :)
код LoadLibrary выполняется, а когда она завершается - удаляется поток.
"на всех ли системах корректно предположить, что после завершения оной процедуры будет возврат в туда, куда ExitThread посылает?"
а ExitThread "никуда не посылает" :) поток - это же отдельная нить выполнения. она завершается вызовом ExitThread - соответственно, дальше уже никуда ничего переходить, возвращаться и посылать не будет, т.к. само выполнение кода прекращено.
"и вот этот вот код (подправленный %-) часом не ваш? а то не помню, у кого спионерил %-)"
:) может и мой. а что? на самом деле, авторство тут не так важно - можно даже сказать, что автор - microsoft, т.к. имея, определенную ms, структуру pe файла сложно написать этот код иначе - у всех он получается примерно одинаковый.
← →
paul_shmakov (2002-11-09 18:44) [34]кстати, CreateRemoteThread в win9x/me тоже реализована на самом деле. только она из kernel32.dll не экспортируется :( способ определения ее точки входа ну очень извращенский. а то было бы приятно...
это так, к слову :)
← →
Ketmar (2002-11-09 19:13) [35]я понял. вопрос просто криво сформулировал. вы-таки все ответили. пошел кастрировать Кассандру %-)
насчет CreateRemoteThread в Win9X: а как? что, руцями искать по сигнатурам и ты ды? впрочем, можно не отвечать, ибо вопрос - чистое баловство и любопытство %-) все равно нету у меня этих систем, дабы проверить.
насчет кода: просто я его из этого форума когда-то скопировал, и забыл, у кого (ну лень мне было писать, а тут как раз валяется %-). а вдруг автор обидится? %-))
и еще вопрос: можно ли предположить, что если я создаю процесс при помощи CreateProcess(blah-blah, CREATE_SUSPENDED, blah-blah), а потом делаю GetThreadContext, то в регистре EAX находится стартовый адрес процесса (т.е. корректно вычесленная EntryPoint из заголовка)? для моего Win2K Advanced Server это так, а для других систем? не знаете, часом?
Satanas Nobiscum! 09-Nov-XXXVII A.S.
← →
paul_shmakov (2002-11-10 13:36) [36]"насчет CreateRemoteThread в Win9X: а как? что, руцями искать по сигнатурам и ты ды? впрочем, можно не отвечать, ибо вопрос - чистое баловство и любопытство %-) все равно нету у меня этих систем, дабы проверить."
у меня тоже этих систем нет, поэтому эта возможность уже не очень актуальна для меня. но если есть интерес, то можно поизучать:
http://www.anticracking.sk/EliCZ/export/RT.ZIP
http://madshi.net
оба пакета достаточно легко дизассемблируются. да и код там не очень длинный.
"можно ли предположить, что если я создаю процесс при помощи CreateProcess(blah-blah, CREATE_SUSPENDED, blah-blah), а потом делаю GetThreadContext, то в регистре EAX находится стартовый адрес процесса (т.е. корректно вычесленная EntryPoint из заголовка)?"
честно говоря, не знаю. и проверить негде. в любом случае - можно entrypoint и самостоятельно получить.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2002.12.23;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.008 c