Frozt
asked on
SubClassing Extern Program
Hello, how can i subclass a program like Microsft internet explorer to get its messages.
which steps i have to follow, if u have already a example for this, could you share it with me.
thank you for your time
which steps i have to follow, if u have already a example for this, could you share it with me.
thank you for your time
Because you can not access the memory space in another process, you can not Subclass, another apps windows. Also I have tried several different methods and memory access routines in several different "HOOK DLLs" to subclass another apps windows, but I got alot of access violations and never did subclass anything.
ASKER
Hi DaFox
i did a dll witch exports 2 procedures:
- SetGlobalHook
- UnSetGlobalHook
procedure SetGlobalHook;
begin
if (hHook = 0) then
hHook := SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, 0);
end;
procedure UnSetGlobalHook;
begin
if (hHook <> 0) then begin
SetWindowLong(Handle, GWL_WNDPROC, OldProc);
UnHookWindowsHookEx(MiHook );
end;
end;
CBTProc is my callback funtion, there i get OldProc calling
OldProc := SetWindowLong(Handle, GWL_WNDPROC, Integer(@NewProc));
when i call UnSetGlobalHook, Handle is 0 and OldProc is also 0.
why is that ? :(, i cant restore OldProc
thank you
i did a dll witch exports 2 procedures:
- SetGlobalHook
- UnSetGlobalHook
procedure SetGlobalHook;
begin
if (hHook = 0) then
hHook := SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, 0);
end;
procedure UnSetGlobalHook;
begin
if (hHook <> 0) then begin
SetWindowLong(Handle, GWL_WNDPROC, OldProc);
UnHookWindowsHookEx(MiHook
end;
end;
CBTProc is my callback funtion, there i get OldProc calling
OldProc := SetWindowLong(Handle, GWL_WNDPROC, Integer(@NewProc));
when i call UnSetGlobalHook, Handle is 0 and OldProc is also 0.
why is that ? :(, i cant restore OldProc
thank you
Hi Frozt!
That's because there's a copy of your dll in every process. But the variables (Handle, OldProc) are only initialized in the your application's process.
Try the following (IPC aka Inter Process Communication):
type
THookRec = packed record
hookHandle : DWord;
oldProc: Pointer;
end;
var
map : dword;
buf : ^THookRec;
bIsDone: Boolean = false;
...
function TrayHookProc(nCode: Integer; wp: wParam; lp: lParam): LongInt; stdcall;
begin
if (nCode >= HC_ACTION) and (not bIsDone) then
begin
bIsDone := true;
SetWindowLong(Handle, GWL_WNDPROC, OldProc);
end;
Result := CallNextHookEx(buf^.Hook, nCode, wp, lp);
end;
procedure SetGlobalHook;
begin
if (hHook = 0) then
begin
map := CreateFileMapping(DWord(-1 ), nil, PAGE_READWRITE, 0, SizeOf(THookRec), 'stift123');
buf := MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
buf^.hHook := SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, 0);
end;
end;
procedure UnSetGlobalHook;
begin
if (buf^.hHook <> 0) then
begin
UnHookWindowsHookEx(buf^.h Hook);
buf^.hHook := 0;
UnmapViewOfFile(buf);
buf := nil;
end;
end;
...
procedure DllEntry(dwReason: DWord);
begin
Case dwReason of
DLL_PROCESS_ATTACH:
begin
map := OpenFileMapping(FILE_MAP_A LL_ACCESS, false, 'stift123');
buf := MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
CloseHandle(map);
map := 0;
end;
end;
DLL_PROCESS_DETACH:
begin
UnmapViewOfFile(buf);
buf := nil;
end;
end;
end;
btw:
1. you don't have to use a system wide hook.
try:
hWnd := FindWindow('somewndclass', nil);
dwThreadId := GetWindowThreadProcessId(h Wnd, nil);
buf^.hHook := SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, dwThreadID);
because you just have to get into the context of your desired process!
2. What are you trying to do with 'Handle' in SetWindowLong()?
Try to call FindWindow to get the hWnd of your external window and take it into the buf.
Regards,
Markus
That's because there's a copy of your dll in every process. But the variables (Handle, OldProc) are only initialized in the your application's process.
Try the following (IPC aka Inter Process Communication):
type
THookRec = packed record
hookHandle : DWord;
oldProc: Pointer;
end;
var
map : dword;
buf : ^THookRec;
bIsDone: Boolean = false;
...
function TrayHookProc(nCode: Integer; wp: wParam; lp: lParam): LongInt; stdcall;
begin
if (nCode >= HC_ACTION) and (not bIsDone) then
begin
bIsDone := true;
SetWindowLong(Handle, GWL_WNDPROC, OldProc);
end;
Result := CallNextHookEx(buf^.Hook, nCode, wp, lp);
end;
procedure SetGlobalHook;
begin
if (hHook = 0) then
begin
map := CreateFileMapping(DWord(-1
buf := MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
buf^.hHook := SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, 0);
end;
end;
procedure UnSetGlobalHook;
begin
if (buf^.hHook <> 0) then
begin
UnHookWindowsHookEx(buf^.h
buf^.hHook := 0;
UnmapViewOfFile(buf);
buf := nil;
end;
end;
...
procedure DllEntry(dwReason: DWord);
begin
Case dwReason of
DLL_PROCESS_ATTACH:
begin
map := OpenFileMapping(FILE_MAP_A
buf := MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
CloseHandle(map);
map := 0;
end;
end;
DLL_PROCESS_DETACH:
begin
UnmapViewOfFile(buf);
buf := nil;
end;
end;
end;
btw:
1. you don't have to use a system wide hook.
try:
hWnd := FindWindow('somewndclass',
dwThreadId := GetWindowThreadProcessId(h
buf^.hHook := SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, dwThreadID);
because you just have to get into the context of your desired process!
2. What are you trying to do with 'Handle' in SetWindowLong()?
Try to call FindWindow to get the hWnd of your external window and take it into the buf.
Regards,
Markus
ASKER
Hi DaFox
i am trying to add an extra menu to Internet Expplorer and when i click in it do something.
i am using SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, 0);
WH_CBT is to get when a window is created o destroyed so i can add the new menu.
so i have this:
function CBTProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
szClass: array[0..256] of Char;
begin
if (nCode < 0) then begin
Result := CallNextHookEx(hHook, nCode, wParam, lParam);
Exit;
end;
if (nCode = HCBT_CREATEWND) then begin //Window Created
hProc := wParam;
FillChar(szClass, 256, 0);
GetClassName(hProc, szClass, 256);
if (szClass = 'IEFrame') then begin // it's IE
hIE := hProc;
OldProc := SetWindowLong(hIE, GWL_WNDPROC, Integer(@IEProc)); //try to subclass
end;
end else if (nCode = HCBT_DESTROYWND) then begin //window destroyed
hProc := wParam;
FillChar(szClass, 256, 0);
GetClassName(hProc, szClass, 256);
if (szClass = 'IEFrame') then begin
hIE := hProc;
SetWindowLong(hIE, GWL_WNDPROC, OldProc);
end; //try to set OldProc back
end;
Result := CallNextHookEx(hHook, nCode, wParam, lParam);
end;
but i guess i'm wrong :(, is ok to hook with WH_CBT ? :s
thank you for your time
i am trying to add an extra menu to Internet Expplorer and when i click in it do something.
i am using SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, 0);
WH_CBT is to get when a window is created o destroyed so i can add the new menu.
so i have this:
function CBTProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
szClass: array[0..256] of Char;
begin
if (nCode < 0) then begin
Result := CallNextHookEx(hHook, nCode, wParam, lParam);
Exit;
end;
if (nCode = HCBT_CREATEWND) then begin //Window Created
hProc := wParam;
FillChar(szClass, 256, 0);
GetClassName(hProc, szClass, 256);
if (szClass = 'IEFrame') then begin // it's IE
hIE := hProc;
OldProc := SetWindowLong(hIE, GWL_WNDPROC, Integer(@IEProc)); //try to subclass
end;
end else if (nCode = HCBT_DESTROYWND) then begin //window destroyed
hProc := wParam;
FillChar(szClass, 256, 0);
GetClassName(hProc, szClass, 256);
if (szClass = 'IEFrame') then begin
hIE := hProc;
SetWindowLong(hIE, GWL_WNDPROC, OldProc);
end; //try to set OldProc back
end;
Result := CallNextHookEx(hHook, nCode, wParam, lParam);
end;
but i guess i'm wrong :(, is ok to hook with WH_CBT ? :s
thank you for your time
Madshi has a greatsimple-to-use component for injecting a dll into a process. It will run on any windows Os (incl xp). You can find it at http://help.madshi.net/madKernel.htm
Here's an example:
To inject a module (dll) into the destination process you can use the method "LoadModule". If you set "autoClose" to "true", the module is unloaded again as soon as the resulting IModule instance is freed. If you don't want that, please set "autoClose" to "false".
function IProcess.LoadModule (fileName : string;
autoClose : boolean = true;
withoutReferences : boolean = false;
onlyAsDataFile : boolean = false;
alteredSearchPath : boolean = false;
timeOut : integer = 3000 ) : IModule;
// Example:
Process('explorer.exe').Lo adModule(' hookExpl.d ll', false);
Here's an example:
To inject a module (dll) into the destination process you can use the method "LoadModule". If you set "autoClose" to "true", the module is unloaded again as soon as the resulting IModule instance is freed. If you don't want that, please set "autoClose" to "false".
function IProcess.LoadModule (fileName : string;
autoClose : boolean = true;
withoutReferences : boolean = false;
onlyAsDataFile : boolean = false;
alteredSearchPath : boolean = false;
timeOut : integer = 3000 ) : IModule;
// Example:
Process('explorer.exe').Lo
Hi Frozt!
Yep, that should be okay.
If you're familiar with C take a look at this little sample: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=3087&lngWId=3
Regards,
Markus
Yep, that should be okay.
If you're familiar with C take a look at this little sample: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=3087&lngWId=3
Regards,
Markus
ASKER
Hello DaFox
I looked that C++ example, and when i try to set back the OldProc, it show me that both variables are 0. so its the same problem i had before.
so i try with the Mapping thing, and i'm doing good (i think)
and when i try to set the oldproc, the window chashes when i click in it :s
how do i give points ?, im new to this forum
thank you
I looked that C++ example, and when i try to set back the OldProc, it show me that both variables are 0. so its the same problem i had before.
so i try with the Mapping thing, and i'm doing good (i think)
and when i try to set the oldproc, the window chashes when i click in it :s
how do i give points ?, im new to this forum
thank you
Hi Frozt!
> it show me that both variables are 0
Are you shure that you are using buf^.oldProc and buf^.hookHandle within the whole dll?
> so i try with the Mapping thing, and i'm doing good (i think)
Good! That's the beginning of your succes ;)
> and when i try to set the oldproc, the window chashes when i click in it :s
Hm, maybe oldProc is not initialized. try to use buf^.oldProc
>how do i give points ?
Click "accept answer" button next to the comment that helped you most. After that you have to give a grade. That's all...
Regards,
Markus
> it show me that both variables are 0
Are you shure that you are using buf^.oldProc and buf^.hookHandle within the whole dll?
> so i try with the Mapping thing, and i'm doing good (i think)
Good! That's the beginning of your succes ;)
> and when i try to set the oldproc, the window chashes when i click in it :s
Hm, maybe oldProc is not initialized. try to use buf^.oldProc
>how do i give points ?
Click "accept answer" button next to the comment that helped you most. After that you have to give a grade. That's all...
Regards,
Markus
ASKER
Hi DaFox
yes i'm trying with the buf^.OldProc, then i set it back, and when i click on the window, it crashes :(
what could be wrong ?
if u want i can send you my dll source.
thanks
yes i'm trying with the buf^.OldProc, then i set it back, and when i click on the window, it crashes :(
what could be wrong ?
if u want i can send you my dll source.
thanks
Yep, you can.
Unfortunately, I don't know how long it will take it until I can take a look at it... :/
Markus
PS: You can find my e-mail address in my profile.
Unfortunately, I don't know how long it will take it until I can take a look at it... :/
Markus
PS: You can find my e-mail address in my profile.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank You Man
Take a look at the functions GetWindowLong(), SetWindowLong to subclass an external application.
Be aware that you have to inject your code (DLL) into the context of this/these external app(s). Normally you achieve this with a hook (SetWindowsHookEx())...
There are some good tutorials on the web.
Ask if you need more information.
Regards,
Markus