[251] | 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.
|
---|