【问题标题】:DLL Injection and Access ViolationDLL 注入和访问冲突
【发布时间】:2013-08-21 22:48:52
【问题描述】:

我有一个简单的 DLL,我将其注入到记事本中,仅用于测试目的。 我的注射器代码是这样的:

uses
  Windows;

var
  BytesWritten:  cardinal;
  PID, Process, Thread, ThreadId, hKernel: dword;
  pLoadLibrary, Paramaters: pointer;
    DLL: AnsiString;

    begin
      DLL := 'C:\test.dll'; // Must be full path name.
      PID := 3160;
      Process := OpenProcess(PROCESS_ALL_ACCESS,
                             False,
                             PID);

      Paramaters := VirtualAllocEx(Process,
                                 nil,
                                   Length(DLL),
                                   MEM_COMMIT,
                                 PAGE_EXECUTE_READWRITE);

      WriteProcessMemory(Process,
                         Paramaters,
                         PAnsiChar(DLL),
                         Length(DLL),
                         BytesWritten);

      hKernel := GetModuleHandle('KERNEL32.DLL');

      pLoadLibrary := GetProcAddress(hKernel,
                                     'LoadLibraryA');

      Thread := CreateRemoteThread(Process,
                                   nil,
                                   0,
                                   pLoadLibrary,
                                   Paramaters,
                                   0,
                                   ThreadId);

      WaitForSingleObject(Thread, INFINITE);

      VirtualFreeEx(Process,
                    Paramaters,
                    0,
                    MEM_RELEASE);

      CloseHandle(Thread);
      CloseHandle(Process);
end.

我的 DLL 代码很简单:

uses
  SysUtils,
  Classes,
  Windows;

{$R *.res}


procedure EntryPoint(Reason: dword); stdcall;
begin
  if Reason = DLL_PROCESS_ATTACH then
  begin
    MessageBox(0, 'DLL Injected', 'DLL Injected', 0);
  end;
end;


begin
  DLLProc:= @EntryPoint;
  EntryPoint(DLL_PROCESS_ATTACH);
end.

当我在记事本进程中注入 dll 时,我得到 MessageBox 说 DLL Injected,但几秒钟后它崩溃说: 在 00FFE102 的模块 test.dll 中出现异常 EAccessViolation。 地址 00FFF102 的访问冲突。写入地址 00FFF102。 我使用的是 Delphi 2010,Windows 7 x64,管理员权限,没有 UAC,记事本和 dll 都是 x32...

【问题讨论】:

  • 您没有为LoadLibrary 调用的“lpFileName”参数的空终止符分配空间。这对问题没有帮助,只是说..
  • @Sertac 原来是调用约定不匹配和 @ 操作符对隐藏问题的过程变量的另一种情况

标签: delphi dll dll-injection


【解决方案1】:

您的 EntryPoint 函数声明不正确。它不应该使用 stdcall。正确的声明是:

procedure EntryPoint(Reason: Integer);

在 RTL 源代码中检查 TDLLProc 的声明,或参考documentation,以确认这是准确的。

如果您在分配给 DLLProc 时没有使用 @ 运算符,编译器将能够告诉您这一点。

正如 Sertac 所说,您还应该在写入目标进程的文件名中包含一个空终止符。

【讨论】:

  • 我用一个测试用例验证了这是原因。并不是说我认为它不会造成麻烦,而是几秒钟后发生的崩溃(显示对话框后)似乎很奇怪。然而它是如何失败的,也许 WER 正在占用它的时间。 +1,很有洞察力..我上下读了几遍代码但没有注意到..
  • 是的,它现在正在工作,即使没有为空终止符添加 +1。无论如何,我稍后会添加它,看看它是如何工作的......谢谢你们,非常有帮助!
  • 你会碰巧侥幸逃脱,因为整个页面都会被映射。但是您肯定应该添加空终止符。还不如做对!
猜你喜欢
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多