Идея такая: нужно заблокировать игру, но сделать все так, чтобы это выглядело ошибкой игры типа "Приложению не удалось запуститься поскольку bink32.dll не был найден" Чтобы это выглядело натурально сам MessageBox с текстом ошибки должен выполнятся в контексте самого процесса игры Но в момент создания потока в ее процессе вылетает ошибка блокируемой игры типа "неизвестная ошибка, отправлять отчет или нет", а если и не вылетает то сам процесс завершается, при этом MessageBox не появляется Инжект производится с помощью MS-Remовского AdvApiHook и nativeApi, плюс в коде используется мой модуль blocking, содержащий функции получения всякого рода хэндлов по id, именам и т.п. Вот код Delphi модуля, где описана функция такого рода блокирования - BlockApps Код (Text): unit BlockEx; interface uses windows,blocking,AdvApiHook; type TBlockItem = record NameOfWindow,TextOfError:string; end; TBlockItems = array of TBlockItem; procedure BlockApps(m:TBlockItems; ShowErrors:boolean); implementation const Kerdll:Pchar='kernel32.dll'; userdll:Pchar='user32.dll'; MesBox:Pchar='MessageBoxA'; ExPr:Pchar='ExitProcess'; err:PChar='Îøèáêà'; type TThreadInfo=record LoadLibrary: function(lpLibFileName: PChar): HMODULE; stdcall; GetProcAddress: function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall; Kernel32 : array[0..16] of Char; User32 : array[0..16] of Char; MessageBoxA : array[0..16] of Char; nExitProcess: array[0..16] of Char; Text : array[0..255] of Char; Title : array[0..16] of Char; end; Var CurInfo:TThreadInfo; procedure RemThread(struct:pointer); stdcall; var MessageBox: function(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall; ExitProcess: procedure (uExitCode: UINT); stdcall; begin with TThreadInfo(struct^) do begin @MessageBox := GetProcAddress(LoadLibrary(User32), MessageBoxA); @ExitProcess := GetProcAddress(LoadLibrary(Kernel32), nExitProcess); MessageBox(0, Text, Title, 0); ExitProcess(0); end; end; procedure ThreadEnd; begin end; procedure BlockApps(m:TBlockItems; ShowErrors:boolean); Var i,len:integer; time,h,pr:cardinal; begin len:=length(m); case len of 1..5:time:=200; 6..10:time:=100; 11..15:time:=50; end; if ShowErrors then begin with CurInfo do begin lstrcpy(User32, userdll); lstrcpy(Kernel32, kerdll); lstrcpy(MessageBoxA, MesBox); lstrcpy(nExitProcess, ExPr); lstrcpy(Title,err); end; len:=high(m); repeat for i:=0 to len do begin h:=FindWindow(nil,PChar(m[i].NameOfWindow)); If (h<>0) and IsWindowVisible(h) then begin ShowWindow(h,SW_HIDE); lstrcpy(CurInfo.Text,Pchar(m[i].TextOfError)); InjectThread(FindProcessHandleByWindowId(h),@RemThread, @CurInfo,sizeof(CurInfo),false); ///функции с Find из blocking end; delay(time); end; until false; end else begin len:=high(m); repeat for i:=0 to len do begin h:=FindWindow(nil,PChar(m[i].NameOfWindow)); If h<>0 then begin pr:=FindProcessHandleByWindowID(h); SendMessage(h,$10,0,0); terminateprocess(pr,0); end; delay(time); end; until false end; end; end. Почему могут вылетать ошибки и не вылетать MessageBox?
ИМХО, можно просто пропатчить екзешник игры. Внутри наверняка содержатся проверки на всевозможные нестандартные ситуации. Штука в том что надо отследить несколько из них, и при необходимости менять в одном из них (выбирать рандомным образом) условный переход на безусловный. ъ?