| 1 | 
 UNIT Unit2; | 
 
 
 
 
 
 | 2 | 
  | 
 
 
 
 
 
 | 3 | 
 INTERFACE | 
 
 
 
 
 
 | 4 | 
 USES Windows, SysUtils, Unit8, Unit11; | 
 
 
 
 
 
 | 5 | 
  | 
 
 
 
 
 
 | 6 | 
 const | 
 
 
 
 
 
 | 7 | 
   _WindowName='ONI '; | 
 
 
 
 
 
 | 8 | 
   _WindowClass='ONI '; | 
 
 
 
 
 
 | 9 | 
   address_message_pointer:LongWord=$10EC0+$4; | 
 
 
 
 
 
 | 10 | 
   address_activate_message_offset:LongWord=$10E0; | 
 
 
 
 
 
 | 11 | 
  | 
 
 
 
 
 
 | 12 | 
 var | 
 
 
 
 
 
 | 13 | 
   _WindowHandle:LongWord; | 
 
 
 
 
 
 | 14 | 
   _ProcessID:LongWord; | 
 
 
 
 
 
 | 15 | 
   _ProcessHandle:LongWord; | 
 
 
 
 
 
 | 16 | 
  | 
 
 
 
 
 
 | 17 | 
 FUNCTION FindWindowA(ClassName:String; WindowName:String):longword; stdcall; external 'user32.dll' name 'FindWindowA'; | 
 
 
 
 
 
 | 18 | 
 FUNCTION GetWindowThreadProcessId(hwnd:longword; out processId:longword):longword; stdcall; external 'user32.dll' name 'GetWindowThreadProcessId'; | 
 
 
 
 
 
 | 19 | 
 FUNCTION OpenProcess(dwDesiredAccess:longword; bInheritHandle:longword; dwProcessId:longword):longword; stdcall; external 'kernel32.dll' name 'OpenProcess'; | 
 
 
 
 
 
 | 20 | 
 FUNCTION ReadProcessMemory(hProcess:longword; lpBaseAddress:longword; out lpBuffer:byte_array; nSize:longword; out lpNumberOfBytesWritten:longword):longword; stdcall; external 'kernel32.dll' name 'ReadProcessMemory'; | 
 
 
 
 
 
 | 21 | 
 FUNCTION WriteProcessMemory(hProcess:longword; lpBaseAddress:longword; lpBuffer:byte_array; nSize:longword; out lpNumberOfBytesWritten:longword):longword; stdcall; external 'kernel32.dll' name 'WriteProcessMemory'; | 
 
 
 
 
 
 | 22 | 
 FUNCTION CloseHandle(hObject:longword):longword; stdcall; external 'kernel32.dll' name 'CloseHandle'; | 
 
 
 
 
 
 | 23 | 
 FUNCTION GetAsyncKeyState(vkey:smallint):word; stdcall; external 'user32.dll' name 'GetAsyncKeyState'; | 
 
 
 
 
 
 | 24 | 
 FUNCTION VirtualProtectEx(hProcess:longword; lpAddress:longword; dwSize:longword; flNewProtect:longword; lpflOldProtect:longword):longword; stdcall; external 'kernel32.dll' name 'VirtualProtectEx'; | 
 
 
 
 
 
 | 25 | 
 FUNCTION GetLastError:longword; stdcall; external 'kernel32.dll' name 'GetLastError'; | 
 
 
 
 
 
 | 26 | 
  | 
 
 
 
 
 
 | 27 | 
 FUNCTION ConnectToProcess:Boolean; | 
 
 
 
 
 
 | 28 | 
 FUNCTION ReadMem(address:longword; size:longword):byte_array; | 
 
 
 
 
 
 | 29 | 
 FUNCTION WriteMem(address:longword; size:longword; _buffer:byte_array):boolean; | 
 
 
 
 
 
 | 30 | 
 //FUNCTION GetKey(key:smallint):boolean; | 
 
 
 
 
 
 | 31 | 
 PROCEDURE SetWindowAOT(Handle:Cardinal;AOT:Boolean); | 
 
 
 
 
 
 | 32 | 
  | 
 
 
 
 
 
 | 33 | 
 FUNCTION Decode_Int(buffer:byte_array):LongWord; | 
 
 
 
 
 
 | 34 | 
 FUNCTION Decode_Float(buffer:byte_array):Single; | 
 
 
 
 
 
 | 35 | 
 FUNCTION Decode_Str(buffer:byte_array):String; | 
 
 
 
 
 
 | 36 | 
 FUNCTION Encode_Int(input:LongWord):byte_array; | 
 
 
 
 
 
 | 37 | 
 FUNCTION Encode_Float(input:Single):byte_array; | 
 
 
 
 
 
 | 38 | 
 FUNCTION Encode_Str(input:String;bytes:byte):byte_array; | 
 
 
 
 
 
 | 39 | 
  | 
 
 
 
 
 
 | 40 | 
 FUNCTION patch_messages_loaded:Boolean; | 
 
 
 
 
 
 | 41 | 
 PROCEDURE SendMessageToOni(_message:String); | 
 
 
 
 
 
 | 42 | 
  | 
 
 
 
 
 
 | 43 | 
 FUNCTION Check_Data_Correct(address:LongWord; requested:array of byte; size:Byte):Byte; | 
 
 
 
 
 
 | 44 | 
 PROCEDURE Incorrect_Data_Message(formhandle:LongWord; address:LongWord; error:Byte); | 
 
 
 
 
 
 | 45 | 
  | 
 
 
 
 
 
 | 46 | 
 implementation | 
 
 
 
 
 
 | 47 | 
  | 
 
 
 
 
 
 | 48 | 
 FUNCTION Check_Data_Correct(address:LongWord; requested:array of byte; size:Byte):Byte; | 
 
 
 
 
 
 | 49 | 
   VAR i:Byte; | 
 
 
 
 
 
 | 50 | 
   BEGIN | 
 
 
 
 
 
 | 51 | 
     result:=0; | 
 
 
 
 
 
 | 52 | 
     _temp:=ReadMem(address,size); | 
 
 
 
 
 
 | 53 | 
     IF (_temp[250]=123) THEN BEGIN | 
 
 
 
 
 
 | 54 | 
       result:=1; | 
 
 
 
 
 
 | 55 | 
       exit; | 
 
 
 
 
 
 | 56 | 
     END; | 
 
 
 
 
 
 | 57 | 
     FOR i:=0 TO size-1 DO BEGIN | 
 
 
 
 
 
 | 58 | 
       IF NOT (_temp[i]=requested[i]) THEN BEGIN | 
 
 
 
 
 
 | 59 | 
         result:=2; | 
 
 
 
 
 
 | 60 | 
         exit; | 
 
 
 
 
 
 | 61 | 
       END; | 
 
 
 
 
 
 | 62 | 
     END; | 
 
 
 
 
 
 | 63 | 
   END; | 
 
 
 
 
 
 | 64 | 
 PROCEDURE Incorrect_Data_Message(formhandle:LongWord; address:LongWord; error:Byte); | 
 
 
 
 
 
 | 65 | 
   BEGIN | 
 
 
 
 
 
 | 66 | 
     CASE error OF | 
 
 
 
 
 
 | 67 | 
       1:BEGIN | 
 
 
 
 
 
 | 68 | 
           MessageBox(formhandle,PChar('Couldn''t read data from $'+IntToHex(address,8)+'!'),PChar('Error'),MB_OK); | 
 
 
 
 
 
 | 69 | 
           exit; | 
 
 
 
 
 
 | 70 | 
         END; | 
 
 
 
 
 
 | 71 | 
       2:BEGIN | 
 
 
 
 
 
 | 72 | 
           MessageBox(formhandle,PChar('Incorrect data found for inserting script-var-address-patch at $'+IntToHex(address,8)+'!'),PChar('Error'),MB_OK); | 
 
 
 
 
 
 | 73 | 
           exit; | 
 
 
 
 
 
 | 74 | 
         END; | 
 
 
 
 
 
 | 75 | 
     END; | 
 
 
 
 
 
 | 76 | 
   END; | 
 
 
 
 
 
 | 77 | 
  | 
 
 
 
 
 
 | 78 | 
 FUNCTION patch_messages_loaded:Boolean; | 
 
 
 
 
 
 | 79 | 
   CONST check_for:LongWord=$10725AE9; | 
 
 
 
 
 
 | 80 | 
     address_at:LongWord=$425B11; | 
 
 
 
 
 
 | 81 | 
   BEGIN | 
 
 
 
 
 
 | 82 | 
     IF Decode_Int(ReadMem(address_at,4))=check_for THEN result:=True | 
 
 
 
 
 
 | 83 | 
     ELSE result:=False; | 
 
 
 
 
 
 | 84 | 
   END; | 
 
 
 
 
 
 | 85 | 
  | 
 
 
 
 
 
 | 86 | 
 PROCEDURE SendMessageToOni(_message:String); | 
 
 
 
 
 
 | 87 | 
   CONST message_length=100; | 
 
 
 
 
 
 | 88 | 
   VAR buffer:byte_array; | 
 
 
 
 
 
 | 89 | 
     i:byte; | 
 
 
 
 
 
 | 90 | 
     adr_message:LongWord; | 
 
 
 
 
 
 | 91 | 
     adr_trigger:LongWord; | 
 
 
 
 
 
 | 92 | 
   BEGIN | 
 
 
 
 
 
 | 93 | 
     IF _connected AND patch_messages_loaded THEN BEGIN | 
 
 
 
 
 
 | 94 | 
       adr_message:=Decode_Int(ReadMem(address_message_pointer,4)); | 
 
 
 
 
 
 | 95 | 
       adr_trigger:=Decode_Int(ReadMem(address_script_var_pointer,4))+address_activate_message_offset; | 
 
 
 
 
 
 | 96 | 
  | 
 
 
 
 
 
 | 97 | 
       IF adr_message>0 THEN BEGIN | 
 
 
 
 
 
 | 98 | 
         FOR i:=0 TO 250 DO buffer[i]:=$00; | 
 
 
 
 
 
 | 99 | 
         IF StrLen(PChar(_message))>message_length THEN BEGIN | 
 
 
 
 
 
 | 100 | 
         END ELSE BEGIN | 
 
 
 
 
 
 | 101 | 
           FOR i:=0 TO StrLen(PChar(_message))-1 DO buffer[i]:=Ord(_message[i+1]); | 
 
 
 
 
 
 | 102 | 
           IF StrLen(PChar(_message))<message_length THEN BEGIN | 
 
 
 
 
 
 | 103 | 
             FOR i:=(StrLen(PChar(_message))) TO message_length-1 DO buffer[i]:=$00; | 
 
 
 
 
 
 | 104 | 
           END; | 
 
 
 
 
 
 | 105 | 
         END; | 
 
 
 
 
 
 | 106 | 
         WriteMem(adr_message,message_length,buffer); | 
 
 
 
 
 
 | 107 | 
         buffer[0]:=1; | 
 
 
 
 
 
 | 108 | 
         WriteMem(adr_trigger,1,buffer); | 
 
 
 
 
 
 | 109 | 
       END; | 
 
 
 
 
 
 | 110 | 
     END; | 
 
 
 
 
 
 | 111 | 
   END; | 
 
 
 
 
 
 | 112 | 
  | 
 
 
 
 
 
 | 113 | 
 FUNCTION Decode_Int(buffer:byte_array):LongWord; | 
 
 
 
 
 
 | 114 | 
   BEGIN | 
 
 
 
 
 
 | 115 | 
     result:=buffer[0]+buffer[1]*256+buffer[2]*256*256+buffer[3]*256*256*256; | 
 
 
 
 
 
 | 116 | 
   END; | 
 
 
 
 
 
 | 117 | 
  | 
 
 
 
 
 
 | 118 | 
 FUNCTION Decode_Float(buffer:byte_array):Single; | 
 
 
 
 
 
 | 119 | 
   BEGIN | 
 
 
 
 
 
 | 120 | 
     _valueswitcher.ValueInt:=Decode_Int(buffer); | 
 
 
 
 
 
 | 121 | 
     result:=_valueswitcher.ValueFloat; | 
 
 
 
 
 
 | 122 | 
   END; | 
 
 
 
 
 
 | 123 | 
  | 
 
 
 
 
 
 | 124 | 
 FUNCTION Decode_Str(buffer:byte_array):String; | 
 
 
 
 
 
 | 125 | 
   VAR i:Byte; | 
 
 
 
 
 
 | 126 | 
   BEGIN | 
 
 
 
 
 
 | 127 | 
     FOR i:=0 TO 249 DO BEGIN | 
 
 
 
 
 
 | 128 | 
       IF buffer[i]=0 THEN break | 
 
 
 
 
 
 | 129 | 
       ELSE result:=result+Chr(buffer[i]); | 
 
 
 
 
 
 | 130 | 
     END; | 
 
 
 
 
 
 | 131 | 
   END; | 
 
 
 
 
 
 | 132 | 
 FUNCTION Encode_Int(input:LongWord):byte_array; | 
 
 
 
 
 
 | 133 | 
   BEGIN | 
 
 
 
 
 
 | 134 | 
     result[0]:=input MOD 256; | 
 
 
 
 
 
 | 135 | 
     input:=input DIV 256; | 
 
 
 
 
 
 | 136 | 
     result[1]:=input MOD 256; | 
 
 
 
 
 
 | 137 | 
     input:=input DIV 256; | 
 
 
 
 
 
 | 138 | 
     result[2]:=input MOD 256; | 
 
 
 
 
 
 | 139 | 
     input:=input DIV 256; | 
 
 
 
 
 
 | 140 | 
     result[3]:=input MOD 256; | 
 
 
 
 
 
 | 141 | 
   END; | 
 
 
 
 
 
 | 142 | 
 FUNCTION Encode_Float(input:Single):byte_array; | 
 
 
 
 
 
 | 143 | 
   BEGIN | 
 
 
 
 
 
 | 144 | 
     _valueswitcher.ValueFloat:=input; | 
 
 
 
 
 
 | 145 | 
     result:=Encode_Int(_valueswitcher.ValueInt); | 
 
 
 
 
 
 | 146 | 
   END; | 
 
 
 
 
 
 | 147 | 
 FUNCTION Encode_Str(input:String;bytes:Byte):byte_array; | 
 
 
 
 
 
 | 148 | 
   VAR i:Byte; | 
 
 
 
 
 
 | 149 | 
   BEGIN | 
 
 
 
 
 
 | 150 | 
     FOR i:=1 TO bytes DO BEGIN | 
 
 
 
 
 
 | 151 | 
       IF i<=Length(input) THEN BEGIN | 
 
 
 
 
 
 | 152 | 
         result[i-1]:=Ord(input[i]); | 
 
 
 
 
 
 | 153 | 
       END ELSE BEGIN | 
 
 
 
 
 
 | 154 | 
         result[i-1]:=$00; | 
 
 
 
 
 
 | 155 | 
       END; | 
 
 
 
 
 
 | 156 | 
     END; | 
 
 
 
 
 
 | 157 | 
   END; | 
 
 
 
 
 
 | 158 | 
  | 
 
 
 
 
 
 | 159 | 
 FUNCTION ConnectToProcess:Boolean; | 
 
 
 
 
 
 | 160 | 
   BEGIN | 
 
 
 
 
 
 | 161 | 
     _WindowHandle:=FindWindowA(''{_WindowClass},_WindowName); | 
 
 
 
 
 
 | 162 | 
     IF not (_WindowHandle>0) THEN BEGIN | 
 
 
 
 
 
 | 163 | 
       result:=False; | 
 
 
 
 
 
 | 164 | 
       exit; | 
 
 
 
 
 
 | 165 | 
     END; | 
 
 
 
 
 
 | 166 | 
     GetWindowThreadProcessId(_WindowHandle, _ProcessID); | 
 
 
 
 
 
 | 167 | 
     IF not (_ProcessID>0) THEN BEGIN | 
 
 
 
 
 
 | 168 | 
       result:=False; | 
 
 
 
 
 
 | 169 | 
       exit; | 
 
 
 
 
 
 | 170 | 
     END; | 
 
 
 
 
 
 | 171 | 
     _ProcessHandle:=OpenProcess(PROCESS_ALL_ACCESS, 0, _ProcessID); | 
 
 
 
 
 
 | 172 | 
     IF not (_ProcessHandle>0) THEN BEGIN | 
 
 
 
 
 
 | 173 | 
       result:=False; | 
 
 
 
 
 
 | 174 | 
       exit; | 
 
 
 
 
 
 | 175 | 
     END; | 
 
 
 
 
 
 | 176 | 
     result:=True; | 
 
 
 
 
 
 | 177 | 
   END; | 
 
 
 
 
 
 | 178 | 
 FUNCTION ReadMem(address:longword; size:longword):byte_array; | 
 
 
 
 
 
 | 179 | 
   VAR _buffer:byte_array; | 
 
 
 
 
 
 | 180 | 
     temp:longword; | 
 
 
 
 
 
 | 181 | 
   BEGIN | 
 
 
 
 
 
 | 182 | 
     FOR temp:=0 TO 250 DO _buffer[temp]:=0; | 
 
 
 
 
 
 | 183 | 
     IF NOT (ReadProcessMemory(_ProcessHandle, address, _buffer, size, temp)>0) THEN BEGIN | 
 
 
 
 
 
 | 184 | 
       _buffer[250]:=123; | 
 
 
 
 
 
 | 185 | 
     END; | 
 
 
 
 
 
 | 186 | 
     result:=_buffer; | 
 
 
 
 
 
 | 187 | 
   END; | 
 
 
 
 
 
 | 188 | 
 FUNCTION WriteMem(address:longword; size:longword; _buffer:byte_array):boolean; | 
 
 
 
 
 
 | 189 | 
   VAR temp:longword; | 
 
 
 
 
 
 | 190 | 
   BEGIN | 
 
 
 
 
 
 | 191 | 
     IF NOT (WriteProcessMemory(_ProcessHandle, address, _buffer, size, temp)>0) THEN BEGIN | 
 
 
 
 
 
 | 192 | 
       result:=False; | 
 
 
 
 
 
 | 193 | 
     END ELSE BEGIN | 
 
 
 
 
 
 | 194 | 
       result:=True; | 
 
 
 
 
 
 | 195 | 
     END; | 
 
 
 
 
 
 | 196 | 
   END; | 
 
 
 
 
 
 | 197 | 
  | 
 
 
 
 
 
 | 198 | 
 PROCEDURE SetWindowAOT(Handle:Cardinal;AOT:Boolean); | 
 
 
 
 
 
 | 199 | 
   VAR aot_value:Integer; | 
 
 
 
 
 
 | 200 | 
   BEGIN | 
 
 
 
 
 
 | 201 | 
     IF AOT THEN aot_value:=HWND_TOPMOST | 
 
 
 
 
 
 | 202 | 
     ELSE aot_value:=HWND_NOTOPMOST; | 
 
 
 
 
 
 | 203 | 
     SetWindowPos(Handle,aot_value,0,0,0,0,SWP_NOACTIVATE+SWP_NOMOVE+SWP_NOOWNERZORDER+SWP_NOSIZE); | 
 
 
 
 
 
 | 204 | 
   END; | 
 
 
 
 
 
 | 205 | 
  | 
 
 
 
 
 
 | 206 | 
 end. |