Biohazard v1.93 (Z... (2463) |
CS 1.6 Zombie v.3.... (2732) |
CSS patch_v34 full... (2796) |
CS 1.6 patch v21 f... (1752) |
Скачать готовый CS... (1881) |
Скачать Adobe Phot... (6600) |
Скачать zm_ карты ... (7406) |
xSpeedPro (SpeedHa... (1354) |
Куча песен о Count... (1989) |
CS 1.6 cfg-pak v2.... (1281) |
Скачать CS 1.6 Pat... (1732) |
Скачать Counter St... (1094) |
CS 1.6 Server Kree... (1913) |
Скачать Tekken 3 (... (997) |
Готовый сервер Cou... (1443) |
Скачать AIM_ Map P... (4057) |
CS 1.6 patch v29 f... (1487) |
Скачать addon War3... (1877) |
Скачать Kz_ maps [... (1121) |
BadBoy v5.0 (BadBo... (1195) |
Biohazard v1.93 (Z... (2463) |
CS 1.6 Zombie v.3.... (2732) |
CSS patch_v34 full... (2796) |
CS 1.6 patch v21 f... (1752) |
Скачать готовый CS... (1881) |
Скачать Adobe Phot... (6600) |
Скачать zm_ карты ... (7406) |
xSpeedPro (SpeedHa... (1354) |
Куча песен о Count... (1989) |
CS 1.6 cfg-pak v2.... (1281) |
Скачать CS 1.6 Pat... (1732) |
Скачать Counter St... (1094) |
CS 1.6 Server Kree... (1913) |
Скачать Tekken 3 (... (997) |
Готовый сервер Cou... (1443) |
Скачать AIM_ Map P... (4057) |
CS 1.6 patch v29 f... (1487) |
Скачать addon War3... (1877) |
Скачать Kz_ maps [... (1121) |
BadBoy v5.0 (BadBo... (1195) |
Главная » Статьи » Статьи Counter-Strike |
Статья о том как получить исходный код плагина из готового файла amxx и
amx (рускоязычная
версия) Введение amx и amxx файлы используются на виртуальной машине, которая содержит набор сценариев. amx файл разбит на три части: заголовок (который содержит информацию о размере), раздел кода и раздел данных. A amxx файл - это простой метод для того, чтобы сохранить два amx файла в одном. Тем самым имеем 32-разрядную и 64-разрядную совместимость в одном файле. Раздел кода содержит коды операций виртуальной машины (то есть примитивные команды виртуальной машины) для компилированного плагина. Раздел данных содержит стек, динамическую память и другие данные, такие как массивы и строки. Виртуальная машина довольно проста. Она основана на двух регистрах (PRI и ALT), стеке и динамической памяти. Регистры - простые ячейки, используемые для хранения временной информации и их возвращения. Стек используется для локальных переменных. Стек имеет две операции: помещение элемента в стек (push) и доставание верхнего элемента из стека (pop). Динамическая память - это простой участок памяти, используемый для хранения временных переменных. Все данные в виртуальной машине вращаются вокруг интегрального типа данных, 'ячейки' (cell). Интегральный - это целочисленный тип данных, который содержит указатель на 32-bit на 32-разрядном процессоре и на 64-bit на 64-разрядном процессоре. AMX обладает способностью вызова процедур (возможность вызывать функцию и возвращать ее значение), которые вращаются вокруг скрытого регистра под названием FRM (который располагается на стеке). При любом вызове процедуры передаются параметры стеку в обратном порядке и закончивается числом помещенных байтов. Например, чтобы вызвать функцию с параметрами A и B, сначала вы поместите параметр B, потом A, а затем число 8 в стек (или 16, если 64-bit). Способы адресации у виртуальной машины - это прежде всего DAT и FRM. Инструкции, относящиеся к FRM, заканчиваются на '.S'. Инструкции, относящиеся к константам, заканчиваются на '.C'. Они относятся к нескольким категориям: *Переходы (JUMP) *Математические вычисления *Манипуляция со стеком (POP, PUSH) *Вызовы процедур (локальный, системный) *Память (установка и восстановление) *Инструкции, относящиеся к регистрам, заканчиваются на '.ALT' или '.PRI'. Описание - это консольное приложение, предназначенное для дизассемблирования .amxx плагинов, автором которого является Steve Dudenhoeffer. Данное приложение будем использовать через командную строку Windows (cmd). Синтаксис использования: amxxdump [параметры] имя_файла.amxx Список
параметров -a
- не показывать адресные положения. -c - не показывать комментарии. -x - список всех public и stock функций плагина и их параметры. -n - список native функций, используемых в плагине. -D <название> - дизассемблирование указанной функции. -d - дизассемблировать код плагина. -s - показать все символы. -m - показать необходимые модули. -r <название> - поиск информации об указанной функции. -R <название> - поиск информации об указанной native функции. -v <значение> - показать значение адреса в разделе данных. -A <размер> - в дополнении к параметру -v, формирует дамп в зависимости от указанного размера ячеек. -V <значение> - показать значение адреса в разделе данных в качестве строки. -F <значение> - показать значение адреса в разделе данных в качестве числа с плавающей точкой. -f - показать названия всех файлов, код которых включен в плагин (stock). -l - показать номер строки и название файла у оператора BREAK. -j - показать метки для jump, switch и case таблиц. -e - попытаться сформировать данные от операторов push.c/const.pri. -E - использовать список параметров для стандартных вызовов native функций. Для работы необходимы .inc файлы. -N - не показывать рамзерность переменных, теги и стандартные значения. Подразумевает параметр -E. -g - список всех глобальных переменных. -h - скрыть номера параметров и их адреса. -! - показать лицензию программы. -? - помощь. Применение Рассмотрим применение amxxdump, к примеру, на стандартном плагине antiflood.amxx из версии AMX Mod X 1.8.1. 1. Узнаем список всех public и stock функций плагина: amxxdump
-x antiflood.amxx Получаем 0x0000004C stock
bool:operator!(Float:)(Float:oper) 0x00000008 stock bool:operator>(Float:,Float:)(Float:oper1,Float:oper2) 0x000001AC public chkFlood(id) 0x00000078 public plugin_init() В данном случае функции operator! и operator> тоже самое, что операторы ! и > в условиях, поэтому их дизассемблировать не обязательно. 2. Узнаем список всех native функций, используемых в плагине: amxxdump
-n antiflood.amxx native: floatadd native: client_print native: get_gametime native: get_pcvar_float native: register_cvar native: register_clcmd native: register_dictionary native: register_plugin native: floatcmp 3. Отобразим все символы: amxxdump
-s antiflood.amxx codestart codeend address type
name 0x00000008 0x0000004C 0x00000010 local val oper2 0x00000008 0x0000004C 0x0000000C local val oper1 0x0000004C 0x00000078 0x0000000C local val oper 0x00000210 0x0000049C 0xFFFFFFF8 local val nexTime 0x000001B8 0x000004B0 0xFFFFFFFC local val maxChat 0x000001AC 0x000004B0 0x0000000C local val id 0x0000004C 0x00000078 0x0000004C stock operator!(Float:) 0x00000008 0x0000004C 0x00000008 stock operator>(Float:,Float:) 0x00000078 0x000004B0 0x00000000 global val AMXX_VERSION_STR[11] 0x00000078 0x000004B0 0x00000134 global val amx_flood_time 0x000001AC 0x000004B0 0x000001AC public chkFlood 0x00000078 0x000004B0 0x000000B0 global val g_Flood[33] 0x00000078 0x000004B0 0x0000002C global val g_Flooding[33] 0x00000078 0x000001AC 0x00000078 public plugin_init local - локальная переменная, то есть может быть использована только в какой-то конкретной функции. global - глобальная переменная, то есть может быть использована во всех функциях плагина. public - public функция. stock - stock функция. 4. Узнаем используемые модули: amxxdump
-m antiflood.amxx No module data detected. Значит другие модули, кроме amxmodx, не используются. 5. Узнаем список всех глобальных переменных: amxxdump -g antiflood.amxx 0x00000000 new AMXX_VERSION_STR[11] 0x00000134 new amx_flood_time 0x000000B0 new g_Flood[33] 0x0000002C new Float:g_Flooding[33] AMXX_VERSION_STR - это константа, в которой содежится текущая версия AMX Mod X. 6. Получаем весь дизассемблированный код плагина: amxxdump -d -l -j -e -E antiflood.amxx 0x8 PROC ;
stock bool:operator>(Float:,Float :)(Float:oper1,Float:oper2) 0xC BREAK ; antiflood.sma:136 0x10 BREAK ; antiflood.sma:137 0x14 PUSH.S 0x10 ; Float:oper2 0x1C PUSH.S 0xC ; Float:oper1 0x24 PUSH.C 0x8 0x2C SYSREQ.C 0x0 ; floatcmp(Float:oper1,Float:oper2) 0x34 STACK 0xC ; free 3 cells 0x3C MOVE.alt 0x40 ZERO.pri 0x44 SLESS 0x48 RETN 0x4C PROC ; stock bool:operator!(Float:)(Float:oper) 0x50 BREAK ; antiflood.sma:172 0x54 BREAK ; antiflood.sma:173 0x58 LOAD.S.pri 0xC ; Float:oper 0x60 CONST.alt 0xFFFFFFFF 0x68 AND 0x6C ZERO.alt 0x70 EQ 0x74 RETN 0x78 PROC ; public plugin_init() 0x7C BREAK ; antiflood.sma:41 0x80 BREAK ; antiflood.sma:43 0x84 PUSH.C 0x164 ; "AMXX Dev Team" 0x8C PUSH.C 0x0 ; AMXX_VERSION_STR[11] "1.8.1.3722" 0x94 PUSH.C 0x138 ; "Anti Flood" 0x9C PUSH.C 0xC 0xA4 SYSREQ.C 0x1 ; register_plugin("Anti Flood",AMXX_VERSION_STR[11]={"1.8.1.3722"},"AMXX Dev Team") 0xAC STACK 0x10 ; free 4 cells 0xB4 BREAK ; antiflood.sma:44 0xB8 PUSH.C 0x19C ; "antiflood.txt" 0xC0 PUSH.C 0x4 0xC8 SYSREQ.C 0x2 ; register_dictionary("antiflood.txt") 0xD0 STACK 0x8 ; free 2 cells 0xD8 BREAK ; antiflood.sma:45 0xDC PUSH.C 0xFFFFFFFF; signed=-1 float=-1.#QNAN0 0xE4 PUSH.C 0x208 ; 0x0 0xEC PUSH.C 0xFFFFFFFF; signed=-1 float=-1.#QNAN0 0xF4 PUSH.C 0x1E4 ; "chkFlood" 0xFC PUSH.C 0x1D4 ; "say" 0x104 PUSH.C 0x14 0x10C SYSREQ.C 0x3 ; register_clcmd("say","chkFlood",-1,"",-1) 0x114 STACK 0x18 ; free 6 cells 0x11C BREAK ; antiflood.sma:46 0x120 PUSH.C 0xFFFFFFFF; signed=-1 float=-1.#QNAN0 0x128 PUSH.C 0x208 ; 0x0 0x130 PUSH.C 0xFFFFFFFF; signed=-1 float=-1.#QNAN0 0x138 PUSH.C 0x230 ; "chkFlood" 0x140 PUSH.C 0x20C ; "say_team" 0x148 PUSH.C 0x14 0x150 SYSREQ.C 0x3 ; register_clcmd("say_team","chkFlood",-1,"",-1) 0x158 STACK 0x18 ; free 6 cells 0x160 BREAK ; antiflood.sma:47 0x164 PUSH.C 0x0 ; AMXX_VERSION_STR[11] "1.8.1.3722" 0x16C PUSH.C 0x0 ; AMXX_VERSION_STR[11] "1.8.1.3722" 0x174 PUSH.C 0x290 ; "0.75" 0x17C PUSH.C 0x254 ; "amx_flood_time" 0x184 PUSH.C 0x10 0x18C SYSREQ.C 0x4 ; register_cvar("amx_flood_time","0.75",0,0.000000) 0x194 STACK 0x14 ; free 5 cells 0x19C STOR.pri 0x134 ; amx_flood_time 0x1A4 ZERO.pri 0x1A8 RETN 0x1AC PROC ; public chkFlood(id) 0x1B0 BREAK ; antiflood.sma:50 0x1B4 BREAK ; antiflood.sma:52 ; new Float:maxChat 0x1B8 STACK 0xFFFFFFFC; allocate 1 cells 0x1C0 PUSH 0x134 ; amx_flood_time 0x1C8 PUSH.C 0x4 0x1D0 SYSREQ.C 0x5 ; Float:get_pcvar_float(amx_flood_time) 0x1D8 STACK 0x8 ; free 2 cells 0x1E0 STOR.S.pri 0xFFFFFFFC; Float:maxChat 0x1E8 BREAK ; antiflood.sma:54 0x1EC PUSH.S 0xFFFFFFFC; Float:maxChat 0x1F4 PUSH.C 0x4 0x1FC CALL 0x4C ; stock bool:operator!(Float:)(Float:oper) 0x204 JNZ 0x49C ; jump_0 0x20C BREAK ; antiflood.sma:56 ; new Float:nexTime 0x210 STACK 0xFFFFFFFC; allocate 1 cells 0x218 PUSH.C 0x0 0x220 SYSREQ.C 0x6 ; Float:get_gametime() 0x228 STACK 0x4 ; free 1 cells 0x230 STOR.S.pri 0xFFFFFFF8; Float:nexTime 0x238 BREAK ; antiflood.sma:58 0x23C CONST.alt 0x2C ; Float:g_Flooding[33]=0x0 (0.00000) 0x244 LOAD.S.pri 0xC ; id 0x24C BOUNDS 0x20 0x254 LIDX 0x258 MOVE.alt 0x25C LOAD.S.pri 0xFFFFFFF8; Float:nexTime 0x264 PUSH.pri 0x268 PUSH.pri 0x26C PUSH.alt 0x270 PUSH.C 0x8 0x278 CALL 0x8 ; stock bool:operator>(Float:,Float:)(Float:oper1,Float:oper2) 0x280 POP.alt 0x284 JZER 0x3DC ; jump_1 0x28C BREAK ; antiflood.sma:60 0x290 CONST.alt 0xB0 ; g_Flood[33]=0x0 (0.00000) 0x298 LOAD.S.pri 0xC ; id 0x2A0 BOUNDS 0x20 0x2A8 LIDX 0x2AC MOVE.alt 0x2B0 CONST.pri 0x3 ; 0x2E00 (11776.00000) 0x2B8 JSGRTR 0x3A0 ; jump_2 0x2C0 BREAK ; antiflood.sma:62 0x2C4 PUSH.C 0x2C8 ; "STOP_FLOOD" 0x2CC PUSH.ADR 0xC ; id 0x2D4 PUSH.C 0x2A4 ; "** %L **" 0x2DC PUSH.C 0x1 ; 0x2E000000 0x2E4 PUSH.S 0xC ; id 0x2EC PUSH.C 0x14 0x2F4 SYSREQ.C 0x7 ; client_print(id,1,"** %L **",id,"STOP_FLOOD") 0x2FC STACK 0x18 ; free 6 cells 0x304 BREAK ; antiflood.sma:63 0x308 CONST.alt 0x2C ; Float:g_Flooding[33]=0x0 (0.00000) 0x310 LOAD.S.pri 0xC ; id 0x318 BOUNDS 0x20 0x320 IDXADDR 0x324 PUSH.pri 0x328 LOAD.S.pri 0xFFFFFFFC; Float:maxChat 0x330 LOAD.S.alt 0xFFFFFFF8; Float:nexTime 0x338 PUSH.pri 0x33C PUSH.alt 0x340 PUSH.C 0x8 0x348 SYSREQ.C 0x8 ; floatadd 0x350 STACK 0xC ; free 3 cells 0x358 CONST.alt 0x40400000 0x360 PUSH.pri 0x364 PUSH.alt 0x368 PUSH.C 0x8 0x370 SYSREQ.C 0x8 ; floatadd 0x378 STACK 0xC ; free 3 cells 0x380 POP.alt 0x384 STOR.I 0x388 BREAK ; antiflood.sma:64 0x38C CONST.pri 0x1 ; 0x2E000000 (771751936.00000) 0x394 STACK 0x8 ; free 2 cells 0x39C RETN 0x3A0 BREAK ; antiflood.sma:66 ; target:jump_2 0x3A4 CONST.alt 0xB0 ; g_Flood[33]=0x0 (0.00000) 0x3AC LOAD.S.pri 0xC ; id 0x3B4 BOUNDS 0x20 0x3BC IDXADDR 0x3C0 PUSH.pri 0x3C4 LOAD.I 0x3C8 SWAP.pri 0x3CC INC.I 0x3D0 POP.pri 0x3D4 JUMP 0x438 ; jump_3 0x3DC BREAK ; antiflood.sma:68 ; target:jump_1 0x3E0 CONST.alt 0xB0 ; g_Flood[33]=0x0 (0.00000) 0x3E8 LOAD.S.pri 0xC ; id 0x3F0 BOUNDS 0x20 0x3F8 LIDX 0x3FC JZER 0x438 ; jump_4 0x404 BREAK ; antiflood.sma:70 0x408 CONST.alt 0xB0 ; g_Flood[33]=0x0 (0.00000) 0x410 LOAD.S.pri 0xC ; id 0x418 BOUNDS 0x20 0x420 IDXADDR 0x424 PUSH.pri 0x428 LOAD.I 0x42C SWAP.pri 0x430 DEC.I 0x434 POP.pri 0x438 BREAK ; antiflood.sma:73 ; target:jump_3 ; target:jump_4 0x43C CONST.alt 0x2C ; Float:g_Flooding[33]=0x0 (0.00000) 0x444 LOAD.S.pri 0xC ; id 0x44C BOUNDS 0x20 0x454 IDXADDR 0x458 PUSH.pri 0x45C LOAD.S.pri 0xFFFFFFFC; Float:maxChat 0x464 LOAD.S.alt 0xFFFFFFF8; Float:nexTime 0x46C PUSH.pri 0x470 PUSH.alt 0x474 PUSH.C 0x8 0x47C SYSREQ.C 0x8 ; floatadd 0x484 STACK 0xC ; free 3 cells 0x48C POP.alt 0x490 STOR.I 0x494 STACK 0x4 ; free 1 cells 0x49C BREAK ; antiflood.sma:76 ; target:jump_0 0x4A0 ZERO.pri 0x4A4 STACK 0x4 ; free 1 cells 0x4AC RETN 7. Рассмотрим только функцию plugin_init. amxxdump -l -j -e -E -D plugin_init
antiflood.amxx 0x78 PROC ; public plugin_init() 0x7C BREAK ; antiflood.sma:41 0x80 BREAK ; antiflood.sma:43 0x84 PUSH.C 0x164 ; "AMXX Dev Team" 0x8C PUSH.C 0x0 ; AMXX_VERSION_STR[11] "1.8.1.3722" 0x94 PUSH.C 0x138 ; "Anti Flood" 0x9C PUSH.C 0xC 0xA4 SYSREQ.C 0x1 ; register_plugin("Anti Flood",AMXX_VERSION_STR[11]={"1.8.1.3722"},"AMXX Dev Team") 0xAC STACK 0x10 ; free 4 cells 0xB4 BREAK ; antiflood.sma:44 0xB8 PUSH.C 0x19C ; "antiflood.txt" 0xC0 PUSH.C 0x4 0xC8 SYSREQ.C 0x2 ; register_dictionary("antiflood.txt") 0xD0 STACK 0x8 ; free 2 cells 0xD8 BREAK ; antiflood.sma:45 0xDC PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0 0xE4 PUSH.C 0x208 ; 0x0 0xEC PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0 0xF4 PUSH.C 0x1E4 ; "chkFlood" 0xFC PUSH.C 0x1D4 ; "say" 0x104 PUSH.C 0x14 0x10C SYSREQ.C 0x3 ; register_clcmd("say","chkFlood",-1,"",-1) 0x114 STACK 0x18 ; free 6 cells 0x11C BREAK ; antiflood.sma:46 0x120 PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0 0x128 PUSH.C 0x208 ; 0x0 0x130 PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0 0x138 PUSH.C 0x230 ; "chkFlood" 0x140 PUSH.C 0x20C ; "say_team" 0x148 PUSH.C 0x14 0x150 SYSREQ.C 0x3 ; register_clcmd("say_team","chkFlood",-1,"",-1) 0x158 STACK 0x18 ; free 6 cells 0x160 BREAK ; antiflood.sma:47 0x164 PUSH.C 0x0 ; AMXX_VERSION_STR[11] "1.8.1.3722" 0x16C PUSH.C 0x0 ; AMXX_VERSION_STR[11] "1.8.1.3722" 0x174 PUSH.C 0x290 ; "0.75" 0x17C PUSH.C 0x254 ; "amx_flood_time" 0x184 PUSH.C 0x10 0x18C SYSREQ.C 0x4 ; register_cvar("amx_flood_time","0.75",0,0.000000) 0x194 STACK 0x14 ; free 5 cells 0x19C STOR.pri 0x134 ; amx_flood_time 0x1A4 ZERO.pri 0x1A8 RETN // PROC - говорит нам о том, что это
процедура (функция), в нашем случае plugin_init 0x78 PROC ; public plugin_init() Запишем как: public
plugin_init() // PUSH.C - означает, что мы помещаем
константу в стек // Поэтому стек будет содержать (0x164, 0x0, 0x138, 0xC) // Последний PUSH.C - это количество параметров в байтах. 0xC - в десятичной системе равно 12. // Размер 32-разрядной ячейки равен 4, поэтому 12/4 = 3 параметра. 0x84 PUSH.C 0x164 ; "AMXX Dev Team" // третий параметр 0x8C PUSH.C 0x0 ; AMXX_VERSION_STR[11] "1.8.1.3722" // второй параметр 0x94 PUSH.C 0x138 ; "Anti Flood" // первый параметр 0x9C PUSH.C 0xC // SYSREQ.C - конечная инструкция, которая работает с данными из стека // Вызывает функцию register_plugin 0xA4 SYSREQ.C 0x1 ; register_plugin("Anti Flood",AMXX_VERSION_STR[11]={"1.8.1.3722"},"AMXX Dev Team") // STACK - означает, что мы освобождаем из стека 4 ячейки (16 байт) 0xAC STACK 0x10 ; free 4 cells // BREAK - означает прерывание, можно понимать это, как конец строки 0xB4 BREAK ; antiflood.sma:44 Так как используется функция register_plugin, то мы знаем ее синтаксис: register_plugin(const plugin_name[],
const version[], const author[]) Запишем как: register_plugin("Anti
Flood", AMXX_VERSION_STR, "AMXX Dev Team") 0xB8
PUSH.C 0x19C ; "antiflood.txt" // Параметр 0xC0 PUSH.C 0x4 // Один параметр 0xC8 SYSREQ.C 0x2 ; register_dictionary("antiflood.txt") // Вызываем функцию register_dictionary 0xD0 STACK 0x8 ; free 2 cells // Освобождаем из стека 2 ячейки 0xD8 BREAK ; antiflood.sma:45 // Конец строки Так как используется функция register_dictionary, то мы знаем ее синтаксис: register_dictionary ( const file[] )
Запишем как: register_dictionary("antiflood.txt") 0xDC PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0 // Пятый аргумент 0xE4 PUSH.C 0x208 ; 0x0 // Четверый аргумент 0xEC PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0 // Третий аргумент 0xF4 PUSH.C 0x1E4 ; "chkFlood" // Второй аргумент 0xFC PUSH.C 0x1D4 ; "say" // Первый аргумент 0x104 PUSH.C 0x14 // Пять аргументов 0x10C SYSREQ.C 0x3 ; register_clcmd("say","chkFlood",-1,"",-1) // Вызываем функцию register_clcmd 0x114 STACK 0x18 ; free 6 cells // Освобождаем из стека 6 ячеек 0x11C BREAK ; antiflood.sma:46 // Конец строки Так как используется функция register_clcmd, то мы знаем ее синтаксис: register_clcmd(const client_cmd[],
const function[], flags=-1, info[]="", FlagManager=-1) Запишем как: register_clcmd("say",
"chkFlood", -1, "", -1) Или: register_clcmd("say", "chkFlood") Смысл не меняется, так как -1 - означает, что мы не используем флаги, а "" что у нас нет описания команды. 0x120 PUSH.C
0xFFFFFFFF ; signed=-1 float=-1.#QNAN0 // Пятый аргумент 0x128 PUSH.C 0x208 ; 0x0 // Четвертый аргумент 0x130 PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0 // Третий аргумент 0x138 PUSH.C 0x230 ; "chkFlood" // Второй аргумент 0x140 PUSH.C 0x20C ; "say_team" // Первый аргумент 0x148 PUSH.C 0x14 // Пять аргументов 0x150 SYSREQ.C 0x3 ; register_clcmd("say_team","chkFlood",-1,"",-1) // Вызываем функцию register_clcmd 0x158 STACK 0x18 ; free 6 cells // Освобождаем из стека 6 ячеек 0x160 BREAK ; antiflood.sma:47 // Конец строки Запишем как: register_clcmd("say_team",
"chkFlood") 0x164 PUSH.C 0x0
; AMXX_VERSION_STR[11] "1.8.1.3722" // Четвертый аргумент и
комментарий AMXX_VERSION_STR[11] "1.8.1.3722" неверный, ошибка работы
параметра -e 0x16C PUSH.C 0x0 ; AMXX_VERSION_STR[11] "1.8.1.3722" // Третий аргумент и комментарий AMXX_VERSION_STR[11] "1.8.1.3722" неверный, ошибка работы параметра -e 0x174 PUSH.C 0x290 ; "0.75" // Второй аргумент 0x17C PUSH.C 0x254 ; "amx_flood_time" // Первый аргумент 0x184 PUSH.C 0x10 // Четыре аргумента 0x18C SYSREQ.C 0x4 ; register_cvar("amx_flood_time","0.75",0,0.000000) // Вызываем функцию register_cvar 0x194 STACK 0x14 ; free 5 cells // Освобождаем из стека 5 ячеек // STOR - означает копирование в указанный адрес памяти значения. Другими словами у нас идет присвоение переменной amx_flood_time определенного значения. 0x19C STOR.pri 0x134 ; amx_flood_time Так как используется функция register_cvar, то мы знаем ее синтаксис: register_cvar(const name[],const
string[],flags = 0,Float:fvalue = 0.0) Запишем как: amx_flood_time
= register_cvar("amx_flood_time", "0.75", 0, 0.0) Или: amx_flood_time =
register_cvar("amx_flood_time", "0.75") Смысл не изменится, так как два последних параметра имеют стандартные значения. //
RETN - означает return (возвращение) функции. // ZERO.pro - говорит нам о том, что возвращается ноль (return 0). Это аналогично return PLUGIN_CONTINUE. 0x1A4 ZERO.pri 0x1A8 RETN Запишем как: Код: Выделить всё return PLUGIN_CONTINUE 8. Рассмотрим только функцию chkFlood. amxxdump -l -j -e -E -D chkFlood
antiflood.amxx 0x1AC PROC
; public chkFlood(id) 0x1B0 BREAK ; antiflood.sma:50 0x1B4 BREAK ; antiflood.sma:52 ; new Float:maxChat 0x1B8 STACK 0xFFFFFFFC ; allocate 1 cells 0x1C0 PUSH 0x134 ; amx_flood_time 0x1C8 PUSH.C 0x4 0x1D0 SYSREQ.C 0x5 ; Float:get_pcvar_float(amx_flood_time) 0x1D8 STACK 0x8 ; free 2 cells 0x1E0 STOR.S.pri 0xFFFFFFFC ; Float:maxChat 0x1E8 BREAK ; antiflood.sma:54 0x1EC PUSH.S 0xFFFFFFFC ; Float:maxChat 0x1F4 PUSH.C 0x4 0x1FC CALL 0x4C ; stock bool:operator!(Float:)(Float:oper) 0x204 JNZ 0x49C ; jump_0 0x20C BREAK ; antiflood.sma:56 ; new Float:nexTime 0x210 STACK 0xFFFFFFFC ; allocate 1 cells 0x218 PUSH.C 0x0 0x220 SYSREQ.C 0x6 ; Float:get_gametime() 0x228 STACK 0x4 ; free 1 cells 0x230 STOR.S.pri 0xFFFFFFF8 ; Float:nexTime 0x238 BREAK ; antiflood.sma:58 0x23C CONST.alt 0x2C ; Float:g_Flooding[33]=0x0 (0.00000) 0x244 LOAD.S.pri 0xC ; id 0x24C BOUNDS 0x20 0x254 LIDX 0x258 MOVE.alt 0x25C LOAD.S.pri 0xFFFFFFF8 ; Float:nexTime 0x264 PUSH.pri 0x268 PUSH.pri 0x26C PUSH.alt 0x270 PUSH.C 0x8 0x278 CALL 0x8 ; stock bool:operator>(Float:,Float:)(Float:oper1,Float:oper2) 0x280 POP.alt 0x284 JZER 0x3DC ; jump_1 0x28C BREAK ; antiflood.sma:60 0x290 CONST.alt 0xB0 ; g_Flood[33]=0x0 (0.00000) 0x298 LOAD.S.pri 0xC ; id 0x2A0 BOUNDS 0x20 0x2A8 LIDX 0x2AC MOVE.alt 0x2B0 CONST.pri 0x3 ; 0x2E00 (11776.00000) 0x2B8 JSGRTR 0x3A0 ; jump_2 0x2C0 BREAK ; antiflood.sma:62 0x2C4 PUSH.C 0x2C8 ; "STOP_FLOOD" 0x2CC PUSH.ADR 0xC ; id 0x2D4 PUSH.C 0x2A4 ; "** %L **" 0x2DC PUSH.C 0x1 ; 0x2E000000 0x2E4 PUSH.S 0xC ; id 0x2EC PUSH.C 0x14 0x2F4 SYSREQ.C 0x7 ; client_print(id,1,"** %L **",id,"STOP_FLOOD") 0x2FC STACK 0x18 ; free 6 cells 0x304 BREAK ; antiflood.sma:63 0x308 CONST.alt 0x2C ; Float:g_Flooding[33]=0x0 (0.00000) 0x310 LOAD.S.pri 0xC ; id 0x318 BOUNDS 0x20 0x320 IDXADDR 0x324 PUSH.pri 0x328 LOAD.S.pri 0xFFFFFFFC ; Float:maxChat 0x330 LOAD.S.alt 0xFFFFFFF8 ; Float:nexTime 0x338 PUSH.pri 0x33C PUSH.alt 0x340 PUSH.C 0x8 0x348 SYSREQ.C 0x8 ; floatadd 0x350 STACK 0xC ; free 3 cells 0x358 CONST.alt 0x40400000 0x360 PUSH.pri 0x364 PUSH.alt 0x368 PUSH.C 0x8 0x370 SYSREQ.C 0x8 ; floatadd 0x378 STACK 0xC ; free 3 cells 0x380 POP.alt 0x384 STOR.I 0x388 BREAK ; antiflood.sma:64 0x38C CONST.pri 0x1 ; 0x2E000000 (771751936.00000) 0x394 STACK 0x8 ; free 2 cells 0x39C RETN 0x3A0 BREAK ; antiflood.sma:66 ; target:jump_2 0x3A4 CONST.alt 0xB0 ; g_Flood[33]=0x0 (0.00000) 0x3AC LOAD.S.pri 0xC ; id 0x3B4 BOUNDS 0x20 0x3BC IDXADDR 0x3C0 PUSH.pri 0x3C4 LOAD.I 0x3C8 SWAP.pri 0x3CC INC.I 0x3D0 POP.pri 0x3D4 JUMP 0x438 ; jump_3 0x3DC BREAK ; antiflood.sma:68 ; target:jump_1 0x3E0 CONST.alt 0xB0 ; g_Flood[33]=0x0 (0.00000) 0x3E8 LOAD.S.pri 0xC ; id 0x3F0 BOUNDS 0x20 0x3F8 LIDX 0x3FC JZER 0x438 ; jump_4 0x404 BREAK ; antiflood.sma:70 0x408 CONST.alt 0xB0 ; g_Flood[33]=0x0 (0.00000) 0x410 LOAD.S.pri 0xC ; id 0x418 BOUNDS 0x20 0x420 IDXADDR 0x424 PUSH.pri 0x428 LOAD.I 0x42C SWAP.pri 0x430 DEC.I 0x434 POP.pri 0x438 BREAK ; antiflood.sma:73 ; target:jump_3 ; target:jump_4 0x43C CONST.alt 0x2C ; Float:g_Flooding[33]=0x0 (0.00000) 0x444 LOAD.S.pri 0xC ; id 0x44C BOUNDS 0x20 0x454 IDXADDR 0x458 PUSH.pri 0x45C LOAD.S.pri 0xFFFFFFFC ; Float:maxChat 0x464 LOAD.S.alt 0xFFFFFFF8 ; Float:nexTime 0x46C PUSH.pri 0x470 PUSH.alt 0x474 PUSH.C 0x8 0x47C SYSREQ.C 0x8 ; floatadd 0x484 STACK 0xC ; free 3 cells 0x48C POP.alt 0x490 STOR.I 0x494 STACK 0x4 ; free 1 cells 0x49C BREAK ; antiflood.sma:76 ; target:jump_0 0x4A0 ZERO.pri 0x4A4 STACK 0x4 ; free 1 cells 0x4AC RETN 9. На основании полученных результатов формируем исходник (antiflood.sma). Дизассемблированный и оригинальный вариант могут отличаться по синтаксису и структуре, потому что получить точную копию оригинала очень сложно и порой невозможно, но обе версии плагина имеют одинаковый смысл и результат работы. Можно провести оптимизацию полученного исходника. Автор статьи DJ_WEST | |
Просмотров: 1424
| Теги: |
Всего комментариев: 0 | |