Tråd bedømmelse:
  • 1 Stemmer - 5 Gennemsnit
  • 1
  • 2
  • 3
  • 4
  • 5
[C++/ASM] GameHack 1/3 - Find funktionens adresse
17-09-2013, 13:28 (Denne besked var sidst ændret: 17-09-2013, 15:40 af Morph3s.)
#1
[C++/ASM] GameHack 1/3 - Find funktionens adresse
Hvad går denne tutorial serie ud på?
Vi har et spil hvor der er runder. En runde er hvor mob angriber player, og player angriber mob. Vi er player. Det er tilfældigt hvem der vinder. Vi vil dog gerne vinde hver gang. Derfor injecter vi en selvskreven DLL ind i processen, hvor vi nu kan kalde funktionen attackMob() ubegrænset, og vinde hvergang.

Denne første del af GameHack serien, vil gå ud på at benytte reverse engineering til at opnå adressen på funktionen attackMob()
Den næste del vil gå ud på at injecte en DLL i GameHack.
Den sidste del vil være at skrive DLL'en så den kan benytte attackMob() funktionen så vi vinder hvergang

Det første er vores mobGame. Læs det, og forstå det. Hvis du ikke forstår det får du ikke noget ud af resten af denne tutorial
mobGame.cpp (Click to View)

Jeg har compilet en version som i kan downloade her: https://mega.co.nz/#!WNph1Rra!HNQwn1ibkX...E9yOJGS-c4
Jeg vil anbefale jer at benytte denne version hvis i er helt nye på området.
Hvis ikke kan i skrive lidt om i koden så der ændres lidt, så i selv skal tænke lidt mere.

Da vores mål er at kunne angribe, uden at blive angrebet, skal vi finde funktionen som angriber mob. Denne kan vi hurtigt finde ved et kig på koden:
	cout << "Attacking!" << endl;
cout << "Round: " << roundNum << endl;
roundNum++;
attackPlayer();
attackMob();
funktionen som angriber mob er så attackMob()

Det vi nu skal gøre er at finde ud af hvor denne funktion ligger i memory når programmet køres. Her vil vi benytte IDA.
Vi starter IDA op og vælger at vi godt vil rode med vores egen fil(Go: Work on your own):
[Billede: 4tyiY.jpg]
Herefter trækker du blot filen mobGame.exe ind i IDA

Vi vil nu blive præsenteret for en anden skærm. Her trykker du blot "ok".
[Billede: 4tykX.png]

Vores .exe mobGame skulle nu gerne være loadet i IDA. Vælg graph view, da det efter min mening er det bedste(Højreklik midt i IDA og tryk graph view. Hvis muligheden ikke er der, er du allerede i graph view)
Det vi gør nu er at kigge på de forskellige ting og ser om vi kan finde noget som giver mening.
Vi kan hurtigt se vores if else statement hvor vi tjekker for hvilke valg der er truffet. Hvis der bliver trykket 1 så går vi til angreb, og hvis vi trykker 2 så flygter vi(programmet afsluttes)
[Billede: 4txvS.png]
Her kan vi tydeligt se hvad for et stykke kode den er igang med. Vi kan også se hvordan den sammenligner choice, med et nummer.
Først flyttes choice over i eax cpu registret.
mov	    eax, [esp+8+choice]
så sammenlignes eax med 1
cmp    eax, 1
Så kommet jnz. Jump if not zero
jnz	short loc_401340
Der bliver hoppet til loc_401340 hvis eax ikke er lig 1
Ellers fortsættes koden bare nedtil det spændende stykke. Nemlig inde i denne if statement:
if(choice==1)
og det er jo netop inde i denne if statement hvor de to funktioner attackMob og attackPlayer bliver kaldt.

Her ser vi et billed af funktionen i assembly:
[Billede: 4txD4.png]
Her ser vi et billed af funktionen i C++:
[Billede: 4txEx.png]

Her kan vi let se hvad det er der sker. Hvordan noget tekst i 2 omgange bliver push'et på stacken og herefter printet ved brug af cout.
Men længere nede ser vi 2 call's som går til attackPlayer og attackMob.
[Billede: 4txGT.png]
Dette er præcis hvad vi har ledt efter.
Vi kan nu se et call til attackMob. Vi klikker nu på attackMob for at se hvad der gemmer sig bag det call.
Meget hurtigt ved et lille kig kan vi se at det er den helt rigtige funktion vi har fat i. Vi klikker nu på den lille tilbage knap oppe i venstre hjørne af IDA for at komme tilbage til start.
Vi sætter nu et breakpoint ved attackMob ved at højreklikke på attackMob og klikke Add Breakpoint.
[Billede: 4txNf.png]
Det call til attackMob vil nu blive rødt.
[Billede: 4txO3.png]

Vi er nu klar til at køre vores program, så den kan stoppe ved breakpoint og fortælle den præcise lokation i memory.
I toppen af IDA, kan vi se en start button, samt pause og en stop
[Billede: 4txR0.png]
Her vælger vi Local Win32 debugger og trykker start
[Billede: 4txRk.png]

Et nyt vindue vil nu åbne, hvor vi kan se vores spil. Her vil vi trykke 1 for at angribe, så den rammer vores breakpoint ved attackMob

Her kan vi nu se at mob angriber player men så stopper/pauser programmet ved vores breakpoint
[Billede: 4txVa.png]
I IDA kan vi også se at den er stoppet ved det rigtige sted
[Billede: 4txXo.png]

Vi kan nu se den præcise lokation som er 003C1339 eller 0x003C1339
Vi har nu fundet funktionens præcise addresse. Denne vil blive brugt i den næste tutorial så følg med.
Følg mig på twitter: https://twitter.com/Morph3s
Find alle beskeder fra denne bruger
Citer denne besked i et svar
17-09-2013, 13:55
#2
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
Den vil blive opdateret, forbedret og rettet hvis folk finder det interessant.
Følg mig på twitter: https://twitter.com/Morph3s
Find alle beskeder fra denne bruger
Citer denne besked i et svar
17-09-2013, 15:44
#3
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
Puha, den er en hjernevrider... Feint -> Faint -> Flee? :D
Rigtig god tutorial fra vores lille matrix-nørd, spændt på at se om der er nogen andre der interesserer sig for dette på forummet :)
Mangler du hjælp?
Regler |  E-mail (PGP)
Besøg denne brugers hjemmeside Find alle beskeder fra denne bruger
Citer denne besked i et svar
17-09-2013, 23:46
#4
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
Jeg har brugt IDA en del, og har også kodet assembler, så jeg følger gladeligt med. :)
Keep it up.
---
Writing a shellcode decoder stub in assembly is like talking gibberish in such a way that it is still perfectly intelligible. - iTick
Besøg denne brugers hjemmeside Find alle beskeder fra denne bruger
Citer denne besked i et svar
18-09-2013, 13:10 (Denne besked var sidst ændret: 18-09-2013, 14:53 af Crypt.)
#5
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
Den tager jeg lige et kig på, jeg ville gøre det lidt anderledes - men det er jo bare mig, ville "Rate" dig hvis jeg kunne!

P.S: Det kunne være dejligt hvis du lige disabled "ASLR" - ellers ville DU også få problemer! :)

Kode:
#include <Windows.h>

DWORD_PTR dwAddress = 0x00DF1410;

void (* CallAttack ) ( ) = ( void ( * ) ( ) ) dwAddress;

DWORD WINAPI dwThread( )
{
    for( ;;Sleep( 100 ) )
    {
        if( GetAsyncKeyState( VK_DELETE ) &1 )
        {
            CallAttack( );
        }
    }
}

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
    UNREFERENCED_PARAMETER( lpvReserved );

    switch( fdwReason )
    {
    case DLL_PROCESS_ATTACH:
        {
            DisableThreadLibraryCalls( hinstDLL );

            CreateThread( NULL, NULL, ( LPTHREAD_START_ROUTINE ) dwThread, NULL, NULL, NULL );
        }
        break;
    }
    return TRUE;
}

[Billede: x5pc77.jpg]

Så skal man ikke andet en at trykke "DELETE", så angriber man! :)

EDIT : Kæft jeg er dum lige nu... Du har jo ikke engang "called" funktionen endnu, min fejl hvis jeg gav koden væk nu! :(

Har lige opdateret min kode rigtigt meget - har "Bypassed" din "ASLR" og det skulle fungere 100 % nu;
Kode:
#include <Windows.h>

const DWORD_PTR dwAddress = reinterpret_cast<DWORD_PTR>( GetModuleHandle( NULL ) ) + 0x1410;

void (* CallAttack ) ( ) = ( void ( * ) ( ) ) dwAddress;

DWORD WINAPI dwThread( )
{
    for( ;;Sleep( 10 ) )
    {
        if( GetAsyncKeyState( VK_DELETE ) &1 )
        {
            CallAttack( );
        }
    }
}

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
    UNREFERENCED_PARAMETER( lpvReserved );

    switch( fdwReason )
    {
    case DLL_PROCESS_ATTACH:
        {
            DisableThreadLibraryCalls( hinstDLL );

            CreateThread( NULL, NULL, reinterpret_cast<LPTHREAD_START_ROUTINE>( dwThread ), NULL, NULL, NULL );
        }
        break;
    }
    return TRUE;
}
Eller...
Kode:
const DWORD_PTR dwAddress = reinterpret_cast<DWORD_PTR>( GetModuleHandle( NULL ) ) + 0x1410;

__asm
{
    call dwAddress;
}

Download DLL; http://gratisupload.dk/vis/701672/
Find alle beskeder fra denne bruger
Citer denne besked i et svar
18-09-2013, 14:47
#6
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
[Billede: 4tyiY.jpg]

Love it..
Find alle beskeder fra denne bruger
Citer denne besked i et svar
18-09-2013, 14:52
#7
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
Da du også har skrevet "ASM", så tænkte jeg lige at jeg ville lave en "Assembly Block" i C/C++;

Kode:
const DWORD_PTR dwAddress = reinterpret_cast<DWORD_PTR>( GetModuleHandle( NULL ) ) + 0x1410;

__asm
{
    call dwAddress;
}

:D
Find alle beskeder fra denne bruger
Citer denne besked i et svar
18-09-2013, 17:11 (Denne besked var sidst ændret: 18-09-2013, 17:15 af Morph3s.)
#8
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
(18-09-2013, 13:10)Crypt Skrev: P.S: Det kunne være dejligt hvis du lige disabled "ASLR" - ellers ville DU også få problemer! :)

Du har helt ret. Min approach er ikke nær så holdbar som din i længden, hvis ASLR er til :)

(18-09-2013, 13:10)Crypt Skrev: EDIT : Kæft jeg er dum lige nu... Du har jo ikke engang "called" funktionen endnu, min fejl hvis jeg gav koden væk nu! :(
Det er jo på ingen måde negativt at du deler kode ud, det er jo bare fedt :) Så kan folk også komme igang hurtigere, end at sidde og vente på at jeg skriver en part 2 :)
Desuden er din DLL ret ubrugelig, så længe folk ikke har et stykke kode som injicere den.

Btw, i min injector bruger jeg den almindelige CreateRemoteThread også LoadLibrary fra kernel32.dll
Hvad bruger du ? og har du nogle pros/cons for den metode ? Er ret ny i feltet :)
Følg mig på twitter: https://twitter.com/Morph3s
Find alle beskeder fra denne bruger
Citer denne besked i et svar
18-09-2013, 19:18 (Denne besked var sidst ændret: 18-09-2013, 19:19 af Crypt.)
#9
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
Der findes mange måder at "Injecte" en DLL på - Den jeg bruger lige p.t. er "LoadLibrary" og "Kernel32" som egentlig også er den mest effektive hvor spillet ikke har nogen Anti-Cheat.

Jeg bruger andre metoder til mine "Loaders" (hvis du kender dem), som jeg godt kan fortælle dig men det er meget avanceret.

Du kan bare bruge denne kode, som er skrevet af en god ven af mine (Credits: PoZHx) - vidst nok den samme som du bruger?
Kode:
bool InjectGame(char * szHackDll, DWORD dwPID)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, 0, dwPID);
    LPVOID RemoteString = VirtualAllocEx(hProcess, NULL, strlen(szHackDll)+1, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    LPVOID LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryA");
    WriteProcessMemory(hProcess, RemoteString, szHackDll, strlen(szHackDll)+1, NULL);
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, RemoteString, NULL, NULL);
    WaitForSingleObject(hThread, WAIT_TIMEOUT);
    VirtualFreeEx(hProcess, RemoteString, NULL, MEM_RELEASE);
    CloseHandle(hProcess);
    CloseHandle(hThread);
    return 1;
}

Tag et kig forbi; www.DarkHook.net - der kan du altid finde mig under samme navn! :)
Find alle beskeder fra denne bruger
Citer denne besked i et svar
18-09-2013, 19:28 (Denne besked var sidst ændret: 18-09-2013, 19:29 af Morph3s.)
#10
RE: [C++/ASM] GameHack 1/3 - Find funktionens adresse
(18-09-2013, 19:18)Crypt Skrev: Der findes mange måder at "Injecte" en DLL på - Den jeg bruger lige p.t. er "LoadLibrary" og "Kernel32" som egentlig også er den mest effektive hvor spillet ikke har nogen Anti-Cheat.

Jeg bruger andre metoder til mine "Loaders" (hvis du kender dem), som jeg godt kan fortælle dig men det er meget avanceret.

Du kan bare bruge denne kode, som er skrevet af en god ven af mine (Credits: PoZHx) - vidst nok den samme som du bruger?
Kode:
bool InjectGame(char * szHackDll, DWORD dwPID)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, 0, dwPID);
    LPVOID RemoteString = VirtualAllocEx(hProcess, NULL, strlen(szHackDll)+1, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    LPVOID LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryA");
    WriteProcessMemory(hProcess, RemoteString, szHackDll, strlen(szHackDll)+1, NULL);
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, RemoteString, NULL, NULL);
    WaitForSingleObject(hThread, WAIT_TIMEOUT);
    VirtualFreeEx(hProcess, RemoteString, NULL, MEM_RELEASE);
    CloseHandle(hProcess);
    CloseHandle(hThread);
    return 1;
}

Tag et kig forbi; www.DarkHook.net - der kan du altid finde mig under samme navn! :)

Det der er jo den eneste måde at benytte CreateRemoteThread, så jo, det ligner ret godt, men ikke helt ens :)
Følg mig på twitter: https://twitter.com/Morph3s
Find alle beskeder fra denne bruger
Citer denne besked i et svar
« Ældre | Nyere »




User(s) browsing this thread: 1 Gæst(er)