在Delphi中利用CreateRemoteThread远程注入例子

小小滴缘分

小小滴缘分

2016-02-19 19:32

下面图老师小编要跟大家分享在Delphi中利用CreateRemoteThread远程注入例子,简单的过程中其实暗藏玄机,还是要细心学习,喜欢还请记得收藏哦!

  花了一个下午翻了MSDN,写了这个例子,为了安全,我用Delphi建了个什么也没有作的程序prjzzhost.exe,将它用作被注入的宿主进程.
  写了一个TestDll.Dll,里面只有一个Log函数,用来在文件Test.Txt中输出信息.最重要的一个程序project1.exe是用来注入的.
  测试环境: windows server 2003 + delphi 7.0
  程序很简单,高手就不用看了.废话不说了,看代码吧!
  
  测试用的TestDll.Dll源代码(它将被注入到prjzzhost.exe中去):
  

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/) 程序代码
  library TestDll;
  
  uses
    SysUtils,
    System,
    windows,
    Classes;
  
    procedure Log( s : PChar);stdcall;
    var
      F : TextFile;
    begin
      assignfile(f,'Test.txt');
      if fileexists('Test.txt') then append(f)
      else rewrite(f);
      writeln(f,s);
      closefile(f);
    end;
  
    procedure DllEntryPoint(dwReason:DWord);
    begin
        case dwReason of
        DLL_PROCESS_ATTACH:
          Log('dll process Attach');
        DLL_PROCESS_DETACH:
        Log('dll process Detach');
        DLL_THREAD_ATTACH:
          Log('dll thread Attach');
        DLL_THREAD_DETACH:
          Log('dll thread Detach');
        end;
  
    end;
  
    exports
      Log;
  
  begin
    DllProc := @DllEntryPoint;
    DllEntryPoint(DLL_PROCESS_ATTACH);
  end.
  

  
  
  
  被注入的宿主进程prjzzhost.exe(它什么也没有作,好无辜哦:),这里就不给出代码了,因为太简单了,哈哈.
  
  
  最后,最重要的来了:
  project1.exe的源代码:
  

程序代码
  unit Unit1;
  
  interface
  
  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls,tlhelp32;
  
  type
  
    TLog = procedure(s : PChar);stdcall;
    TServiceMain = procedure(argc : Integer; VAR argv : pchar);stdcall;
  
    EDLLLoadError = class(Exception);
  
    TForm1 = class(TForm)
      Button3: TButton;
      procedure Button3Click(Sender: TObject);
    private
      { Private declarations }
    public
      { Public declarations }
    end;
  
  
  var
    Form1: TForm1;
  
  implementation
  
  {$R *.dfm}
  
  { 列举进程 }
  procedure GetMyProcessID(const AFilename: string; const PathMatch: Boolean; var ProcessID: DWORD);
  var
    lppe: TProcessEntry32;
    SsHandle: Thandle;
    FoundAProc, FoundOK: boolean;
  begin
    ProcessID :=0;
    { 创建系统快照 }
    SsHandle := CreateToolHelp32SnapShot(TH32CS_SnapProcess, 0);
  
    { 取得快照中的第一个进程 }
    { 一定要设置结构的大小,否则将返回False }
    lppe.dwSize := sizeof(TProcessEntry32);
    FoundAProc := Process32First(Sshandle, lppe);
    while FoundAProc do
    begin
      { 进行匹配 }
      if PathMatch then
        FoundOK := AnsiStricomp(lppe.szExefile, PChar(AFilename)) = 0
      else
        FoundOK := AnsiStricomp(PChar(ExtractFilename(lppe.szExefile)), PChar(ExtractFilename(AFilename))) = 0;
      if FoundOK then
      begin
        ProcessID := lppe.th32ProcessID;
        break;
      end;
      { 未找到,继续下一个进程 }
      FoundAProc := Process32Next(SsHandle, lppe);
    end;
    CloseHandle(SsHandle);
  end;
  
  
  { 设置权限 }
  function EnabledDebugPrivilege(const Enabled : Boolean) : Boolean;
  var
    hTk : THandle; { 打开令牌句柄 }
    rtnTemp : Dword; { 调整权限时返回的值 }
    TokenPri : TOKEN_PRIVILEGES;
  const
    SE_DEBUG = 'SeDebugPrivilege'; { 查询值 }
  begin
    Result := False;
    { 获取进程令牌句柄,设置权限 }
    if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,hTk)) then
    begin
      TokenPri.PrivilegeCount := 1;
      { 获取Luid值 }
      LookupPrivilegeValue(nil,SE_DEBUG,TokenPri.Privileges[0].Luid);
  
      if Enabled then
        TokenPri.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
      else
        TokenPri.Privileges[0].Attributes := 0;
  
      rtnTemp := 0;
      { 设置新的权限 }
      AdjustTokenPrivileges(hTk,False,TokenPri,sizeof(TokenPri),nil,rtnTemp);
  
      Result := GetLastError = ERROR_SUCCESS;
      CloseHandle(hTk);
  
    end;
  end;
  
  
  { 调试函数 }
  procedure OutPutText(var CH:PChar);
  var
    FileHandle: TextFile;
  Begin
    AssignFile(FileHandle,'zztest.txt');
    Append(FileHandle);
    Writeln(FileHandle,CH);
    Flush(FileHandle);
    CloseFile(FileHandle);
  END;
  
  { 注入远程进程 }
  function InjectTo(const Host, Guest: string; const PID: DWORD = 0): DWORD;
  var
    { 被注入的进程句柄,进程ID}
    hRemoteProcess: THandle;
    dwRemoteProcessId: DWORD;
  
    { 写入远程进程的内容大小 }
    memSize: DWORD;
  
    { 写入到远程进程后的地址 }
    pszLibFileRemote: Pointer;
  
    iReturnCode: Boolean;
    TempVar: DWORD;
  
    { 指向函数LoadLibraryW的地址 }
    pfnStartAddr: TFNThreadStartRoutine;
  
    { dll全路径,需要写到远程进程的内存中去 }
    pszLibAFilename: PwideChar;
  begin
    Result := 0;
    { 设置权限 }
    EnabledDebugPrivilege(True);
  
    { 为注入的dll文件路径分配内存大小,由于为WideChar,故要乘2 }
    Getmem(pszLibAFilename, Length(Guest) * 2 + 1);
    StringToWideChar(Guest, pszLibAFilename, Length(Guest) * 2 + 1);
  
    { 获取进程ID }
    if PID  0 then
       dwRemoteProcessID := PID
    else
       GetMyProcessID(Host, False, dwRemoteProcessID);
  
    { 取得远程进程句柄,具有写入权限}
    hRemoteProcess := OpenProcess(PROCESS_CREATE_THREAD + {允许远程创建线程}
        PROCESS_VM_OPERATION + {允许远程VM操作}
        PROCESS_VM_WRITE, {允许远程VM写}
        FALSE, dwRemoteProcessId);
  
    { 用函数VirtualAllocex在远程进程分配空间,并用WriteProcessMemory中写入dll路径 }
    memSize := (1 + lstrlenW(pszLibAFilename)) * sizeof(WCHAR);
    pszLibFileRemote := PWIDESTRING(VirtualAllocEx(hRemoteProcess, nil, memSize, MEM_COMMIT, PAGE_READWRITE));
    TempVar := 0;
    iReturnCode := WriteProcessMemory(hRemoteProcess, pszLibFileRemote, pszLibAFilename, memSize, TempVar);
  
    if iReturnCode then
    begin
      pfnStartAddr := GetProcAddress(GetModuleHandle('Kernel32'), 'LoadLibraryW');
      TempVar := 0;
      { 在远程进程中启动dll }
      Result := CreateRemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, TempVar);
    end;
  
    { 释放内存空间 }
    Freemem(pszLibAFilename);
  end;
  
    { 测试 }
  procedure TForm1.Button3Click(Sender: TObject);
  begin
  
    InjectTo('prjzzhost.exe', extractfilepath(paramstr(0))+'TestDll.dll');
  end;
  
  end.
  

  
  
  
  代码中并没有考虑dll被载入后的善后处理,请不要使用系统进程进行测试,以免发生意外.
  

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)
展开更多 50%)
分享

猜你喜欢

在Delphi中利用CreateRemoteThread远程注入例子

编程语言 网络编程
在Delphi中利用CreateRemoteThread远程注入例子

在delphi7中利用mscomm控件编程

编程语言 网络编程
在delphi7中利用mscomm控件编程

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

在PHP中利用XML技术构造远程服务(1)

Web开发
在PHP中利用XML技术构造远程服务(1)

在PHP中利用XML技术构造远程服务(2)

Web开发
在PHP中利用XML技术构造远程服务(2)

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

在PHP中利用XML技术构造远程服务(上)

PHP
在PHP中利用XML技术构造远程服务(上)

在PHP中利用XML技术构造远程服务(下)

PHP
在PHP中利用XML技术构造远程服务(下)

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

QQ窗体自动隐藏效果探究

QQ窗体自动隐藏效果探究

使用JMail组件代替Sql Mail发送Email 遇到的问题

使用JMail组件代替Sql Mail发送Email 遇到的问题
下拉加载更多内容 ↓