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

发布于 2024-09-08 21:58:26 字数 1667 浏览 7 评论 0原文

我想使用代码注入来调用 SHFileOperation 。我的代码在调用 simple 时工作正常 类似于 user32.dll 中的 MessageBox 的功能,但在从 shell32.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;
                      ....

I want to call SHFileOperation using code injection. My code works fine while calling simple
functions like MessageBox from user32.dll, but won't while calling ShFileOperation from shell32.dll.

I'll post the part of the code that I think has the problem. I know the problem is in the struct implementation.

Here is the image of RemoteInfo value:

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;
                      ....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晌融 2024-09-15 21:58:26

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

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

在程序的整个过程中,您将使用 CreateRemoteThread 三次。第一次是注入对 LoadLibrary 的调用,以将 DLL 放入目标进程的地址空间。第二次是调用注入的函数,第三次是在完成后调用 FreeLibrary。棘手的部分是在目标进程中找到注入函数的地址。 Alexey Kurakin 关于 Code Project 的文章 演示了如何为此,您可以在自己的进程中查找该函数的相对地址,并将该偏移量应用到远程进程以确定要传递给第二次调用 CreateRemoteThread 的参数>。

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

The immediate problem in this code is that you're storing pointers to the string parameters in your record. Those pointers are addresses in your main process; they are not valid in the target process. You should store those values in fixed-size arrays in your record, just like you're already doing with the module and function names. Then initialize the pointer fields inside the remote function.

But you're really making it more complicated than it needs to be. You don't need to use GetProcAddress in the remote function at all. Put you entire function in a DLL. There you can call whatever functions you want, and the Delphi linker and the OS loader will ensure that they're all available to call at run time. You also don't need to allocate all your variables with VirtualAllocEx; you can use ordinary local variables in your DLL function.

You'll use CreateRemoteThread three times over the course of your program. The first time is to inject a call to LoadLibrary to get your DLL into the target process's address space. The second time is to invoke your injected function, and the third time is to call FreeLibrary after you're finished. The tricky part is finding the address of your injected function in the target process. Alexey Kurakin's article on Code Project demonstrates how to do that by finding the relative address of the function in your own process, and the applying that offset to the remote process to determine the argument to pass to your second call to CreateRemoteThread.

Finally, there's no need to declare the support records for ShFileOperation yourself. Delphi already declares them for you in the ShellAPI unit. There you'll also find the named constants for the various flags you need, like fo_Copy instead of $0002.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文