Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > General Coding > Coding Tutorials
You last visited: Today at 23:03

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Tutorial] Manipulieren von ungemappten PE-Dateien

Discussion on [Tutorial] Manipulieren von ungemappten PE-Dateien within the Coding Tutorials forum part of the General Coding category.

Reply
 
Old   #1


 
Jeoni's Avatar
 
elite*gold: 966
Join Date: Apr 2010
Posts: 1,105
Received Thanks: 681
[Tutorial] Manipulieren von ungemappten PE-Dateien

0. Vorwort
1. Die Theorie
1.1 Das PE-Format
1.2 Code-Injection
2. Umsetzung in die Praxis
2.1 Header manipulieren
2.2 Unsere Section bauen und in die DLL schreiben


0. Vorwort
In diesem Tutorial wollen wir unseren Code in eine fremde DLL bringen ohne dass sich diese gemappt im Arbeitsspeicher befindet. Wir sorgen dafür, dass unser Code als angenommen und danach der originale EntryPoint aufgerufen wird, wenn wir es wollen. Das schöne hierbei ist, dass das für alle Prozesse gilt, die die DLL nutzen.
Eigentlich wollte ich etwas mehr schreiben und alles detaillierter Erläutern, wusste aber nicht genau, was und befinde, dass es relativ gut so ist, wie es ist
Ich bin eben nicht so toll, wenn's um's Erklären geht und etwas unkoordiniert, was man sicher auch hier wiederfindet. Nichtsdestotrotz hoffe ich natürlich, dass es halbwegs lehrreich ist, für die, die es noch nicht kannten
Wenn euch etwas fehlt (das tut es sicherlich), schreibt es in den Thread oder mir per PN, dann füge ich es hinzu
Um meinen konfusen Ausführungen folgen zu können solltet ihr nebenbei Erklärungen zum und zum offen haben. Ich werde hier nicht auf jedes einzelne Feld der Strukturen eingehen, sondern werde nur wichtige benennen und ihr dürft sie euch dann im MSDN anschauen, tut mir leid
Weiterhin möchte ich euch bitten, es zu entschuldigen, wenn ich zu oft das Wort "Header" benutze. Tut mir Leid und ich hoffe, dass es nicht allzu stark stört.

1. Die Theorie
1.1 Das PE-Format
Dieses Bild zeigt uns letztendlich alles, was wir über den Grundlegenden Aufbau des PE-Formates wissen sollten. Jede PE-Datei fängt mit dem DOS-Header an. Für uns ist der nur wichtig, da diese Struktur einen relativen Pointer auf den für uns relevanten PE-Header beinhaltet. Der PE-Header ist für uns wichtiger. Er enthält die relative Adresse des EntryPointes (den wollen wir ja ändern) und die Anzahl der Sektoren. Direkt nach dem PE-Header kommt ein Array aus Sektor-Headern. Die Länge bzw. die Anzahl der Indices dieses Arrays kann man dem PE-Header entnehmen. Jede Section benutzt bestimmte Daten aus der DLL und wird an eine bestimmte Adresse relativ zur Modulbase gemappt. Ist die Größe der Section größer, als die angegebenen Daten (steht alles im Header :P ), so wird der Rest mit Nullen gefüllt.

1.2 Code-Injection
So, nun zur Theorie des Manipulierens. Der Plan ist ja unseren Code als Entrypoint verwenden zu lassen. Aber wo ist Platz für unseren Code? Wenn wir ihn einfach so an's Ende der DLL klatschen, wird er nicht gemappt, das ist ja nicht Sinn der Sache. Aber wenn wir unseren Code an die Code-Section klatschen und dessen Größe nur anpassen, müssen wir alle darauffolgenden Sections verändern, da sich deren Daten ja dann an anderer Stelle befinden. Die Lösung: Wir machen einfach eine neue Section, deren Daten (unser Code) wir an's Ende der DLL packen. Was muss dafür gemacht werden? Wir müssen einen neuen Section-Header einfügen, die Anzahl der Section, die im PE-Header stehen, um 1 erhöhen, den Entrypoint auf unsere Funktion in unserer Section verschieben und unsere Daten mitsamt dem veränderten Rest auf die Festplatte schreiben. Zudem müssen wir irgendwo den alten Entrypoint speichern. Hier schlage ich vor, dass wir uns eine Struct bauen, in der wir den alten Entrypoint und Daten für unsere Funktion unterbringen. Jetzt wird man sich sicher fragen: Welche Daten sollen warum dort rein? OK, wenn ihr einen String benutzt, nutzt ihr eigentlich nicht den String an sich, sondern ein Pointer auf ein Char-Array. Dieses Array liegt im kompilierten Programm aber in der Data-Section und ist für uns somit nur über umwege zu erreichen. Daher nutzen wir also die Struct, um solche Daten, dort unterzubringen.
Da wir schon bei Einschränkungen sind: Außer dieser Einschränkung gibt es noch weitere:
- die Funktion darf maximal 4KB an lokalen Variablen benutzen (für mehr kann man ja die Struktur nutzen). Dies kommt daher, dass ja eigentlich für die lokalen Variablen der Stackpointer um deren Größe reduziert wird (sub esp, <Größe der lokalen Variablen>). Werden aber mehr als 4KB lokaler Variablen gebraucht, wird ESP nicht direkt reduziert, sondern über eine spezielle Funktion, welche gecallt wird. In der DLL (bzw. im Prozess, der die DLL lädt) ist diese Funktion natürlich nicht da, oder an einem anderen Platz, weswegen der Call in's Leere geht.
- viele Compiler machen Buffer Security Checks, unter anderem um die Integrität des Stacks zu gewährleisten. Diese werden aber auch durch externe Funktionen erledigt, weswegen auch die wegmüssen (bei den meisten Compilern ist das der /Gz-Switch).
- alle API-Aufrufe, die nicht zur kernel32.dll oder user32.dll gehören, dürfen nicht direkt aufgerufen werden, da sich die Module, die die Funktionen beinhalten an unterschiedlichen Stellen befinden können. Daher müssen wir hier zuerst mit GetModuleHandle das Modul bekommen und dann mit GetProcessAddress die Adresse der Funktion, die wir dann aufrufen wollen (vergesst nicht, nur Strings aus unserer Struktur zu nehmen).
So also unsere Section beinhaltet erst unsere Daten-Struktur und dann unsere Funktion für den neuen EntryPoint. Aber wie können wir aus unserer Funktion auf die Datenstruktur (anfang der Section) zugreifen? Ich habe dieses Problem so gelöst, dass ich den relativen Pointer zur Section (und damit ja zur Datenstruktur) in das "LoaderFlags"-Feld des NTHeader.OptionalHeader geschrieben habe. Dieses Feld ist laut MSDN "obsolete", weswegen wir es deswegen einfach missbrauchen :P

2. Umsetzung in die Praxis
So jetzt erstmal zum vorgeplänkel unseres Programms. Wir müssen die Opfer-DLL einlesen (nicht mit LoadLibrary oder sonstwie mappen!). Wie, ist jedem selbst überlassen. Am Ende befindet sie sich jedenfalls im Arbeitsspeicher und wir haben einen Pointer, der auf das erste Byte der DLL zeigt.

2.1 Header manipulieren
So, um die Header zu manipulieren, müssen wir sie erstmal kriegen. Nach dem PE-Format befindet sich ganz am Anfang der DOS-Header, also ab dem ersten Byte. Wir können also gleich einen IMAGE_DOS_HEADER-Pointer aus dem DLL-Pointer machen. Dann nutzen wir das Feld e_lfanew, um an den NT-Header (= PE-Header) zu kommen. Natürlich müssen wir diesen Wert noch mit der Basis addieren, da es nur ein relativer Pointer ist.
Code:
IMAGE_NT_HEADER* pNTHeader = (IMAGE_NT_HEADER*)(((IMAGE_DOS_HEADER*)pDLL)->e_lfanew + (DWORD)pDLL);
Auf Basis des NT-Headers holen wir uns nun das Section-Header-Array. Da es ja direkt an den NTHeaders anschließt können wir hier den pNTHeader mit der NTHeader-Größe addieren, um einen Pointer auf das Section-Header-Array zu kriegen, richtig? Leider nicht, da der OptionalHeader, der Teil des NT-Headers ist eine variable Größe haben kann, da sein IMAGE_DATA_DIRECTORY-Array unterschiedlich viele Einträge haben kann (obwohl es MEISTENS 16 hat). Glücklicherweise bietet der FileHeader, welcher auch Teil, des NTHeaders ist (ich hoffe, ihr habt die MSDN-Links vom Vorwort offen) ein Feld, welches passend mit "SizeOfOptionalHeader" benannt wurde. Wir addieren also zum NTHeader-Pointer 4 für die Signatur und sizeof(IMAGE_FILE_HEADER) und das oben benannte Feld um dann einen Pointer auf das SectionHeader-Array zu erhalten.
Code:
IMAGE_SECTION_HEADER* pSectionHeaders = (IMAGE_SECTION_HEADER*)((DWORD)pNTHeader + 4 + pNTHeader->FileHeader.SizeOfOptionalHeader);
Gut, aber wofür brauchen wir das? Da wir ja unsere eigene Section machen wollen, müssen wir auch den Header für diese zusammenschrauben. Wir müssen also eine virtuelle Adresse finden, die noch Platz genug für unsere Section bietet, also noch nicht durch andere Sections belegt ist. Wir gehen also die Sections durch und packen unsere Section ganz an's Ende. Der folgende Code dürfte durch diese Hintergrundinformationen selbsterklärend sein:
Code:
	for (int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++)
	{
		if (dwVAofSection < (pSectionHeaders[i].VirtualAddress + pSectionHeaders[i].Misc.VirtualSize))
		{
			dwVAofSection = (pSectionHeaders[i].VirtualAddress + pSectionHeaders[i].Misc.VirtualSize) + 0x1000 - ((pSectionHeaders[i].VirtualAddress + pSectionHeaders[i].Misc.VirtualSize) % 0x1000);
		}
	}
Danach steht in dwVAofSection eine durch 0x1000 teilbare virtuelle Adresse für unsere Section. Gemappt ist unsere Section also ab der Adresse Modulbase + dwVAofSection verfügbar.
Jetzt kommen wir zum "PointerToRawData" für unsere Section. Da wir unsere Section ja an's Ende der DLL packen wollen muss hier also die aktuelle Größe der DLL rein. Die einzige Einschränkung ist, dass PointerToRawData uns SizeOfRawData vielfaches des FileAlignment-Feldes des FileHeaders im NTHeader sein müssen. Aber das ist ja kein Problem für uns. Wenn die Größe der Datei nicht glatt durch den FileAlignment-Wert teilbar ist (ist bei mir noch nicht vorgekommen), schreiben wir eben noch ein kleines Buffer vor unserer Section in die Datei. Genauso schrieben wir ein kleines Buffer nach unserer Section in die Datei, wenn die Größe unserer Section nicht durch den FileAlignment-Wert teilbar ist (das kommt öfter vor).
Wir berechnen nach diesen vorgaben nun also die Größe unserer Section (SizeOfRawData und Misc.VirtualSize) und den "PointerToRawData":
Code:
DWORD dwSectionSize = dwFuncLength + sizeof(SomeData) + NTHeader->OptionalHeader.FileAlignment - (dwContentLength % NTHeader->OptionalHeader.FileAlignment);
dwFuncLength ist am Anfang von 2.2 erläutert

Code:
	if (dwSizeOfDLL % pNTHeader->OptionalHeader.FileAlignment == 0)
	{
		dwPointerToRawData = dwSizeOfDLL;
	}
	else
	{
		dwPointerToRawData = dwSizeOfDLL + pNTHeader->OptionalHeader.FileAlignment - (dwSizeOfDLL % pNTHeader->OptionalHeader.FileAlignment);
		dwPreSectionBufferLength = dwPointerToRawData - dwSizeOfDLL;
	}
"dwPreSectionBufferLength" dient später dazu, einen Buffer in der neuen DLL zwischen der alten DLL und unserer Section einzubauen, damit PointerToRawData die FileAlignment-Auflagen erfüllt und nicht auf irgendwelchem Müll zeigt.
Wichtig ist auch noch das "Characteristics"-Feld im Section Header. Da wir ja unseren Code ausführen, unsere Datenstruktur lesen und vielleicht auch zur Laufzeit bearbeiten müssen. Setzen wir also auch so unser Characteristics-Feld fest:
Code:
DWORD dwCharacteristics = IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE;
Zum schluss kreieren wir noch unseren Header (kann man natürlich schon dabei machen, ohne die ganzen lokalen Variablen, aber naja) und geben der Section einen Namen (max. 8 Stellen):
Code:
IMAGE_SECTION_HEADER MyHeader;

memcpy(MyHeader.Name, ".Jeoni", 8);
MyHeader.Misc.VirtualSize = dwSectionSize;
MyHeader.SizeOfRawData = dwSectionSize;
MyHeader.VirtualAddress = dwVAofSection;
MyHeader.PointerToRawData = dwPointerToRawData;
// restliche Felder mit 0 füllen
Diesen SectionHeader kopieren wir nach Abfrage, ob denn noch Platz für einen weiteren SectionHeader ist, einfach an's Ende des SectionHeader-Arrays:
Code:
if ((NTHeader->FileHeader.NumberOfSections + 1) * sizeof(IMAGE_SECTION_HEADER) <= NTHeader->OptionalHeader.SizeOfHeaders)
{
   memcpy((void*)((DWORD)pSectionHeaders + ((NTHeader->FileHeader.NumberOfSections)*sizeof(IMAGE_SECTION_HEADER))), (void*)&MySectionHeader, sizeof(IMAGE_SECTION_HEADER));
}
Als nächstes passen wir den NTHeader noch an:
Code:
SectionData.OriginalEntryPoint = NTHeader->OptionalHeader.AddressOfEntryPoint;
NTHeader->OptionalHeader.LoaderFlags = dwVAofSection;
NTHeader->OptionalHeader.AddressOfEntryPoint = dwVAofSection + sizeof(SomeData);
NTHeader->FileHeader.NumberOfSections += 1;
NTHeader->OptionalHeader.SizeOfImage += dwSectionSize;
NTHeader->OptionalHeader.SizeOfCode += dwSectionSize; // da wir der Section ja Code-Characteristics gegeben haben
Wegen SectionData und SomeData siehe 2.2

2.2 Unsere Section bauen und in die DLL schreiben
Ok, wir wollen also unsere Section schreiben. Mehr als unser Code und die Datenstruktur muss da ja eigentlich nicht rein. Aber wie bekommen wir unseren Code da rein? Entweder wir schreiben die gesamte Funktion mit ASM, und kopieren dann die Offsets da rein, oder wir machen uns eine Funktion in unserem Manipulator, kompilieren sie und fügen das dann zur Laufzeit ein. Aber wie kriegen wir die Länge unserer Funktion? Man könnte das Programm natürlich einmal kompilieren und dann mit einem Debugger nachschauen oder eine der disasm libs nutzen.
In diesem Tutorial bedienen wir uns aber eines kleinen Tricks (nicht schön, aber einfach): direkt nach unserer Funktion machen wir noch eine und rechnen dann einfach
Code:
DWORD dwFuncLength = &EndFunction - &NewEntryPoint;

bool _stdcall NewEntryPoint(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) // EntryPoint gemäß MSDN
{
   // ...
}

__declspec(naked) void EndFunction(){}
Im kompiliertem Programm sieht dass dann so aus:

So kriegen wir relativ genau die Länge unserer Funktion. Wichtig hierbei ist, dass in den Compileroptionen das Incremental Linking ausgestellt wird oder die beiden Funktionen als static erklärt werden. Sonst liefert der '&'-Operator nicht die Adresse der eigentlichen Funktion, sondern die eines Jumps zur Funktion. Und da die Jumps zu den Funktionen meist direkt hintereinander stehen, wird man dann hier immer 1 herausbekommen, was natürlich falsch ist.
OK, kommen wir mal kurz zu unserem Code bzw. was wir eigentlich machen wollen. Hier werde ich mal nur die Funktion MessageBeep(0) ausführen und danach den originalen EntryPoint aufrufen.
In die Datenstruktur kommt daher nur der relative Pointer zum originalen EntryPoint rein. Das ist also völlig ausreichend:
Code:
struct SomeData
{
	DWORD OriginalEntryPoint;
}SectionData;
Wir wissen ja, dass NTHeader->LoaderFlags einen relativen Pointer auf unsere Section enthält und dass unsere Datenstruktur zuerst in unserer Section steht.
Aufgrunddessen sieht unsere Funktion wie folgt aus:
Code:
bool _stdcall NewEntryPoint(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
	MessageBeep(0);
	IMAGE_NT_HEADERS32* NTHeader = (IMAGE_NT_HEADERS32*)(((IMAGE_DOS_HEADER*)hModule)->e_lfanew + (DWORD)hModule);
	SomeData* Data = (SomeData*)(NTHeader->OptionalHeader.LoaderFlags + (DWORD)hModule);
	DLLEntry_t pOrigEntryPoint = (DLLEntry_t)(Data->OrginalEntryPoint + (DWORD)hModule);

	return pOrigEntryPoint(hModule, ul_reason_for_call, lpReserved);
}
Das "+ (DWORD)hModule" macht aus Pointern, die relativ zur Modulbase sind absolute Pointer, die wir auch wirklich nutzen können.
Kommen wir zum schreiben unserer Section. Da wir natürlich an die Richtlinien für die Größe unserer Section gebunden sind, allokieren wir erstmal Platz für unsere Section bevor wir sie schreiben:
Code:
void* pMySection = malloc(pMySectionHeader->SizeOfRawData);
Nun kopieren wir hier unsere Datenstruktur hinein und danach unseren Code:
Code:
memcpy(pMySection, &SectionData, sizeof(SomeData));
memcpy((void*)((DWORD)pMySection + sizeof(SomeData)), &NewEntryPoint, dwFuncLength;
Wenn wir wollen können wir auch noch den Rest des Section-Buffers (da er ja aufgrund der FileAlignment-Richtlinie größer ist, als DatenStruktur + Funktion) mit Nullen oder so füllen, aber das könnt ihr ja sicher auch ohne mich.

Jetzt schreiben wir also das alte DLL-Buffer wieder in eine DLL auf die Festplatte, hängen unsere Section dran und sind fertig

Ähnlich könnt ihr es auch mit exportierten Funktionen der DLL machen. Dahingehend solltet ihr euch das "DataDirectory"-Feld des OptionalHeaders anschauen.
Jeoni is offline  
Thanks
8 Users
Old 11/19/2012, 19:18   #2
 
flickz.'s Avatar
 
elite*gold: 5
Join Date: May 2012
Posts: 589
Received Thanks: 139
Gehört in Coding Tutorials.
flickz. is offline  
Old 11/19/2012, 19:29   #3


 
Jeoni's Avatar
 
elite*gold: 966
Join Date: Apr 2010
Posts: 1,105
Received Thanks: 681
Ich weiß (ist mir leider erst nach dem Posten aufgefallen), steht sogar in der ersten Zeile nach der Überschrift. Hab's auch schon deswegen reported.
Jeoni is offline  
Old 11/20/2012, 21:19   #4


 
MrSm!th's Avatar
 
elite*gold: 7110
Join Date: Jun 2009
Posts: 28,909
Received Thanks: 25,409
Arrow Coding Releases -> Coding Tutorials

#moved
MrSm!th is offline  
Thanks
1 User
Old 11/23/2012, 11:45   #5
 
Tyrar's Avatar
 
elite*gold: 0
Join Date: Oct 2008
Posts: 1,637
Received Thanks: 1,119
habs zwar nur überflogen, sieht aber gut aus. mir fehlt allerdings der bereich für die relocs, da man die in dlls recht oft benötigt, kann auch sein dass ich den abschnitt nur übersehn habe

mir is schon klar, das kann man bei vielen dingen schon gebrauchen, wenn man allerdings nur code fest injecten will, wäre es da nicht sinnvoller nen eintrag in der IAT vorzunehmen, der auf ein eigenes modul verweist? also ich mein ja nur
Tyrar is offline  
Thanks
1 User
Old 11/23/2012, 12:00   #6


 
Jeoni's Avatar
 
elite*gold: 966
Join Date: Apr 2010
Posts: 1,105
Received Thanks: 681
Relocs und der Orginalcode der DLL werden hier nicht berührt. Klar kann man auch relocs nutzen um z.B. den originalen EntryPoint anzugeben. Aber um eine Datenstruktur kommt man allgemein kaum herum (klar kann man für jede manipulierte DLL einzeln Daten bzw. relocs in der Section angeben, ist aber nicht sehr komfortabel).
Der IAT Eintrag auf ein eigenes Modul macht für dieses Tutorial vermutlich kaum Sinn, wäre aber möglich. Sinn war es ja, Code auszuführen, wann immer und wo immer die DLL geladen wird und am besten den Code von der DLL ausführen zu lassen, damit's unauffälliger ist (hatte ich sicher vergessen zu erwähnen ). Wäre lediglich ein Eintrag in der IAT vorhanden, müsste noch unser Modul geladen werden (woher der windowsloader auch immer weiß, wo es sich befindet (vermutlich im Windows-Ordner)).
Ginge es lediglich um eigenen Code, der beim Laden ausgeführt werden sollte, so hätte man es, wie du es beschrieben hast, einfacher lösen können.
Aber das mit dem EntryPoint war nur ein Beispiel. Sicher hat es mehr Anwendungen, wenn man die DLL-Exporte verändert, also seinen Code zwischen schreiben kann. Und die kann man doch nicht auf externe Module legen, oder?
Ich hoffe, dass ich verstanden habe, was du meintest und habe deine Frage(n) beantworten können
MfG
Jeoni
Jeoni is offline  
Old 11/23/2012, 14:30   #7
 
Tyrar's Avatar
 
elite*gold: 0
Join Date: Oct 2008
Posts: 1,637
Received Thanks: 1,119
Quote:
Originally Posted by Jeoni View Post
Relocs und der Orginalcode der DLL werden hier nicht berührt. Klar kann man auch relocs nutzen um z.B. den originalen EntryPoint anzugeben. Aber um eine Datenstruktur kommt man allgemein kaum herum (klar kann man für jede manipulierte DLL einzeln Daten bzw. relocs in der Section angeben, ist aber nicht sehr komfortabel).
Der IAT Eintrag auf ein eigenes Modul macht für dieses Tutorial vermutlich kaum Sinn, wäre aber möglich. Sinn war es ja, Code auszuführen, wann immer und wo immer die DLL geladen wird und am besten den Code von der DLL ausführen zu lassen, damit's unauffälliger ist (hatte ich sicher vergessen zu erwähnen ). Wäre lediglich ein Eintrag in der IAT vorhanden, müsste noch unser Modul geladen werden (woher der windowsloader auch immer weiß, wo es sich befindet (vermutlich im Windows-Ordner)).
Ginge es lediglich um eigenen Code, der beim Laden ausgeführt werden sollte, so hätte man es, wie du es beschrieben hast, einfacher lösen können.
Aber das mit dem EntryPoint war nur ein Beispiel. Sicher hat es mehr Anwendungen, wenn man die DLL-Exporte verändert, also seinen Code zwischen schreiben kann. Und die kann man doch nicht auf externe Module legen, oder?
Ich hoffe, dass ich verstanden habe, was du meintest und habe deine Frage(n) beantworten können
MfG
Jeoni
der sinn von relocations liegt darin absolute adressen (wie z.b. für stings in der MessageBoxA/W funktion) zu nutzen, da man eine absolute adresse übergeben muss! (die sich bei einer verschobenen base adresse logischerweise ändert)

wenn es um das faken von exports geht kann man auch einfach ne proxy dll laden lassen

der grund warum ich die methode des direkten manipulierens bisher verwendet habe das simple protecten einiger dateien, für was anderes macht das denke ich nicht viel sinn... aber das überlasse ich jedem selbst
Tyrar is offline  
Reply

Tags
manipulation, pe-datei, tutorial, ungemappt


Similar Threads Similar Threads
[TuT] Savefiles manipulieren
01/30/2012 - Tutorials - 4 Replies
hi leute ;) vorab die infomation "was es bringen soll": seiten wie zb. Kongregate: Play free games online und andere flashgameanbieter haben sicherheitssysteme die cheatengine und die meisten anderen anfängerprogramme lächerlich einfach lahmlegen und euch mit etwas pech sogar bannen ich zeig euch eine variante viele dateien auf eurem pc 100% sicher und gratis zu bearbeiten ohne die geringste banngefahr solange ihr es nicht übertreibt ;) wir benötigen: einen account bei dem...
Darkorbit manipulieren
09/19/2010 - DarkOrbit - 5 Replies
Hallo Ich habe hier im forum ein bisschen rumgelesen und da wurde gesagt dass man die pakete (oder wie auch immer man das nennt) die zwischen dem do server und deinem pc versendet werden, manipulierbar sind. Kann man so nicht eigentlich auch mehr schaden macht, wenn man sie richtig verändert?
[Tutorial] For Noobs in iteminfo.x4 Dateien
01/05/2010 - S4 League - 11 Replies
Hi Hier its For Noobs in iteminfo.x4 Dateien 1.Step Dowladen:RapidShare: 1-CLICK Web hosting - Easy Filehosting 2.Step Dowladen:RapidShare: 1-CLICK Web hosting - Easy Filehosting hier its elitepvpers server or new skill and weapons dowladen Hier:http://rapidshare.com/files/330213377/iteminf o.x4 Hier its 100% no virus 3.Step Open in Vista:http://i49.tinypic.com/24o3cc0.jpg S4Hack Ressourcen Tool in S4 Folder



All times are GMT +1. The time now is 23:04.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.