I tried Dll Injection on windows 8.1 P.E., works fine with explicitly installed applications but it doesn't work with notepad, calc or internet explorer. My idea is that from windows xp onwards it is not supported like this way but didn't find any help over internet.
here's my code:
#include <windows.h>
#include "resource.h"
#include "..\HookInjEx_DLL\HookInjEx_DLL.h"
//-----------------------------------------------
// global variables & forward declarations
//
HWND hStart,hndl2,hndl3,hndl4,hndl5; // handle to start buttoN
BOOL CALLBACK MainDlgProc (HWND,UINT,WPARAM,LPARAM);
//-----------------------------------------------
// WinMain
//
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// For Notepad --------------------------------------------------------------
hStart = FindWindow(NULL,"Untitled - Notepad");
hndl2 = FindWindowExA(hStart,NULL,"Edit",NULL);
// ---------------------------------------------------------------------------
::DialogBoxParam (hInstance, MAKEINTRESOURCE (IDD_WININFO), NULL, MainDlgProc, NULL);
return 0;
}
//-----------------------------------------------
// MainDlgProc
// Notice: dialog procedure
//
BOOL CALLBACK MainDlgProc (HWND hDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam ) // second message parameter
{
static int bChecked = false;
switch (uMsg) {
case WM_INITDIALOG:
::SetTimer( hDlg, 101, 300, NULL );
return true;
// if running more instances of HookInjEx,
// keep their interface consistent
case WM_TIMER:
bChecked = (IsDlgButtonChecked( hDlg, IDC_BUTTON ) == BST_CHECKED);
if( g_bSubclassed && !bChecked) {
::CheckDlgButton( hDlg, IDC_BUTTON, BST_CHECKED );
// ::SetDlgItemText( hDlg, IDC_BUTTON, "Unmap Dll" );
}
else if (!g_bSubclassed && bChecked) {
::CheckDlgButton( hDlg, IDC_BUTTON, BST_UNCHECKED );
::SetDlgItemText( hDlg, IDC_BUTTON, "Inject Dll" );
}
break;
case WM_COMMAND:
if( !g_bSubclassed) {
InjectDll( hndl2 );
}
else {
if( !g_bSubclassed )
::SetDlgItemText( hDlg, IDC_BUTTON, "Inject Dll" );
}
break;
case WM_CLOSE:
if( g_bSubclassed )
::EndDialog (hDlg, 0);
break;
}
return false;
}
Here's my code for DLL:
#include <windows.h>
#include "HookInjEx_DLL.h"
//-------------------------------
#include <stdio.h>
#include <wchar.h>
#include <Windows.h>
#include <Exdisp.h>
//This imports the shell extionsions
//we disable warnings of multiple defines
#pragma warning(disable: 4192)
#pragma warning(disable: 4146)
#import <mshtml.tlb>
#import <shdocvw.dll>
//-------------------------------
//-------------------------------------------------------------
// shared data
// Notice: seen by both: the instance of "HookInjEx.dll" mapped
// into "explorer.exe" as well as by the instance
// of "HookInjEx.dll" mapped into our "HookInjEx.exe"
#pragma data_seg (".shared")
int g_bSubclassed = 0; // START button subclassed?
UINT WM_HOOKEX = 0;
HWND g_hWnd = 0; // handle of START button
HHOOK g_hHook = 0;
#pragma data_seg ()
#pragma comment(linker,"/SECTION:.shared,RWS")
//-------------------------------------------------------------
// global variables (unshared!)
//
HINSTANCE hDll;
// New & old window procedure of the subclassed START button
WNDPROC OldProc = NULL;
LRESULT CALLBACK NewProc( HWND,UINT,WPARAM,LPARAM );
//--------------------------------------------------
// DllMain
//
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if( ul_reason_for_call == DLL_PROCESS_ATTACH )
{
hDll = (HINSTANCE) hModule;
::DisableThreadLibraryCalls( hDll );
if( WM_HOOKEX==NULL )
WM_HOOKEX = ::RegisterWindowMessage( "WM_HOOKEX_RK" );
}
return TRUE;
}
#define pCW ((CWPSTRUCT*)lParam)
LRESULT HookProc (
int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam // keystroke-message information
)
{
if( (pCW->message == WM_HOOKEX) && pCW->lParam )
{
::UnhookWindowsHookEx( g_hHook );
if( g_bSubclassed )
goto END; // already subclassed?
// Let's increase the reference count of the DLL (via LoadLibrary),
// so it's NOT unmapped once the hook is removed;
char lib_name[MAX_PATH];
::GetModuleFileName( hDll, lib_name, MAX_PATH );
if( !::LoadLibrary( lib_name ) )
goto END;
// Subclass START button
OldProc = (WNDPROC)
::SetWindowLong( g_hWnd, GWL_WNDPROC, (long)NewProc );
if( OldProc==NULL ) // failed?
::FreeLibrary( hDll );
else { // success -> leave "HookInjEx.dll"
::MessageBeep(MB_OK); // mapped into "explorer.exe"
g_bSubclassed = true;
}
}
else if( pCW->message == WM_HOOKEX )
{
::UnhookWindowsHookEx( g_hHook );
// Failed to restore old window procedure? => Don't unmap the
// DLL either. Why? Because then "explorer.exe" would call our
// "unmapped" NewProc and crash!!
if( !SetWindowLong( g_hWnd, GWL_WNDPROC, (long)OldProc ) )
goto END;
::FreeLibrary( hDll );
::MessageBeep(MB_OK);
g_bSubclassed = false;
}
END:
return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}
LRESULT CALLBACK NewProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch (uMsg)
{
case WM_LBUTTONDOWN:
MessageBox(NULL,"HI","",MB_OK);
break;
}
return CallWindowProc( OldProc,hwnd,uMsg,wParam,lParam );
}
int InjectDll( HWND hWnd )
{
g_hWnd = hWnd;
// Hook "explorer.exe"
g_hHook = SetWindowsHookEx( WH_CALLWNDPROC,(HOOKPROC)HookProc,
hDll, GetWindowThreadProcessId(hWnd,NULL) );
if( g_hHook==NULL )
return 0;
// By the time SendMessage returns,
// the START button has already been subclassed
SendMessage( hWnd,WM_HOOKEX,0,1 );
return g_bSubclassed;
}