Decompilando un plugin - Dia 1: Natives, funciones, stocks e includes
Bueno, hoy vamos a obtener informacion de nuestro plugin mediante el AMXDump, simplemente copiamos en la carpeta del AMXDump, el AMXDump_util.exe y nuestro .amxx
(chanta.amxx), ejecutamos AMXDump_util.exe y ponemos el nombre del plugin. Seguidamente copiamos toda la consola a un .txt para mayor comodidad =)
Este es mi dump:
PHP Code:
Escribe el nombre del plugin:
chanta
Procesando...
Forced loaded modules: fakemeta, hamsandwich
Required libraries: fakemeta, hamsandwich
native: SetHamParamFloat
native: random_float
native: set_pdata_int
native: get_pdata_int
native: is_user_alive
native: get_maxplayers
native: client_print
native: TrieKeyExists
native: get_user_authid
native: TrieSetCell
native: TrieCreate
native: RegisterHam
native: register_clcmd
native: register_plugin
native: set_fail_state
native: callfunc_end
native: callfunc_push_str
native: callfunc_push_int
native: callfunc_begin_i
native: get_func_id
native: floatcmp
0x00000008 stock bool:operator<(Float:,Float:)(Float:oper1,Float:oper2)
0x00000398 public Chanta(id)
0x0000004C public __fatal_ham_error(Ham:id,HamError:err,reason[])
0x00000780 public client_putinserver(id)
0x0000052C public fw_TakeDamage(victim,inflictor,attacker,Float:damage,damage_ty
pe)
0x000002C4 public plugin_cfg()
0x00000200 public plugin_init()
codestart codeend address type name
0x00000008 0x0000004C 0x00000010 local val oper2
0x00000008 0x0000004C 0x0000000C local val oper1
0x00000094 0x000001F8 0xFFFFFFF8 local val fail
0x00000058 0x000001F8 0xFFFFFFFC local val func
0x0000004C 0x00000200 0x00000014 local ref reason[0]
0x0000004C 0x00000200 0x00000010 local val err
0x0000004C 0x00000200 0x0000000C local val id
0x000002F4 0x00000390 0xFFFFFFFC local val i
0x000003A4 0x0000052C 0xFFFFFF74 local val authid[35]
0x00000398 0x0000052C 0x0000000C local val id
0x000006B8 0x00000780 0x000002A0 static val Damage
0x0000052C 0x00000780 0x0000001C local val damage_type
0x0000052C 0x00000780 0x00000018 local val damage
0x0000052C 0x00000780 0x00000014 local val attacker
0x0000052C 0x00000780 0x00000010 local val inflictor
0x0000052C 0x00000780 0x0000000C local val victim
0x00000780 0x000007BC 0x0000000C local val id
0x00000008 0x0000004C 0x00000008 stock operator<(Float:,Float:)
0x00000200 0x000007BC 0x000000AC global val AuthId
0x00000398 0x0000052C 0x00000398 public Chanta
0x00000200 0x000007BC 0x000000B0 global val Users[2][0]
0x0000004C 0x00000200 0x0000004C public __fatal_ham_error
0x00000200 0x000007BC 0x00000028 global val chanta[33]
0x00000780 0x000007BC 0x00000780 public client_putinserver
0x0000052C 0x00000780 0x0000052C public fw_TakeDamage
0x000002C4 0x00000398 0x000002C4 public plugin_cfg
0x00000200 0x000002C4 0x00000200 public plugin_init
0x000000AC new Trie:AuthId
0x000000B0 new Users[2][]
0x00000028 new bool:chanta[33]
0x8 PROC ; stock bool:operator<(Float:,Float
:)(Float:oper1,Float:oper2)
0xC BREAK ; hamsandwich.inc:154
0x10 BREAK ; hamsandwich.inc:155
0x14 PUSH.S 0x10 ; Float:oper2
0x1C PUSH.S 0xC ; Float:oper1
0x24 PUSH.C 0x8
0x2C SYSREQ.C 0x0 ; floatcmp
0x34 STACK 0xC ; free 3 cells
0x3C MOVE.alt
0x40 ZERO.pri
0x44 SGRTR
0x48 RETN
0x4C PROC ; public __fatal_ham_error(Ham:id,H
amError:err,reason[])
0x50 BREAK ; chanta.sma:357
0x54 BREAK ; chanta.sma:360
; new func
0x58 STACK 0xFFFFFFFC ; allocate 1 cells
0x60 PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0
0x68 PUSH.C 0x0 ; "HamFilter"
0x70 PUSH.C 0x8
0x78 SYSREQ.C 0x1 ; get_func_id
0x80 STACK 0xC ; free 3 cells
0x88 STOR.S.pri 0xFFFFFFFC ; func
0x90 BREAK ; chanta.sma:361
; new bool:fail
0x94 PUSH.C 0x1 ; 0x61000000
0x9C BREAK ; chanta.sma:363
0xA0 LOAD.S.pri 0xFFFFFFFC ; func
0xA8 CONST.alt 0xFFFFFFFF
0xB0 JEQ 0x100 ; jump_0
0xB8 PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0
0xC0 PUSH.S 0xFFFFFFFC ; func
0xC8 PUSH.C 0x8
0xD0 SYSREQ.C 0x2 ; callfunc_begin_i
0xD8 STACK 0xC ; free 3 cells
0xE0 EQ.C.pri 0x1
0xE8 JZER 0x100 ; jump_1
0xF0 CONST.pri 0x1 ; 0x61000000 (1627389952.00000)
0xF8 JUMP 0x104 ; jump_2
0x100 ZERO.pri ; target:jump_0
; target:jump_1
0x104 JZER 0x1B8 ; jump_3
; target:jump_2
0x10C BREAK ; chanta.sma:365
0x110 PUSH.S 0xC ; Ham:id
0x118 PUSH.C 0x4
0x120 SYSREQ.C 0x3 ; callfunc_push_int
0x128 STACK 0x8 ; free 2 cells
0x130 BREAK ; chanta.sma:366
0x134 PUSH.S 0x10 ; HamError:err
0x13C PUSH.C 0x4
0x144 SYSREQ.C 0x3 ; callfunc_push_int
0x14C STACK 0x8 ; free 2 cells
0x154 BREAK ; chanta.sma:367
0x158 PUSH.C 0x0 ; "HamFilter"
0x160 PUSH.S 0x14 ; reason[]
0x168 PUSH.C 0x8
0x170 SYSREQ.C 0x4 ; callfunc_push_str
0x178 STACK 0xC ; free 3 cells
0x180 BREAK ; chanta.sma:368
0x184 PUSH.C 0x0
0x18C SYSREQ.C 0x5 ; callfunc_end
0x194 STACK 0x4 ; free 1 cells
0x19C EQ.C.pri 0x1
0x1A4 JZER 0x1B8 ; jump_4
0x1AC BREAK ; chanta.sma:370
0x1B0 ZERO.S 0xFFFFFFF8 ; bool:fail
0x1B8 BREAK ; chanta.sma:373
; target:jump_3
; target:jump_4
0x1BC LOAD.S.pri 0xFFFFFFF8 ; bool:fail
0x1C4 JZER 0x1F0 ; jump_5
0x1CC BREAK ; chanta.sma:375
0x1D0 PUSH.S 0x14 ; reason[]
0x1D8 PUSH.C 0x4
0x1E0 SYSREQ.C 0x6 ; set_fail_state
0x1E8 STACK 0x8 ; free 2 cells
0x1F0 STACK 0x8 ; free 2 cells
; target:jump_5
0x1F8 ZERO.pri
0x1FC RETN
0x200 PROC ; public plugin_init()
0x204 BREAK ; chanta.sma:17
0x208 BREAK ; chanta.sma:18
0x20C PUSH.C 0x17C ; "[R]ak"
0x214 PUSH.C 0x16C ; "1.7"
0x21C PUSH.C 0x150 ; "Chanta"
0x224 PUSH.C 0xC
0x22C SYSREQ.C 0x7 ; register_plugin
0x234 STACK 0x10 ; free 4 cells
0x23C BREAK ; chanta.sma:19
0x240 PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0
0x248 PUSH.C 0x1CC ; 0x0
0x250 PUSH.C 0xFFFFFFFF ; signed=-1 float=-1.#QNAN0
0x258 PUSH.C 0x1B0 ; "Chanta"
0x260 PUSH.C 0x194 ; "chanta"
0x268 PUSH.C 0x14
0x270 SYSREQ.C 0x8 ; register_clcmd
0x278 STACK 0x18 ; free 6 cells
0x280 BREAK ; chanta.sma:20
0x284 PUSH.C 0x0 ; "HamFilter"
0x28C PUSH.C 0x1EC ; "fw_TakeDamage"
0x294 PUSH.C 0x1D0 ; "player"
0x29C PUSH.C 0x9 ; 0x46000000
0x2A4 PUSH.C 0x10
0x2AC SYSREQ.C 0x9 ; RegisterHam
0x2B4 STACK 0x14 ; free 5 cells
0x2BC ZERO.pri
0x2C0 RETN
0x2C4 PROC ; public plugin_cfg()
0x2C8 BREAK ; chanta.sma:23
0x2CC BREAK ; chanta.sma:24
0x2D0 PUSH.C 0x0
0x2D8 SYSREQ.C 0xA ; TrieCreate
0x2E0 STACK 0x4 ; free 1 cells
0x2E8 STOR.pri 0xAC ; Trie:AuthId
0x2F0 BREAK ; chanta.sma:25
; new i
0x2F4 PUSH.C 0x0 ; "HamFilter"
0x2FC JUMP 0x310 ; jump_6
0x304 BREAK ; chanta.sma:26
; target:jump_8
0x308 INC.S 0xFFFFFFFC ; i
0x310 LOAD.S.pri 0xFFFFFFFC ; i
; target:jump_6
0x318 CONST.alt 0x2 ; 0x610000 (6356992.00000)
0x320 JSGEQ 0x388 ; jump_7
0x328 BREAK ; chanta.sma:26
0x32C PUSH.C 0x1 ; 0x61000000
0x334 CONST.alt 0xB0 ; Users[2][]=0x8 (8.00000)
0x33C LOAD.S.pri 0xFFFFFFFC ; i
0x344 BOUNDS 0x1
0x34C IDXADDR
0x350 MOVE.alt
0x354 LOAD.I
0x358 ADD
0x35C PUSH.pri
0x360 PUSH 0xAC ; Trie:AuthId
0x368 PUSH.C 0xC
0x370 SYSREQ.C 0xB ; TrieSetCell
0x378 STACK 0x10 ; free 4 cells
0x380 JUMP 0x304 ; jump_8
0x388 STACK 0x4 ; free 1 cells
; target:jump_7
0x390 ZERO.pri
0x394 RETN
0x398 PROC ; public Chanta(id)
0x39C BREAK ; chanta.sma:29
0x3A0 BREAK ; chanta.sma:30
; new authid[35]
0x3A4 STACK 0xFFFFFF74 ; allocate 35 cells
0x3AC ZERO.pri
0x3B0 ADDR.alt 0xFFFFFF74
0x3B8 FILL 0x8C ; 35 cells
0x3C0 BREAK ; chanta.sma:31
0x3C4 PUSH.C 0x22 ; 0x0
0x3CC PUSH.ADR 0xFFFFFF74 ; authid[35]
0x3D4 PUSH.S 0xC ; id
0x3DC PUSH.C 0xC
0x3E4 SYSREQ.C 0xC ; get_user_authid
0x3EC STACK 0x10 ; free 4 cells
0x3F4 BREAK ; chanta.sma:32
0x3F8 PUSH.ADR 0xFFFFFF74 ; authid[35]
0x400 PUSH 0xAC ; Trie:AuthId
0x408 PUSH.C 0x8
0x410 SYSREQ.C 0xD ; TrieKeyExists
0x418 STACK 0xC ; free 3 cells
0x420 JZER 0x518 ; jump_9
0x428 BREAK ; chanta.sma:33
0x42C CONST.alt 0x28 ; bool:chanta[33]=0x0 (0.00000)
0x434 LOAD.S.pri 0xC ; id
0x43C BOUNDS 0x20
0x444 IDXADDR
0x448 PUSH.pri
0x44C CONST.alt 0x28 ; bool:chanta[33]=0x0 (0.00000)
0x454 LOAD.S.pri 0xC ; id
0x45C BOUNDS 0x20
0x464 LIDX
0x468 JZER 0x47C ; jump_10
0x470 ZERO.pri
0x474 JUMP 0x484 ; jump_11
0x47C CONST.pri 0x1 ; 0x61000000 (1627389952.00000)
; target:jump_10
0x484 POP.alt ; target:jump_11
0x488 STOR.I
0x48C BREAK ; chanta.sma:34
0x490 CONST.alt 0x28 ; bool:chanta[33]=0x0 (0.00000)
0x498 LOAD.S.pri 0xC ; id
0x4A0 BOUNDS 0x20
0x4A8 LIDX
0x4AC JZER 0x4C4 ; jump_12
0x4B4 CONST.pri 0x24C ; "Activado"
0x4BC JUMP 0x4CC ; jump_13
0x4C4 CONST.pri 0x270 ; "Desactivado"
; target:jump_12
0x4CC PUSH.pri ; target:jump_13
0x4D0 PUSH.C 0x224 ; "Chanta %s"
0x4D8 PUSH.C 0x4 ; "amFilter"
0x4E0 PUSH.S 0xC ; id
0x4E8 PUSH.C 0x10
0x4F0 SYSREQ.C 0xE ; client_print
0x4F8 STACK 0x14 ; free 5 cells
0x500 BREAK ; chanta.sma:35
0x504 CONST.pri 0x1 ; 0x61000000 (1627389952.00000)
0x50C STACK 0x8C ; free 35 cells
0x514 RETN
0x518 BREAK ; chanta.sma:37
; target:jump_9
0x51C ZERO.pri
0x520 STACK 0x8C ; free 35 cells
0x528 RETN
0x52C PROC ; public fw_TakeDamage(victim,infli
ctor,attacker,Float:damage,damage_type)
0x530 BREAK ; chanta.sma:40
0x534 BREAK ; chanta.sma:41
0x538 LOAD.S.pri 0x14 ; attacker
0x540 LOAD.S.alt 0xC ; victim
0x548 JEQ 0x658 ; jump_14
0x550 CONST.pri 0x1 ; 0x61000000 (1627389952.00000)
0x558 LOAD.S.alt 0x14 ; attacker
0x560 SLEQ
0x564 PUSH.pri
0x568 PUSH.alt
0x56C PUSH.C 0x0
0x574 SYSREQ.C 0xF ; get_maxplayers
0x57C STACK 0x4 ; free 1 cells
0x584 POP.alt
0x588 SGEQ
0x58C POP.alt
0x590 AND
0x594 JZER 0x5D4 ; jump_15
0x59C PUSH.S 0x14 ; attacker
0x5A4 PUSH.C 0x4
0x5AC SYSREQ.C 0x10 ; is_user_alive
0x5B4 STACK 0x8 ; free 2 cells
0x5BC JZER 0x5D4 ; jump_16
0x5C4 CONST.pri 0x1 ; 0x61000000 (1627389952.00000)
0x5CC JUMP 0x5D8 ; jump_17
0x5D4 ZERO.pri ; target:jump_15
; target:jump_16
0x5D8 NOT ; target:jump_17
0x5DC JNZ 0x658 ; jump_18
0x5E4 PUSH.C 0x5 ; 0x6D000000
0x5EC PUSH.C 0x4B ; 0x0
0x5F4 PUSH.S 0xC ; victim
0x5FC PUSH.C 0xC
0x604 SYSREQ.C 0x11 ; get_pdata_int
0x60C STACK 0x10 ; free 4 cells
0x614 EQ.C.pri 0x1
0x61C JNZ 0x658 ; jump_19
0x624 CONST.alt 0x28 ; bool:chanta[33]=0x0 (0.00000)
0x62C LOAD.S.pri 0x14 ; attacker
0x634 BOUNDS 0x20
0x63C LIDX
0x640 NOT
0x644 JNZ 0x658 ; jump_20
0x64C ZERO.pri
0x650 JUMP 0x660 ; jump_21
0x658 CONST.pri 0x1 ; 0x61000000 (1627389952.00000)
; target:jump_14
; target:jump_18
; target:jump_19
; target:jump_20
0x660 JZER 0x678 ; jump_22
; target:jump_21
0x668 BREAK ; chanta.sma:42
0x66C CONST.pri 0x1 ; 0x61000000 (1627389952.00000)
0x674 RETN
0x678 BREAK ; chanta.sma:44
; target:jump_22
0x67C PUSH.C 0x5 ; 0x6D000000
0x684 PUSH.C 0x1 ; 0x61000000
0x68C PUSH.C 0x4B ; 0x0
0x694 PUSH.S 0xC ; victim
0x69C PUSH.C 0x10
0x6A4 SYSREQ.C 0x12 ; set_pdata_int
0x6AC STACK 0x14 ; free 5 cells
0x6B4 BREAK ; chanta.sma:45
; static Float:Damage
0x6B8 BREAK ; chanta.sma:47
0x6BC CONST.pri 0x42700000 ; signed=1114636288 float=60.000000
0x6C4 LOAD.S.alt 0x18 ; Float:damage
0x6CC PUSH.pri
0x6D0 PUSH.pri
0x6D4 PUSH.alt
0x6D8 PUSH.C 0x8
0x6E0 CALL 0x8 ; stock bool:operator<(Float:,Float
:)(Float:oper1,Float:oper2)
0x6E8 POP.alt
0x6EC JZER 0x730 ; jump_23
0x6F4 BREAK ; chanta.sma:48
0x6F8 PUSH.C 0x43020000 ; signed=1124204544 float=130.00000
0
0x700 PUSH.C 0x42700000 ; signed=1114636288 float=60.000000
0x708 PUSH.C 0x8
0x710 SYSREQ.C 0x13 ; random_float
0x718 STACK 0xC ; free 3 cells
0x720 STOR.pri 0x2A0 ; Float:Damage
0x728 JUMP 0x744 ; jump_24
0x730 BREAK ; chanta.sma:50
; target:jump_23
0x734 LOAD.S.pri 0x18 ; Float:damage
0x73C STOR.pri 0x2A0 ; Float:Damage
0x744 BREAK ; chanta.sma:52
; target:jump_24
0x748 PUSH 0x2A0 ; Float:Damage
0x750 PUSH.C 0x4 ; "amFilter"
0x758 PUSH.C 0x8
0x760 SYSREQ.C 0x14 ; SetHamParamFloat
0x768 STACK 0xC ; free 3 cells
0x770 BREAK ; chanta.sma:53
0x774 CONST.pri 0x1 ; 0x61000000 (1627389952.00000)
0x77C RETN
0x780 PROC ; public client_putinserver(id)
0x784 BREAK ; chanta.sma:56
0x788 BREAK ; chanta.sma:57
0x78C CONST.alt 0x28 ; bool:chanta[33]=0x0 (0.00000)
0x794 LOAD.S.pri 0xC ; id
0x79C BOUNDS 0x20
0x7A4 IDXADDR
0x7A8 MOVE.alt
0x7AC ZERO.pri
0x7B0 STOR.I
0x7B4 ZERO.pri
0x7B8 RETN
file: float.inc
file: hamsandwich.inc
file: chanta.sma
Presione una tecla para continuar . . .
Como pueden observar, el AMXDump dumpea de forma ordenada las native calls, forwards, etc. Con esto tenemos ya la primera impresion de como es el plugin:
PHP Code:
Forced loaded modules: fakemeta, hamsandwich
Required libraries: fakemeta, hamsandwich
native: SetHamParamFloat
native: random_float
native: set_pdata_int
native: get_pdata_int
native: is_user_alive
native: get_maxplayers
native: client_print
native: TrieKeyExists
native: get_user_authid
native: TrieSetCell
native: TrieCreate
native: RegisterHam
native: register_clcmd
native: register_plugin
native: set_fail_state
native: callfunc_end
native: callfunc_push_str
native: callfunc_push_int
native: callfunc_begin_i
native: get_func_id
native: floatcmp
0x00000008 stock bool:operator<(Float:,Float:)(Float:oper1,Float:oper2)
0x00000398 public Chanta(id)
0x0000004C public __fatal_ham_error(Ham:id,HamError:err,reason[])
0x00000780 public client_putinserver(id)
0x0000052C public fw_TakeDamage(victim,inflictor,attacker,Float:damage,damage_ty
pe)
0x000002C4 public plugin_cfg()
0x00000200 public plugin_init()
2 Modulos y sus librerias: fakemeta y hamsandwich
PHP Code:
Forced loaded modules: fakemeta, hamsandwich
Required libraries: fakemeta, hamsandwich
21 Native calls:
PHP Code:
native: SetHamParamFloat
native: random_float
native: set_pdata_int
native: get_pdata_int
native: is_user_alive
native: get_maxplayers
native: client_print
native: TrieKeyExists
native: get_user_authid
native: TrieSetCell
native: TrieCreate
native: RegisterHam
native: register_clcmd
native: register_plugin
native: set_fail_state
native: callfunc_end
native: callfunc_push_str
native: callfunc_push_int
native: callfunc_begin_i
native: get_func_id
native: floatcmp
Luego comprobaremos que las que "realmente usa" el plugin son menos, la razon de esto es que las funciones de fakemeta y hamsandwich estan formadas por natives
y demas movidas que deben ser incluidas en el plugin para que este funcione (Usando la vista del Scasm en el AMXXDisassembler esto quedara mucho mas claro =)
6 Forwards y 1 Stock:
PHP Code:
stock bool:operator<(Float:,Float:)(Float:oper1,Float:oper2)
public Chanta(id)
public __fatal_ham_error(Ham:id,HamError:err,reason[])
public client_putinserver(id)
public fw_TakeDamage(victim,inflictor,attacker,Float:damage,damage_type)
public plugin_cfg()
public plugin_init()
De estas 6 forwards y 1 stock, nuestro .sma del plugin decompilado "solo tendra" 5 forwards:
PHP Code:
public Chanta(id)
public client_putinserver(id)
public fw_TakeDamage(victim,inflictor,attacker,Float:damage,damage_type)
public plugin_cfg()
public plugin_init()
¿Por que? el stock stock bool
perator<(Float:,Float
(Float
per1,Flo at
per2) viene con la libreria float.inc, que ya esta incluida en el amxmodx.inc,
public __fatal_ham_error(Ham:id,HamError:err,reason[]) esta definida en la libreria del modulo Hamsandwich (hamsandwich.inc)
Con toda esta informacion ya somos capaces de hacer el esqueleto del plugin de una manera sencilla:
PHP Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
public plugin_init()
{
}
public plugin_cfg()
{
}
public client_putinserver(id)
{
}
public fw_TakeDamage(victim,inflictor,attacker,Float:damage,damage_type)
{
}
Esto ya nos da alguna pista, obviamente tendremos que registrar el callback de Takedamage con RegisterHam.
Bueno, tal y como va la cosa nadie deberia de tener ningun problema para entender esto, como ven, en poquito tiempo ya hemos identificado los modulos y librerias
que utiliza el plugin, sus forwards y natives sin esfuerzo alguno
Posiblemente, la entrega de este cutre day-a-day sea sobre la decompilacion de plugin_init, estoy pensandomelo y cuando lo sepa lo pongo =)
pD: Cualquier cosa mal, solo diganme ^^
Proximo-> Dia 2: Decompilando funciones. plugin_init
__________________