-
Subclassing Problem
I have a small problem relating to window subclassing in a remote thread I was hoping someone could help me with.
What I'm trying to do is subclass en edit control of another process's window. I release that i cannot use SetWindowLong() unless the window im subclassing is in the current thread so I assume this wouldn't work.
But I have been playing around with windows hooks and was wondering - if I hook the remote program and then try to use SetWindowLong(), would that work ?
I'm basically unsure how to make my program/dll run in the right address space so that I can use SetWindowLong or some alternative to subclass the remote edit control.
Anyone have any ideas ?
Thanks in advance :) - Thunder
-
I think if you were to create the process you're trying to access programatically, defining your program as a debugger, that could allow you to do it. I haven't done that for a while and I'm not at home so I can't check my files, but it involves CreateProcess. Perhaps someone else could give you more information on how it works.
-
1. Create a DLL. The entry point contains the subclassing code. It will also have your window procedure.
2. Put the DLL in the same folder as the target EXE.
3. Use CreateRemoteThread() with the function LoadLibrary and your DLL name to force the target process to load your DLL.
4. Bingo.
It's worked for me before. Here's some code:
Code:
const std::string strMod = "easy.dll";
HWND hWnd = FindWindow(0,"Calculator");
DWORD dwProc;
GetWindowThreadProcessId(hWnd,&dwProc);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProc);
HMODULE hKern = GetModuleHandle("kernel32.dll");
WNDPROC lpfLoadLibraryA = reinterpret_cast<WNDPROC>
(GetProcAddress(hKern,"LoadLibraryA"));
LPVOID lpMemAddress = VirtualAllocEx(hProc,0,strMod.length() + 1,MEM_COMMIT,PAGE_READWRITE);
SIZE_T stBytesWritten;
WriteProcessMemory(hProc,lpMemAddress,(LPVOID)strMod.c_str(),
strMod.length() + 1,&stBytesWritten);
DWORD dwThreadID;
HANDLE hRemThread = CreateRemoteThread(hProc,0,0,reinterpret_cast<LPTHREAD_START_ROUTINE>(lpfLoadLibraryA),lpMemAddress,0,&dwThreadID);
WaitForSingleObject(hRemThread,INFINITE);
That's all chopped and changed, but you see the basic idea. You get the address of LoadLibraryA (the same for every process), place the DLL name (parameter of LoadLibraryA) in the target process, and call CreateRemoteThread() to force the target process to load the DLL. Then any code executed by your DLL is inside the target process. It's yours (provided you have correct access rights)!
-
Thanks for your reply Ben .... That's helped me a lot.
:)
-
It's my pleasure.
One thing to note is that the DLL entry point will run in the context of your remote thread, which will terminate pretty quickly. So, it's safer to subclass the window and place your code in your new window procedure, as the window procedure will run in the context of the initial thread. From the DLL entry point, PostMessage() a Register[ed]WindowMessage(), and that way you are assured that you will not interfere with your target application's message handling.