Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.12.23;
Скачать: CL | DM;

Вниз

Вот вопросик для мастеров!   Найти похожие ветки 

 
Василий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) [18]



 
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 вся ветка

Текущий архив: 2002.12.23;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.012 c
1-74724
Separator
2002-12-12 08:16
2002.12.23
Простое число


3-74606
Evladar
2002-12-05 10:38
2002.12.23
Circular DataLinks are not allowed


1-74777
Zorro
2002-12-11 11:09
2002.12.23
Win.ini - СРОЧНО!!


14-74966
PVOzerski
2002-12-02 21:37
2002.12.23
Что-то у меня с домашним компом всё-таки не то...


14-74893
AK-74
2002-12-04 13:23
2002.12.23
Говорящие программы