hlmod.hu

Magyar Half-Life Mód közösség!
Pontos idő: 2024.04.23. 16:42



Jelenlévő felhasználók

Jelenleg 156 felhasználó van jelen :: 0 regisztrált, 0 rejtett és 156 vendég

A legtöbb felhasználó (1565 fő) 2020.11.21. 11:26-kor tartózkodott itt.

Regisztrált felhasználók: nincs regisztrált felhasználó az elmúlt 5 percben aktív felhasználók alapján

Utoljára aktív
Ahhoz hogy lásd ki volt utoljára aktív, be kell jelentkezned.



Az oldal teljeskörű
használatához regisztrálj.

Regisztráció

Kereső


Új téma nyitása  Hozzászólás a témához  [ 11 hozzászólás ]  Oldal 1 2 Következő
Szerző Üzenet
 Hozzászólás témája: Nem akarja valaki lefordítani magyarra?
HozzászólásElküldve: 2014.03.12. 18:43 
Offline
Tag
Avatar

Csatlakozott: 2013.04.28. 11:55
Hozzászólások: 57
Megköszönt másnak: 9 alkalommal
Megköszönték neki: 2 alkalommal
Sziasztok!
Találtam, egy fontos leírást, hogyan kell amx-filet sma-vá konvertálni.
De, sajnos rósz angol tudásomnak hála, nem tudom az egész szöveget lefordítani...

Aki, lefordítaná ezer hála...

https://forums.alliedmods.net/showthread.php?t=19368?t=19368

_________________
Kép


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.12. 18:57 
Offline
Jómunkásember
Avatar

Csatlakozott: 2013.09.21. 12:03
Hozzászólások: 318
Megköszönt másnak: 31 alkalommal
Megköszönték neki: 30 alkalommal
Ennek nem itt a helye! És szerintem ez neked nem fog menni ...már bocs!

_________________
Kép


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.12. 19:01 
Offline
Tiszteletbeli
Avatar

Csatlakozott: 2011.09.18. 13:01
Hozzászólások: 4270
Megköszönt másnak: 55 alkalommal
Megköszönték neki: 513 alkalommal
lis789 írta:
Ennek nem itt a helye! És szerintem ez neked nem fog menni ...már bocs!

Hat ha ezt erti akkor mehet :D

_________________
Idk. Csak ugy funbooo.
Kép

Ők köszönték meg DeteCT0R nek ezt a hozzászólást: lis789 (2014.03.12. 19:10)
  Népszerűség: 2.27%


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.12. 21:43 
Offline
Tiszteletbeli
Avatar

Csatlakozott: 2011.08.15. 14:42
Hozzászólások: 1345
Megköszönt másnak: 10 alkalommal
Megköszönték neki: 277 alkalommal
Nemesis: Halott ötlet! bocsi, ezt én sem vállalnám be
Detector: Mi ez a WTF??? Ne húzz fel! xD

_________________
Üdvözlettel: BBk
[AmxModX] Általam fordított pluginok
Death of Legend Fun Server History
NetMozi.com - Filmes fórum Badboy.killer
foximaxi


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.12. 22:32 
Offline
Tiszteletbeli
Avatar

Csatlakozott: 2011.09.18. 13:01
Hozzászólások: 4270
Megköszönt másnak: 55 alkalommal
Megköszönték neki: 513 alkalommal
amxx visszaforditva. Nekerdezd ense ertem. Csak mar reg megvolt a program a gepemen ha visszakeresel meg kerdeztem volt errol enis.

_________________
Idk. Csak ugy funbooo.
Kép


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.13. 20:03 
Offline
Tag
Avatar

Csatlakozott: 2013.04.28. 11:55
Hozzászólások: 57
Megköszönt másnak: 9 alkalommal
Megköszönték neki: 2 alkalommal
DeteCT0R írta:
lis789 írta:
Ennek nem itt a helye! És szerintem ez neked nem fog menni ...már bocs!

Hat ha ezt erti akkor mehet :D


Helló! Ha egy leírást vagy valamit dobnál is mellé akkor tényleg nagyon megköszönném :DD

_________________
Kép


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.14. 06:01 
Offline
Őskövület
Avatar

Csatlakozott: 2012.02.27. 09:42
Hozzászólások: 2588
Megköszönt másnak: 25 alkalommal
Megköszönték neki: 418 alkalommal
tökéletes kódot nem fogsz kapni. Disassembler -el kapsz 1 kódot ami alapján újra tudod írni magadnak a plugint.

_________________
Kép


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.14. 11:17 
Offline
Beavatott

Csatlakozott: 2014.01.15. 08:48
Hozzászólások: 85
Megköszönték neki: 41 alkalommal
Kód:
Téma: Hogyan dekódolsz egy zárt forrásbeépülő modult vissza forráskódba? Ez valami népnek egy forró téma, és engem sokszor erről kérdeztek. A Sputnik53 incidens után úgy döntöttem, hogy publically felfedem, hogy ez hogyan kész. Jelenleg írok egy multipart-article-t a SourceMod devlog. Ez van nem az elájul szív, és neked C és processzor-memóriaalaprajzra vonatkozó tudással kellene belépned ebbe. Frissíteni fogom ezt a pozíciót, ahogy a leírásból fejezek be.

Nagyából ne várd tökéletesre :P

meg még itt vannak ezek is

Part 1 - bevezetés a VMbe
Part 2 - alapvető szétszerelés
Part 3 - dekódoló ágak
Part 4 - Local eljárások, változók, és multi-kettéválik
Part 5 - optimalizálás
Part 6 - Feltölt, lebeg, ternáris üzemeltetők, és hurkokért
Part 7 -Sok részből álló ha nyilatkozatok, multi-dimenzionális sorok


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.14. 11:25 
Offline
Beavatott

Csatlakozott: 2014.01.15. 08:48
Hozzászólások: 85
Megköszönték neki: 41 alkalommal
Kód:
 Visszafejtése AMX Plugins, 1. rész
A minap az AMX Mod X fórumokon, mi volt az örömben, hogy találkozik egy zárt forráskódú plugin. Kevesen tudják, a Lidérc AMX-olvasó , és még kevesebben képesek robbantási a szétszerelés vissza a forráskódot. Az elmúlt évben, vagy úgy kaptam többszöri kérése hogy ezt pontosan hogyan történik, ha ez egyáltalán lehetséges. A válasz?

A rövid válasz nem egy, hanem hosszú válaszoljon igennel az if. Nem, nem tud az eredeti forráskód - de igen, az idő nagy részében, akkor lehetséges, hogy rekonstruálni hasonló forráskód amely megvalósítja ugyanezt. Az első része ez a cikk egy rövid bevezető, hogy hogyan. AMX formátum megállapított, valamint alapozót a VM is. Ez ugyanaz a VM az Admin-Mod, AMX Mod és AMX Mod X használata (bár a verzió nagyban különböznek - 1.8.4, 2.7.3 és 3.0).

Egy. AMXX vagy. AMX fájl nem nagyon különleges, mágikus. Ez a fájlformátum által használt semmit, hogy beágyazza "AMX", vagy a virtuális gép, amely hatáskört a Kis (ma Pawn ) programozási nyelv, amely így AMX Mod kapta a nevét. Egy. AMX fájl oszlik három darab: a header (amely méretét információ), a kód részben, és az adatokat részben. Egy. AMXX fájl egyszerűen egy módszer tárolására kettő. Amx fájl egy, annak érdekében, hogy a 32 bites és 64 bites kompatibilitást egy fájlban. A kód a rész a VM többi utasítás tényleg (vagyis a VM primitív utasítások) a lefordított plugin. Az adatok a fejezet a verem, halom, és minden előre lefordított szerkezetek, mint a tömbök vagy szálakat.

A VM meglehetősen egyszerű. Ez alapján a két nyilvántartás (PRI és ALT), egy halom, és egy halom. A nyilvántartások egyszerűen használt cellák ideiglenes információt tárolnak és visszatérési értékek. A verem használják lokális változók (stack, jobb ha tudod, hogy a két művelet: nyomja egy elemet a verembe, és pop a felső elemet ki). A halom egyszerűen egy darab használt memória ideiglenes változókat. Minden adat a VM körül forog a beépített adattípus, a "cell" (szerves azt jelenti, hogy egy egész adattípus, amely elfér a mutató -, ezért 32 bites színmélységben a 32 bites processzorral és 64 bites a 64 bites processzor).

AMX van eljárás hívás (a képesség, hogy hívja a funkció és vissza), amely köré egy rejtett nyilvántartás nevű FRM (ami egy helyet a stack). Két hívási egyezmények. Mindkét át a paramétereket fordított sorrendben a verem, megszűnik a bájtok száma tolta. Például, hogy hívja a funkció és b paraméterekkel jellemzett, azt nyomja a B, majd A, majd a számot a '8 'a verembe (vagy '16' egy 64 bites gép). Helyi eljárás hívások pop saját paraméterek visszatérés, takarítás a hívó fél stack használat. Rendszer / natív hívásokat megköveteli a hívó fél, hogy a pop a paramétereket le saját verem. A helyi eljárás hívás, hogy egy függvény található, a script is (a kód részben). A rendszer / natív eljárás hívás ágai kívül a VM, például egy modul vagy valami kiterjesztése VM (például get_user_frags () egy natív hívás).

Végül VM utasítások nagyon egyszerű. Mivel a Gyalog 3.0, szinte minden utasítások legfeljebb két sejt (az egyik cella áll maga az utasítás, és egy másikat a paraméter, ha van). Ezek körül forog a verem, és a két nyilvántartás. Címzési módok elsősorban DAT és FRM relatív (FRM maga DAT relatív). Utasítások, amelyek FRM viszonylagos elnevezése. "S". Utasítások foglalkozó állandók után ". C '. Ezek esik néhány általános kategóriába: elágazás (ugrás, feltételes ugrás), Math (egyszerű számítások, cím indexelés), Stack manipuláció (toló, popping) Eljárás hívások (helyi rendszer), memória (beállítás és visszakeresése). Utasítások specifikus nyilvántartás véget. "ALT" vagy ". PRI".

Tehát, vessünk egy pillantást a Gyalog Végrehajtási PDF (különösen a fejezetet Abstract Machine Design), és felkészülni egy plugin decompiling bevezetés holnap!

A mai bónusz kérdés: Már említettem beépített adattípusok, hogy egész adattípust képes egy mutató. Ez nagyon fontos a VM végrehajtását, de miért lenne fontos, hogy a kiegészítőket?


Kód:
Visszafejtése AMX Plugins, 2. rész
Itt az ideje, hogy a keze piszkos. Sajnos, AMX Mod X 1.60 plugin nem lehet szétszerelni még, úgyhogy használtam AMX Mod '2005 0,1 beta " e részét. AMX Mod használ Kis 2.7.3. Ehhez a bemutató, de csak akkor van szükség:

Lidérc AMXReader / Disassembler
minta. AMX Fájl (leszünk decompiling ezt)

Indítsa el AMXReader. Ha nincs kedve fordítás magad, fuss AmxReader / bin / Debug / AmxReader.exe. (Mellékesen jegyzem meg, kérjük, vegye figyelembe, hogy a "AMX" nem azt jelenti, "AMX Mod" - AMX a virtuális gép, amely hatáskört a kis / Gyalog programozási nyelv). Folytassa a fájl megnyitásához. Meg fog jelenni a képernyőn:


Ez az alapértelmezett "WinForms véleménye típusát AMXReader. A másik típus, ScAsm, nem hasznos leszereléséhez. Ez azt jelentette, hogy táplálják vissza a assembler scasm írtam, miközben Wraith dolgozott a programban. WinForms nézet azt mutatja, további információkat DAT darab, ami hasznos lehet. Különben is, kezdjük!

Az első dolog, amit észre ez inkább a helyén keresi sort a tetején:

 0x0 HALT 0x0
Ez egy konkrét utasítás, amely mindig létezik COD offset 0, minden plugin. A VM elindítja a verem megnyomásával egy hamis visszatérési érték - 0 - rá. Amikor a script befejezte a végrehajtását, az utolsó visszahívás jelenik meg a 0 le a verem, mint a return-to-CIP (code utasítás mutató), és ugrik a HALT utasítás. Ily módon, szkriptek megszakítás nélkül extra logikát, amint elkészült.

Alatta, vesszük a következő kódrészletet:

 0x8 PROC; plugin_init
Most, hogy az aktuális plugin-forráskód. Az első sor kezdődik egy új eljárás (funkció). A megjegyzés a jobb azt mondja, hogy ennek neve public_init - állami feladatok mindig a nevük szerepel, mert a VM köze név kereséseket. Tehát, az első sorban ad nekünk:

nyilvános plugin_init ()
{
}
Ezt hívják a prológ. Minden eljárás kezdődik a Prológus és végződik egy epilógus. A kettő között az az eljárás, logika. Ez az egyedi funkció úgy tűnik, hogy szépen ossza két állítás. Nézzük az elsőt.

 0x18 PUSH.C 0x28
 0x20 PUSH.C 0x18
 0x28 PUSH.C 0x0
 0x30 PUSH.C 0xC
 0x38 SYSREQ.C register_plugin
 0x40 STACK 0x10
Ez az alap, klasszikus szerkezet egy AMX natív hívást. Ők szinte mindig ugyanúgy néz ki - PUSH.S, PUSH.C vagy PUSHADDR, majd SYSREQ.C, majd a verem. Tudjuk amxmod.inc hogy register_plugin van ez a prototípus:

register_plugin (const PLUGIN_NAME [], const verzió [] const szerző [])
Strings, mint minden tömbök kicsi, át való hivatkozással . Ez azt jelenti, a natív mindig kap egy korrekciót az adatokat (DAT) rész - más néven DAT relatív eltolás. Szerencsére AMXReader megpróbálja felsorolni DAT ellensúlyozza az Ön számára.

A PUSH.C opcode tolja folyamatosan a verembe. Így a stack tartalmaz (0 × 28, 0 × 18, 0 × 0, 0xC) mielőtt a hívás. SYSREQ.C mindig megelőzi egy utasítás megnyomásával a szélessége a paraméterek a verembe, így a végső PUSH . C jelentése a paraméterek száma bájtban. Ez 0xC, amely 12; akkora, mint egy sejt 32bit 4 és 12/4 3 egyenlő. Így nem kell 3 másik PUSH utasítások, ami valójában mind megfelel a szétszerelését és a követelmény a 3-paraméterek register_plugin .

A DAT fejezet kezdődik a kódolt, előre lefordított darab memória. A vonósok és a globális tömbök tartanak ott. A következő előre lefordított adatok a halom, és verem, de ezek nem érintenek minket. Ez a három-korrekciók vannak a legelején a DAT, így bővült az első három DAT karakterlánc bejegyzések AMXReader:


Bingo! Ahol AMXReader azt mondja a "Start" az offset, hogy a darab a DAT részben. Az első három húrok vannak 0 × 0, 0 × 18, 0 × 28. A plugin törekszik a három ellensúlyozza a verembe, akkor használja SYSREQ.C hívni "register_plugin". Mivel a natív hívások nem sikerül megoldani a verem, a Stack opcode eltávolítására használt, itt 0 × 10 (vagy 16 bájt, vagy 4 sejtek) a stack pointer.

A rekonstruált ál-összeszerelés néz ki:

nyomja meg a ["BAILOPAN"]
nyomja meg a ["1.0"]
nyomja meg a ["Hello"]
natív register_plugin
Ezek közül mi az első sorban a valós kód:

nyilvános plugin_init ()
{
    register_plugin ("Hello", "1.0", "BAILOPAN")
}
Holnap: Folytatva a példát, megy úszók, ágak, és a helyi eljárás hívás.

Bónusz kérdés: Miért paraméterek tolta fordított sorrendben? (Hint: a verem, mint minden halom, felülről lefelé, ami azt jelenti, hogy kezdődik a lehető legmagasabb címet. A toló nő lefelé, és a pop nő felfelé).


Kód:
Visszafejtése AMX Plugins, 3. rész
Amikor utoljára láttuk, hogyan lehet visszafordítani egy egyszerű őshonos vissza a forráskódot. Fejezzük be az első eljárást dolgoztunk tovább, majd lépni.

A következő mini-blokk szétszerelés a plugin_init funkció:

 0x54 PUSH.C 0x0
 0x5C PUSH.C 0x0
 0x64 PUSH.C 0x78
 0x6C PUSH.C 0x4C
 0x74 PUSH.C 0x10
 0x7C SYSREQ.C register_cvar
Keresi a natív prototípus:

register_cvar (const name [], const string [], flags = 0, Float: fvalue = 0,0);
A két opcionális paraméterek mindig tolta - ők nem kizárt, annak ellenére, hogy már kötelező. Mivel tolt két nulla, akkor hiszem, hogy a szerző a alapértelmezett. Ellenőrzése DAT részben azoknak eltolások:



Tehát, plugin_init néz ki:

nyilvános plugin_init ()
{
    register_plugin ("Hello", "1.0", "BAILOPAN")
    register_cvar ("pl_enabled", "1")
}
A többi már az epilógus:

 0x8C ZERO.pri
 0x90 RETN
Mivel a PRI regiszter kezeli a visszatérési értékek, ez azt jelenti, hogy a funkció visszatér 0-ra.

Nos, nézzük a következő public function:

 0x94 PROC; client_authorized
 0xA4 PUSH.C 0x80
 0xAC PUSH.C 0x4
 0xB4 SYSREQ.C get_cvar_num
A mi string table, 0 × 80 "pl_enabled". De várjunk csak - ez a szöveg már megtörtént korábban! Egyértelmű, hogy a kis-2.7.3 nem memóriahasználat optimalizálása, és egyszerűen megismétli húrok a memóriában, nem pedig egyesíti őket. Az eredmény get_cvar_num, mint minden eljárás hívás, tárolásra kerül a PRI. Next:

 0xC4 NEM
 0xC8 JZER jump_0000
 0xDC ZERO.pri
A fordító a megfordításával a logikai értéke PRI (PRI =! PRI), majd a tesztelés, ha ez nulla (ugrás a nulla). Ha az érték nulla, akkor egy másik ág le irányba. Ellenkező esetben folytatódni fog. NOT + JZER létezik egy utasítást, JNZ - több bizonyíték arra, hogy a fordító csak ez triviális optimalizálás. Így a kódot kell értelmezni "Jump, ha a visszatérési értéke get_cvar_num () nem nulla." A fióktelep akkor így néz ki:

nyilvános client_authorized (id)
{
   if (get_cvar_num ("pl_enabled")! = 0)
   {
       / / Feltételes code
   }
   / / Fiókirodába
}
A disassembler jobb alsó panelen, azt látjuk, hogy jump_0000 Helyszín 0xE4. Akár, hogy van:

 0xDC ZERO.pri
 0xE0 RETN
Ezért ez az eljárás valószínűleg azt mondja:

nyilvános client_authorized (id)
{
   if (! get_cvar_num ("pl_enabled"))
      vissza PLUGIN_CONTINUE
   / / Elágazó code
}
Most fejezzük be ezt a funkciót ki nézi az elágazó kódot.

 0xF0 PUSH.C 0x0
 0xF8 CONST.pri 0xD0
 0x100 HEAP 0x4
 0x108 MOV 0x4
 0x110 PUSH.alt
 0x114 PUSH.C 0x0
 0x11C CONST.pri 0xCC
 0x124 HEAP 0x4
 0x12C MOV 0x4
 0x134 PUSH.alt
 0x138 PUSH.S 0xC
 0x140 PUSH.C 0xAC
 0x148 PUSH.C 0x41200000
 0x150 PUSH.C 0x1C
 0x158 SYSREQ.C set_task
/ / Set_task hivatkozás:
set_task (Float: idő, const funkció [], id = 0 paraméter [] = "", len = 0, zászlók [] = "", ismétlés = 0)
Az első lökést 0. Ez gondoskodik az ismétlés .

Ezután mi 0xD0 tárolódik PRI. A disassembler tűnik, zavarba ebben -, hogy van egy titokzatos "Tömb [2] bejegyzést DAT, kezdődő 0xCC. Ezért van 0xD0 Tömb [1]. A tömb "üres". Ezután a kupac 4 utasítást elosztása négy bájt a halom, és tárolja a címet ALT. MOV 4 másol a négy byte-PRI (DAT cím) a ALT (a HEA cím). A címe ALT Ezután tolni, ami csak a zászlók paramétert. Mi történt?

A tömb a disassembler nem tudtam kitalálni, a fordítóprogram tároló két karakterlánc nulla hosszúságú (üres húrok). Az alapértelmezett paraméter zászlók üres, de nem adja át a DAT eltolt valamit nem const, mert lehet változtatni. Így a fordító elosztása átmeneti memória a halom, másolás a húr, és halad a címet. Végén a funkció, a halom helyre fog állni. Ezt a trükköt használják máskor, és ki tudjuk küszöbölni paraméter és len , amíg ez jelenik meg:

0x138 PUSH.S 0xC
Ez az első FRM offset utasítás láttunk. Az FRM relatív, hogy minden eljárás, így minden eljárást egy alapvonal, ahol a helyi stack elindul, és a szülő stack véget ér. CALL + PROC adjunk hozzá két bejegyzést a verembe, és a végső PUSH.C, amely kimondja a paraméter szélessége egy harmadik bejegyzés. Ezért a paraméterek mindig kezdje a 12. bájt (0xC) a helyi hívások. Ez az utasítás törekszik az első paraméter, amely client_authorized , az "id". Ha ki szeretné próbálni, hogy ez a tisztább, csináltam egy diagram:


Next egyszerű - nézz fel az offset 0xAC a string "display". A következő szám Float: idő - de ez szétszerelt mint 0 × 41200000! Úszók tárolják a formában nevű IEEE Single / Double Precision . Dekódolni, én is használtam egy egyszerű C program:

# Include <stdio .h>

typedef union
{
        int num;
        float f;
} Floatswp;

int main ()
{
        floatswp SWP;
        scanf ("% x", és SWP);
        printf ("% f \ n", swp.f);
}
Az eredmény: dvander @ Wichita ~ $ cc float.c-ofloat dvander @ Wichita ~ $. / float 0x41200000 10,000000





Tehát végre az összes paramétert, és a legtöbb alapértelmezett. A funkció valószínűleg így néz ki:

nyilvános client_authorized (id)
{
   if (! get_cvar_num ("pl_enabled"))
      visszatérés
   set_task (10.0 "kijelző", id)
   visszatérés
}
Mint tudod talán látni már, visszafejtése nagyon időigényes feladat, különösen, lépésről lépésre - ez a cikk volt elég hosszú. Holnap befejezem ezt a plugint. Ezután, hogy mi lesz egy gyors pillantást tényleges zárt forráskódú bővítmény jelenleg használatban, majd befejezi a sorozatot le egy 64 bites vitát.

Ez belépés volt kifüggesztett szombat október 15, 2005 at 1:15 és van iktatott Coding . Tudod követ akármi válasz-hoz ez belépés átmenő a RSS 2.0 feed. Azt, hogy kihagyja a végéig, és hagy egy válasz. Kopogó van jelenleg nem engedélyezett.

3 Responses to "Lebontás AMX Plugins, 3. rész"


Kód:
Visszafejtése AMX Plugins, 4. rész
Eddig tudjuk, hogy két dolgot: van egy regisztrált cvar nevű pl_enabled, és ha ez meg az 1-közben client_authorized, a "Display" időzítő beállítása 10 másodpercig.

Szerencsére, a következő funkció a "Display" funkció:

 0x178 PROC; kijelző
 0x188 PUSH.S 0xC
 0x190 PUSH.C 0x4
 0x198 CALL func_00
Már találkoztam az első helyi eljáráshívás - Privát funkciót, akinek a nevét nem tároljuk, csak azonosítható a "func_00" és annak címét. Tudjuk, hogy a végső PUSH.C, hogy ez a funkció csak akkor kap egy paramétert. Hogy az egyik paraméter az első változó a stack - az id át a kijelző () függvényt. Ne feledje, hogy ha a set_task nincs egy sor meg, akkor egyszerűen át feladatát id az időzített funkció.

Ugorjunk le func_00 és nézd meg mit csinál:

 0x1E4 PROC; func_00
 0x1F4 verem 0x80
 0x1FC ZERO.pri
 0x200 ADDR.alt-0x80
 0x208 FILL 0x80
 0x210 verem 0x30
 0x218 ZERO.pri
 0x21C ADDR.alt-0XB0
 0x224 FILL 0x30
Azt már tudjuk, ez a függvény legalább egy paramétert (mivel ennyi szorult rá). Szóval, mi van ezekkel a furcsa utasításokat?

A köteget utasítás egyszerűen mozgatja a stack pointer - negatív (lefelé) hatékonyan osztja, és pozitív (felfelé) felszabadítja. Minden STACK utasítás célja, hogy akár tartalék vagy fesztelenség helyi memóriát. -0 × 80 elosztásakor 0 × 80 bájt a verem. Ez a 128 decimális vagy osztva a cellsize (4), 32. sejteket. A következő három utasítás fontos. ZERO.pri nyilvánvaló, a PRI regiszter nullázni. ADDR.alt a mi második FRM viszonylagos utasítást. Ez határozza meg a ALT regisztert címet a helyi verem keret. Ebben az esetben, a stack pointer került lejjebb 0 × 80 bájt, így van értelme, hogy a kezdő címét a lefoglalt blokk FRM - 0 × 80. A kitöltési utasítás, majd kitölti a memóriában ALT a számot PRI, N bájt. Tehát összefoglalva, a változó a 32 sejt jött létre a verem, majd felülírja a számot PRI, ami nulla. A koncepció a verem tároló készült nehéz megérteni, mert felülről lefelé, ezért csináltam egy gyors diagram:


A következő négy utasítások pontosan ugyanaz, lényegében. Ezúttal csak 12 sejtek fenntartva (0 × 30, vagy 48 bájt). Mivel a verem mutató most a FRM-0 × 80, meg kell mozgatni lefelé (FRM-0 × 80) × 30 -0, vagy FRM-0XB0. Így ADDR.alt beállítja a kitöltési cím-0XB0, majd töltse nullák a 12 cella. Most már levelet prológ, hogy ezt a funkciót:

func_00 (id)
{
   új var1 [32]
   új var2 [12]
}
Megjegyzés - nem volt szükség a = {0, ...} után minden változó. A fordító nullák ki változókat automatikusan. A helyi funkciók, ez egy nagy teljesítménycsökkenést okoz, de ez teszi scripting sokkal könnyebb! -Ra a többi funkció:

 0x238 PUSH.C 0x1F
 0x240 PUSHADDR-0x80
 0x248 PUSH.S 0xC
 0x250 PUSH.C 0xC
 0x258 SYSREQ.C get_user_name
 0x260 STACK 0x10
 0x274 PUSH.C 0x0
 0x27C CONST.pri 0x110
 0x284 HEAP 0x4
 0x28C MOV 0x4
 0x294 PUSH.alt
 0x298 PUSH.S 0xC
 0x2A0 PUSH.C 0xC
 0x2A8 SYSREQ.C get_user_team
/ / Get_user_name (index, név [], len)
/ / Get_user_team (index, csapat [] = "", len = 0)
Az első natív elég straighforward. PUSH.c halad 0 × 1F vagy 31, a bájtok száma a karaktersorozat fér. PUSHADDR másik FRM viszonylagos utasítást, és ez nyomja a cím FRM-0 × 80, amely kényelmesen van var1 [32]. PUSH.S, mintha már látott, törekszik egy átadott paraméter, megint ez az első egy adott funkció (ezen a ponton azt feltételezzük, hogy ez a játékos id). A második natív jól használja a jól ismert trükk az átmeneti tárolás. Most már:

func_00 (id)
{
   új var1 [32]
   új var2 [12]

   get_user_name (id, var1, 31)
   get_user_team (id)
}
Közvetlenül utána, kapunk egy meglepetés:

 0x2C0 EQ.C.pri 0x1
 0x2C8 JZER jump_0001
EQ.C.pri ellenőrzi, hogy az értéket a PRI egyenlő a opcod-paraméter (ebben az esetben 0 × 1). Ha ez igaz, PRI értéke 1, különben PRI értéke 0-ra. Ez az ág előforduló ha PRI nulla. Az eredmény származó SYSREQ.C (get_user_team) tárolt PRI volt, nem pedig egy átmeneti változó, így a visszatérési értéke a függvény kell használni közvetlenül az ág. Összefoglalva, ha a PRI nem egyenlő 1-gyel, az ág kerül sor. Ezért:

func_00 (id)
{
   új var1 [32]
   új var2 [12]

   get_user_name (id, var1, 31)
   if (get_user_team (id) == 1)
   {
      / / Feltételes code
   }
   / / Elágazó kód (jump_0001)
}
Reading a feltételes kódot, amely mindent a jump_0001:

 0x2DC PUSH.C 0x114
 0x2E4 PUSH.C 0xB
 0x2EC PUSHADDR-0XB0
 0x2F4 PUSH.C 0xC
 0x2FC SYSREQ.C copy
 0x304 STACK 0x10
 0x30C JUMP jump_0002
Ez egy egyszerű hívás másolni () - mi halad DAT cím 0 × 114, ami AMXReader azt mondja, az a string "T". 0xB 11 bájt, és FRM-0XB0 a címe var2. Akkor mi ugrás jump_0002. Várj, ugrás? Nem egyszerűen lépni a elágazó kódot? Tény, hogy pontosan mi történik. Egy HA ... ENDIF blokk egyik feltétele van jelölve, és legfeljebb egy ág kerül sor. Egy if / else / ENDIF blokk, minden feltételes kódrészleteket kell ág már a fennmaradó feltételes ellenőrzéseket annak érdekében, hogy lépni. Tehát ezen a ponton, akkor hiszem, hogy a funkció a következő:

func_00 (id)
{
   új var1 [32]
   új var2 [12]

   get_user_name (id, var1, 31)
   if (get_user_team (id) == 1)
   {
      másolás (var2, 11, "T")
   } Else [?] {/ / Elágazó kód (jump_0001)
      / / [Un] feltételes kód
   }
   / / Elágazó kód (jump_0002)
}
Ugró múlt, hogy ág, érkezünk a helyen jump_0001:

 0x354 SYSREQ.C get_user_team
 0x36C EQ.C.pri 0x2
 0x374 JZER jump_0002
Itt látjuk pontosan ugyanolyan kódot fenti get_user_team, és egy másik feltételes ág. Ha az eredmény nem 0 × 2, az ág kerül sor. Ez egy újabb feltételes blokk, ami egy "else if" helyett egy "más" nyilatkozatot. Továbbá, mivel az eredmény a funkció újraszámolták újra tudjuk, hogy az összehasonlítás keletkezett a nyilatkozatot. A kód előforduló folyamatos, amíg jump_0002 triviális úgyhogy tartalmazza azt.

func_00 (id)
{
   új var1 [32]
   új var2 [12]

   get_user_name (id, var1, 31)
   if (get_user_team (id) == 1)
   {
      másolás (var2, 11, "T")
      / / Fióktelep jump_0002, hogy kihagyja a következő blokk
   } Else if (get_user_team (id) == 2) {/ / elágazó kód (jump_0001)
      másolás (var2, 11, "CT")
   }
   / / Elágazó kód (jump_0002)
}
Végül minden ágát már megoldódott, és megérkeznek jump_0002:

 0x3C4 PUSHADDR-0x80
 0x3CC PUSHADDR-0XB0
 0x3D4 PUSH.C 0x128
 0x3DC PUSH.S 0xC
 0x3E4 PUSH.C 0x10
 0x3EC SYSREQ.C client_cmd
Az egyetlen nehéz része ez eszébe jutott, hogy PUSHADDR a helyi FRM, és így -0 × 80 var1 és-0XB0 is var2. A szöveg maga is megtalálja a AMXReader a DAT nézőt. Megjegyzés: a funkció megtisztítja a verem helyreállít a stack pointer - teszi hozzá (unreserving) 0XB0, amely a byte-ok száma is kiosztott. Végül, vegye figyelembe, hogy a függvény RETN, amely megtisztítja a saját hívó verem használata paraméterek.

Majd valóban visszatér a kijelző funkció már, amit látunk tartalmaz triviálisan dekódolható client_print funkciót. Nem használható STACK után CALL mert a helyi hívás tisztították meg automatikusan. Ez az egyik oka a paraméterek száma tolta előtt minden eljárás hívás: RETN pop az érték, és ez alapján korrigálja a verem, mielőtt visszatért.

Végül, mi a teljes forráskódot, hogy ezt a plugint:

nyilvános plugin_init ()
{
   register_plugin ("Hello", "1.0", "BAILOPAN")
   register_cvar ("pl_enabled", "1")
}

nyilvános client_authorized (id)
{
   if (! get_cvar_num ("pl_enabled"))
      visszatérés
   set_task (10.0 "kijelző", id)
   visszatérés
}

nyilvános kijelző (id)
{
   func_00 (id)
   / / Megjegyzés - láttuk PUSH.C 3, a folyamatos 3 'print_chat "
   client_print (id, print_chat "[HELLO] Hello.")
}

func_00 (id)
{
   új var1 [32]
   új var2 [12]

   get_user_name (id, var1, 31)
   if (get_user_team (id) == 1)
   {
      másolás (var2, 11, "T")
   } Else if (get_user_team (id) == 2) {/ / elágazó kód (jump_0001)
      másolás (var2, 11, "CT")
   }
   client_cmd (id, "[% s]% s", var2, var1)
}
Végül, már szétszerelt meglehetősen egyszerű és triviális plugin. Bár úgy tűnik, mint egy hosszú folyamat, és végül lesz nagyon könnyű, hogy mintákat fordítóprogramok használatát. Mint bármi, visszafejtése gyakorlást. További gyakorlatban fogok szétszerelése egy kis része a valós zárt forrás plugint a következő cikkben.

Bónusz kérdés: Miért a stack nő lefelé? Hát nem egyszerűbb és kevésbé zavaró, hogy nő felfelé?

Ez belépés volt kifüggesztett vasárnap, október 16, 2005 at 5:27 és van iktatott Coding . Tudod követ akármi válasz-hoz ez belépés átmenő a RSS 2.0 feed. Azt, hogy kihagyja a végéig, és hagy egy válasz. Kopogó van jelenleg nem engedélyezett.

3 Responses to "Lebontás AMX Plugins, 4. rész"


Kód:
Visszafejtése AMX Plugins, 5. rész
Én kihagyom érdekében egy kicsit, hogy egy kis szünetet. Először is, a Wraith kiadott egy vadonatúj változatát AMXReader ! Ez a verzió a moduláris és a szervezett, támogatja az új Small 3.0 utasításokra, és olvassa el AMX Mod X 1.60 dugó. Végül van egy bináris csak a letöltést.

Ma szeretnék tekint vissza, amit már elért eddig, és vegye figyelembe néhány szabályt a helyeken, ahol optimalizálás nyilvánvaló.

1. szabály: Csak a kiszámításához valamit egyszer!
Láttuk a sample.amx hogy get_user_team hívták minden , ha ha. Azt is láttuk, a szétszerelési, hogy ez hozzá egy jó adag extra utasítások, nem számítva a több száz aktuális processzor utasításokat, amelyek akkor jelentkeznek, hogy SYSREQ.C ugrás AMX a C natív, és futtassa a natív, a tényleges natív funkció is, , majd a visszatérés a hívó. Ez egy költséges művelet, és ez lehetséges, hogy get_user_team maga nagyon drága (bár ez nem).

Az ökölszabály az, hogy kiszámítható, ha, és mentse az eredmény, mert a memória lookup MINDIG gyorsabb:

új csapat = get_user_team (id)
if (team == 1)
/ / ...
else if (team == 2)
/ / ...
Szabály # 2: Watch tömb határait!
Kis maga ellenőrzi array határokat közvetlen hozzáférések, de a bennszülöttek nem kell, és általában nem is próbálja. Például:

új str [] = "60"
új tömb [32]
array [str_to_num (str)] = 5.
Generál AMX_ERR_BOUNDS hibát. Ez azonban nem fog:

új Gaben [60]
új tömb [1]
másolás (array, 60, "Hello!")
Nyilvánvaló, hogy akartam másolni Gaben , hanem másoltam a tömb . Ne feledje, a stack layout előtt? Minden változó határozza egyik tetejére a másik a verem. A másolási funkció egyszerűen másolja 60 cellák határok ellenőrzése, az írás egy "H" a tömbben , de a töltés Gaben a többit. Ez vezet mindenféle hóbortos hibákat és gyakran összeomlik. A tanulság: mindig át puffer legalább eggyel kevesebb, mint a legnagyobb méret! Egy példa ez a probléma a gyakorlatban a tévesen benyújtott hibajelentést a felhasználó látni egy teljesen más változó felklippeljük egy karakterlánc terminátor.

Szabály # 3: Ha meg akarsz ismételni valamit, cache is.
Ez a szabály kiterjeszti # 1.. Például, észrevette, hogy a DAT rész nem optimális. Akkor ismételje meg a szöveg a 800-szor, és a DAT rész lesz egy bejegyzést minden egyes ismétlés. A megoldás?

/ / BAD
# Define COMMON_STRING "Gaben"
/ / JÓ
új COMMON_STRING [] = "Gaben"
Így, DAT csak egy referencia. Továbbá, talán még gyorsabb, mert abban az esetben nem const a fordító nem kell másolni azt a kupac először. Sok esetben tudod, hogy soha nem lehet módosítani, és a natív nyilatkozat egyszerűen elfelejtette a "const" kulcsszó.

Egy másik példa:

/ / BAD
állomány GetWeaponName (id, név [] max)
{
   if (id == 0)
      másolás (név, max "weapon_none")
   else if (id == 1)
      másolás (név, max "weapon_gaben")
   / / ....
}
/ / JÓ
új g_WeaponNames [] = {
     "Weapon_none", / / ​​0
    "Weapon_gaben", / / ​​1
}
A keresési tábla közelében, azonnali végrehajtás. A fordító csak kell hozzá egy egész, hogy egy alap memória offset. Hívása funkció drága - elágazás-előrejelző, cache hiányzik, több utasítást adhat fel nagyon gyorsan. Ha a funkció nagyon gyakran, ez egy jó ötlet, hogy az idő, hogy ezeket a triviális és érdemleges optimalizálás. Meg tudod csinálni lookup táblákat a kis semmire mely alapanyagokat egy egész és kimenetek bármilyen más adattípust, mindaddig, amíg a készlet bemenetről rögzített határt. Ez rendben van, hogy létrejöjjön a keresési tábla futási időben, amíg nem kell tennie, hogy gyakran (vagy épület gyakran ellensúlyozza a számítástechnikai bejegyzések teljesen dinamikus).

4.. Nem kell, hogy mindent nyilvánosságra.
Sokan egyszerűen neve elé a "köz", hogy minden egyes funkciót. Nem kell ezt tenned. Bár ez csak növeli a néhány byte (kell tárolni a nevét funkció), ez rossz design. Tömegközlekedési eszközök "külső", vagy a "mindenki számára látható". Private funkciók nem kellett volna ez a kulcsszó. A "sample.amx" Például, "func_00" volt a magán-, mint kellett volna.

5.. Nem kell, hogy visszatérjen PLUGIN_CONTINUE és PLUGIN_HANDLED minden alkalommal.
A fordító automatikusan visszatér 0 az Ön számára. Mivel azonban az emberek hajlamosak nem engedelmeskednek # 4, ők is inkább véletlenszerűen ad vissza értéket a végén minden egyes funkciót. Ez nem szükséges. A szabályok a visszatérő következők:
explicit return - visszatérés, ahol vissza értéket (Cserébe X ;)
implicit visszatérés - visszatérés, ahol megadhatja nincs értéke (visszatérés ;)
Ha megad egy explicit return, akkor specificy kifejezett visszatérés Minden áramkörökben.
Ha megadod az implicit visszatérés, a fordító visszatér 0 minden áramkörökben.
Ha megadod nem tér vissza, a fordító visszatér 0 minden áramkörökben.

Végül, a legtöbb közvélemény előre semmit sem a visszatérési érték. Például vissza kifejezett értéket client_disconnect, a set_task vagy plugin_init fog tenni semmit.


Kód:
Visszafejtése AMX Plugins, 6. rész
Két nappal később, itt van a következő részlet a decompiling / szétszerelés cikket. Ma döntöttem visszafordítani egy részét valós zárt forráskódú plugin. Ez a plugin "Hack Mod" a krot @ l. Azért választottam ezt a plugint, mert a felhasználó, aki kérte a forráskód által megkövetelt GPL nem engedték be. Az eredeti link itt , vagy letölthető a tükör a bináris:

www.bailopan.net / hackmod.amx

Az első dolog, amit észre, amikor betölti ezt a plugint a disassembler, hogy ez a nagy : 9200 vonalak szétszerelés. Mivel a 5-15 vonalak szétszerelés egy tényleges vonal forrás, akkor nyugodtan megbecsülni ezt a plugin a durván 1000 sornyi kódot.

A második dolog, amit meg kell észrevenni a beállított furcsa, meg nem nevezett funkciók a tetején a script. Az első ez:

 0x8 PROC; func_00
 0x18 PUSH.S 0x10, 2. paraméter funkció
 0x20 PUSH.C 0x4; 4bytes = 1parameter
 0x28 SYSREQ.C úszó
 0x30 STACK 0x8
 0x38 PUSH.pri, nyomja eredménye float ()
 0x3C PUSH.S 0xC, nyomja első paraméter
 0x44 PUSH.C 0x8; bájt = 2parameters
 0x4C SYSREQ.C floatmul
 0x54 STACK 0xC
 0x5C RETN, visszatér floatmul () eredmény
, Bennszülöttek használják:
natív Float: float (érték);
natív Float: floatmul (Float: oper1, Float: oper2);
Ez az állomány funkciót. A készletek csak össze, ha használják őket, és mivel ezek átmennek a. Inc fájlokat, ezek általában először a kódot. De ami raktáron van? A mi hazai definíciók, akkor szét ezt:

állomány stock001 (param1, param2)
   vissza floatmul (param1, float (param2))
Nézzük korrigálni hozzáadásával a címkék ezek a bennszülöttek vissza / szüksége:

állomány Float: stock001 (Float: param1, param2)
   vissza floatmul (param1, float (param2))
Ez a függvény argumentumként egy úszó és egy nem úszó és megsokszorozza azokat. Melyik állomány ez? Nézd meg float.inc :

állomány Float: operátor * (Float: oper1, oper2)
   vissza floatmul (oper1, float (oper2)) / * "*" kommutatív * /
Ez a kód megszorozzuk egy úszó egy nem úszó . Bár az MMX ezt lehet tenni néhány nagyon gyors utasítást, Kis igényel állomány és két bennszülöttek. Lebeg a kis drágák. Mivel nincs adattípusok más, mint a cella, címkéket nem érvényesíteni bármilyen típusú szabályok, inkább ezek segítségével túlterhelés szereplők és szimulálni típusú ellenőrzése a "címke ellenőrzés". Mivel az úszók nem őshonos, és csak kerületi címkézést, akkor sajnos nem lehet optimalizálni őket a VM szinten, ha új utasítást adunk, és a fordító támogatja őket. (Mivel a fordító már speciális támogatást úszók, nem hiszem, hogy ez megtöri a Kis-design).

Nos, vessünk egy gyors sétát a húrok ebben a plugin. A legtöbb ilyen dolgok elég általános, maxspeeds, gravitáció, hit dobozok, respawning, et cetera. Azonban ez a plugin is, nem valami aimbot trükköt szeretnék tudni. A böngészés az állami feladatok, a szerző tette a standard hibát elnevezési magán függvény public: "set_aim". Ez egy vörös zászlót, és ezt hívják a client_prethink. A client_PreThink előre adtunk AMX Mod X 0.10, és feltehetően másolt egy későbbi változata VexD (különböző kapitalizációja, persze, hogy torzítja eredetét). Ez előre nagyon drága - ezt hívják egyszer server keret minden ügyfél . Ez azt jelenti, hogy 32-szer egy keret, a szerver lehet ugrás natív kódot, hogy a kis plugin.

A COD cím 0xC0A0 látni fogja a PROC a client_prethink a hackmod.amx. Úgy indul, viszonylag egyszerű:

nyilvános client_prethink (id)
{
   if (get_cvar_num ("hackmod_active")! = 0)
      vissza PLUGIN_CONTINUE
   if (! is_user_alive (id))
      vissza PLUGIN_CONTINUE
}
Következő, ráakad egy új utasítást:

 0xC148 CONST.alt 0x2CC
 0xC150 LOAD.S.pri 0xC
 0xC160 LIDX
 0xC164 JZER jump_0416
LIDX egyik utasítások eléréséhez használt tömböket. A ALT , mint az alap-címet, ez lesz a cella található a megadott címre az ALT + (PRI * cellsize) . A cím 0 × 2CC egyértelműen valami a disassembler nem tudott kitalálni, hogyan kell elemezni: azt látja, hogy ezt a 825 cella tömb. Mivel ez a tömb indexei az "id" paraméterrel, tegyük fel, hogy ez csak egy sor a játékosok. Aztán ott van:

   if (g_PlayerArray [id])
   {
      új var1 [32], var2

      / / Ne feledje, hogy a fióktelep által get_user_team () így néz ki:
      / / 0xC224 JZER jump_0417
      / / 0xC22C CONST.pri 0xA44C
      / / 0xC234 JUMP jump_0418
      / / 0xC23C CONST.pri 0xA458: cél jump_0417
      / / Mivel csak arra szolgál, hogy váltani két PRI értéke, a következtetésem
      / /, Hogy volt ágyazva a hármas operátor. Ennek van értelme, mert
      / / Az érték PRI azonnal tolni a következő függvényhívás.
      get_players (var1, var2 "ae", get_user_team (id) == 1? "terrorista": "CT")
      / / CODE
   } Else {/ / ágaztatva jump_0416
   }
Amikor eljut a marker, ahol azt írtam: "CODE", van néhány trükkös ugrások. Ez ugrik már egy műveleti kódot, majd ugrik vissza, mielőtt ezt a műveleti kódot. Azaz, egy kezdeti érték van beállítva, akkor a kód végigmegy, amíg a feltétel már nem teljesül. Minden iteráció, hogy az eredetileg kihagyott blokk kód fut. Már találkozott egy a -loop. Ahhoz, hogy ez könnyebb követni, már felbomlott a hurok sajátosságait:

for (
   / / 0xC284 PUSH.C 0x0
   / / 0xC28C JUMP jump_0419
 new i = 0;
   / / 0xC2A8 LOAD.S.pri-0x90: cél jump_0419
   / / 0xC2B0 LOAD.S.alt-0x8C
   / / 0xC2B8 JSGEQ jump_0420
 i <var2;
   / / 0xC294 LINE vonal 0x543: cél jump_0423
   / / 0xC2A0 INC.S-0x90
 i + +)
{
  / / LOOP KÓD
}
Mi a fordító csinál? Ez nyomja a 0 -ra a verem (ez ugyanaz, mint a STACK -4 , kivéve, hogy nem kell kifejezetten TÖLTSE és ZERO meg). Ez teszi a hurok érték címen FRM-0x90. Akkor ugrik már a növekmény lépést, és nem az összehasonlítás lépést. Ha az érték a FRM-kevesebb, mint 0x90-FRM 0x8C (i, var2), majd addig folytatja. Továbbra által ugrás vissza a növekmény + összehasonlítás lépés, ami látható lesz egy ugrás a jump_0423 .

Legközelebb: mi továbbra is szétszedni client_prethink és a találkozás a förtelmes CASETBL utasítást.

Ez belépés volt kifüggesztett péntek, október 28, 2005 at 4:06 és van iktatott Coding . Tudod követ akármi válasz-hoz ez belépés átmenő a RSS 2.0 feed. Azt, hogy kihagyja a végéig, és hagy egy válasz. Kopogó van jelenleg nem engedélyezett.

6 Responses to "Lebontás AMX Plugins, 6. rész"


Kód:
Visszafejtése AMX Plugins, 7. rész
Folytassuk decompiling client_prethink a hackmod.amx . Ha emlékszik, utoljára tudtuk szed kód valahogy így:

új g_PlayerArray [33]

nyilvános client_prethink (id)
{
   if (get_cvar_num ("hackmod_active")! = 0)
      vissza PLUGIN_CONTINUE
   if (! is_user_alive (id))
      vissza PLUGIN_CONTINUE

   if (g_PlayerArray [id])
   {
      / / Nyomkövetése egy kicsit, már két titokzatos vars előtt létrehozott
      / / A másik kettő. Kizártam ezeket, mert nem használták utoljára:
      / / 0xC178 PUSH.C 0x270F
      / / 0xC18C PUSH.C 0x0
      / / 0xC1A0 verem 0x80
      / / 0xC1BC PUSH.C 0x0

      új VAR3 = 9999 / / FRM-0x04
      új var4 / / FRM-0x08
      új var1 [32] / / FRM-0x88
      új var2 / / FRM-0x8C

      get_players (var1, var2 "ae", get_user_team (id) == 1? "terrorista": "CT")

      for (new i = 0; i <var2; i + +)
      {
      }
   }
}
Folytassuk a finom, húsos belső Ennek a hurok:

 0xC2CC ADDR.alt-0x88
 0xC2D4 LOAD.S.pri-0x90
 0xC2DC KÍVÜLISÉG 0x1F
FRM-0x88 a címe var1 tömb. FRM-0x90 az i változó. Ne feledje, hogy a fordító a tömb indexelésével nélkül ideiglenesen tárolja azt. Ez azt jelenti, a szerző ezt tette: var1 [i] helyett ezt: új játékos ... játékos = var1 [i] Mi az eredmény nem tárolja azt egy átmeneti változó? A fordító szegény optimalizálás reindexes a tömb minden egyes használat. Éppen most használta fel 3-5 utasításokat amit meg kell venni nulla vagy egy.






if (can_see (id, var1 [i]))
{
   / / Ez leképezve func_04, amely egyértelműen az állomány.
   / / Szétszerelése, és keresi VexdUM_stoc.inc megmutatja, hogy ez
   / / Get_entity_distance ()
   / / Figyelembe, hogy ez ágak jump_0421, valamint, ha a szülő, ha helyzet nem sikerül.
   / / Ez kell, azt jelenti, hogy az ügy, ha nem Alternativ,
   / / Különben ugrik valahol máshol (Small nincs GOTOS).
   if (get_entity_distance (id, var1 [i]) <= VAR3)
   {
      / / Ne feledje, ez az alkalom, hogy var1 [i] újraszámolják, mint az egész
      / / Get_entity_distance funkció! a teljesítmény miatt, ezt mindig
      / / Menteni egy ideiglenes változó.
      / / 0xC3B0 STOR.S.pri-0x4
      / / Szintén fontos megjegyezni, STOR.S.pri tárolja az eredmény vissza VAR3.
      VAR3 = get_entity_distance (id, var1 [i])
      / / Végül, azt látjuk, amit a titokzatos var4 van a ... ez tárolja a játékos index
      / / Kitalálni? Az aimbot tárolja a legközelebbi játékos.
      var4 = var1 [i]
   }
}
/ / 0xC3E8 JUMP jump_0423: cél jump_0421
/ / Ez a cél mindkét esetben a két, ha nyilatkozatok.
/ / Minden véget ér itt, és ugrik vissza jump_0423, ami ...
/ / 0xC294 LINE vonal 0x543: cél jump_0423
/ / A kezdete a hurok! Végeztünk.
Egy utolsó pillantás a for ciklus:

nyilvános client_prethink (id)
{
   if (g_PlayerArray [id])
   {
      új VAR3 = 9999 / / FRM-0x04
      új var4 / / FRM-0x08
      új var1 [32] / / FRM-0x88
      új var2 / / FRM-0x8C

      get_players (var1, var2 "ae", get_user_team (id) == 1? "terrorista": "CT")

      for (new i = 0; i <var2; i + +)
      {
         if (! can_see (id, var1 [i]))
            folytatódik
         if (get_entity_distance (id, var1 [i]) <= VAR3)
         {
            VAR3 = get_entity_distance (id, var1 [i])
            var4 = var1 [i]
         }
      }
      / / CODE
   }
}
Nézzük tovább, ahol azt írta: "kód":

if (var4 <= 0)
{
   / / I megjelölt ezeket Float: azért, mert a bennszülöttek ők használják
   new Float: LOCAL1 [3] / / FRM-0x98
   new Float: LOCAL2 [3] / / FRM-0xA4

   / / Ezután találkozunk 0x1B hogy át entity_get_int.
   / / Melyik szám az ENUM meg ez? 27, vagy EV_INT_flags
   / / Ezután már zászlók 0x4000, amely az (1 << 14), vagy FL_DUCKING
   / / Továbbá, vegye figyelembe, hogy a fordító trickily lefordítja ezt, ha blokk.
   / / Meg lehet osztani: if ((expr) && (kifejezés))
   / / A fordító teszi minden EXPR egy mini-ha eset. Ha minden esetben helyes,
   / / Ez határozza PRI 1-re. Egyébként kitör, amelyben PRI 0-ra.
   / / Egy utolsó esetben ellenőrzi, hogy PRI értéke 1 vagy 0, hogy a nyilatkozatot a munka.
   if ((entity_get_int (var4, EV_INT_flags) és FL_DUCKING) && (entity_get_int (var4, EV_INT_bInDuck)))
   {
      / / Itt látjuk a fordító kiszámításának második cella LOCAL1,
      / / Mentés a címet a verem, hozzátéve, az értéket 0x40E00000 (7,0),
      / / Akkor popping a címet és tárolja az eredményt is.
      LOCAL1 [2] + = 7,0
      / / Itt csak egyszerű tárolás
      / / Megjegyzés: a fordító kiszámolja a címet PRI miatt ADD.C
      / / Csak, hogy képes dolgozni egy regiszter. Ezután mozog PRI ALT
      / / Használata érdekében STOR.I.
      LOCAL2 [1] = 0.2
      / / Branch jump_0429
   } Else {/ / Branch jump_0428
      if (VAR3 <800)
         LOCAL1 [2] + = 2.0
   }
   / / Jump_0429
   if (VAR3> = 800)
   {
      / / Győződjön meg róla, hogy nyomon követhesse a papírköteget ez!
      / / Csak két nyilvántartás, a fordító folyamatosan takarít
      / / PRI és az alt, gyakran egyszerűen csak váltani őket körül később.
      LOCAL1 [2] - = var3/1600
   }
   set_aim (id, var4, LOCAL2)
   if (g_PlayerArray2 [id])
   {
      új klip / / FRM-0xA8
      új lőszer / / FRM-0xAC
      új fegyver / / FRM-0XB0

      fegyver = get_user_weapon (id, lőszer, clip)

      / / Megjegyzés ugyanazt a trükköt alkalmazzák s az előző két if.
      / / G_PlayerArray3 az 0x3D4
      if (klip <= 0 &&! g_PlayerArray3 [id])
      {
         / / De _another_ globális tömb hivatkozik itt.
         / / 0x140
         / / Megjegyzés: a indexelés ...
         / / PRI = & g_PlayerArray [id]
         / / ALT = PRI
         / / PRI = * PRI
         / / PRI + = ALT
         / / Így többdimenziós tömbök munkát a kis / Pawn;
         / / A dimenzió al el van tolva az első, így g [A] [B]
         / / Található (& g [A] + g [A] + B)
         / / Nincs B itt, ezért B = 0
         g_PlayerArray4 [id] [0] = var4
         g_PlayerArray4 [id] [1] = 0
         g_PlayerArray3 [id] = 1
         / / Ez valószínűleg egy sor fegyverek ...
         / / Talán reload alkalommal mindegyik?
         set_task (g_WeaponArray [local5], "reset_wait_shoot", 1000 + id)
      }
   }
}
Pfuj! Ez sok volt. Nem elég, hogy el CASETBL ma, de fedett többrészes ha a nyilatkozatok és többdimenziós tömbök. Egy jó része, hogy nem sokat, hogy semmi értelme. Mi értelme LOCAL1 és LOCAL2? Mi az reset_wait_shoot és set_aim ()? Az a gyanúm, a aimbot kikapcsol ideiglenesen közben újratöltés. Én nem egészen felfogni, amit a fel nem használt lokális változó az, de lehetséges, csináltam egy hiba a szétszerelés.

Legközelebb: Mivel ez a része client_PreThink befejeződött, akkor szét reset_wait_shoot és set_aim. A teljes funkció eddig alább.

új g_PlayerArray [33]
új g_PlayerArray3 [33]
új g_PlayerArray4 [33]
új g_WeaponArray [30]

nyilvános client_prethink (id)
{
   if (get_cvar_num ("hackmod_active")! = 0)
      vissza PLUGIN_CONTINUE
   if (! is_user_alive (id))
      vissza PLUGIN_CONTINUE

   if (g_PlayerArray [id])
   {
      új VAR3 = 9999 var4, var1 [32], var2

      get_players (var1, var2 "ae", get_user_team (id) == 1? "terrorista": "CT")
      for (new i = 0; i <var2; i + +)
      {
         if (! can_see (id, var1 [i]))
            folytatódik
         if (get_entity_distance (id, var1 [i]) <= VAR3)
         {
            VAR3 = get_entity_distance (id, var1 [i])
            var4 = var1 [i]
         }
      }
      if (var4 <= 0)
      {
         new Float: LOCAL1 [3], Float: LOCAL2 [3]

         if ((entity_get_int (var4, EV_INT_flags) és FL_DUCKING) && (entity_get_int (var4, EV_INT_bInDuck)))
         {
            LOCAL1 [2] + = 7,0
            LOCAL2 [1] = 0.2
         } Else {
            if (VAR3 <800)
               LOCAL1 [2] + = 2.0
         }
         if (VAR3> = 800)
         {
            LOCAL1 [2] - = var3/1600
         }
         set_aim (id, var4, LOCAL2)
         if (g_PlayerArray2 [id])
         {
            Új klip, lőszer, fegyver

            fegyver = get_user_weapon (id, lőszer, clip)

            if (klip <= 0 &&! g_PlayerArray3 [id])
            {
               g_PlayerArray4 [id] [0] = var4
               g_PlayerArray4 [id] [1] = 0
               g_PlayerArray3 [id] = 1
               set_task (g_WeaponArray [fegyver], "reset_wait_shoot", 1000 + id)
            }
         }
      }
   }
}
Ez belépés volt kifüggesztett vasárnap, október 30, 2005 at 5:47 és van iktatott Coding . Tudod követ akármi válasz-hoz ez belépés átmenő a RSS 2.0 feed. Azt, hogy kihagyja a végéig, és hagy egy válasz. Kopogó van jelenleg nem engedélyezett.

6 Responses to "Lebontás AMX Plugins, 7. rész"


nem teljesen tökéletes de valamit ki tudsz hozni ..


Hozzászólás jelentése
Vissza a tetejére
   
HozzászólásElküldve: 2014.03.24. 10:03 
Offline
Imperátor
Avatar

Csatlakozott: 2009.04.21. 09:33
Hozzászólások: 3991
Megköszönt másnak: 5 alkalommal
Megköszönték neki: 135 alkalommal
Jajj ne, könyörgöm, google fordítóval ne...
Ha nem értesz az assemblyhez, akkor ne is kezd neki (se lefordítani, se decomplier-ezni).

_________________
Kód:
I'm back

Kép


Hozzászólás jelentése
Vissza a tetejére
   
Hozzászólások megjelenítése:  Rendezés  
Új téma nyitása  Hozzászólás a témához  [ 11 hozzászólás ]  Oldal 1 2 Következő


Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 9 vendég


Nyithatsz új témákat ebben a fórumban.
Válaszolhatsz egy témára ebben a fórumban.
Nem szerkesztheted a hozzászólásaidat ebben a fórumban.
Nem törölheted a hozzászólásaidat ebben a fórumban.
Nem küldhetsz csatolmányokat ebben a fórumban.

Keresés:
Ugrás:  
Powered by phpBB® Forum Software © phpBB Limited
Magyar fordítás © Magyar phpBB Közösség
Portal: Kiss Portal Extension © Michael O'Toole