DLL注入

点击下载演示工程

DLL注入

unit Unit1;



interface



uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, TLHelp32, ComCtrls;



type

  TForm1 = class(TForm)

    Button1: TButton;

    ListView1: TListView;

    Button2: TButton;

    Button3: TButton;

    OpenDialog1: TOpenDialog;

    procedure Button1Click(Sender: TObject);

    procedure Button2Click(Sender: TObject);

    procedure Button3Click(Sender: TObject);

    procedure ListView1SelectItem(Sender: TObject; Item: TListItem;

      Selected: Boolean);

  private

    { Private declarations }

  public

    { Public declarations }

  end;



var

  Form1: TForm1;

  hProcess:THandle;

  Procedure GetProcess();

  function LoadLibraryA(lpLibFileName: PAnsiChar): HMODULE; stdcall;

  external kernel32 name 'LoadLibraryA';

implementation



{$R *.dfm}



procedure TForm1.Button1Click(Sender: TObject);begin

    GetProcess;

end;



Procedure GetProcess();

var

  hSnapshot:THandle;

  pe32:TProcessEntry32;

  item:TListItem;

  count:Integer;

begin

    count:=1;

    hSnapshot:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

    if hSnapshot=0 then begin

        Form1.Caption:='创建进程快照失败!';

        Abort();

    end else begin

        Form1.Caption:='创建进程快照成功!';

    end;

    pe32.dwSize:=SizeOf(PROCESSENTRY32);

    if not Process32First(hSnapshot,pe32) then begin

        Form1.Caption:='获取第'+IntToStr(count)+'个进程失败!';

    end else begin

        Form1.Caption:='获取第'+IntToStr(count)+'个进程成功!';

    end;

    Form1.ListView1.Clear;

    repeat

         count:=count+1;

         Form1.Caption:='获取第'+IntToStr(count)+'个进程成功!';

         item:=Form1.ListView1.Items.Add;

         item.Caption:=IntToStr(pe32.th32ProcessID);

         item.SubItems.Add(pe32.szExeFile);

         item.SubItems.Add(IntToStr(pe32.pcPriClassBase));

         item.SubItems.Add(IntToStr(pe32.th32ParentProcessID));

    until not Process32Next(hSnapshot,pe32);

    Form1.Caption:='成功获取'+IntToStr(count)+'个进程!';

end;



procedure TForm1.Button2Click(Sender: TObject);

begin

    ShowMessage('程序名称:DLL注入'+#13+

                '版本:1.0.0.0'+#13+

                '日期:2010-10-5'+#13+

                '作者:江湖一键客'+#13+

                '业务联系QQ:82530662');

end;



procedure TForm1.Button3Click(Sender: TObject);



var

    lpBaseAddress:Pointer;

    flProtect: DWORD;

    lNOBW: DWORD;

    fileName:String;

    len:Integer;

    wFlag:Bool;

    pLoadLibrary:FARPROC;

    lpThreadId:DWORD;

    hThread:THandle;

begin

    if OpenDialog1.Execute then begin

       fileName:=OpenDialog1.FileName;

       len:=Length(fileName)+1;

    end else begin

       Abort(); 

    end;

    lpBaseAddress:=VirtualAllocEx(hProcess,nil,Len,MEM_COMMIT,PAGE_READWRITE);

    if lpBaseAddress=nil then begin

       Form1.Caption:='分配虚拟内存失败!';

       Abort();

    end;

    Form1.Caption:='分配虚拟内存成功';

    wFlag:=WriteProcessMemory(hProcess,lpBaseAddress,pchar(@fileName[1]),len,lNOBW);

    if (not wFlag) and (lNOBW<>len) then begin

       Form1.Caption:='写入内存失败!';

       VirtualFreeEx(hProcess, lpBaseAddress,len,MEM_COMMIT);

       CloseHandle(hProcess);

       Abort();

    end;

    Form1.Caption:='写入内存成功!';

    pLoadLibrary:=GetProcAddress(GetModuleHandle('kernel32.dll'),'LoadLibraryA');

    if pLoadLibrary=nil then begin

       Form1.Caption:='获取输出库函数地址失败!';

       Abort();

    end;

    Form1.Caption:='获取输出库函数地址成功!';

    hThread:=CreateRemoteThread(hProcess,nil,0,pLoadLibrary,

                                lpBaseAddress,0,lpThreadId);

    if hThread=0 then begin

       Form1.Caption:='创建远程线程失败!';

    end;

    Form1.Caption:='创建远程线程成功!';

    WaitForSingleObject(hThread,INFINITE);

    VirtualFreeEx(hProcess, lpBaseAddress,len,MEM_COMMIT);

    CloseHandle(hThread);

    CloseHandle(hProcess);

end;



procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;

  Selected: Boolean);

var

    dwProcessId:DWORD;

begin

      dwProcessId:=StrToInt(Trim(item.Caption));

      hProcess:=OpenProcess(PROCESS_ALL_ACCESS ,False, dwProcessId);

      if hProcess=0 then begin

          Form1.Caption:='打开进程失败!';

          CloseHandle(hProcess);

          Abort();

      end;

      Form1.Caption:='打开进程成功!';

end;



end.

{下面是所用到的函数的详细说明:

{function VirtualAllocEx(hProcess: THandle; lpAddress: Pointer;
                      dwSize, flAllocationType: DWORD; flProtect: DWORD):
                      Pointer; stdcall;
{VirtualAllocEx 函数的作用是在指定进程的虚拟空间保留或提交内存区域,          
{               除非指定MEM_RESET参数,否则将该内存区域置0。                  
{参数说明:                                                                    
{hProcess: 申请内存所在的进程句柄。                                           
{lpAddress:保留页面的内存地址;一般用nil自动分配 。                           
{dwSize:欲分配的内存大小,字节单位;注意实际分 配的内存大小是页内存大小的整数倍
{flAllocationType:可取下面表1的值                                             
{flProtect:       可取下面表2的值                                             

{表1:}
{MEM_COMMIT:     为特定的页面区域分配内存中或磁盘的页面文件中的物理存储      
{MEM_PHYSICAL :  分配物理内存(仅用于地址窗口扩展内存)                      
{MEM_RESERVE:    保留进程的虚拟地址空间,而不分配任何物理存储。              
{                 保留页面可通过继续调用VirtualAlloc()而被占用              
{MEM_RESET :     指明在内存中由参数lpAddress和dwSize指定的数据无效           
{MEM_TOP_DOWN:   在尽可能高的地址上分配内存(Windows 98忽略此标志)          
{MEM_WRITE_WATCH:必须与MEM_RESERVE一起指定,使系统跟踪那些被写入             
{                 分配区域的页面(仅针对Windows 98)                          

{表2:}
{PAGE_READONLY: 该区域为只读。如果应用程序试图访问区域中的页的时候,     
{                将会被拒绝访问PAGE_READWRITE 区域可被应用程序读写       
{PAGE_EXECUTE:  区域包含可被系统执行的代码。试图读写该区域的操作将被拒绝。
{PAGE_EXECUTE_READ :     区域包含可执行代码,应用程序可以读该区域。      
{PAGE_EXECUTE_READWRITE: 区域包含可执行代码,应用程序可以读写该区域。    
{PAGE_GUARD: 区域第一次被访问时进入一个STATUS_GUARD_PAGE异常,           
{             这个标志要和其他保护标志合并使用,表明区域被第一次访问的权限
{PAGE_NOACCESS: 任何访问该区域的操作将被拒绝                           
{PAGE_NOCACHE:  RAM中的页映射到该区域时将不会被微处理器缓存(cached)      

{********************************优伤的分隔线******************************

{function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL;
dwProcessId: DWORD): THandle; stdcall;}
{OpenProcess 函数用来打开一个已存在的进程对象,并返回进程的句柄。
{参数说明:}
{dwDesiredAccess是访问进程的权限。见下面表3
{bInheritHandle 是句柄是否继承进程属性。  
{dwProcessId    是进程ID。              

{表3}
{PROCESS_ALL_ACCESS        所有能获得的权限                         
{PROCESS_CREATE_PROCESS    需要创建一个进程                         
{PROCESS_CREATE_THREAD     需要创建一个线程                         
{PROCESS_DUP_HANDLE        重复使用DuplicateHandle句柄              
{PROCESS_QUERY_INFORMATION 获得进程信息的权限,如它的退出代码、优先级
{PROCESS_QUERY_LIMITED_INFORMATION    获得某些信息的权限,如果获得了
{                                     PROCESS_QUERY_INFORMATION,   
{也拥有PROCESS_QUERY_LIMITED_INFORMATION权限                        
{PROCESS_SET_INFORMATION   设置某些信息的权限,如进程优先级69       
{PROCESS_SET_QUOTA         设置内存限制的权限,
                           使用SetProcessWorkingSetSize             
{PROCESS_SUSPEND_RESUME    暂停或恢复进程的权限                     
{PROCESS_TERMINATE         终止一个进程的权限,使用TerminateProcess 
{PROCESS_VM_OPERATION      操作进程内存空间的权限
                           (可用VirtualProtectEx和WriteProcessMemory)
{PROCESS_VM_READ           读取进程内存空间的权限,可使用ReadProcessMemory
{PROCESS_VM_WRITE          读取进程内存空间的权限,可使用WriteProcessMemory
{SYNCHRONIZE               等待进程终止                                   

{********************************性感的分隔线******************************

{function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle; 
{CreateToolhelp32Snapshot函数功能:函数为指定的进程、进程使用的堆[HEAP]、    
{模块[MODULE]、线程[THREAD])建立一个快照[snapshot]。                       
{参数1说明:dwFlags                                                          
{TH32CS_INHERIT        声明快照句柄是可继承的。                             
{TH32CS_SNAPALL        在快照中包含系统中所有的进程和线程。                 
{TH32CS_SNAPHEAPLIST   在快照中包含在th32ProcessID中指定的进程的所有的堆。  
{TH32CS_SNAPMODULE     在快照中包含在th32ProcessID中指定的进程的所有的模块。
{TH32CS_SNAPPROCESS    在快照中包含系统中所有的进程。                       
{TH32CS_SNAPTHREAD     在快照中包含系统中所有的线程。                       
{参数2说明:th32ProcessID                                                    
{指定将要快照的进程ID。如果该参数为0表示快照当前进程。该参数只有在设置了    
{TH32CS_SNAPHEAPLIST或者TH32CS_SNAPMODULE后才有效,在其他情况下该参数被忽略,
{所有的进程都会被快照。                                                     
{返回值:                                                                   
{调用成功,返回快照的句柄,调用失败,返回0。                                

{********************************优美的分隔线******************************

{PROCESSENTRY32结构}
{tagPROCESSENTRY32 = packed record
  dwSize: DWORD;              结构的大小
  cntUsage: DWORD;            此进程的引用计数
  th32ProcessID: DWORD;       进程ID
  th32DefaultHeapID: DWORD;   进程默认堆
  th32ModuleID: DWORD;        进程模块IDThis
  cntThreads: DWORD;          此进程开启的线程计数
  th32ParentProcessID: DWORD; 父进程的ID
  pcPriClassBase: Longint;    线程优先权
  dwFlags: DWORD;
  szExeFile: array[0..MAX_PATH - 1] of Char; 进程全名
end;

{********************************优美的分隔线******************************

{function Process32First(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL;
{Process32First 是一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()   
{获得当前运行进程的快照后,我们可以利用process32First函数来获得第一个进程的句柄
{参数1说明:hSnapshot                                                          
{CreateToolhelp32Snapshot获取进程快照的句柄                                   
{参数2说明:lppe                                                               
{TProcessEntry32创建的结构体                                                  
{返回值:                                                                     
{调用成功,返回True,调用失败,返回False。                                    

{********************************优美的分隔线******************************

{function Process32Next(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL; 
{Process32Next是一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()     
{获得当前运行进程的快照后,我们可以利用Process32Next函数来获得下一个进程的句柄 
{参数1说明:hSnapshot                                                          
{CreateToolhelp32Snapshot获取进程快照的句柄                                   
{参数2说明:lppe                                                               
{TProcessEntry32创建的结构体                                                  
{返回值:                                                                     
{调用成功,返回True,调用失败,返回False。                                    

{********************************优美的分隔线******************************

{function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer;
lpBuffer: Pointer;nSize:DWORD; var lpNumberOfBytesWritten: DWORD):BOOL;stdcall;
{WriteProcessMemory是一个写内存函数                                           
{参数说明:                                                                    
{hProcess:              进程的句柄                                            
{lpBaseAddress:         写入进程的位置(地址)                                
{lpBuffer:              数据当前存放地址                                      
{nSize:                 数据的长度                                            
{lpNumberOfBytesWritten:实际数据的长度                                        

{********************************优美的分隔线******************************

{function LoadLibrary(lpLibFileName: PChar): HMODULE; stdcall;                
{LoadLibrary函数载入指定的动态链接库,并将它映射到当前进程使用的地址空间。一旦
{载入,即可访问库内保存的资源。                                               
{参数说明:                                                                    
{lpLibFileName:指定要载入的动态链接库的名称。                                 
{返回值:                                                                      
{成功则返回库模块的句柄,零表示失败。                                         

{********************************优美的分隔线******************************

{function CreateRemoteThread(hProcess: THandle;
                            lpThreadAttributes: Pointer;
                            dwStackSize: DWORD;
                            lpStartAddress: TFNThreadStartRoutine;
                            lpParameter: Pointer;
                            dwCreationFlags: DWORD;
                            var lpThreadId: DWORD): THandle; stdcall;
{CreateRemoteThread函数在远程进程中创建线程                                        
{参数说明:                                                                         
{hProcess:进程句柄                                                                 
{lpThreadAttributes:线程安全描述字,指向SECURITY_ATTRIBUTES结构的指针              
{dwStackSize:线程栈大小,以字节表示                                                
{lpStartAddress:一个LPTHREAD_START_ROUTINE类型的指针,指向在远程进程中执行的函数地址}
{lpParameter:传入参数                                                              
{dwCreationFlags:创建线程的其它标志                                                
{lpThreadId:线程身份标志,如果为NULL,则不返回                                      
{返回值:                                                                           
{成功返回新线程句柄,失败返回nil。                                                 

{********************************优美的分隔线******************************

{function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD):
                              DWORD; stdcall;}
{WaitForSingleObject函数用来检测hHandle事件的信号状态,                        
{当函数的执行时间超过dwMilliseconds就返回,                                    
{但如果参数dwMilliseconds为INFINITE时函数将直到相应时间                        
{事件变成有信号状态才返回,否则就一直等待下去,                                
{直到WaitForSingleObject有返回值才执行后面的代码。                             
{参数说明:                                                                     
{hHandle:同步对象的句柄                                                        
{dwMilliseconds:超时间隔,单位为毫秒,为INFINITE时超时是无限的                   

{********************************优美的分隔线******************************

{function GetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
{GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。                
{参数说明:                                                                      
{hModule:DLL模块句柄                                                            
{lpProcName:函数名                                                              
{返回值:                                                                        
{如果函数调用成功,返回值是DLL中的输出函数地址。 如果函数调用失败,返回值是nil  

{********************************优美的分隔线******************************

{function GetModuleHandle(lpModuleName: PChar): HMODULE; stdcall;             
{GetModuleHandle函数获取一个应用程序或动态链接库的模块句柄                    
{参数说明:                                                                    
{lpModuleName:模块名,这通常是与模块的文件名相同的一个名字                    
{返回值:                                                                      
{如执行成功成功,则返回模块句柄                                               

你可能感兴趣的:(dll)