External MW3 Hack unter der Lupe

Der Secunet-User sup3ria war so freundlich mir diesen Hack für eine Analyse zukommen zu lassen. sup3ria hatte den Bot cracked, danke auch dafür :) Dieser Hack wurde für 10€ verkauft, ob ein ESP und ein Aimbot diesen Preis gerechtfertigen…

Trotzdem ist es schön ein .NET-Hack zu analysieren, allein aus der Tatsache dass es ein reiner .NET Hack ohne C++/CLR ist.

Nach dem HWID-Check wird ein einem neuen Thread das Overlay initialisiert. Das ist einfach nur eine transparente Form mit einem Control, das ESP Control. Dieses Control überschreibt OnPaint und ruft dabei die Draw-Funktion auf:

// mw3_by_stefsot.ESP
protected override void OnPaint(PaintEventArgs e)
{
	this.draw(e.Graphics);
	base.OnPaint(e);
}

Die ESP Draw-Loop sieht dabei schon interessanter aus. Nach ein paar Checks werden alle Spieler durchgegangen und dabei je nach Position, Team und weiteres eine Box gezeichnet. Source gibt es hier keinen zu sehen, da alle Variablen unleserlich sind und sich vieles wiederholt. Interessant sind allerdings diese Zeilen:

if ((Class0.struct1_0 - Class0.class1_0[i].struct1_0).method_0() / 48f < 12f & Class0.class1_0[i].color_0 == Color.Red & Class0.bool_2 & Class0.smethod_2(Class0.class1_0[i].struct1_0.float_2, 70) & Class0.class1_0[i].bool_0)
{
   int num2 = (int)Math.Round((double)(gr.MeasureString("AN ENEMY IS NEAR YOU!", new Font("Arial", 25f, FontStyle.Bold)).Width / 2f));
    gr.DrawString("AN ENEMY IS NEAR YOU!", new Font("Arial", 25f, FontStyle.Bold), Brushes.Cyan, (float)((double)this.Width / 2.0 - (double)num2), (float)((double)this.Height / 2.0 + (double)Class0.float_1));
   }

Wenn der Abstand von PlayerVector (Class0.Struct1_0) zum Vector des aktuellen Gegners (class1_0[i].Struct1_0) kleiner als 12 ist, so wird eine Warnmeldung ausgegeben. Nette Idee :)

Der Source des Aimbots sieht wie ein Schlachfeld aus, ich habe wirkliche Probleme daraus Informationen zu ziehen :D Soweit ich das sehe wird aus der Screen-Position ein Offset errechnet und dann der Mauscursor um diesen Offset verschoben. Und wer mir nicht glaubt dass der Source so schrecklich ist sollte sich mal das geben, so geht das geschätzte 200 Zeilen lang!

Class0.Class2 class2_ = new Class0.Class2((double)(location.X + Class0.int_0[0]), (double)unchecked((float)checked(form_0.Location.Y + Class0.int_0[1]) + Class0.float_1));
						Class0.Class2 class2_2 = unchecked(new Class0.Class2(Class0.class1_0[Class3.int_0].class2_1.double_0 - Class0.class1_0[Class3.int_0].class2_2.double_0 / 2.0, Class0.class1_0[Class3.int_0].class2_1.double_1 + (double)Class0.float_1 - Class0.class1_0[Class3.int_0].class2_2.double_1));
						Class0.Class2 class2_3 = new Class0.Class2(Class0.class1_0[Class3.int_0].class2_2.double_0, Class0.class1_0[Class3.int_0].class2_2.double_1);
						if (!Class3.smethod_2(class2_, class2_2, class2_3))
						{
							location = new Point((int)Math.Round((double)unchecked((float)point.X * Class0.float_2 + (float)Class3.point_0.X * Class0.float_3)), (int)Math.Round((double)unchecked((float)point.Y * Class0.float_2 + (float)Class3.point_0.Y * Class0.float_3)));
							Class3.smethod_1(location, form_0);
						}

Weitere Kritikpunkte an dem Bot:

  • Jede Variable wird einzeln per ReadProcessMemory aus dem Speicher gelesen, da sind ca. 1000 RPM Aufrufe pro Durchgang. Warum nicht einfach eine Struktur auslesen und über Marshal.PtrToStructure das ganze gescheit casten? Die Strukturen sind übrigens auch ein Chaos.
  • Es werden 2 Threads mit je einem Sleep von 13 Millisekunden gestartet. Das reicht nicht für einen effektiven ESP/Aimbot gegen andere Cheater, was immer meine Intention war. Injecten und Hooken ist das einzig wahre, so sehr ich externe Hacks auch respektiere.
  • Der “Lag-Fix” ist einfach nur ein Aufruf von GC.Collect. Dabei räumt der GarbageCollector alle nicht gebrauchten Objekte auf. Da diese aber sofort wirder befüllt werden ist der Sinn null. Hört sich halt cool an, ein “LagFix”.
  • Das ProcessHandle wird über GetWindowA und GetWindowThreadProcessId abgerufen. Schonmal was von der System.Diagnostics.Process Klasse gehört?
  • Bei diesem Code denke ich nur: “DAFUG?”. ReadInt mit einer Angabe der Bytes die gelesen werden sollen?
public static object readInt(int address, int bytes)
{
	long num = 0L;
	int arg_1A_0 = (int)Memory.pHandle;
	int num2 = 0;
	Memory.ReadProcessMemory_1(arg_1A_0, address, ref num, bytes, ref num2);
	return num;
}

Soweit zu dieser Analyse. Als Fazit ist zu sagen: Guter Versuch, kopierte Memory-Klasse und keine Ahnung vom Speicher. Der Code ist grausam, nicht nur durch den Deobfuscator. Warum wird sowas für GELD verkauft?

Greez

9 people like this post.
    • Becks
    • 25. Jul. 2012 2:17pm

    Das Ding funktioniert ja nichtmal richtig ^^

    Danke für die Analyse!

    • OrangeAw
    • 25. Jul. 2012 3:40pm

    Wieder ein guter Artikel. Schön.

    • hoschi111
    • 29. Jul. 2012 9:29am

    Hallo easysurfer,
    ich liebe deine Analysen und habe sofort erkannt, um welchen Sourcecode es geht.
    Dieser Sourcecode ist Public! Man musste lediglich die Offsets an die aktuelle Version anpassen.
    Bei diesem Hack wurde anscheinend nur eine HWID-Überprüfung eingefügt.

    Wenn du magst, schick ich dir diesen Source als E-Mail (schreib mir einfach dazu eine kurze E-Mail)

    • bella
    • 9. Okt. 2012 6:01pm

    Wenn man keine Ahnung hat…

    Der Code wurde reflected, das ist jawohl klar.
    Kein Programmierer würde mit “Class0″ arbeiten, macht ja garkeit Sinn.

    Desweiteren ist es völlig egal, wie man einen Handle erzeugt.
    Ob es nun API- calls verwendet oder die Process- Class, sowas von irrelevant.

    Zum Artikel: Ich dachte ich lese einen vernümpftigen Artikel mit Fachwissen, stattdessen schreibt da ein Mensch ohne wirkliches Wissen irgendein Mist zusammen und verbreitet es noch.
    Wunderbar, ich bin dankbar, dass Leute wie du den Anfängern Müll “beibrigen”.

      • Easysurfer
      • 9. Okt. 2012 9:37pm

      Ich habe nie behauptet dass dieser der “Orignalsource” ist. Wenn ich ein File analysiere, so liegt es meist als obfuskierte Binary vor, Class0 ist eine Umbennenung der noch unlesbareren Strings.

      PInvoke wurde dafür entwickelt, Funktionen die das .NET Framework nicht bereit stellt, über die WinAPI zu lösen. Das verlangt Zugriff auf nativen Speicher, ist unkonfortabel (Strukturen als Zeiger!) und langsam. Natürlich ist es jedem selbst überlassen was man nun Verwendet, man sollte das allerdings im Hinterkopf behalten. Würde mich übrigens interessieren was Du zu den anderen Kritikpunkten sagst und nicht nur den schwächsten Ansprichst ;-)

      Wenn Du Artikel mit Fachwissen willst, so lege ich Dir die Artikel über den MW2 Bot, besonders aber den Artikel über natives Detouring und mASM, ans Herz.

      Da ich annehme dass Du der “Coder” dieses Bots bist noch eine kleine Anmerkung an die anderen Leser dieses Kommentares: Der hier verkaufte “Bot” ist eine leicht modifizierte Version des öffentlichen Sources “External mw3 wall & aim by stefsot “. Und jetzt kannst Du mir, bella, nochmal was von Müll erzählen :)

  1. Noch keine TrackBacks.


2 − = eins