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(Re开发者_StackOverflow社区moteInfo.shf.pto, 'f:\1.jpg' + #0#0); RemoteInfo.shf.fFlags := FOF_ALLOWUNDO; RemoteInfo.shf.fAnyOperationsAborted := false; ....
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
.
精彩评论