Questions about DLL Injection
Questions about DLL Injection
Can I use MadCodeHook to inject a specified DLL into a desired process (for example, target.exe) and achieve the following goal:
Add menu item to the popupmenu of target process and implement onclick event?
Thank you very much.
Add menu item to the popupmenu of target process and implement onclick event?
Thank you very much.
-
- Posts: 380
- Joined: Sat Dec 11, 2004 2:11 am
- Location: San Francisco Bay Area, CA USA
- Contact:
Re: Questions about DLL Injection
Yes, you can. Call madCodeHook's InjectLibrary() to inject your DLL into the target process. Then in the DllMain() of your DLL, call the Windows API GetMenu(hwnd) where hwnd is the frame window of the target.exe.Pacino wrote:Can I use MadCodeHook to inject a specified DLL into a desired process (for example, target.exe) and achieve the following goal:
Add menu item to the popupmenu of target process and implement onclick event?
You can manipulate the menu bar from the returned HMENU.
Cheers,
David
Re: Questions about DLL Injection
Thanks for your quick answer, but how can I implement the onclick event for the new menu item? Should I hook WM_COMMAND message?dcsoft wrote:Yes, you can. Call madCodeHook's InjectLibrary() to inject your DLL into the target process. Then in the DllMain() of your DLL, call the Windows API GetMenu(hwnd) where hwnd is the frame window of the target.exe.Pacino wrote:Can I use MadCodeHook to inject a specified DLL into a desired process (for example, target.exe) and achieve the following goal:
Add menu item to the popupmenu of target process and implement onclick event?
You can manipulate the menu bar from the returned HMENU.
Cheers,
David
Well, I use SetWindowsHookEx to solve my problem now. There's still another problem. Can anyone help me? Thank you.
//Loader.exe
uses
madCodeHook
...
CreateProcessEx(nil, 'Target.exe', nil, nil, false, 0, nil, nil, si, pi,'Plugin.dll')
...
//plugin.dll
.....
procedure Hook(ThreadID:DWORD); stdcall;
begin
hNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance,ThreadID);
end;
procedure UnHook; stdcall;
begin
if hNextHook <> 0 then
UnhookWindowsHookEx(hNextHook);
end;
function DllMain(dwReason: DWord):boolean;
.....
case dwReason of
DLL_PROCESS_ATTACH:
begin
Hook(ProcID); //ProcID has been initialized
end;
DLL_PROCESS_DETACH:
begin
showMSG('UnHooked');
UnHook;
end;
...................
begin
hNextHook := 0;
DllProc:=@DllMain;
DllMain(DLL_PROCESS_ATTACH);
end.
When I run load.exe, something strange occured. It seems that plugin.dll is injected into explorer.exe and other processes that depend on explorer.exe (namely, has tray icon or minimized to tray), include target.exe. How to solve this tough probelm? I just want plugin.dll injected to my target.exe.
//bow&thanks
//Loader.exe
uses
madCodeHook
...
CreateProcessEx(nil, 'Target.exe', nil, nil, false, 0, nil, nil, si, pi,'Plugin.dll')
...
//plugin.dll
.....
procedure Hook(ThreadID:DWORD); stdcall;
begin
hNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance,ThreadID);
end;
procedure UnHook; stdcall;
begin
if hNextHook <> 0 then
UnhookWindowsHookEx(hNextHook);
end;
function DllMain(dwReason: DWord):boolean;
.....
case dwReason of
DLL_PROCESS_ATTACH:
begin
Hook(ProcID); //ProcID has been initialized
end;
DLL_PROCESS_DETACH:
begin
showMSG('UnHooked');
UnHook;
end;
...................
begin
hNextHook := 0;
DllProc:=@DllMain;
DllMain(DLL_PROCESS_ATTACH);
end.
When I run load.exe, something strange occured. It seems that plugin.dll is injected into explorer.exe and other processes that depend on explorer.exe (namely, has tray icon or minimized to tray), include target.exe. How to solve this tough probelm? I just want plugin.dll injected to my target.exe.
//bow&thanks
-
- Posts: 380
- Joined: Sat Dec 11, 2004 2:11 am
- Location: San Francisco Bay Area, CA USA
- Contact:
SetWindowsHookEx() is not really appropriate here. Since your dll is already in the target process, a much simpler way is to subclass the desired window. That involves callingPacino wrote:Well, I use SetWindowsHookEx to solve my problem now. There's still another problem. Can anyone help me? Thank you.
Code: Select all
SetWindowLong (hwnd, GWL_WNDPROC, (LONG) YourWndProc)
-- David
-
- Posts: 380
- Joined: Sat Dec 11, 2004 2:11 am
- Location: San Francisco Bay Area, CA USA
- Contact:
What is ThreadId? If set to 0, you are setting a systemwide hook so your dll would be injected into all other threads of the current desktop. Make sure ThreadId is the thread that created the hwnd you're interested in. To do this callPacino wrote:...Code: Select all
hNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance,ThreadID);
When I run load.exe, something strange occured. It seems that plugin.dll is injected into explorer.exe.
But as I said, using a windows hook is totally unnecessary if you're using madCodeHook.GetWindowThreadProcessId(hwnd)
-- David
Well, the desired window to hook is a child form. I can't get its handle until it's created by main form. Then how can I use SetWindowLong without the required hwnd?dcsoft wrote:SetWindowsHookEx() is not really appropriate here. Since your dll is already in the target process, a much simpler way is to subclass the desired window. That involves callingPacino wrote:Well, I use SetWindowsHookEx to solve my problem now. There's still another problem. Can anyone help me? Thank you.
so that YourWndProc gets called for every message sent to hwnd. There, you would handle the WM_COMMAND message generated by your inserted menu item.Code: Select all
SetWindowLong (hwnd, GWL_WNDPROC, (LONG) YourWndProc)
-- David
Thank you for your answerdcsoft wrote:What is ThreadId? If set to 0, you are setting a systemwide hook so your dll would be injected into all other threads of the current desktop. Make sure ThreadId is the thread that created the hwnd you're interested in. To do this callPacino wrote:...Code: Select all
hNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance,ThreadID);
When I run load.exe, something strange occured. It seems that plugin.dll is injected into explorer.exe.
But as I said, using a windows hook is totally unnecessary if you're using madCodeHook.GetWindowThreadProcessId(hwnd)
-- David
ThreadID refers to the Process ID of target.exe (misspelled as ThreadID, sorry). As follows:
Code: Select all
ProcID:=GetCurrentProcessId;
Hook(ProcID);
Maybe SetWindowsHookEx won't take affect in the same process?
-
- Posts: 380
- Joined: Sat Dec 11, 2004 2:11 am
- Location: San Francisco Bay Area, CA USA
- Contact:
Well, you need the hwnd first thing, or you won't even be able to modify its menu. Remember, you need to do a GetMenu(hwnd) to get the HMENU you want to modify.Pacino wrote:Well, the desired window to hook is a child form. I can't get its handle until it's created by main form. Then how can I use SetWindowLong without the required hwnd?
What I've done is to use an Active Accessibility hook (SetWinEventHook) to get notified when a new window is created. If it's one I'm interested in, that's when I InjectLibrary() into the process that created it, subclass the window, etc.
In your case, this is better than CreateProcessEx() since you don't need to be injected at process startup, it is better to wait until the desired window is created.
-- David
-
- Posts: 380
- Joined: Sat Dec 11, 2004 2:11 am
- Location: San Francisco Bay Area, CA USA
- Contact:
The last parameter to SetWindowsHookEx() needs to be a thread id. Windows belong to threads, so this specifies which thread's windows you will get called for. Don't use a process id, it makes no sense.Pacino wrote:...Code: Select all
hNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance,ThreadID);
ThreadID refers to the Process ID of target.exe (misspelled as ThreadID, sorry). As follows:Code: Select all
ProcID:=GetCurrentProcessId; Hook(ProcID);
-- David
dcsoft
I'm also interested in this a bit. I created a menu in another program (process other than my own) and I'd like to be able to add functionality to it. Any ideas on using SetWindowLong as you described? I dont really see the point of hooking because the dll is injected in the target process. SetWindowLong(0, GWL_WNDPROC .. or whatever confuses me because there seems to be many window procedures in windows sdk. Lets say I have menu in another program that I appended to it and a user clicks the 3rd item in the menu, how would I try and act on the click event?
any help would be grateful
any help would be grateful
subclass dll
Found this online but it doesn't seem to work but it compiles. Anyone know how to get this working as an example on notepad or something similar?
Code: Select all
library MSNHook;
uses
Windows,
Messages;
type
THookRec = record
hMSNHook: HHOOK;
hMSNWnd: HWND;
oldProc: Integer;
end;
var
map: DWord;
buf: ^THookRec;
// msn window proc - runs in context of ms messenger
function MSNWndProc(Handle: hWnd; Msg: uInt; wp: wParam; lp: lParam): LongInt; stdcall;
var
MiMenu, SysMenu, NewMenu : HMENU;
begin
try
case Msg of
WM_COMMAND:
begin
if (wp = $1000) then MessageBox(0, 'Item #1 Clicked', 'Extra IE', MB_OK);
if (wp = $1001) then MessageBox(0, 'Item #2 Clicked', 'Extra IE', MB_OK);
end;
WM_SYSCOMMAND:
begin
if (wp = $1002) then MessageBox(0, 'Extra MSN', 'Extra', MB_OK);
end;
WM_SHOWWINDOW:
begin
SetWindowText(Handle, 'Extra MSN');
NewMenu := CreatePopupMenu;
MiMenu := GetMenu(Handle);
AppendMenu(MiMenu, MF_POPUP, NewMenu, '&Extra Menu');
AppendMenu(NewMenu, MF_STRING, $1000, '&Item #1');
AppendMenu(NewMenu, MF_STRING, $1001, 'I&tem #2');
SysMenu := GetSystemMenu(Handle, False);
AppendMenu(SysMenu, MF_SEPARATOR, 0, '-');
AppendMenu(SysMenu, MF_STRING, $1002, '&Extra MSN');
end;
// user definied message to stop subclassing
WM_USER + 1:
begin
// delete custom menu entries (quick'n'dirty)
SetWindowLong(buf^.hMSNWnd, GWL_WNDPROC, buf^.oldProc);
DeleteMenu(GetMenu(Handle), GetMenuItemCount(GetMenu(Handle)) - 1, MF_BYPOSITION);
DrawMenuBar(GetMenu(Handle));
DeleteMenu(GetSystemMenu(Handle, False), GetMenuItemCount(GetMenu(Handle)) - 1, MF_BYPOSITION);
DeleteMenu(GetSystemMenu(Handle, False), GetMenuItemCount(GetMenu(Handle)) - 2, MF_BYPOSITION);
DrawMenuBar(GetMenu(Handle));
end;
end;
Result := CallWindowProc(Pointer(buf^.oldProc), Handle, Msg, wp, lp);
except
Result := 0;
MessageBox(0, 'error in MSNWndProc', 'error', MB_OK);
end;
end;
// hook proc - waits for msn window to be created
function MSNHookProc(nCode: Integer; wp: wParam; lp: lParam): LongInt; stdcall;
var
hTemp: hWnd;
szClass: array[0..255] of Char;
begin
try
if (nCode >= HC_ACTION) then
begin
Case nCode of
HCBT_CREATEWND:
begin
hTemp := HWND(wp);
FillChar(szClass, 256, 0);
GetClassName(hTemp, szClass, 256);
if (szClass = 'MSBLClass') then
begin
buf^.hMSNWnd := hTemp;
buf^.oldProc := GetWindowLong(buf^.hMSNWnd, GWL_WNDPROC);
SetWindowLong(buf^.hMSNWnd, GWL_WNDPROC, Integer(@MSNWndProc));
end;
end;
HCBT_DESTROYWND:
begin
hTemp := HWND(wp);
FillChar(szClass, 256, 0);
GetClassName(hTemp, szClass, 256);
if (szClass = 'MSBLClass') then
begin
SetWindowLong(buf^.hMSNWnd, GWL_WNDPROC, buf^.OldProc);
end;
end;
end;
end;
Result := CallNextHookEx(buf^.hMSNHook, nCode, wp, lp);
except
Result := 0;
MessageBox(0, 'error in MSNHookProc', 'error', MB_OK);
end;
end;
// sets up hook
function SetHook: Boolean; stdcall; export;
begin
try
Result := false;
if (not assigned(buf)) then
begin
map := CreateFileMapping(DWord(-1), nil, PAGE_READWRITE, 0, SizeOf(THookRec), 'HookRecMemBlock');
buf := MapViewOfFile(map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
buf^.hMSNHook := SetWindowsHookEx(WH_CBT, @MSNHookProc, hInstance, 0);
Result := true;
end;
except
Result := false;
MessageBox(0, 'error in SetHook', 'error', MB_OK);
end;
end;
// removes hook
function RemoveHook: Boolean; stdcall; export;
begin
Result := false;
if (assigned(buf)) then
begin
// tell our new msn wnd proc to stop subclassing
// (has to be done in context of msn)
SendMessage(buf^.hMSNWnd, wm_User + 1, 1, 0);
if (buf^.hMSNHook <> 0) then UnhookWindowsHookEx(buf^.hMSNHook);
buf^.hMSNHook := 0;
UnmapViewOfFile(buf);
buf := nil;
Result := true;
end;
end;
// DLL entry point
procedure DllEntry(dwReason: DWord);
begin
Case dwReason of
DLL_PROCESS_ATTACH:
begin
if (not assigned(buf)) then
begin
map := OpenFileMapping(FILE_MAP_ALL_ACCESS, false, 'HookRecMemBlock');
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;
exports
SetHook,
RemoveHook;
// main
begin
DisableThreadLibraryCalls(hInstance);
DllProc := @DLLEntry;
DllEntry(DLL_PROCESS_ATTACH);
end.
-
- Posts: 380
- Joined: Sat Dec 11, 2004 2:11 am
- Location: San Francisco Bay Area, CA USA
- Contact:
Re: dcsoft
The only thing you would use madCodeHook for is for DLL injection. Once your DLL is injected, you need to :Dracula wrote:I'm also interested in this a bit. I created a menu in another program (process other than my own) and I'd like to be able to add functionality to it. Any ideas on using SetWindowLong as you described? I dont really see the point of hooking because the dll is injected in the target process. SetWindowLong(0, GWL_WNDPROC .. or whatever confuses me because there seems to be many window procedures in windows sdk. Lets say I have menu in another program that I appended to it and a user clicks the 3rd item in the menu, how would I try and act on the click event?
any help would be grateful
HMENU hMenu = GetMenu(hwnd)
AppendMenu (hMenu), <your menu item>
Then you need to subclass hwnd so you can react to WM_COMMAND messages generated by <your menu item>
SetWindowLong (hwnd, GWL_WNDPROC, <your proc>)
Then you need to handle the WM_COMMAND message in <your proc>
Code: Select all
function YourProc(Handle: hWnd; Msg: uInt; wp: wParam; lp: lParam): LongInt; stdcall;
begin
try
case Msg of
WM_COMMAND:
begin
if (wp = <your menu item id>) then MessageBox(0, 'My appended Item Clicked', 'Extra IE', MB_OK);
David[/code]
dcsoft
i'll look at what you said to do, i started with this using vcl in my application.
seems to append fine but the popup is weird on mouse over event
Code: Select all
var
mnu: HMENU;
struct: TMENUITEMINFO;
mm: TMAINMENU;
itm: TMENUITEM;
h: hWnd;
Procedure MakeMenu();
const txt: pchar = 'test';
begin
mm := TMainMenu.Create(nil);
// itm := TMenuItem.Create(mm);
try
// itm.Caption := 'test';
// mm.Items.Add(itm);
h := FindWindow(nil, 'window_caption_of_target');
if ( h <> 0 ) then
mnu := GetMenu(h);
if ( mnu <> NULL ) then
begin
DrawMenuBar(h);
appendmenu(mnu, MF_STRING, mm.handle, txt);
DrawMenuBar(h);
end;
finally
end;
end;
..
Okay I'll mess with it when I get home from work today a bit more. I'm new to injecting dlls and window subclass stuff, sry i'm a noobie
Here's what i've been playing around with
Any additional help ontop of what dcsoft has helped me with would be swell as I'd like to see it done cuz it interests me
Thanks!
Here's what i've been playing around with
Code: Select all
library injct;
// nmnu = Handle to New Menu
// mnu = Handle to the Target Menu We're Appending
uses
messages, windows;
Function WndProc(Handle: hWnd; Msg: uInt; wp: wParam; lp: lParam): LRESULT; stdcall;
begin
case Msg of
WM_COMMAND:
begin
if (wp = $1000) then MessageBoxA(0, 'My appended Item Clicked', 'Extra', MB_OK);
if (wp = $1001) then MessageBoxA(0, 'My 2nd appended Item Clicked', 'Extra', MB_OK);
end;
end;
end;
Procedure MenuConstructor(); stdcall
var h: THandle;
mnu, nmnu: HMENU;
pid: cardinal;
begin
PID := GetCurrentProcessID();
h := Openprocess(PROCESS_ALL_ACCESS, bool(0), PID);
mnu := GetMenu(h);
nmnu := CreatePopupMenu();
AppendMenu(mnu, MF_POPUP, nmnu, '&Extra Menu');
AppendMenu(nmnu, MF_STRING, $1000, '&Item #1');
AppendMenu(nmnu, MF_STRING, $1001, 'I&tem #2');
DrawMenubar(h);
SetWindowLong(h, GWL_WNDPROC, LongInt(@WndProc));
DrawMenuBar(h);
end;
procedure DllEntry(dwReason: DWORD);
begin
Case dwReason of
DLL_PROCESS_ATTACH:
begin
end;
DLL_PROCESS_DETACH:
begin
end;
end;
end;
begin
DllProc := @DLLEntry;
DllEntry(DLL_PROCESS_ATTACH);
end.
Thanks!