Авторизация Регистрация Забыли пароль?
Реклама

Статьи
Наш игровой сервер
Наши сервисы
Мониторинг серверов
Информация
Нам интересно знать
Популярные теги
Популярные материалы
    Партнеры
    Счетчики
    Вы находитесь:

    Категория: Мувы

    Decompiling Plugins (.amx/x -> .sma) rus (часть 2)

    Автор: crash94

    Дата: 25 февраля 2010

    Просмотров: 2 658

    Комментариев: 1

    Decompiling Plugins (.amx/x -> .sma) rus (часть 2)

    Статья о том как получить исходный код плагина из готового файла 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'.

    Описание

    amxxdump.zip [0 b] (cкачиваний: 2880) - это консольное приложение, предназначенное для дизассемблирования .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
    Похожие публикации
    Комментарии на сайте
    abdobiskra

    Написал: abdobiskra 20 октября 2015 21:50 Группа: Юзер
    nice )))
    Цитировать
    Новый комментарий

    Информация

    Посетители, находящиеся в группе lamo, не могут оставлять комментарии к данной публикации.