Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Внедрение DLL


Автор: a.S.d 14.3.2005, 01:51
Я внедряю длл в чужой процесс. В длл код, который должен отсылать почту. Но почему-то ничего не отсылается(если сделать просто приложение, то отсылка работает).
Вот код, внедряющий длл:
Код
 
dll:='c:\testlib.dll'; 
pid:=GetIDProcess('IEXPLORE.exe'); //процедура GetIDProcess 
//описана ранее 
Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID); 
param:=VirtualAllocEx(Process, nil, 40960, MEM_COMMIT, PAGE_READWRITE); 
WriteProcessMemory(Process, param, pointer(dll), 4096, byt); 
CreateRemoteThread(Process, nil, 0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'LoadLibraryA'), Param, 0, ThreadId); 

Сама длл:
Код
 
library testlib; 
uses 
  Windows, 
  Messages, 
  sysutils, 
  system, 
  registry,idsmtp,IdMessage; 
 
var 
mes:tidmessage; 
smtp:tidsmtp; 
procedure MailSend; 
begin 
 smtp:=TIdSMTP.Create(nil); 
 mes:=TIdMessage.Create(smtp); 
 smtp.Host := 'smtp.xxx.ru'; 
 smtp.Port := 25; 
 mes.From.Text := 'xxx@xxx.ru'; 
 mes.Recipients.EMailAddresses := 'xxx@xxx.ru'; 
 mes.Subject := 'XXX'; 
 mes.Body.Text :='YYYYYYYYYYY '; 
 smtp.Connect(100000); 
 smtp.Send(mes); 
 smtp.Disconnect; 
 mes.Free; smtp.Free; 
end; 
begin 
mailsend; 
end. 

В чём тут дело?


Автор: a.S.d 14.3.2005, 02:13
Причём запарывается на smtp.Connect(100000); почему-то.

Автор: a.S.d 15.3.2005, 00:18
Как выяспилось в библиотеке не работает всё, что связано с сетью, даже просто соединение сокетов, не зависимо от того какой процесс её подгружает. Как сделать чтоб отправка работала?

Автор: oleg1973 15.3.2005, 01:22
я вообще удевляюсь как оно у тебя работает
фактически ты просто впихиваеш длл в процесс,даже не как длл а как просто кусок кода, без учета специфики загоузки РЕ файлов в винде,
тамже нада импорты заполнить да и секции раскидать по своим местам





Автор: p0s0l 15.3.2005, 01:58
Цитата(oleg1973 @ 15.3.2005, 01:22)
я вообще удевляюсь как оно у тебя работает
фактически ты просто впихиваеш длл в процесс,даже не как длл а как просто кусок кода, без учета специфики загоузки РЕ файлов в винде,
тамже нада импорты заполнить да и секции раскидать по своим местам

Дык вроде у него судя по коду всё-таки DLL подгружается к чужому процессу... CreateRemoteThread "вызывает" LoadLibrary ('c:\testlib.dll')... А в DLL при подключении делаются свои дела...
Delphi нормально должна компилить DLL, с импортами и секциями...

Или ты про что ?...

Автор: RA 15.3.2005, 06:18
А причём тут внедрение? smile

проблема там где ты пытаешься отправить почту, тот код отправки сам посебе вобще работоспобен?

и что за smtp.Connect(100000); ?
у моих индейцев такого вообще нет, просто smtp.Connect;
(может у меня старая версия индейцев)
Добавлено @ 06:21
Кстати есть такаой компонент CTRLSOCK (не VCL) специально для таких целей.

http://tothpaul.free.fr/zip/CRTSOCK.ZIP

Автор: a.S.d 15.3.2005, 09:28
RAdmin
Код работоспособен, я же написал что если сделать приложение а не библиотеку, то всё работает.

Автор: RA 15.3.2005, 10:15
a.S.d Ладно тогда покажи полный код того как ты внедряешь DLL.

Автор: oleg1973 15.3.2005, 11:26
Код

CreateRemoteThread(Process, nil, 0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'LoadLibraryA'), Param, 0, ThreadId); 

вся фигня в том что после этого куска что происходит?
выполнив LoadLibrary треад заканчивает свою работу и соответственно автоматом выгружается либа

я думаю тут косяк

Автор: RA 15.3.2005, 11:35
Знач, после этого куска нужно вставить WaitForSingleObject(Thread,INFINITE);

Автор: Girder 15.3.2005, 13:00
Цитата(oleg1973 @ 15.3.2005, 11:26)
я думаю тут косяк
smile

Цитата(RAdmin @ 15.3.2005, 11:35)
Знач, после этого куска нужно вставить WaitForSingleObject(Thread,INFINITE);
smile

Код

 dll:='e:\testlib.dll'+#0;
 pid:=...
 Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
 param:=VirtualAllocEx(Process, nil, Length(dll), MEM_COMMIT, PAGE_READWRITE);
 WriteProcessMemory(Process, param, PChar(dll), Length(dll), byt);
 oTheread:=CreateRemoteThread(Process, nil, 0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'LoadLibraryA'), Param, 0, ThreadId);
 ...


Код
library testlib;

uses
  Windows, idsmtp, IdMessage;


{$R *.res}

var mes:tidmessage;
    smtp:tidsmtp;
procedure MailSend;
begin
 smtp:=TIdSMTP.Create(nil);
 mes:=TIdMessage.Create(nil);
 smtp.Host := 'smtp.XXX.XX';    
 smtp.Port := 25;
 smtp.Password:='Мой пароль';
 smtp.Username:='Мой логин';
 smtp.AuthenticationType:=atLogin; //Типо по паролю и все такое
 smtp.HeloName:='Info';
 mes.From.Text := 'XXX@From.XX';
 mes.Sender.Text:='XXX@From.XX';
 mes.Recipients.EMailAddresses:='XXX@Recipient.XX';
 mes.Subject := 'Gbvier';
 mes.Body.Text :='YYYYYYYYYYY';
 mes.MessageParts.Clear;
 try
  smtp.Connect;
  smtp.Send(mes);
 except
 end;
 smtp.Disconnect;
 mes.Free;
 smtp.Free;
end;

begin
 mailsend; 
end.


PS: Если не хочеш по паролю и все такое... то береш нужный тебе домен к примеру newmail.ru и через DNS определяеш Mail сервера (IdDNSResolver.QueryRecords:=[qtMX]) для данного адресса и пытаешся послать письмо через полученные Mail сервера(в ентом случаи smtp.AuthenticationType:=atNone).

Автор: RA 15.3.2005, 13:27
Я просто имел в виду это:

Код


uses
  Windows, TLHelp32, SysUtils;

VAR
  PID     : DWORD;
  Process : DWORD;


function GetProcessID(PeFile:STRING) : Integer;
VAR
  hProcSnap : THandle;
  pe32      : TProcessEntry32;
BEGIN
  Result:=-1;
  hProcSnap:=CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS,0);
  IF hProcSnap=INVALID_HANDLE_VALUE THEN Exit;
  pe32.dwSize:=SizeOf(ProcessEntry32);
  IF Process32First(hProcSnap,pe32)=True THEN
  WHILE Process32Next(hProcSnap,pe32)=True DO IF Pos(PeFile,UpperCase(pe32.szExeFile))>0 THEN Result:=pe32.th32ProcessID;
end;

function InjectLibrary(Process:LongWord;DLLPath:pChar) : Boolean;
VAR
  BytesWritten : DWORD;
  Thread       : DWORD;
  ThreadID     : DWORD;
  Parameters   : Pointer;
BEGIN
  Result:=False;
  Parameters:=VirtualAllocEx(Process,NIL,4096,MEM_COMMIT,PAGE_READWRITE);
  IF Parameters=NIL THEN Exit;
  WriteProcessMemory(Process,Parameters,Pointer(DLLPath),4096,BytesWritten);
  Thread:=CreateRemoteThread(Process,NIL,0,GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'LoadLibraryA'),Parameters,0,ThreadId);
  WaitForSingleObject(Thread,INFINITE);
  VirtualFreeEx(Process,Parameters,0,MEM_RELEASE);
  IF Thread=0 THEN Exit;
  CloseHandle(Thread);
  Result:=True;
end;

  PID:=GetProcessID('HL.EXE');
  Process:=OpenProcess(PROCESS_ALL_ACCESS,False,PID);
  InjectLibrary(Process,'C:\cd.dll');


Автор: Girder 15.3.2005, 15:41
Цитата(RAdmin @ 15.3.2005, 13:27)
Я просто имел в виду это:
Можно... конечно(Но ожидание все таки... лишние - нам же результат не нужен).

PS: a.S.d не забудь выгружать библиотеку smile

Автор: a.S.d 15.3.2005, 16:54
Всем спасибо, всё работает, проблема была здесь:
Код

try    
smtp.Connect;    
smtp.Send(mes);    
except    
end;

Автор: a.S.d 16.3.2005, 21:49
Ещё вопрос: почему приложение, которое подгружает библиотеку, всё время виснет, ведь библиотека работает независимо от приложения? Как этого избежать?
Girder
А как её выгружать? Надо опять писать в память процесса процедуру выгрузки?

Автор: Girder 17.3.2005, 02:42
Цитата(a @ 16.3.2005, 21:49)
Как этого избежать?
Для начала надо код показать. (У меня мой пример... работал на ура)

Цитата(a @ 16.3.2005, 21:49)
А как её выгружать?
FreeLibraryAndExitThread

Автор: p0s0l 17.3.2005, 10:47
Цитата
FreeLibraryAndExitThread
ИМХО, это не совсем удобно, т.к. надо передавать 2 параметра, в данном случае удобнее сделать просто FreeLibrary (1 параметр), а поток и так сразу же после FreeLibrary завершится... smile
Код
// hModule - адрес загруженной DLL...
CreateRemoteThread(Process, nil, 0, GetProcAddress(GetModuleHandle('KERNEL32.DLL'), 'FreeLibrary'), Pointer(hModule), 0, ThreadId);


Автор: Girder 17.3.2005, 12:43
Цитата(p0s0l @ 17.3.2005, 10:47)
т.к. надо передавать 2 параметра,
Ничего дополнительного передавать не надо smile

Главное помнить енто:
Цитата
The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in subsequent calls to the GetModuleFileName function and other functions that require a module handle.

Т.o:
Код
...
begin
 mailsend;
 FreeLibraryAndExitThread(HInstance,0);
end.

PS: Можеш в меня камнем... бросить - если я ошибаюсь smile

Автор: p0s0l 17.3.2005, 12:49
А ну ты так... а я про другое подумал smile (в смысле вопрос через одно место понял smile )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)