Beiträge von Lead0b110010100

    Der Service ist bis zum 29.05.21 pausiert, Dauer & Stammkunden sind davon nicht betroffen.

    Wenn ich nicht antworte, bitte geduldig sein und in einer Woche nochmal schreiben.


    Brauch nur mal Urlaub von dem Kram und muss ein paar Arzttermine nachholen, nichts Wildes!


    P.S: Ihr seid echt wie brennende Schafe die in alle Richtungen laufen, ihr habt nicht mal eine Woche ausgehalten :D Bin wieder da, hab euch lieb.

    Kleine Anmerkung:


    Wenn ich mich auslogge und wieder einlogge, dann bin ich nicht mehr locked.

    Denn du persistierst diese Variable 'm_isLocked' nicht weiter, die wird bei CHARACTER::Initialize wieder auf false standartmäßig gesetzt.


    Also Client killen und neu starten und dann hat sich das.

    Es ist zwar echt nett das du gefundene Lücken releasen willst, aber es schadet gleichzeitig deinem Geschäft.

    Ich würde mir diesen Punkt also gut überlegen und allgemein ist es besser, 'Services' anzubieten, die monatliche Zahlungen beinhalten anstatt deine Zeit gegen Geld zu tauschen.

    Geh ich mit.

    OH wow, dude. That's awesome!!!

    I wish I could like that thread 5 times more, that will open a whole new set of features that could be implemented. I never even thought of that idea of bringing events to the client too (The way with python and the OnUpdate function get's really messy over time).


    I am installing this in my code base right now, thanks! <3

    Moin.


    Da ich immernoch am ausprobieren sämtlicher Tools und Hilfestellungen bin und heute random die Option zum "AdressSanitizer" in Visual Studio gefunden habe, dachte ich schadet es nicht wenn ich einen potenziellen und offensichtlichen Fehler mit euch teile. Gleichzeitig empfehle ich jedem angehenden Entwickler folgendes Video hier:


    Bitte melden Sie sich an, um dieses Medienelement zu sehen.


    -------------------------------------------------------------------------------------------------------------------------


    Was zum Fick?


    Ums kurz zu erklären, was tun wir in den folgenden drei Zeilen Code?

    Code
    1.     char name[36];
    2.     snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", item_table->szName, (int) item.vnum, item.count);
    3.     sys_log(0, "SHOP_ITEM: %-36s PRICE %-5d", name, item.price);


    1) Wir erstellen ein char array im Stack mit der Länge / Größe 36. Also können genau 35 Zeichen + im Optimalfall (üblicherweise) der Null-Terminator '\0' reingeschrieben werden ins Array.

    2) Wir schreiben einen formatierten String in den Buffer, grob gesagt. Eigentlich streamen wir den formatierten String in ihn, aber gut.

    3) Wir geben den String als Teilkomponente in der sys_log aus, dafür benutzen wir den Variablennamen für das Char-Array also 'name'. Was eig. nur ein Pointer auf das erste Zeichen im Array ist, wenn mans so will. Beim Ausgeben liest dann das Programm von diesem Pointer aus im Speicher die Stellen und gibt sie aus bis ein '\0' - Terminator kommt.


    Setzen wir doch mal einfach Werte in den formattierten String ein und schauen uns z.B an was passiert wenn ich als Serverbetreiber '100x Zen-Bohne' im Shop verkaufen möchte und in die shop_item in der Datenbank so eintrage:


    Code
    1. Zen-Bohne (#70102) (x 100)


    Sieht harmlos aus oder? Wie viele Zeichen sind das? (Es sind genau 36)

    Es fehlt also der Platz für den Nullterminator im char array, snprintf wird das Array nicht vergrößern. Stattdessen findet man bei der Recherche folgendes über den Rückgabewert der 'printf' - Funktionen:


    Wir haben ein Char Array der Größe 36 erstellt und genau 36 Zeichen reingeschrieben. Demnach ist dieser 'string' wenn mans so sehen möchte nicht null terminiert. Der char - Array resultiert also eig. in sowas hier was wir nicht wollten:

    Code
    1. Zen-Bohne (#70102) (x 100)¼±µÎ


    Es werden mehr Zeichen repräsentiert als angegeben (36), weil im Speicher nun zufällig erst nach 4 random Zeichen der Nullterminator kommt. Das könnten auch 500 Zeichen sein, oder gar keiner. Also wenn ihr noch keinen Crash beim Hochfahren des Servers hattest, hattet ihr entweder einen wirklich schlauen Compiler der das erkannt und die Gefahr gebannt hat oder einfach Glück.


    Wie fixxe ich das nun?


    Ganz einfach, macht den Buffer entsprechend größer. Theoretisch reicht es, ihn auf 40-50 zu setzen. Ich nehm jetzt einfach 512 um ultra sicher zu sein (Nutze damit mehr Speicher im Stack, ist aber unproblematisch, weils schnell wieder gecleared wird und nicht dauerhaft da bleibt):


    shop.cpp

    Suchen

    Code
    1. char name[36];
    2. snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", item_table->szName, (int) item.vnum, item.count);
    3. sys_log(0, "SHOP_ITEM: %-36s PRICE %-5d", name, item.price);


    Ersetzen mit

    Code
    1. char name[512];
    2. snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", item_table->szName, (int) item.vnum, item.count);
    3. sys_log(0, "SHOP_ITEM: %-36s PRICE %-5d", name, item.price);


    Was lernen wir daraus?

    Wir sollten alle Tools nutzen die es gibt um unser Programm bestmöglichst zu härten und Bugs vorzubeugen.

    Bugs erst zu fixxen, wenn sie auftauchen ist keine Good Practice. Vieles kann vorher schon verhindert werden.

    Good job, hab zwar noch niemanden gesehen der dieses Paket aktiv nutzt um Buffer Overflows zu erzeugen - Aber bei genug Paketen ist das aufjedenfall möglich.

    War mir bisher so nicht aufgefallen und wäre es auch nicht denke ich (bis mich jemand aktiv mit dieser Methode angreift).

    Ich finde es sehr gut, dass du nicht nur von den Vorteilen und Möglichkeiten erzählst sondern direkt auch alle Illusionen zerstörst zwecks Kosteneinsparung und Umsetzbarkeit.

    Wie du schon sagtest, brauch es dafür wirklich fähige Developer (Nein, ein einziger wird da nicht reichen) und einen, der sich mit Clouddiensten auskennt.


    Klar, ich kann bei Google Cloud Server kaufen, aufsetzen und skalieren - Aber ich verstehe nicht ansatzweise genug um das architektonisch am Ende auch schlau und kosteneffizient umzusetzen.


    Good job - Ich mag solche Experimente. Gerne mehr davon, ist immer schön zu sehen was theoretisch so geht (Auch wenn praktisch bei Metin2 wirklich unnötig. Cloud und Gameinstanzen zu separieren find ich noch sinnvoll aber den Chat? Naja..).

    packet_info.cpp (Server-Source) und PythonNetworkStream.cpp (Client-Source)


    Da ist für jedes Paket nochmal spezifiziert ob es ein statisches oder dynamisches Paket ist.

    Ich sehe das nicht so eindeutig, um mir eine qualifizierte Meinung zu bilden.

    Einerseits erledigst du, .colossus. hiermit deinen einzigen Konkurrenten der ein ähnliches System anbietet und erhöhst damit deine Reichweite und damit auch deinen Profit.

    Andererseits spielt dein Konkurrent auch nicht fair, zumindestens wenn man dir glauben will und ist selbst nicht ganz töfte unterwegs.


    Ist es also okay, so ein "HOW TO" ohne wirklichen FIX zu veröffentlichen? Das muss jeder für sich selbst entscheiden, ich finde: Nein.

    Du schadest mit diesem Thread nicht nur diesem 'gefährlichen' Menschen sondern auch jedem Server der seinen Service in gutglauben angenommen hat.


    Technisch muss ich hier aber trotzdem noch erwähnen, dass mir und jedem mit dem ich gesprochen habe zu diesem 'Fix' bereits beim ersten Durchsehen der Bottleneck (Webserver) und der laue Schutz (whitelist von ips über GET) aufgefallen ist und das auch ein Grund für mich war, von diesem Schutz abzuraten. Also wenn .colossus. dieses HOW-TO gemacht hätte, hätte es wahrscheinlich ein Anderer gemacht. Oder noch schlimmer: Ein Angreifer hätte darüber erfahren und hätte dann explizit die Webserver der Server angegriffen, die den Schutz gekauft haben.


    Schwierige Sache, für mich keine "gut oder böse" - Frage.

    So ganz unbenutzt ist es nicht. die ANTI Skills z.B müssen initial mit Skillbüchern und danach per Point gelevelt werden.

    Diese passiven Skills könnte man da aus meiner Sicht echt entfernen in der cmd_general, würden durch die Abfrage sowieso verhindert werden.

    Bin ich grade, willst du ein Video?

    Dir fehlt einfach nur der Flag in der skill_proto:


    DISABLE_BY_POINT_UP


    So muss das dann aussehen:


    Bitte melden Sie sich an, um dieses Bild zu sehen.

    Ist mir schon klar, jedoch wird das von ein paar Spielern noch ausgenutzt, was vor allem im PVP ärgerlich ist :)

    Was gibt es da auszunutzen? Es passiert nichts.

    Hab das aus der Kraizy Source da oben, kein Exploit zu sehen. Vllt. erklärst du den nochmal genauer?


    Habs btw. ausprobiert, bei mir passiert da nichts bei /skillup 141/142 usw.

    Es war nie ein Exploit. Denn beide Skills haben den Flag:

    Code
    1. DISABLE_BY_POINT_UP


    und folgende Abfrage in der SkillLevelUp Funktion verhindert den 'Exploit'. Diese existiert standartmäßig:

    Code
    1. if (bMethod == SKILL_UP_BY_POINT)
    2. {
    3. [...]
    4. if (IS_SET(pkSk->dwFlag, SKILL_FLAG_DISABLE_BY_POINT_UP))
    5. return;
    6. }


    Für die ANTI - Skills verhindert folgende Abfrage das initiale hochleveln (lvl 0 zu lvl 1):

    Code
    1. if (SKILL_7_A_ANTI_TANHWAN <= dwVnum && dwVnum <= SKILL_8_D_ANTI_BYEURAK)
    2. {
    3. if (0 == GetSkillLevel(dwVnum))
    4. return;
    5. }