SHOW:
|
|
- or go back to the newest paste.
| 1 | /*----------------------------------------------------------------------------*\ | |
| 2 | =========================== | |
| 3 | Y Sever Includes - Writemem | |
| 4 | =========================== | |
| 5 | Description: | |
| 6 | Write to any absolute address in the SA:MP server in pure PAWN with embedded | |
| 7 | assembly (i.e. a new native). Calls "VirtualProtect" to make writes safe. | |
| 8 | Legal: | |
| 9 | Version: MPL 1.1 | |
| 10 | ||
| 11 | The contents of this file are subject to the Mozilla Public License Version | |
| 12 | 1.1 (the "License"); you may not use this file except in compliance with | |
| 13 | the License. You may obtain a copy of the License at | |
| 14 | http://www.mozilla.org/MPL/ | |
| 15 | ||
| 16 | Software distributed under the License is distributed on an "AS IS" basis, | |
| 17 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
| 18 | for the specific language governing rights and limitations under the | |
| 19 | License. | |
| 20 | ||
| 21 | The Original Code is the YSI ini include. | |
| 22 | ||
| 23 | The Initial Developer of the Original Code is Alex "Y_Less" Cole. | |
| 24 | Portions created by the Initial Developer are Copyright (C) 2011 | |
| 25 | the Initial Developer. All Rights Reserved. | |
| 26 | ||
| 27 | Contributors: | |
| 28 | ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice | |
| 29 | ||
| 30 | Thanks: | |
| 31 | JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL. | |
| 32 | ZeeX - Very productive conversations. | |
| 33 | koolk - IsPlayerinAreaEx code. | |
| 34 | TheAlpha - Danish translation. | |
| 35 | breadfish - German translation. | |
| 36 | Fireburn - Dutch translation. | |
| 37 | yom - French translation. | |
| 38 | 50p - Polish translation. | |
| 39 | Zamaroht - Spanish translation. | |
| 40 | Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes | |
| 41 | for me to strive to better. | |
| 42 | Pixels^ - Running XScripters where the idea was born. | |
| 43 | Matite - Pestering me to release it and using it. | |
| 44 | ||
| 45 | Very special thanks to: | |
| 46 | Thiadmer - PAWN, whose limits continue to amaze me! | |
| 47 | Kye/Kalcor - SA:MP. | |
| 48 | SA:MP Team past, present and future - SA:MP. | |
| 49 | ||
| 50 | Version: | |
| 51 | 1.0 | |
| 52 | Changelog: | |
| 53 | 01/02/12: | |
| 54 | Added "VirtualProtect" calls to the code. | |
| 55 | First version. | |
| 56 | Functions: | |
| 57 | Public: | |
| 58 | - | |
| 59 | Core: | |
| 60 | - | |
| 61 | Stock: | |
| 62 | - | |
| 63 | Static: | |
| 64 | - | |
| 65 | Inline: | |
| 66 | - | |
| 67 | API: | |
| 68 | WriteMem - Write data to an address. | |
| 69 | Callbacks: | |
| 70 | - | |
| 71 | Definitions: | |
| 72 | asm - Convert a stream of assembly to a cell. | |
| 73 | Enums: | |
| 74 | - | |
| 75 | Macros: | |
| 76 | - | |
| 77 | Tags: | |
| 78 | - | |
| 79 | Variables: | |
| 80 | Global: | |
| 81 | - | |
| 82 | Static: | |
| 83 | YSI_g_sWriteMem - The assembly. | |
| 84 | Commands: | |
| 85 | - | |
| 86 | Compile options: | |
| 87 | - | |
| 88 | Operators: | |
| 89 | - | |
| 90 | \*----------------------------------------------------------------------------*/ | |
| 91 | ||
| 92 | #include <a_samp> | |
| 93 | #include <YSI\y_amx> | |
| 94 | #include <YSI\y_hooks> | |
| 95 | #include <YSI\y_utils> | |
| 96 | ||
| 97 | forward WriteMem(addr, value); | |
| 98 | ||
| 99 | #define asm(%0,%1,%2,%3) ((0x%0<<0)|(0x%1<<8)|(0x%2<<16)|(0x%3<<24)) | |
| 100 | ||
| 101 | /* | |
| 102 | cell AMX_NATIVE_CALL | |
| 103 | n_WriteMem(AMX * amx, cell * params) | |
| 104 | {
| |
| 105 | if (params[0] == 8) | |
| 106 | {
| |
| 107 | DWORD | |
| 108 | oldp; | |
| 109 | VirtualProtect((cell *)params[1], 4, PAGE_EXECUTE_READWRITE, &oldp); | |
| 110 | *((cell *)params[1]) = params[2]; | |
| 111 | } | |
| 112 | return 0; | |
| 113 | } | |
| 114 | ||
| 115 | BECOMES: | |
| 116 | ||
| 117 | align 16 | |
| 118 | push ebp | |
| 119 | mov ebp, esp | |
| 120 | push esi | |
| 121 | mov esi, [ebp+12] | |
| 122 | cmp dword ptr [esi], 8 | |
| 123 | jnz short loc_ret | |
| 124 | mov ecx, [esi+4] | |
| 125 | lea eax, [ebp+12] | |
| 126 | push eax | |
| 127 | push 40h | |
| 128 | push 4 | |
| 129 | push ecx | |
| 130 | call ds:__imp__VirtualProtect@16 | |
| 131 | mov edx, [esi+4] | |
| 132 | mov eax, [esi+8] | |
| 133 | mov [edx], eax | |
| 134 | loc_ret: | |
| 135 | xor eax, eax | |
| 136 | pop esi | |
| 137 | pop ebp | |
| 138 | retn | |
| 139 | ||
| 140 | BECOMES: | |
| 141 | */ | |
| 142 | ||
| 143 | static | |
| 144 | YSI_g_sWriteMem[] = | |
| 145 | {
| |
| 146 | asm(CC,CC,CC,CC), asm(CC,CC,CC,CC), asm(CC,CC,CC,CC), asm(CC,CC,CC,CC), | |
| 147 | asm(55,8B,EC,56), asm(8B,75,0C,83), asm(3E,08,75,1A), asm(8B,4E,04,8D), | |
| 148 | asm(45,0C,50,6A), asm(40,6A,04,51), asm(FF,15,3C,70), asm(00,10,8B,56), | |
| 149 | asm(04,8B,46,08), asm(89,02,33,C0), asm(5E,5D,C3,CC) | |
| 150 | }; | |
| 151 | ||
| 152 | static | |
| 153 | YSI_g_sDoWriteMem[] = | |
| 154 | {
| |
| 155 | 135, // sysreq.d opcode | |
| 156 | - | -1, // will be set later |
| 156 | + | 0, // will be set later |
| 157 | }; | |
| 158 | ||
| 159 | stock | |
| 160 | WriteMem(addr, value) | |
| 161 | {
| |
| 162 | - | printf("WriteMem(%x, %x)", addr, value);
|
| 162 | + | |
| 163 | #emit PUSH.S value | |
| 164 | - | printf("native = %x", YSI_g_sDoWriteMem[1]);
|
| 164 | + | |
| 165 | #emit PUSH.C 8 | |
| 166 | ||
| 167 | // Get the jump address. | |
| 168 | #emit CONST.PRI YSI_g_sDoWriteMem | |
| 169 | #emit LOAD.ALT AMX_HEADER_DAT | |
| 170 | #emit ADD | |
| 171 | #emit LOAD.ALT AMX_HEADER_COD | |
| 172 | #emit SUB | |
| 173 | ||
| 174 | // Jump to the code stored in YSI_g_sDoWriteMem. | |
| 175 | // This will result in execution of the native code stored in YSI_g_sWriteMem. | |
| 176 | #emit JUMP.PRI | |
| 177 | ||
| 178 | // Pop native arguments. | |
| 179 | #emit STACK 12 | |
| 180 | } | |
| 181 | ||
| 182 | static | |
| 183 | WM_Shift(from, to, data[], len = sizeof (data)) | |
| 184 | {
| |
| 185 | if (FALSE) | |
| 186 | {
| |
| 187 | WriteMem(0, 0); | |
| 188 | } | |
| 189 | while (from < len) | |
| 190 | {
| |
| 191 | data[to++] = data[from++]; | |
| 192 | } | |
| 193 | } | |
| 194 | ||
| 195 | hook OnScriptInit() | |
| 196 | {
| |
| 197 | new | |
| 198 | addr = AMX_GetGlobalAddress(YSI_g_sWriteMem); | |
| 199 | // Align the code to a 16-byte boundary. | |
| 200 | switch (addr & 15) | |
| 201 | {
| |
| 202 | case 0: | |
| 203 | {
| |
| 204 | WM_Shift(4, 0, YSI_g_sWriteMem); | |
| 205 | } | |
| 206 | case 4: | |
| 207 | {
| |
| 208 | WM_Shift(4, 3, YSI_g_sWriteMem); | |
| 209 | addr += 12; | |
| 210 | } | |
| 211 | case 8: | |
| 212 | {
| |
| 213 | WM_Shift(4, 2, YSI_g_sWriteMem); | |
| 214 | addr += 8; | |
| 215 | } | |
| 216 | case 12: | |
| 217 | {
| |
| 218 | WM_Shift(4, 1, YSI_g_sWriteMem); | |
| 219 | addr += 4; | |
| 220 | } | |
| 221 | default: | |
| 222 | {
| |
| 223 | P:E("Cannot relocate YSI_g_sWriteMem");
| |
| 224 | } | |
| 225 | } | |
| 226 | YSI_g_sDoWriteMem[1] = addr; | |
| 227 | return 1; | |
| 228 | } |