-=ИгРы и ПрОгИ=-
-=СоФт БлОк=-
-=МиНи-ЧаТ=-
-=НаШ ОпРоС=-
Как вам новый дизайн?
Всего ответов: 64
[Обсудить опрос на форуме]
-=ProUserS=-
-=ФоРмА ВхОдА=-
Суббота
28.12.2024
10:41

-=НаШа СсЫлКа=-
ProUserS team portaL

Мы будем очень
благодарны если вы
разместите нашь баннер
у себя на сайте!
© ProUserS PortaL
www.ProUserS.ru

-=СтАтИсТиКа=-
Сегодняшние посетители:
 

Online: 1
Guests: 1
UserS: 0
Реклама на нашем сайте

banka3 banka3 banka3 banka3

Не пропусти!
  • S.T.A.L.K.E.R. 2 в 2012
    S.T.A.L.K.E.R. 2 в 2012
  • Todd Hollenshead о Doom 4 и Wolfenstein
    Todd Hollenshead о Doom 4 и Wolfenstein
  • Assassin's Creed: Revelations! Захватывающее продолжение?
    Assassin's Creed: Revelations! Захватывающее продолжение?
  • Уникальные статьи на заказ (копирайт / рерайт / описание сайтов / SEO статьи)
    Уникальные статьи на заказ (копирайт / рерайт / описание сайтов / SEO статьи)
  • img
    AllStars - игровые консоли
  • Загрузка...
Главная » Статьи » Статьи Counter-Strike

Decompiling Plugins (.amx/x -> .sma) rus
Статья о том как получить исходный код плагина из готового файла 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  - это консольное приложение, предназначенное для дизассемблирования .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
Категория: Статьи Counter-Strike | Добавил: FoXm@n (27.02.2010)
Просмотров: 1424 | Теги: amx, amxxdump, amxx, cs, sma, Valve, steam | Рейтинг: 0.0/0

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Реклама на нашем сайте
banka2

banka3 banka3 banka3 banka3

--