// "Zeitmaschine", Dritter Versuch mit »detours«
// Datumsänderung für bestimmten Prozess
// h#s 07/04
#if defined(__BORLANDC__)
#pragma option -a4 // DWORD-Alignment. Wichtig, sonst schlägt GetThreadContext
// feht, wenn Context-Struktur nicht korrekt aligned ist.
#endif
#if defined(_MSC_VER)
#pragma auto_inline(off)
#pragma optimize("s",on)
#endif
#include "iwatchsu.h"
#include "detours.h"
#include "FakeHelp.h"
#include <commdlg.h>
#include <commctrl.h>
#include <shellapi.h>
HINSTANCE ghInstance = 0;
MYDATE MyDate;
void _cdecl Alert(PCTSTR s,...) {
TCHAR buf[1024];
wvsprintf(buf,s,(va_list)(&s+1));
MessageBox((HWND)0,buf,T("Zeitmaschine"),MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
}
BOOL IsWin32(PCTSTR AppName) {
// GetBinaryType() wäre geeignet, funktioniert aber unter Win95 nicht richtig
BOOL OK=FALSE;
DWORD D;
CHAR Signature[2];
DWORD Result;
HANDLE f = CreateFile(AppName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (f == INVALID_HANDLE_VALUE) return FALSE;
if (SetFilePointer(f,0x3C,NULL,FILE_BEGIN)
&& ReadFile(f,&D,sizeof D,&Result,NULL)
&& D
&& SetFilePointer(f,D,NULL,FILE_BEGIN)
&& ReadFile(f,Signature,sizeof Signature,&Result,NULL)
&& Signature[0]=='P' && Signature[1]=='E') OK=TRUE;
CloseHandle(f);
return OK;
}
BOOL WINAPI EnterDateDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
// Parameter ist Zeiger auf MYDATE-Struktur
switch (Msg) {
case WM_INITDIALOG: {
SetWindowLong(Wnd,DWL_USER,lParam);
}return TRUE;
case WM_WININICHANGE: {
SendDlgItemMessage(Wnd,102,Msg,wParam,lParam); // MSDN sagt: durchreichen!
}break;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDOK: {
SYSTEMTIME st;
lParam=GetWindowLong(Wnd,DWL_USER);
#define MyDate ((PMYDATE)lParam)
SendDlgItemMessage(Wnd,102,DTM_GETSYSTEMTIME,0,(LPARAM)&st);
MyDate->day=(BYTE)st.wDay;
MyDate->month=(BYTE)st.wMonth;
MyDate->year=st.wYear;
#undef MyDate
}nobreak;
case IDCANCEL: EndDialog(Wnd,LOWORD(wParam));
}
}
return FALSE;
}
BOOL GetAppFileName(PTSTR AppName,int AppNameSize) {
OPENFILENAME ofn;
InitStruct(&ofn,sizeof ofn);
ofn.lpstrFilter=T("Win32-Anwendung (*.exe)\0*.exe\0");
ofn.lpstrFile =AppName;
ofn.nMaxFile =AppNameSize;
ofn.lpstrTitle =T("Das Programm für die \"Zeitmaschine\"");
ofn.Flags =OFN_HIDEREADONLY|OFN_FILEMUSTEXIST;
AppName[0]='\0';
return GetOpenFileName(&ofn);
}
PTSTR NextCmdItem(PTSTR s) {
// Liefert Zeiger auf nächstes Kommandozeilenargument, niemals NULL
// patcht s und entfernt dabei die doppelten Hochkommata
PTSTR d=s;
BOOL InQuote=FALSE;
while (*s==T(' ') || *s==T('\t')) s++; // Führenden Quell-Weißraum übergehen
for (;;s++) switch (*s) { // keine DBCS-Gefahr hier
case 0: *d=0; return s; // Zeiger auf die 0
case T('"'): InQuote=!InQuote; break; // alle " entfernen, umschalten
case T(' '):
case T('\t'): if (!InQuote) {*d=0; return ++s;} // else nobreak;
default: *d++=*s;
}
}
int FAR PASCAL WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR cmdLine,int cmdShow) {
PTSTR argv0,argv1,argv2;
int ReturnCode;
PROCESS_INFORMATION pi;
STARTUPINFO si;
TCHAR AppName[MAX_PATH];
TCHAR IniName[MAX_PATH];
TCHAR DllName[MAX_PATH];
ghInstance=hInst;
argv0=GetCommandLine(); // Eigener EXE-Name
argv1=NextCmdItem(argv0); // Zu startendes Programm
argv2=NextCmdItem(argv1); // Programm-Argumente (Rest der Zeile, unmodifiziert)
if ((unsigned)FindExecutable(argv1,NULL,AppName)<=32) // bei Fehler...
GetFullPathName(argv1,elemof(AppName),AppName,NULL); // in Puffer und mit Pfad ergänzen
if (!argv1[0] && !GetAppFileName(AppName,elemof(AppName))) {
Alert(T("Aufruf: %s <Programmname> [<Arg1> <Arg2>...]\n"),argv0);
return 10;
}
if (!IsWin32(AppName)) {
Alert(T("'%s' ist keine Win32-Anwendung und kann daher nicht überwacht ausgeführt werden!\n"),AppName);
return 13;
}
GetModuleFileName(0,IniName,elemof(IniName));
lstrcpy(GetFileNameExt(IniName),T(".ini"));
MyDate.all=GetPrivateProfileInt(T("Apps"),AppName,0,IniName);
if (!MyDate.all) {
TCHAR buf[16];
INITCOMMONCONTROLSEX icc={sizeof(icc),ICC_DATE_CLASSES};
InitCommonControlsEx(&icc);
if (DialogBoxParam(ghInstance,MAKEINTRESOURCE(100),0,EnterDateDlgProc,(LPARAM)&MyDate)!=IDOK) return 10;
wsprintf(buf,T("%ld"),MyDate.all);
WritePrivateProfileString(T("Apps"),AppName,buf,IniName);
}
GetModuleFileName(0,DllName,elemof(DllName));
lstrcpy(GetFileNameExt(DllName),T(".dll"));
InitStruct(&si,sizeof(si));
GetStartupInfo(&si); // durchreichen!
ReturnCode=13;
if (!DetourCreateProcessWithDll(AppName,argv2,NULL,NULL,TRUE,
CREATE_DEFAULT_ERROR_MODE,NULL,NULL,&si,&pi,DllName,NULL)) {
Alert(T("Kann Programm '%s' nicht starten, Fehlerkode = %d\n"),AppName,GetLastError());
return ReturnCode;
}
WaitForSingleObject(pi.hProcess,INFINITE);
GetExitCodeProcess(pi.hProcess,&ReturnCode);
ExitProcess(ReturnCode); // sonst bleibt das Programm hängen, aber nur, wenn man GetOpenFileName aufrief
return ReturnCode;
}
Vorgefundene Kodierung: ANSI (CP1252) | 4
|
|