Dynamic Memory Allocation für Anti-Cheating-Zwecke

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Dynamic Memory Allocation für Anti-Cheating-Zwecke

Beitrag von Thorium »

Dynamic Memory Allocation (DMA) heißt nichts weiter, als das der benötigte Speicher für Daten während der Laufzeit des Programms festgelegt und reserviert (allokiert) wird.

Für Anti-Cheating-Zwecke ist das deswegen gut geeignet, da bei jedem Programmstart die Speicheradressen der allokierten Speicherblöcke anders sind. Viele Trainer-Coder haben Probleme mit DMA, da sie den Pointer im Speicher finden müssen, bevor der Trainer auf die Daten zugreifen kann. Allerdings gibt es auch viele die das können, also DMA bietet keinen absoluten Schutz. Aber es ist besser als garnichts.

Wie man im folgenden Code sehen kann, ist DMA in PureBasic sehr simpel. Lässt sich also ohne weiteres in jedes PB-Spiel implementieren.

Es ist darauf zu achten, dass nicht für jede Variable ein eigener Speicherblock allokiert wird, denn die Untergrenze für Speicherregionen befindet sich bei Win32-Systemen bei 4 Kilobyte. Das heißt, wenn wir jede Variable einzeln allokieren, haben wir für jede Variable einen Speicherverbrauch von 4 KB.

Wenns Fragen gibt, ruhig fragen, obwohl ich denke der Code ist eindeutig und leicht verständlich.

Code: Alles auswählen

;--------------------------------------------------------
;| Dynamic Memory Allocation for Anti-Cheating purposes |
;|                                                      |
;| Version 1.00                                         |
;| Developed by Thorium, http://www.SacredVault.de/     |
;|                                                      |
;| PureBasic 4.00 Code                                  |
;--------------------------------------------------------

EnableExplicit

;die Pointer der kritischen Variablen
Global Hitpoints.l ;Lebensenergie, hier wollen wir ein Long haben
Global Lifes.l ; Lebensanzahl, hier wollen wir ein Byte haben, müssen aber dennoch ein Long definieren

Procedure AllocCriticalVars()
Define Temp.l

;allokieren einer zufälligen Größe an Speicher
;ohne dies werden unsere Variablen immer an der gleichen Speicheradresse liegen

Temp = AllocateMemory(Random($10000)+1)

;allokieren des Speichers für die Hitpoints und Lifes
;wir wollen ein Long und ein Byte haben, also müssen wir 5 Byte allokieren
;Long=4Byte Byte=1Byte
;Jede Variable einzeln zu allokieren, währe Speicherverschwendung,
;da die Mindestgrenze für eine Speicherregion bei 4 Kilobyte liegt.

Hitpoints = AllocateMemory(5)

;Hitpoints sind ein Long, also 4 Byte,
;also müssen wir nur + 4 zur Speicheradresse von Hitpoints
;addieren um den Pointer zu Lifes zu bekommen

Lifes = Hitpoints + 4

;freigeben des zufällig allokierten Speichers
;immer schön aufräumen und freigeben, was wir nichtmehr benötigen
FreeMemory(Temp)
EndProcedure


;allokieren des Speichers für kritische Variablen
AllocCriticalVars()

;wir sehen, das sich unsere Variablen bei jedem Programmaufruf an einer anderen Speicheradresse befinden
Debug("Pointer to Hitpoints: " + Str(Hitpoints))
Debug("Pointer to Lifes: " + Str(Lifes))

;so müssen wir nun auf die Variablen zugreifen:

;schreiben
PokeL(Hitpoints,100)
PokeB(Lifes,3)

;lesen
Debug("Hitpoints: " + Str(PeekL(Hitpoints)))
Debug("Lifes: " + Str(PeekB(Lifes)))
Zuletzt geändert von Thorium am 16.06.2006 18:52, insgesamt 1-mal geändert.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Ein

Code: Alles auswählen

TEMP = AllocateMemory(Random($10000)+1) 
sonst kannst du den zufälligen Speicherbereich nicht freigeben.
Optimismus ist ein Mangel an Information.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Hellhound66 hat geschrieben:Ein

Code: Alles auswählen

TEMP = AllocateMemory(Random($10000)+1) 
sonst kannst du den zufälligen Speicherbereich nicht freigeben.
Ups, hab ich doch glatt vergessen, thx ist korrigiert.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Code: Alles auswählen

;lesen
Debug("Hitpoints: " + Str(PeekL(Hitpoints)))
Debug("Lifes: " + Str(PeekB(Lifes))) 
Das beweist mir garnichts, weil aus einer fremden Anwendung funktioniert das nicht.
Aus dem Spiel heraus ist es doch ein eingebautes Feature, warum also dieses wieder kaputt machen. Naja, ich Spiele aber nie. muß das also nicht verstehen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Ne bessere Variante wäre vielleicht das sekündliche Wechseln des Speicherbereichs für die wichtigsten Werte. Dann kann sich ein Trainer totsuchen.
Optimismus ist ein Mangel an Information.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

ts-soft hat geschrieben:

Code: Alles auswählen

;lesen
Debug("Hitpoints: " + Str(PeekL(Hitpoints)))
Debug("Lifes: " + Str(PeekB(Lifes))) 
Das beweist mir garnichts, weil aus einer fremden Anwendung funktioniert das nicht.
Aus dem Spiel heraus ist es doch ein eingebautes Feature, warum also dieses wieder kaputt machen. Naja, ich Spiele aber nie. muß das also nicht verstehen.
Ich verstehe nicht was du nicht verstehst?

Der Code, den du zitiert hast, ist auch nicht dafür da was zu beweisen, sondern zu zeigen, wie man mit den Variablen operieren kann, ohne sie wirklich als Variable deklariert zu haben, man hat halt nur die Pointer.

Der Sinn der Sache ist es, das die Variablen bei jedem Programmstart an einer anderen Speicheradresse liegen um es zu erschweren ein Programm zu machen, welches diese Variablen von aussen manipuliert.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Hellhound66 hat geschrieben:Ne bessere Variante wäre vielleicht das sekündliche Wechseln des Speicherbereichs für die wichtigsten Werte. Dann kann sich ein Trainer totsuchen.
Jep. :allright:
Ich hab noch viele Ideen im Kopf, eins nach dem anderen. :D
Das DMA, was ich hier gepostet habe ist sehr simpel und wird so auch in vielen komerziellen Spielen eingesetzt.

Wenn du das Programmieren willst, ich verlinke gerne alles was mit Anti-Cheating zutun hat in meinem Artikel.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Sorry, ich behaupte jetzt mal, dass das so nicht verwendet wird. Versuch
mal so ein Spiel zu schreiben, total mühsam. Besser:

Code: Alles auswählen

EnableExplicit 

Structure CRITICAL
  Life.l
  Points.l
EndStructure
Global *datas.CRITICAL

Procedure AllocCriticalVars() 
  Define Temp.l 
  
  Temp = AllocateMemory(Random($10000)+1) 
  *datas = AllocateMemory(SizeOf(CRITICAL))
  FreeMemory(Temp) 
EndProcedure 



AllocCriticalVars() 

Debug("Pointer to Data: " + Str(@*datas\Life)) 


*datas\Points = 100
*datas\Life = 3

Debug("Hitpoints: " + Str(*datas\Points))
Debug("Lifes: " + Str(*datas\Life))
Andere Varianten wären mit z. B. Linked Lists / Arrays oder Objekten (OOP).

Aber das Prinzip deines Codes stimmt natürlich. :)
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag von Thorium »

Jo hast recht. Mir war es jetzt auch nur wichtig das Prinzip rüberzubringen. Wie man das am besten implementiert muss man dann sowieso von Fall zu Fall schauen.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
Konne
Beiträge: 764
Registriert: 30.03.2005 02:20
Kontaktdaten:

Beitrag von Konne »

So ein schutz ist IMHO aber nicht wirklch noetig. Wenn jemand einen Spielwert aus dem Varoablen Stack auslesen kann ist es auch ein leichtes den Pointer auszulesen und damit dann auf den Memory zuzugreifen.
Antworten