Русское сообщество по скриптингу

Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Статьи или фрагменты кода для новичков и уже опытных скриптеров по AMXX.

Модератор: Chuvi

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только обучающему материалу по AMX Mod X.

Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение DJ_WEST » 13 сен 2009, 14:46

Автор: DJ_WEST

Введение
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 - это консольное приложение, предназначенное для дизассемблирования .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


Код: Выделить всё

                                             ; 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) // Вызываем функцию get_pcvar_float
0x1D8                     STACK  0x8         ; free 2 cells // Освобождаем из стека 2 ячейки
0x1E0                STOR.S.pri  0xFFFFFFFC  ; Float:maxChat // Присвоение переменной maxChat
0x1E8                     BREAK              ; antiflood.sma:54

Так как используется функция get_pcvar_float, то мы знаем ее синтаксис:
Код: Выделить всё
get_pcvar_float(pcvar)

Запишем как:
Код: Выделить всё
new Float:maxChat = get_pcvar_float(amx_flood_time)


Код: Выделить всё

0x1EC                    PUSH.S  0xFFFFFFFC  ; Float:maxChat // Аргумент
0x1F4                    PUSH.C  0x4 // Один аргумент
// CALL - означает вызов приватной функции, которая идентифицируется, как operator!
0x1FC                      CALL  0x4C        ; stock bool:operator!(Float:)(Float:oper)

// JNZ (Jump Not Zero) - переход на метку jump_0, если не равно нулю, то есть maxChat != 0. Но выше у нас есть вызов оператора !, который означает отрицание, то есть если !(maxChat != 0) будет true, то произойдет переход на jump_0.
0x204                       JNZ  0x49C       ; jump_0
0x20C                     BREAK              ; antiflood.sma:56

Запишем как:
Код: Выделить всё

if 
(maxChat)


Код: Выделить всё

                                             ; new Float:nexTime
0x210                     STACK  0xFFFFFFFC  ; allocate 1 cells
0x218                    PUSH.C  0x0 // Нет параметров
0x220                  SYSREQ.C  0x6         ; Float:get_gametime() // Вызов функции get_gametime
0x228                     STACK  0x4         ; free 1 cells // Освобождаем из стека одну ячейку
0x230                STOR.S.pri  0xFFFFFFF8  ; Float:nexTime // Присвоение переменной nexTime
0x238                     BREAK              ; antiflood.sma:58

Так как используется функция get_gametime, то мы знаем ее синтаксис:
Код: Выделить всё
get_gametime()

Запишем как:
Код: Выделить всё

new Float
:nexTime = get_gametime()


Код: Выделить всё

// CONST.alt - означает, что в ALT у нас будет хранение 0x2C
0x23C                 CONST.alt  0x2C        ; Float:g_Flooding[33]=0x0 (0.00000)
0x244                LOAD.S.pri  0xC         ; id // Загружаем индекс id массива

// BOUNDS - rоличество элементов массива. В данном случае 32 (размерность 33).
0x24C                    BOUNDS  0x20

// LIDX - одна из инструкций, используемая для доступа к массиву.
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
// JZER (Jump on ZERo) - так как мы имеем сверху вызов оператора >, то в данном случае это условие будет означать следующее, если g_Flooding[id] не больше nexTime, то переходим на метку jump_1.
0x284                      JZER  0x3DC       ; jump_1
0x28C                     BREAK              ; antiflood.sma:60

Запишем как:
Код: Выделить всё

if 
(g_Flooding[id] > nexTime)


Код: Выделить всё

0x290                 CONST.alt  0xB0        ; g_Flood[33]=0x0 (0.00000) // Помещаем в ALT значение g_Flood[id]
0x298                LOAD.S.pri  0xC         ; id
0x2A0                    BOUNDS  0x20
0x2A8                      LIDX
0x2AC                  MOVE.alt
0x2B0                 CONST.pri  0x3         ; 0x2E00 (11776.00000) // Помещаем в PRI значение 3

// JSGRTR - означает переход на метку jump_2, если PRI > ALT. То есть если g_Flood[id] меньше 3 - это true и значит переходим на метку jump_2.
0x2B8                    JSGRTR  0x3A0       ; jump_2
0x2C0                     BREAK              ; antiflood.sma:62

Запишем как:
Код: Выделить всё

if 
(g_Flood[id] >= 3)


Код: Выделить всё

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") // Вызываем функцию client_print
0x2FC                     STACK  0x18        ; free 6 cells
0x304                     BREAK              ; antiflood.sma:63

Так как используется функция client_print, то мы знаем ее синтаксис:
Код: Выделить всё
client_print(index, type, const message[], ...)

Запишем как:
Код: Выделить всё

client_print
(id, 1, "** %L **", id, "STOP_FLOOD")

Или:
Код: Выделить всё

client_print
(id, print_notify, "** %L **", id, "STOP_FLOOD")

Потому что второй аргумент - это константа:
print_notify = 1
print_console = 2
print_chat = 3
print_center = 4


Код: Выделить всё

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 // Два параметра
// floatadd - это функция сложения двух float переменных. Аналогичное действие имеет сложение +.
0x348                  SYSREQ.C  0x8         ; floatadd
0x350                     STACK  0xC         ; free 3 cells
0x358                 CONST.alt  0x40400000 // Помещаем в ALT значение 3.0
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   // Присвоение g_Flooding[id]
0x388                     BREAK              ; antiflood.sma:64

Так как используется функция floatadd, то мы знаем ее синтаксис:
Код: Выделить всё
floatadd(Float:oper1, Float:oper2)

Запишем как:
Код: Выделить всё

g_Flooding
[id] = floatadd(floatadd(maxChat, nexTime), 3.0)


Код: Выделить всё

0x38C                 CONST.pri  0x1         ; 0x2E000000 (771751936.00000) // Означает return 1, что аналогично return PLUGIN_HANDLED
0x394                     STACK  0x8         ; free 2 cells
0x39C                      RETN
0x3A0                     BREAK

Запишем как:
Код: Выделить всё
return PLUGIN_HANDLED


Код: Выделить всё

// Метка jump_2
                                             ; target:jump_2
// Данный кусок кода обозначает, что это массив g_Flood размерностью 33 и индексом id
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

// INC - обозначает увеличение (increment), то есть операция ++
0x3CC                     INC.I
0x3D0                   POP.pri

// JUMP - переход на метку. Но так как мы находимся уже внутри условия, поэтому это может означать, что есть еще else или else if при выполнении перехода на метку jump_1.
0x3D4                      JUMP  0x438       ; jump_3
0x3DC                     BREAK              ; antiflood.sma:68

Запишем как:
Код: Выделить всё

g_Flood
[id]++


Код: Выделить всё

// Метка jump_1
                                             ; target:jump_1
// Данный кусок кода обозначает, что это массив g_Flood размерностью 33 и индексом id                              
0x3E0                 CONST.alt  0xB0        ; g_Flood[33]=0x0 (0.00000)
0x3E8                LOAD.S.pri  0xC         ; id
0x3F0                    BOUNDS  0x20
0x3F8                      LIDX
// Если g_Flood[id] равен 0 будет true, значит перейдем на метку jump_4
0x3FC                      JZER  0x438       ; jump_4
0x404                     BREAK              ; antiflood.sma:70

Запишем как (учитывая JUMP переход выше, следует, что у нас else if, так как в коде есть еще JZER условие):
Код: Выделить всё

else if 
(g_Flood[id])


Код: Выделить всё

// Данный кусок кода обозначает, что это массив g_Flood размерностью 33 и индексом id
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
// DEC - обозначает уменьшение (decrement), то есть операция --
0x430                     DEC.I
0x434                   POP.pri
0x438                     BREAK              ; antiflood.sma:73

Запишем как:
Код: Выделить всё

g_Flood
[id]--


Код: Выделить всё

                                             ; target:jump_3

Метка 3 в нашем случае не содержит кода.

Код: Выделить всё

// Метка jump_4
                                             ; target:jump_4
// Данный кусок кода обозначает, что это массив g_Flooding размерностью 33 и индексом id                              
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 // Помещаем maxChat в PRI
0x464                LOAD.S.alt  0xFFFFFFF8  ; Float:nexTime // Помещаем nexTime в ALT
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   // Присвоение g_Floodind[id]
0x494                     STACK  0x4         ; free 1 cells
0x49C                     BREAK              ; antiflood.sma:76

Запишем как:
Код: Выделить всё

g_Flooding
[id] = floatadd(maxChat, nexTime)


Код: Выделить всё

// Метка jump_0
                                             ; target:jump_0
0x4A0                  ZERO.pri // Означает, что мы возвращаем 0, то есть return 0, а это аналогично return PLUGIN_CONTINUE
0x4A4                     STACK  0x4         ; free 1 cells
0x4AC                      RETN

Запишем как:
Код: Выделить всё

return PLUGIN_CONTINUE


9. На основании полученных результатов формируем исходник (antiflood.sma).
Код: Выделить всё
#include <amxmodx>

new amx_flood_time
new g_Flood
[33]
new Float:g_Flooding[33]

public plugin_init() 
{
    register_plugin("Anti Flood", AMXX_VERSION_STR, "AMXX Dev Team")
    register_dictionary("antiflood.txt")
    register_clcmd("say", "chkFlood")
    register_clcmd("say_team", "chkFlood")
    amx_flood_time = register_cvar("amx_flood_time", "0.75")
    
    return PLUGIN_CONTINUE
}

public chkFlood(id)
{
    new Float:maxChat = get_pcvar_float(amx_flood_time)
    
    if 
(maxChat)
    {    
        new Float
:nexTime = get_gametime()
        
        if 
(g_Flooding[id] > nexTime)
        {
            if (g_Flood[id] >= 3)
            {
                client_print(id, print_notify, "** %L **", id, "STOP_FLOOD")
                g_Flooding[id] = floatadd(floatadd(maxChat, nexTime), 3.0)
            
                return PLUGIN_HANDLED
            
}
            g_Flood[id]++
        }
        else if (g_Flood[id])
            g_Flood[id]--
            
        g_Flooding
[id] = floatadd(maxChat, nexTime)
    }
    
    return PLUGIN_CONTINUE
}

Дизассемблированный и оригинальный вариант могут отличаться по синтаксису и структуре, потому что получить точную копию оригинала очень сложно и порой невозможно, но обе версии плагина имеют одинаковый смысл и результат работы. Можно провести оптимизацию полученного исходника, например:
1. return PLUGIN_CONTINUE в plugin_init можно убрать, так как даже его не указывая будет аналогичный результат.
2. floatadd можно заменить оператором +, так как сложение float переменных нам даст точно такой же результат.
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3641
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2209 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение Endi » 13 сен 2009, 15:50

Норм статья, и дампер тоже давольно мощная штука.
Вест, а знаешь как сокрыть плагин от дампа ? :)
Аватара пользователя
Endi
 
Сообщения: 95
Зарегистрирован: 25 авг 2009, 11:26
Благодарил (а): 13 раз.
Поблагодарили: 20 раз.
Опыт программирования: Около 6 месяцев
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение DJ_WEST » 13 сен 2009, 16:29

Вест, а знаешь как сокрыть плагин от дампа ?

Конечно =) Но этим ты не скроешь его от AMX disassembler от Wraith.
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3641
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2209 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение Ser_UFL » 13 сен 2009, 17:31

На основании этой статьи у меня возник вопрос: почему до сих пор не написан автоматизированный декомпилятор, который будет выдавать готовый исходный код плагина, анализируя декомпилированный код, делая несложные подсчеты (как я понял) и записывая все на основе синтаксиса переменных, которые будут заложены в базу?
Запомните, всегда по жизни вас будут красить вежливость и спокойствие, а не наезды и дешевые понты ;)
Аватара пользователя
Ser_UFL
 
Сообщения: 975
Зарегистрирован: 22 авг 2009, 19:30
Откуда: Hell
Благодарил (а): 276 раз.
Поблагодарили: 380 раз.
Языки программирования: Counter-Strike 1.6:
WebMod-scripts, little Pawn.

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение Fedcomp » 13 сен 2009, 21:48

Надо радоваться что хотя бы amxx декомпилятор сделали ...
:ps: Спс за статью будем разбираться, хотя бы на русском
Не помогаю в ЛС - есть форум.
Плагины тоже не пишу, на форуме достаточно хороших скриптеров.


"я ставлю зависимости потому что мне приятно" - subb98 @ 2017
Аватара пользователя
Fedcomp
Администратор
 
Сообщения: 4936
Зарегистрирован: 28 авг 2009, 20:47
Благодарил (а): 813 раз.
Поблагодарили: 1317 раз.
Языки программирования: =>
pawn / php / python / ruby
javascript / rust

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение Endi » 13 сен 2009, 22:09

Ладно, чуток покритикую :)
Не совсем точно обозначает название статьи суть содержимого, если конечно не будет серия статей на эту тему. Ибо примитивные вызовы функций восстанавливать и самый обычным чуловек смогет с очень поверхностным багажем знаний по скриптингу. А вот например такой код
Код: Выделить всё
new num = random(872195943)
new pass = (num % 1214) * ((num / 2) % 27)

думаю долеко не каждый смогет восстановить.
Аватара пользователя
Endi
 
Сообщения: 95
Зарегистрирован: 25 авг 2009, 11:26
Благодарил (а): 13 раз.
Поблагодарили: 20 раз.
Опыт программирования: Около 6 месяцев
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение DJ_WEST » 13 сен 2009, 23:34

На основании этой статьи у меня возник вопрос: почему до сих пор не написан автоматизированный декомпилятор, который будет выдавать готовый исходный код плагина, анализируя декомпилированный код, делая несложные подсчеты (как я понял) и записывая все на основе синтаксиса переменных, которые будут заложены в базу?

Ну теоретически сделать можно, только программа может сделать с ошибками, здесь еще нужна человеческая логика.
думаю долеко не каждый смогет восстановить.

Статья дает немного основы, показывая на примере, конечно, чем больше плагин и сложней код, тем больше нужно подумать. Ну твои строки в UCP я расшифровывал =)
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3641
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2209 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение Endi » 14 сен 2009, 09:38

Offtop:
А почему тогда досехпор никаких намеков на баги или обход через эмуляцию авторизации? :P

Ontop:
Хоть у amx возможности ограничены, но не до такой степени чтобы быстренько накатать полноценный декомпилятор. Например где Вы видели программу которая бы восстановила по exe'шнику исходный код на си или дельфи. Да и это уже совсем для нубов.. :) Кому надо, дизасмит и сам соберет.
Аватара пользователя
Endi
 
Сообщения: 95
Зарегистрирован: 25 авг 2009, 11:26
Благодарил (а): 13 раз.
Поблагодарили: 20 раз.
Опыт программирования: Около 6 месяцев
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение Fedcomp » 14 сен 2009, 10:12

Endi писал(а):Например где Вы видели программу которая бы восстановила по exe'шнику исходный код на си или дельфи

Была такая, к сожалению только под 5 дельфятник
Не помогаю в ЛС - есть форум.
Плагины тоже не пишу, на форуме достаточно хороших скриптеров.


"я ставлю зависимости потому что мне приятно" - subb98 @ 2017
Аватара пользователя
Fedcomp
Администратор
 
Сообщения: 4936
Зарегистрирован: 28 авг 2009, 20:47
Благодарил (а): 813 раз.
Поблагодарили: 1317 раз.
Языки программирования: =>
pawn / php / python / ruby
javascript / rust

Re: Декомпиляция плагинов (из .amxx в .sma) на основе amxxdump

Сообщение DJ_WEST » 14 сен 2009, 10:29

А почему тогда досехпор никаких намеков на баги или обход через эмуляцию авторизации? :P

У меня нет желания декомпилить весь плагин, я только расшифровал строки. При наличии времени и желания можно и весь плагин получить =)
Не пишите мне в ЛС: если вам нужна помощь на бесплатной основе. Любые вопросы на форум.
Аватара пользователя
DJ_WEST
Администратор
 
Сообщения: 3641
Зарегистрирован: 22 авг 2009, 00:38
Благодарил (а): 48 раз.
Поблагодарили: 2209 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Counter-Strike: Source
Left 4 Dead
Left 4 Dead 2

След.

Вернуться в Статьи / фрагменты кода

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10