在远程线程中,如何调用参数包含指针的函数?

时间:2010-07-10 13:59:15

标签: delphi code-injection dll-injection

我想使用代码注入来调用SHFileOperation。调用简单时,我的代码工作正常 来自MessageBox的{​​{1}}等功能,但在user32.dll调用ShFileOperation时则不会。

我会发布我认为存在问题的部分代码。我知道问题出在结构实现中。

这是RemoteInfo值的图像:

http://www.freeimagehosting.net/uploads/219d79fc30.jpg

//Structure
type
  LPSHFILEOPSTRUCT = ^SHFILEOPSTRUCT;
  SHFILEOPSTRUCT = packed record
    Wnd: HWND;
    wFunc: UINT;
    pFrom: PAnsiChar;
    pTo: PAnsiChar;
    fFlags: FILEOP_FLAGS;
    fAnyOperationsAborted: BOOL;
    hNameMappings: Pointer;
    lpszProgressTitle: PAnsiChar;
  end;

//Remote Info
type
  TRemoteInfo = record
    LoadLibrary: function(lpLibFileName: PChar): HMODULE; stdcall;
    GetProcAddress: function(hModule: HMODULE;
      lpProcName: LPCSTR): FARPROC; stdcall;
    shf: SHFILEOPSTRUCT; ;
    Kernel32: array[0..20] of Char;
    shell32: array[0..20] of Char;
    SHFileOperationA: array[0..20] of Char;
    Fromlpbuff: array[0..20] of char; //Source path
    Tolpbuff: array[0..20] of Char;   //Des Path
  end;

//Initialize                      
                      ....
ZeroMemory(@RemoteInfo, SizeOf(RemoteInfo));
  RemoteInfo.shf.Wnd := 0;
  RemoteInfo.shf.wFunc := FO_COPY;
  RemoteInfo.shf.pFrom := @remoteInfo.Fromlpbuff;
  RemoteInfo.shf.pto := @remoteInfo.tolpbuff;
  lstrcpy(RemoteInfo.shf.pFrom, 'e:\1.jpg' + #0#0);
  lstrcpy(RemoteInfo.shf.pto, 'f:\1.jpg' + #0#0);
  RemoteInfo.shf.fFlags := FOF_ALLOWUNDO;
  RemoteInfo.shf.fAnyOperationsAborted := false;
                      ....

1 个答案:

答案 0 :(得分:2)

此代码中的直接问题是您存储指向记录中字符串参数的指针。这些指针是 main 进程中的地址;它们在目标进程中无效。您应该将这些值存储在记录中的固定大小数组中,就像您已经使用模块和函数名称一样。然后初始化远程函数内的指针字段。

但是你真的让它变得比它需要的更复杂。您根本不需要在远程功能中使用GetProcAddress。将整个函数放入DLL中。在那里你可以调用你想要的任何函数,Delphi链接器和OS加载器将确保它们在运行时都可以调用。您也不需要使用VirtualAllocEx分配所有变量;你可以在你的DLL函数中使用普通的局部变量。

在整个程序过程中,您将使用CreateRemoteThread三次。第一次是对LoadLibrary进行调用,以使您的DLL进入目标进程的地址空间。第二次是调用注入的函数,第三次是在完成后调用FreeLibrary。棘手的部分是在目标进程中找到注入函数的地址。 Alexey Kurakin's article on Code Project演示了如何通过在您自己的进程中查找函数的 relative 地址,以及将该偏移量应用于远程进程以确定传递给第二次调用的参数来实现此目的。 CreateRemoteThread

最后,没有必要自己声明ShFileOperation的支持记录。 Delphi已经在 ShellAPI 单元中为您声明了它们。在那里,您还可以找到所需的各种标志的命名常量,例如fo_Copy而不是$0002