Przerobka _asm na __fastcall

2

Yo,
Troche zaczalem bawic sie w RE i nie moge odwzorowac kodu assemblera w __fastcall. Wersja __fastcall crashuje mi gierke a wersja z _asm dziala.
Problem jest tutaj MOV ECX, DWORD PTR DS : [0x667D90], gdyz nie wiem jak to wywolac w __fastcallu. Bede wdzieczny za wskazowki :)

typedef void(__fastcall* _AttackSpeed)(int val);
_AttackSpeed AttackSpeed;

void attack(int value) {
    DWORD func = 0x0046D810;
    _asm {
        MOV ECX, DWORD PTR DS : [0x667D90]
        SETNE AL
        MOVZX EAX, AL
        PUSH value
        CALL func
    }
}
DWORD WINAPI HackThread(HMODULE hModule)
{
    AllocConsole();
    FILE* f;
    freopen_s(&f, "CONOUT$", "w", stdout);

    std::cout << "dll injected\n" << std::endl;
    
    uintptr_t moduleBase = (uintptr_t)GetModuleHandle(L"game.exe");

    AttackSpeed = (_AttackSpeed)(0x0046D810);

    while (true) 
    {
        if (GetAsyncKeyState(VK_CONTROL) & 1)
        {
            attack(1);
        }
        if (GetAsyncKeyState(VK_SHIFT) & 1)
        {
            AttackSpeed(1);
        }
        Sleep(10);
    }
    fclose(f);
    FreeConsole();
    FreeLibraryAndExitThread(hModule, 0);
    return 0;
}
0

Sprawa wygląda tak, że w wersji asemblerowej przekazujesz dwa argumenty - w ECX i na stosie... choć jak czytam dokumentację Microsoftu, to VS implementuje tę konwencję tak: ECX, EDX, (stos od prawej do lewej) Ergo masz zły prototyp funkcji, bo powinien on wyglądać tak:

void __fastcall AttackSpeed(int, int, int val); // zgaduje, że pierwszy argument to wskaźnik na obiekt jakiejś klasy

Zastanawiające jest to ustawianie rejestru EAX, bo microsoftowym __fastcallu nie ma on znaczenia. No i rejestr EDX - dlaczego nie jest ustawiany?

Pytanie, w czym ta gra została skompilowana.

0

@_0x666_: spacjlanie dla Ciebie edit ;d
Gierka to Metin2 a co do samej komendy... ECX znam czyli MOV ECX, DWORD PTR DS : [0x667D90], EDX nie. Czyli 1 argument podmienic, drugi zostawic, no i 3 wartosc do podmianki. Si ?

0

Gierka to Metin2

Nie wiele to mówi o kompilatorze. Pewnie VS, ale...

Czyli 1 argument podmienic, drugi zostawic, no i 3 wartosc do podmianki. Si ?

Nie wiem, co rozumiesz przez "zostawić", po prostu daj tam zero.

3

Najwyraźniej nie wiesz co oznacza słowo __fastcall.
Zmienia ono ABI funkcji - sposób przekazywania parametrów, dlatego PUSH value jest źle, bo ta wartość nie bedzie przekazana przez stos, ale przez rejestr.
https://docs.microsoft.com/en-us/cpp/cpp/fastcall?view=vs-2019

Jako, że do stosu dodałeś coś nieoczekiwanego, to w trakcie powrotu następuje skok do nieprzewidywalnego miejsca i masz crash.

Offtopic:
Jak każdy początkujący napaliłeś się na assemblera (tez tak miałem).
Jeśli celem jest uczenie się asemblera to spoko. Jeśli chcesz przyspieszyć swoją grę to tracisz czas. Obecne kompilatory potrafią wygenerować kod lepszy od pisanego ręcznie.

2

@ledi12: Już mam. To nie jest konwencja __fastcall, tylko __thiscall. W tej konwencji adres this przekazywany jest w rejestrze ECX, a reszta parametrów na stosie. To by tłumaczyło, dlaczego wywołanie funkcji jest w asm - paradoksalnie jest to bardziej przenośne między kompilatorami niż w postaci kodu C.

Czyli prototyp powinien wyglądać tak:

void __thiscall AttackSpeed(void*, int val);
0
0x666 napisał(a):

@ledi12: Już mam. To nie jest konwencja __fastcall, tylko __thiscall. W tej konwencji adres this przekazywany jest w rejestrze ECX, a reszta parametrów na stosie. To by tłumaczyło, dlaczego wywołanie funkcji jest w asm - paradoksalnie jest to bardziej przenośne między kompilatorami niż w postaci kodu C.

Czyli prototyp powinien wyglądać tak:

void __thiscall AttackSpeed(void*, int val);

Patrze dokumentację oraz w jego kod i czegoś nie rozumiem.

The Microsoft-specific __thiscall calling convention is used on C++ class member functions on the x86 architecture.

Gdzie w jego kodzie masz metody? Może widzisz więcej jego kodu niż my?

1

@MarekR22: w jego kodzie metod nie ma, ale on wywołuje obcą funkcję (dll injection?). Po sposobie wywołania (w asm) można wydedukować, że chodzi o metodę klasy ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1