Introduction
Sometimes, we need to run code in another module, without having the source code such as Microsoft Word, Microsoft Excel or any other module. How can this be done? In such cases, what can you do if your manager asks you to change style dialog inside Microsoft Process.
Using the Code
First of all, we have to talk about kernel mode. Kernel mode means how you can have access inside any process in the system like kernel system process.
So to have this power, there are some undocumented functions inside coredll.dll like:
extern "C" {
BOOL SetKMode(BOOL fMode);
DWORD SetProcPermissions(DWORD);
LPVOID MapPtrToProcess (LPVOID lpv, HANDLE hProc);
DWORD PerformCallBack4(PCALLBACKINFO pcbi, ...); }
The first two functions give you access to the other process:
BOOL bMode = SetKMode(TRUE);
DWORD dwPerm = SetProcPermissions(0xFFFFFFFF);
Imagine yourself inside note.exe and that you want to load any DLL. You will surely call LoadLibrary(L”xxx.dll”)
;
But if you want to Load library but don't have the source code, you should use the performcallback
function:
HANDLE hProcess=GetProcessHandle(L"notes.exe");
CALLBACKINFO cbi;
cbi.hProc = hProcess;
cbi.pfn = (FARPROC)MapPtrToProcess(GetProcAddress
(GetModuleHandle(L"COREDLL"), L"LoadLibraryW"), hProcess);
cbi.pvArg0 = (LPVOID)MapPtrToProcess(L"\\windows\\mydll.dll", GetCurrentProcess());
HINSTANCE hInst = (HINSTANCE)PerformCallBack4(&cbi, 0,0,0);
The first statement is just to get a handle to a specific process. Now you can call the CallBack
function through sending handle and your DLL which you want to copy in Process Address space ….
Note: Sometimes PerformCallBack
does not work well. "Be careful."
To check if mydll.dll now attaches inside note.exe, go to remote process view.
Now your DLL attaches into note.exe, so my mission now is to subclass the edit control. To get a handle, I have to open note.exe and open RemoteSpy tools like this:
To get this handle programmatically:
HWND m_hWnd=::GetForegroundWindow();m_hWnd=::GetWindow(m_hWnd,GW_CHILD);m_hWnd=::GetWindow(m_hWnd,GW_CHILD);cbi.hProc = hProcess;
cbi.pfn = (FARPROC)MapPtrToProcess(GetProcAddress
(hInst, L"SubClassEdit"), hProcess);cbi.pvArg0 = m_hWnd;hInst = (HINSTANCE)PerformCallBack4(&cbi, 0,0,0);
If you are sure "note" its foreground window call GetForegroundWindow()
function, otherwise I recommend to use FindWindow(L"Worker","Note")
to obtain a window handle for more information about FindWindow
function.
Now you can jump to any specific control inside note.exe, in our case we need to go for "richink
" by using getwindow
function.
Don't forget you have to check if handle is correct before calling the callback function.
Let me talk about callback function parameters:
hProc
: Handle for specific Process, in our case we talk about note.exe
pFn
: The function inside this process, which we want to call
pvArg0
: Function argument, SubClassEdit
function takes handle m_hWnd
_declspec(dllexport) void SubClassEdit(HWND m_editHandle)
Look inside mydll.dll:
Now let us talk about mydll.dll. It is very simple. Just have one function to subclass like this:
__declspec(dllexport) void SubClassEdit(HWND m_editHandle)
{
g_pOldWndProc = (WNDPROC)GetWindowLong(m_editHandle, GWL_WNDPROC);
SetWindowLong(m_editHandle, GWL_WNDPROC, (LONG)EditTopmostProc);
}
LRESULT EditTopmostProc(HWND hWnd, UINT uMsgs, WPARAM wParam, LPARAM lParam)
{
if ( uMsgs == WM_KILLFOCUS ) {
GetWindowText(hWnd,buffer,1025);
MessageBox(hWnd,buffer,L"you saved",MB_OK);
return CallWindowProc(g_pOldWndProc, hWnd,
uMsgs, wParam, lParam); }
return CallWindowProc(g_pOldWndProc,
hWnd, uMsgs, wParam, lParam); }
In SubClass theory, you should take and save the old procedure handle to use it.
g_pOldWndProc = (WNDPROC)GetWindowLong(m_editHandle, GWL_WNDPROC);
g_pOldWndProc
now has the original pointer for richink
procedure.
Now you can set your procedure instead of the original one:
SetWindowLong(m_editHandle, GWL_WNDPROC, (LONG)EditTopmostProc);
In EditTopmostProc
, I want to replace WM_KILLFOCUS
, otherwise I will call the original one:
CallWindowProc(g_pOldWndProc, hWnd, uMsgs, wParam, lParam);
Sure you can replace any function...
... and click ok.
Points of Interest
In this sample, you can learn about subclassing. Subclassing is a technique that allows an application to intercept messages destined for another window. An application can augment, monitor, or modify the default behavior of a window by intercepting messages meant for another window. Subclassing is an effective way to change or extend the behavior of a window without redeveloping the window. Subclassing the default control window classes (button controls, edit controls, list controls, combo box controls, static controls, and scroll bar controls) is a convenient way to obtain the functionality of the control and to modify its behavior. For example, if a multiline edit control is included in a dialog box and the user presses the ENTER key, the dialog box closes. By subclassing the edit control, an application can have the edit control insert a carriage return and line feed into the text without exiting the dialog box. An edit control does not have to be developed specifically for the needs of the application.
You can also learn about PerformCallBack
which is a Microsoft technique to execute code inside another process.
How Does This Help Someone Else
This can be used if somebody wants a custom control inside an external process, like adding a right to left feature in some editable control.
History
- 25th July, 2009: Initial post