?
BOOL InjectDLL( STARTUPINFO *lpSi, PROCESS_INFORMATION *lpPi )
{
PSTR pszLibFileRemote;
PSTR pszLibFile = "inject.dll";
int nSize;
PTHREAD_START_ROUTINE pfnThreadRtn;
HANDLE hRemoteThread;
// allocate memory in target process' address space
nSize = lstrlen(pszLibFile) + 1;
pszLibFileRemote = (PSTR) VirtualAllocEx( lpPi->hProcess, NULL, nSize,
MEM_COMMIT, PAGE_READWRITE );
if( pszLibFileRemote == NULL ) {
MessageBox( NULL, "VirtualAllocEx failed", "Error", MB_ICONERROR );
CloseHandle( lpPi->hProcess );
CloseHandle( lpPi->hThread );
return FALSE;
}
// copy DLL name into address space of target process
if( !WriteProcessMemory( lpPi->hProcess, pszLibFileRemote, pszLibFile, nSize, NULL ) ) {
MessageBox( NULL, "WriteProcessMemory failed", "Error", MB_ICONERROR );
VirtualFreeEx( lpPi->hProcess, pszLibFileRemote, 0, MEM_RELEASE );
CloseHandle( lpPi->hProcess );
CloseHandle( lpPi->hThread );
return FALSE;
}
// figure out real address of LoadLibraryA.
// this assumes Kernel32.dll has the same base address in every process
// which is true for all current versions of windows.
pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress( GetModuleHandle("Kernel32"),
"LoadLibraryA" );
if( pfnThreadRtn == NULL ) {
MessageBox( NULL, "GetProcAddress failed", "Error", MB_ICONERROR );
VirtualFreeEx( lpPi->hProcess, pszLibFileRemote, 0, MEM_RELEASE );
CloseHandle( lpPi->hProcess );
CloseHandle( lpPi->hThread );
return FALSE;
}
// create the remote thread
// this triggers a DLL_PROCESS_ATTACH message in the injected dll
hRemoteThread = CreateRemoteThread( lpPi->hProcess, NULL, 0, pfnThreadRtn,
pszLibFileRemote, 0, NULL );
if( hRemoteThread == NULL ) {
MessageBox( NULL, "CreateRemoteThread failed", "Error", MB_ICONERROR );
VirtualFreeEx( lpPi->hProcess, pszLibFileRemote, 0, MEM_RELEASE );
CloseHandle( lpPi->hProcess );
CloseHandle( lpPi->hThread );
return FALSE;
}
// wait for remote thread to finish
WaitForSingleObject( hRemoteThread, INFINITE );
// free allocated memory
if( pszLibFileRemote != NULL )
VirtualFreeEx( lpPi->hProcess, pszLibFileRemote, 0, MEM_RELEASE );
CloseHandle( lpPi->hProcess );
CloseHandle( lpPi->hThread );
// DLL has been injected
return TRUE;
}
...
ZeroMemory( &pi, sizeof(pi) );
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
CreateProcess( GetUOExePath(), NULL, NULL, NULL,
FALSE, 0, NULL, GetUODir(), &si, &pi );
// wait until all windows have been created
WaitForInputIdle( pi.hProcess, INFINITE );
// inject DLL into UO Client Process
if(!InjectDLL(&si, &pi))
MessageBox( NULL, "Fehler beim Initialisieren", "P3 Loader", MB_ICONERROR );
if(!(hWnd = FindWindow( "Ultima Online", NULL ))) {
MessageBox( NULL, "Could not find UO Window", "Error", MB_ICONERROR );
}
else {
SendMessage( hWnd, WM_ESTABLISH_HOTKEY, 0, 0 );
}
...
Inject.dll
...
LRESULT CALLBACK UOWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
SYSTEMTIME Time;
TCHAR szFileName[MAX_PATH];
HDC hDC;
HICON hIcon;
int nWidth, nHeight, nX;
RECT rt;
switch(uMsg)
{
// RegisterHotKey won't register a hotkey for a window created by
// another thread so it can't be called from DllMain directly.
case WM_ESTABLISH_HOTKEY:
SetupHotKey(hWnd);
// refresh so camera icon gets drawn
InvalidateRect( NULL, NULL, TRUE );
return 0;
case WM_HOTKEY:
GetLocalTime(&Time);
_stprintf( szFileName, TEXT("%s\\%02i.%02i.%02i - %02i-%02i-%02i.JPG"),
szPath,
Time.wDay, Time.wMonth, Time.wYear, Time.wHour, Time.wMinute,
Time.wSecond );
WindowScreenShot( hWnd, szFileName );
return 0;
case WM_SYSCOMMAND:
case WM_SETTEXT:
case WM_NCACTIVATE:
case WM_NCPAINT:
CallWindowProcW( lpOldWndProc, hWnd, uMsg, wParam, lParam );
// draw overlay camera icon
GetWindowRect( hWnd, &rt );
hDC = GetWindowDC(hWnd);
nWidth = GetSystemMetrics(SM_CXSIZE);
nHeight = GetSystemMetrics(SM_CYSIZE);
nX = (rt.right - rt.left) - 5 - 4 * nWidth;
hIcon = LoadIcon( DllInstance, MAKEINTRESOURCE(IDI_CAMERA) );
DrawIconEx( hDC, nX, 4, hIcon, nWidth, nHeight, 0, NULL, DI_NORMAL );
DeleteObject(hIcon);
ReleaseDC( hWnd, hDC );
return 0;
}
// unicode
return CallWindowProcW( lpOldWndProc, hWnd, uMsg, wParam, lParam );
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved
)
{
HWND hWnd;
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DllInstance = hModule;
// subclass wndproc of uo client window
hWnd = FindWindow( "Ultima Online", NULL );
if(!hWnd) {
MessageBox( NULL, "Could not find UO Window", "Error", MB_ICONERROR );
}
else {
lpOldWndProc = (WNDPROC) GetWindowLong( hWnd, GWL_WNDPROC );
if(!lpOldWndProc) {
MessageBox( NULL, "Could not subclass Client", "Error", MB_ICONERROR );
}
else {
SetWindowLong( hWnd, GWL_WNDPROC, (LONG) UOWndProc );
}
}
break;
}
return TRUE;
}
...
Grüsse,
Riq