Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[Pytanie] Wyszukiwanie adres�w po update'a


Rekomendowane odpowiedzi

Opublikowano

W sieci krąży kilka programów pod WarRock'a nazywane popularnie addressloggerami. Ich zadaniem jest odnajdywanie nowych adresów po update'ach. Zastanawiałem się jak jak one działają i doszedłem do wniosku, że skanują pamięć w poszukiwaniu konkretnych wartości. Adresy się zmieniają, ale wartości powinny być takie same - i to pierwsze założenie. No dobrze, ktoś powie, że przecież wartość z jednej komórki może w pamięci występować nawet dziesiątki tysięcy razy. Dlatego nie szukamy wartości z jednego adresu tylko ciągu wartości z kilkunastu, lub kilkudziesięciu kolejnych adresów. Im dłuższy ciąg, tym jest bardziej unikalny i mniej prawdopodobne, że drugi taki sam występuje w pamięci.

 

Żeby sprawdzić tę tezę napisałem mały program do testów:

 

DOWNLOAD

SKAN

 

W zakładce kreator sygnatury wprowadzamy adres opcji z hacków, który już znamy. Uruchamiamy grę i przyciskiem "Stwórz sygnaturę" sczytujemy 12-bajtową wartość z adresu, który wprowadziliśmy. Zakres poszukiwań wprowadziłem po to, żeby ograniczyć później obszar pamięci do przeszukania. Przyjąłem, że nasz adres po updejdzie nie "skoczy" dalej jak &H90000 adresów w tył, lub &H90000 w przód. Nie wiem, czy słusznie, ale zakres zawsze można poprawić ręcznie w pierwszej zakładce już przy wyszukiwaniu nowego adresu. Skanowanie całego możliwego obszaru, czyli powiedzmy od &H00400000 do &H7FFFFFFF wydaje się dość karkołomne (w sumie 2143289343 adresów). Możemy też zapisać sygnaturę z zakresem do pliku i wczytać po updejdzie w pierwszej zakładce.

 

af1mk9.jpg

 

W zakładce "Wyszukiwanie" wczytujemy nasze dane i skanujemy pamięć w poszukiwaniu nowego adresu.

 

af2je3.jpg

 

Jeśli się okaże, że znajduje więcej niż 1 adres, to będzie znaczyło, że 12 bajtowa sygnatura jest za "słaba". Nie testowałem tego jeszcze na żadnej update'owanej grze, ale samo wyszukiwanie adresu po sygnaturze powinno działać.

Opublikowano

Sprawdź teraz. Dodałem pasek postępu skanowania i poprawiłem sygnaturę na 8 bajtów, bo z większą były problemy. Przetestowałem na Warrocku kreowanie sygnatur i wyszukiwanie adresów po nich. To np sygnatura dla ESP: 69CE8B0C558B2375

Opublikowano

A po co się tak cackać. Tak pomagasz innym to zrób program, który po wł. WR robi vip hacka :P

Uznaj to za komplement ;)

bez gif.

Opublikowano
A po co się tak cackać. Tak pomagasz innym to zrób program, który po wł. WR robi vip hacka :P

Uznaj to za komplement ;)

 

Może od razu niech robi kawę i drapie po pleckach :P Gdyby pomysł z wyszukiwaniem się sprawdził, to można by się pokusić o opcje autoupdejdu w hacku. Ale wszystko w swoim czasie.

Opublikowano
Może od razu niech robi kawę i drapie po pleckach :P Gdyby pomysł z wyszukiwaniem się sprawdził, to można by się pokusić o opcje autoupdejdu w hacku. Ale wszystko w swoim czasie.

Wlasnie to pobralem .. zaraz sprawdze...

Tobie za wszstko do tej pory nalezy sie od kazdego 5*

Hmmm...

Ladowanie sygnaturki zakonczone w 50 %...........Errorrrr.....Sygnaturka sie nie załaduje.....

 

Sprzedam/Wymienie mojego Vip hacka wiecej na gg 2383934

Wymienie na konto na plemionach lub ogame....

  • 8 miesięcy temu...
Opublikowano

sorry za odswiezanie tematu ale mam pytanie czy projekt offsets logger jest moze prowadzony dalej?? nie ukrywam ze jestem zainteresowany tym projektem

chcesz nauczyc sie programowania czitów do swojej ulubionej gry?? zapraszam na stronke xxx zostan koderem hacków do gier!!! wszystko za darmo są tutki video i krok po kroku co i jak.. uwaga zlamiesz kazda gre!!!!!! tylko troche silnej woli a jak nie umiesz po angielsku to uzywaj przegladarki chrome automatycznie przetumaczy baw sie i publikuj czity tutaj

Opublikowano

Tamten pomysł był średnio udany, głównie z tego względu, że zamiast tablic używałem zwykłych zmiennych (max 8 bajtów). Przed chwilą pomyślałem o czymś nowym i chciałbym to przetestować. Zacznę od tego, że znalazłem nowy adres dla ESP w WarRock (0x00507133) i skopiowałem fragment z instrukcjami asm i bajtami. Wiem, że pisałem o szukaniu statycznych adresów, ale to chyba nie ma sensu. Takich adresów jest stosunkowo mało. Z drugiej strony jeśli gdzieś w pamięci jest jakaś procedura z naszym adresem, to przecież po update nie rozjedzie się całkiem, chyba że autorzy zmienią jej kod. Owszem, po update ta sama procedura będzie ulokowana w pamięci gdzie indziej, ale zmienią się tylko referencje do komórek pamięci a instrukcje powinny być takie same. Weźmy taki przykład:

 

adres-bajty-asm

 

00507170 - e8 ab 09 22 00 - call 00727b20

 

Gdy procedura z takim wywołaniem trafi po update do innego rejonu pamięci, to sama funkcja call się nie zmieni, ale zmieni się adres wywoływanej procedury. Pierwszy bajt - e8 - oznacza właśnie funkcje call a kolejne mają nam określić lokalizacje tego, co wywołujemy.

http://faydoc.tripod.com/cpu/call.htm - tutaj ładnie wszystkie funkcje są opisane.

 

Pomysł polega na tym, żeby pozbyć się tych referencji do pamięci i odnotować tylko bajty samych instrukcji w odpowiedniej kolejności a potem wyszukać ich w pamięci.

 

Na szybko zrobiłem coś takiego dla ESP:

 

00507133 - 75 22 - jne 00507157

00507135 - 8b cf - mov ecx,edi

00507137 - 69 c9 40 1a 00 00 - imul ecx,ecx,00001a40

0050713D - 8b 81 98 20 c5 00 - mov eax,[ecx+00c52098]

00507143 - 8b d5 - mov edx,ebp

00507145 - 69 d2 40 1a 00 00 - imul edx,edx,00001a40

0050714B - 3b 82 98 20 c5 00 - cmp eax,[edx+00c52098]

00507151 - 0f 85 49 01 00 00 - jne 005072a0

00507157 - 8b 0d 70 58 b0 00 - mov ecx,[00b05870] : 07E4E9E0

0050715D - 6a 05 - push 05

0050715F - 6a 2f - push 2f

00507161 - e8 ba 09 22 00 - call 00727b20

00507166 - 8b 0d 70 58 b0 00 - mov ecx,[00b05870] : 07E4E9E0

0050716C - 6a 01 - push 01

0050716E - 6a 1b - push 1b

00507170 - e8 ab 09 22 00 - call 00727b20

00507175 - 8b 0d 70 58 b0 00 - mov ecx,[00b05870] : 07E4E9E0

0050717B - 6a 01 - push 01

0050717D - 6a 0f - push 0f

0050717F - e8 9c 09 22 00 - call 00727b20

00507184 - 8b 0d 70 58 b0 00 - mov ecx,[00b05870] : 07E4E9E0

0050718A - 6a 00 - push 00

0050718C - 68 89 00 00 00 - push 00000089

 

00507133 - 75

00507134 - X

00507135 - 8b

00507136 - cf

00507137 - 69

00507138 - c9

00507139 - X

0050713A - X

0050713B - X

0050713C - X

0050713D - 8b

0050713E - 81

0050713F - X

00507140 - X

00507141 - X

00507142 - X

00507143 - 8b

00507144 - d5

 

Może koło południa znajdę chwile i spróbuje napisać program, który tego wyszuka. W między czasie możesz popróbować z innymi adresami, albo pomyśleć nad algorytmem przeszukiwania pamięci z taką wybiórczą tablicą bajtów. Nie będzie łatwo wymyślić coś szybkiego.

Opublikowano

wiesz .. taki dobry nie jestem w asm ale mozna by bylo to podejsc z innej strony przy pomocy autooffsetów w cs1.6 i poznac na jakiej to zasadzie sie odbywa;

ma m tu rózne podejscia do tego zagadnienia:

 

 

 

[Delphi] Auto Offsets

 

 

unit uOffsets;

interface
uses
  Windows,
  Sysutils;

//==============================
// GLOBAL VARS
//==============================
var
  PushAddrPattern : array[0..4] of BYTE = ($68, $90, $90, $90, $90);
  CommandPattern : array[0..10] of BYTE = ($68, $FF, $FF, $FF, $FF, $68, $FF, $FF, $FF, $FF, $E8);

  EngineString : array[0..100] of char = 'ScreenFade';
  StudioString : array[0..100] of char = 'Couldn''t get client .dll studio model rendering interface.';
  SoundsString : array[0..100] of char = 'S_StartDynamicSound: %s volume > 255';
  ModelRString : array[0..100] of char = 'cl_himodels';

//==============================
// FOR GLOBAL USAGE :p
//==============================
function FindEngine: Pointer;
function FindStudio: Pointer;
function FindExport: Pointer;
function FindSounds: Pointer;
function FindModelR: Pointer;
function FindHLCommand(szName : PChar) : Pointer;

implementation

//==============================
// memory search functions
//==============================
function EqualStrings(string1, string2: PChar): Boolean;
var
  Len, i: Integer;
begin
  result := false;
  Len := strlen(string1);
  if(strlen(string2) <> Len) Then
    Exit;

  For I := 0 To Len-1 Do
    Begin
      if not (PChar(string1+i)^ = PChar(string2+i)^) Then
        Exit;
    End;

  result := true;  
end;

function CompareMemory (bAddress, bCode: PByte; Size: Integer): Boolean;
var
  i: Integer;
begin
  result := false;
  For i := 0 To Size-1 Do
    begin
      if ((PByte(DWORD(bAddress) + DWORD(i))^ <> PByte(DWORD(bCode) + DWORD(i))^) and (PByte(DWORD(bCode) + DWORD(i))^ <> $FF)) Then
        exit;
    end;
    result := true;
end;

function FindCodeAddress(dwStart, dwEnd: DWORD; bCode: PByte; Codesize, OpcodeNum: Integer): Pointer;
var
  d: DWORD;
begin
  For d:= dwStart To dwEnd - (1 + CodeSize) Do
    begin
      if (CompareMemory(PByte(d), PByte(bCode), CodeSize) = true) Then
        begin
          result := Pointer(d + OpcodeNum);
          exit;
        end;
    end;
  result := nil;
end;

//=======================================
// FindModelR
// Returns a pointer to CStudioModelRenderer class
//=======================================
function FindModelR : Pointer;
var
  hlBase, hlSize, Temp: DWORD;
begin
  hlBase := Dword(GetModuleHandle(nil));
  hlSize := $2116000;

  PPointer(DWORD(@PushAddrPattern) + 1)^ := FindCodeAddress(hlBase, hlBase + hlSize, @ModelRString, strlen(ModelRString), 0);
  Temp := DWORD(FindCodeAddress(hlBase, hlBase + hlSize, @PushAddrPattern, 5, -3));
  result := FindCodeAddress(hlBase, hlBase + hlSize, @Temp, 4, -8);
end;

//==============================
// FindEngine
// Returns a pointer to cl_enginefuncs_s struct
//==============================
function FindEngine : Pointer;
var
  hlBase, hlSize: DWORD;
begin
  hlBase := DWord(GetModuleHandle(nil));
  hlSize := $2116000;

  PPointer(DWORD(@PushAddrPattern) + 1)^ := FindCodeAddress(hlBase, hlBase + hlSize, @EngineString, strlen(EngineString),0);
  result := PPointer(FindCodeAddress(hlBase, hlBase + hlSize, @PushAddrPattern, 5, 13))^;
end;

//=======================================
// FindStudio
// Returns a pointer to engine_studio_api_s struct
//=======================================
function FindStudio: Pointer;
var
  hlBase, hlSize: DWORD;
begin
  hlBase := DWord(GetModuleHandle(nil));
  hlSize := $2116000;

  PPointer(DWORD(@PushAddrPattern) + 1)^ := FindCodeAddress(hlBase, hlSize + hlBase, @StudioString, strlen(StudioString), 0);
  result := PPointer(FindCodeAddress(hlBase, hlBase + hlSize, @PushAddrPattern, 5, -20))^;
end;

//=======================================
// FindExport
// Returns a pointer to cdll's exporttable
//=======================================
function FindExport: Pointer;
var
  hlBase, hlSize: DWORD;
begin
  hlBase := GetModuleHandle(nil);
  hlSize := $2116000;

  PPointer(DWORD(@PushAddrPattern) + 1)^ :=  FindCodeAddress(hlBase, hlBase + hlSize, @StudioString, strlen(StudioString), 0);
  result := PPointer((PDword(FindCodeAddress(hlBase, hlBase + hlSize, @PushAddrPattern, 5, -29)))^ - $9C);
end;

//=======================================
// FindSounds
// Returns a pointer to PreS_Dynamicsound function
//=======================================
function FindSounds: Pointer;
var
  hlBase, hlSize: DWORD;
begin
  hlBase := GetModuleHandle(nil);
  hlSize := $2116000;

  PPointer(DWORD(@PushAddrPattern) + 1)^ := FindCodeAddress(hlBase, hlBase + hlSize, @SoundsString, strlen(SoundsString), 0);
  result := FindCodeAddress(hlBase, hlBase + hlSize, @PushAddrPattern, 5, -$9C);
end;

//==============================
// FindHLCommand
// Returns pointer to the given event / usermsg / command
//==============================
function FindHLCommand(szName : PChar) : Pointer;
var
  hlBase, hlSize, dwCommand: DWORD;
begin
  hlBase := GetModuleHandle(nil);
  hlSize := $2116000;
  dwCommand := hlBase;

  While (dwCommand >  0) Do
    begin
      if not ( IsBadReadPtr(PPointer(dwCommand+6)^, strlen(szName)) or IsBadReadPtr(PPointer(dwCommand+1)^, 4)) Then
        Begin
          result := PPointer(dwCommand+1)^;
          if(EqualStrings(PPchar(dwCommand+6)^, szName) = true) Then
            Exit;
        End;
      dwCommand := DWORD(FindCodeAddress(dwCommand+1, hlBase + hlSize, @CommandPattern, 10, 0));
    end;
    result := nil;
end;

end.Credits: h1web, DeepBlueSea, xgx

 

c++

 

//==============================
// GLOBAL VARS
//==============================
BYTE PushAddrPattern[5] = {0x68, 0x90, 0x90, 0x90, 0x90};
BYTE CommandPattern[11] = {0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xE8};

char EngineString[] = "ScreenFade";
char StudioString[] = "Couldn't get client .dll studio model rendering interface.";
char SoundsString[] = "S_StartDynamicSound: %s volume > 255";
char ModelRString[] = "cl_himodels";

//==============================
// memory search functions
//==============================
bool CompareMemory(LPCBYTE bAddress, LPCBYTE bCode, int Size)
{
    for(int i=0; i<Size; i++, bCode++, bAddress++)
    {
        if((*bAddress != *bCode) && (*bCode != 0xFF))
            return false;
    }
    return true;
}

DWORD FindCodeAddress(DWORD dwStart, DWORD dwEnd, LPBYTE bCode, int CodeSize, int OpcodeNum)
{
    for(DWORD d=dwStart; (d+CodeSize) < dwEnd; d++)
    {
        if( CompareMemory((LPBYTE)d, bCode, CodeSize))
            return (DWORD)(d+OpcodeNum);
    }
    return 0x00000000;
}

//=======================================
// FindModelR
// Returns a pointer to CStudioModelRenderer class
//=======================================
DWORD FindModelR()
{
    DWORD hlBase = (DWORD)GetModuleHandle(NULL);
    DWORD hlSize = (DWORD)0x2116000;

    DWORD Himodels = FindCodeAddress(hlBase, hlBase + hlSize, (PBYTE)ModelRString, sizeof(ModelRString)-1, 0);
    RtlCopyMemory((PVOID)((char*)&PushAddrPattern + 1), &Himodels, 4);

    DWORD CInit = FindCodeAddress(hlBase, hlBase + hlSize, (PBYTE)&PushAddrPattern, 5, -3);
    return FindCodeAddress(hlBase, hlBase + hlSize, (PBYTE)&CInit, sizeof(DWORD), -8);
}

//==============================
// FindEngine
// Returns a pointer to cl_enginefuncs_s struct
//==============================
DWORD FindEngine()
{
    DWORD hlBase = (DWORD)GetModuleHandle(NULL);
    DWORD hlSize = (DWORD)0x2116000;

    LPSTR ScreenFade = (LPSTR)FindCodeAddress(hlBase, hlBase + hlSize, (PBYTE)EngineString, sizeof(EngineString)-1, 0);
    RtlCopyMemory((PVOID)((char*)&PushAddrPattern + 1), &ScreenFade, 4);

    return *(DWORD*)FindCodeAddress(hlBase, hlBase + hlSize, (PBYTE)&PushAddrPattern, 5, 13);
}

//=======================================
// FindStudio
// Returns a pointer to engine_studio_api_s struct
//=======================================
DWORD FindStudio()
{
    DWORD hlBase = (DWORD)GetModuleHandle(NULL);
    DWORD hlSize = (DWORD)0x2116000;

    DWORD StudioStringAddress = FindCodeAddress(hlBase, hlBase + hlSize, (PBYTE)StudioString, sizeof(StudioString)-1, 0);
    RtlCopyMemory((PVOID)((char*)&PushAddrPattern + 1), &StudioStringAddress, 4);

    return *(DWORD*)FindCodeAddress(hlBase, hlBase + hlSize, PushAddrPattern, 5, -20);
}

//=======================================
// FindExport
// Returns a pointer to cdll's exporttable
//=======================================
DWORD FindExport()
{
    DWORD hlBase = (DWORD)GetModuleHandle(NULL);
    DWORD hlSize = (DWORD)0x2116000;

    DWORD StudioStringAddress = FindCodeAddress(hlBase, hlBase + hlSize, (PBYTE)StudioString, sizeof(StudioString)-1, 0);
    RtlCopyMemory((PVOID)((char*)&PushAddrPattern + 1), &StudioStringAddress, 4);

    return *(DWORD*)FindCodeAddress(hlBase, hlBase + hlSize, PushAddrPattern, 5, -29) - 0x9C;
}

//=======================================
// FindSounds
// Returns a pointer to PreS_Dynamicsound function
//=======================================
DWORD FindSounds()
{
    DWORD hlBase = (DWORD)GetModuleHandle(NULL);
    DWORD hlSize = (DWORD)0x2116000;

    DWORD SoundsStringAddress = FindCodeAddress(hlBase, hlBase + hlSize, (PBYTE)SoundsString, sizeof(SoundsString)-1, 0);
    RtlCopyMemory((PVOID)((char*)&PushAddrPattern + 1), &SoundsStringAddress, 4);

    return FindCodeAddress(hlBase, hlBase + hlSize, PushAddrPattern, 5, -0x9C);
}

//==============================
// FindHLCommand
// Returns pointer to the given event / usermsg / command
//==============================
DWORD FindHLCommand(LPCSTR szName)
{
    DWORD hlBase = (DWORD)GetModuleHandle(NULL);
    DWORD hlSize = (DWORD)0x2116000;

    DWORD dwCommand = hlBase;
    while( (dwCommand=FindCodeAddress(dwCommand+1, hlBase + hlSize, (LPBYTE)CommandPattern, sizeof(CommandPattern)-1, 0)) != NULL)
    {
        if(IsBadReadPtr((void*)*(DWORD*)(dwCommand+6), strlen(szName)) || IsBadReadPtr((void*)*(DWORD*)(dwCommand+1), 4))
            continue;

        if( !stricmp(*(char**)(dwCommand+6), szName) )
            return *(DWORD*)(dwCommand+1);    
    }
    return 0x00000000;
}Delphi

Code:

nastepny:

 

DWORD dwHW       = (DWORD)GetModuleHandle("hw.dll");
DWORD dwHWSize = 0x122A000;


BYTE Sound_SIG[] = "\x83\xEC\x00\xA1\x00\x00\x00\x00\x53\x55\x56\x85\xC0";
CHAR Sound_MSK[] = "xx?x????xxxxx";
SOUND = dwFindPattern(dwHW, dwHWSize, Sound_SIG, Sound_MSK);


BYTE Export_SIG[] = "\x8B\x44\x24\x04\x6A\x00\x68\x00\x00\x00\x00\x68";
CHAR Export_MSK[] = "xxxxxxx????x";
DWORD dwExport = dwFindPattern(dwHW, dwHWSize, Export_SIG, Export_MSK) + 0x7;
pExport = (ExportTable_s*)*(DWORD*)dwExport;
//8B 44 24 04 6A 00 68 ?? ?? ?? ?? 68 +0x7*


DWORD dwEngfuncs = (DWORD)*pExport->Initialize + 0x1C;
pEngfuncs = (cl_enginefunc_t*)*(DWORD*)dwEngfuncs;
//067DE1C0  0AEA4ED0  Initialize
//$+1B     >|.  BF 901BF80A   MOV EDI,client.0AF81B90


DWORD dwEngstudio = (DWORD)*pExport->HUD_GetStudioModelInterface + 0x1A;
pEngstudio = (engine_studio_api_s*)*(DWORD*)dwEngstudio;
//067DE25C  0AEAADB0  HUD_GetStudioModelInterface
//$+19     >|.  BF 408DF90A   MOV EDI,client.0AF98D40

 

ale najlepiej bedzie jak zobaczysz baze z autooffsetami:

baza

podejzewam ze przyda nam sie jeszcze program do skanowania pamieci:

memory scan

chcesz nauczyc sie programowania czitów do swojej ulubionej gry?? zapraszam na stronke xxx zostan koderem hacków do gier!!! wszystko za darmo są tutki video i krok po kroku co i jak.. uwaga zlamiesz kazda gre!!!!!! tylko troche silnej woli a jak nie umiesz po angielsku to uzywaj przegladarki chrome automatycznie przetumaczy baw sie i publikuj czity tutaj

Opublikowano

Można by zaadoptować któryś z kodów, ale chciałem to zrobić po swojemu. Napisałem bibliotekę w C# do wyszukiwania ESP: LINK

Kod wyszukiwania wygląda tak:

 

byte[] esp = { 0x75, 0x22, 0x8b, 0, 0x69, 0xc9, 0, 0, 0, 0,0x8b, 0x81, 0, 0, 0, 0, 0x8b, 0, 0x69, 0xd2,0 };
            
             byte[] tabout;

             for (int adrstart = 0x00400000; adrstart <= 0x00600000; adrstart++)
             {

                 tabout = new byte[20];
                 int ileprzecz;
                 tabout = edytpam.CzytajPamiec((IntPtr)adrstart, 20, out ileprzecz);
                 
                 //bool test = portab(esp, tabout);
                 //if (true==test)
                 if (tabout[0] == esp[0] && tabout[1] == esp[1] && tabout[2] == esp[2] && tabout[4] == esp[4] &&
                     tabout[5] == esp[5] && tabout[10] == esp[10] && tabout[11] == esp[11] && tabout[16] == esp[16] &&
                     tabout[18] == esp[18] && tabout[19] == esp[19])
                 {
                     string[] rowX1 = { "ESP", adrstart.ToString("X") };
                     dataGridView1.Rows.Add(rowX1);
                 }

 

byte[] esp, to tablica, której szukam. Zerami wypełniłem miejsca bajtów, który się zmieniają. Skanuje tylko przedział od 0x00400000 do 0x00600000 i trzeba to będzie kiedyś dopracować. Można użyć funkcji, która znajdowałaby entrypoint execa i skanować od tego adresu. Samo porównywanie tablic wygląda koszmarnie, a to dlatego, ze funkcja którą miała to robić za mnie wyszukuje zupełnie błędne adresy. Wygląda tak:

 

        private bool portab(byte[] tabgl, byte[] tabdopor)
         {
             for (int i = 0; i < 20; i++ )
             {
                 if (tabdopor[i] != 0 && tabdopor[i] != tabgl[i]) return false;
             }
             return true;
         }

 

Porównuje kolejne elementy tablicy (założyłem, że będzie 20-o elementowa) i jeśli element jest różny od zera i różny od elementu z takim samym indeksem w drugiej tablicy, to zwraca wartość fałszu. W innym wypadku zwraca prawdę. Z jakichś przyczyn to nie działa. Może znajdziesz jakiś inny, działający sposób. W każdym bądź razie If i porównywanie w instrukcji warunkowej elementów działa bez zarzutu. Jedyny minus tego wszystkiego, to szybkość. Prawdopodobnie użycie klasy Marshall byłoby szybsze, ale trzeba pokombinować nad jej dobrym użyciem, bo nie czyta tablic a jedynie konkretne zmienne.

 

             string wyjscie = "";
             for (int adres = 0x00507133; adres <= 0x00507146; adres++)
             {
                 IntPtr adresptr = (IntPtr)(adres);
                 byte wart = Marshal.ReadByte(adresptr);
                 wyjscie += wart.ToString("X") + " ";

             }
             MessageBox.Show(wyjscie);

 

W przykładzie powyżej użyłem Marshalla do przeczytania 20 bajtów i zapisania w formie zmiennej string. Potem wyświetla mi komunikat z tym stringiem. Także można się tym bawić również w tworzenia odpowiednich tablic do porównania. Na razie to tyle.

 

@Edit:

Zrobiłem inną wersje z paskiem postępu i możliwością zapisywania wyników do pliku + użyłem Marshalla: LINK.

 

Okazuje się, że jest porównywalny jeśli chodzi o szybkość z ReadProcessMemory, przy czym popełniłem bardzo nieelegancką pętlę wykorzystującą tę klasę:

 

                 for (int i = 0; i < 20; i++)
                {
                    int adr2 = adres;
                    IntPtr adresptr = (IntPtr)(adr2 + i);
                    tabout[i] = Marshal.ReadByte(adresptr);  
                }

 

To akurat było pójście na łatwiznę, bo przy każdym adresie tablice do porównania tworzy się przez przeczytanie kolejnych dwudziestu bajtów a wystarczyłoby usunąć jakoś pierwszy element w tablicy, przesunąć tablice w "lewo" i nowo sczytany bajt zapisać na końcu. Efekt lenistwa, to 19 wywołań Marshal.ReadByte więcej. Dlatego tak zależało mi na dobrym algorytmie wyszukiwania, bo przy kilku milionach adresów liczą się ułamki sekund.

Opublikowano

Napisalem ostatnio program do adresow w oparciu o informacje z innych for, wyszukuje adresy w doslownie sekunde, nastepnie zapisuje je do logow w folderze, w ktorym jest dll+exe. Mniej wiecej wyglada to tak :

Funckja, ktora pozwala nam szukac adresow:

bool bCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
    for(;*szMask;++szMask,++pData,++bMask)
        if(*szMask=='x' && *pData!=*bMask ) 
            return false;
    return (*szMask) == NULL;
}

DWORD FindPattern(DWORD dwAddress,DWORD dwLen,BYTE *bMask,char * szMask)
{
    for(DWORD i=0; i < dwLen; i++)
        if( bCompare( (BYTE*)( dwAddress+i ),bMask,szMask) )
            return (DWORD)(dwAddress+i);

    return 0;
}

Tym znajdujemy nasze adresy w pamieci:

DWORD   esp   = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x75\x23\x8B\xCB\x69\xC9\x28\x1A\x00\x00\x8B\x81\xD8\x66\xBD","x?x?xx?xxxxx???");

Przyklad dla ESP, wlasciwie to juz wszystko, teraz wystarczy zrobic logi i zapisac je do pliku .txt. Najtrudniejsza czesc, to wyszukuac te bajty adresu :P. Szczerze mowiac mam z tym problemy, bo CE wykrywalny a inaczej troche trudno.

Przyklad logu:

 

 

 

Nieskonczona Amunicja1(UnAmmo) -> 0x005025E6 

Nieskonczona Amunicja2 (UnAmmo) 0x005025F7 

Nieskonczona Amunicja3 (UnAmmo) 0x005025FD 

Anty kick -> 0x00000000 

Leżenie na mapkach cqc (CQC Prone) -> 0x00000000 

Widzenie nickow przeciwnikow  (ESP)-> 0x00507133 

Niewidzialnosc (Invisible) -> 0x005084F3 

Automatyczne leczenie(AutoMedic) -> 0x00000000

 

Te zera to dlatego, ze ostatnio zmienili bajty i trzeba szukac nowych sygnatur dla adresow.

I jescze kodu, ktorych uzylem do tych adresow:

DWORD UnAmmo1   = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x89\x7E\x24\x7E\x15\x6A\x40\x6A\x01\xE8\x6C\x0A\x17\x00\x83","xxxxxxxxxx???xx");
DWORD  kick     = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x8B\x85\xFC\xE2\x04\x00\x39\x44\x24\x10\x75\x76\x8D\x8D\x70","xx??xxxxxxxxxx?");

DWORD   ammo2    = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x89\x46\x20\x0F\xAF\xC7\x89\x46\x24\x5F\xB8\x01\x00\x00\x00","xxxxxxxxxxxxxxx");////
DWORD   ammo3   = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x89\x46\x24\x5F\xB8\x01\x00\x00\x00\x5E\xC2\x04\x00\xCC\xCC","xxxxxxxxxxxxxxx");
DWORD  prone     = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x84\xC0\x74\x0C\x8B\x8E\x78\x02\x00\x00\x8B\x01\x56\xFF\x50\x2C\x5E\xC3\x83","xxx?xx??xxxxxxxxxxx");
DWORD   esp   = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x75\x23\x8B\xCB\x69\xC9\x28\x1A\x00\x00\x8B\x81\xD8\x66\xBD","x?x?xx?xxxxx???");
DWORD   invi     = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x2C\x8B\x56\x10\x89\x57\x34\x66\x89\x2F\x8A\x86\x18\x02\x00","xx?xx?xxx?x??xx"); ///
DWORD   med      = FindPattern(0x400000, 0x01400000,(unsigned char*)"\x0F\x85\xA6\x00\x00\x00\x85\xC9\xC7\x05\x30\x1D\xB1\x00\x00\x00\x00\x40","xx????xxxx????xxxx");

Zalaczam projekt, ktory zrobilem: Klik

 

 

Opublikowano

rozumiem ze zrobiles to do warrocka ale ten kod mozna wykozystac do kazdej gry prawda??

chcesz nauczyc sie programowania czitów do swojej ulubionej gry?? zapraszam na stronke xxx zostan koderem hacków do gier!!! wszystko za darmo są tutki video i krok po kroku co i jak.. uwaga zlamiesz kazda gre!!!!!! tylko troche silnej woli a jak nie umiesz po angielsku to uzywaj przegladarki chrome automatycznie przetumaczy baw sie i publikuj czity tutaj

Opublikowano

Tak, do kazdej, jesli tylko znasz bajty, ktore trzeba wyszukac dla danego adresu, zamienisz je i adresslogger do kazdej gry gotowy.

Ta sygnatura jest do WarRocka.

@down

Tak source, ale postaraj sie tak nie spamowac, wystarczy sciagnac :P. Po co mial bym dawac dll.

Mozesz uzyc tego, dziala.

Klik

Opublikowano

a jakiego loadera proponujesz???

chcesz nauczyc sie programowania czitów do swojej ulubionej gry?? zapraszam na stronke xxx zostan koderem hacków do gier!!! wszystko za darmo są tutki video i krok po kroku co i jak.. uwaga zlamiesz kazda gre!!!!!! tylko troche silnej woli a jak nie umiesz po angielsku to uzywaj przegladarki chrome automatycznie przetumaczy baw sie i publikuj czity tutaj

Opublikowano
Najtrudniejsza czesc, to wyszukuac te bajty adresu :P . Szczerze mowiac mam z tym problemy, bo CE wykrywalny a inaczej troche trudno.

 

Do projektu powyżej dołączyłem taki quasi-bajpas nad którym już kiedyś kombinowaliśmy. Po jakimś czasie w grze rozłącza z serwerem, ale żeby szukać bajtów nie musisz się nawet logować do gry.

 

int wynbajt;
byte[] bajtbypass = { 0x90, 0x90 }; //75 0C

edytpam.ZapiszPamiec((IntPtr)0x004D77A0, bajtbypass, out wynbajt);

 

Adres wyszukuje zawsze przez IDA, ale można by kiedyś stworzyć i dla niego sygnaturę.

 

Jak odpalisz grę i nadpiszesz te dwa bajty, to możesz włączyć śmiało CE. Żeby otworzyć grę musisz jeszcze w opcjach CE mieć zaznaczone przy "Use the fallowing CE Kernel routines...": Read/Write Process Memory i Open Process. U siebie mam jeszcze zaznaczone obie opcje ze "Stealth mode", ale to może nie będzie konieczne.

 

@down:

Tym sposobem nopujesz skok do okna wszystkich komunikatów o hacku, także nie powinieneś mieć błędów w grze. A co do ehsvc.dll, to rozpakowałem ją programem o nazwie stripper v213 b9 (bez skana, bo to przez google znalezione).

 

Edit: tym z kolei programem wyszukuje czym są spakowane exe'ki i dll'ki: PEiD

 

Edit2: Wydaje mi się, że bez hookowania też dałoby się to zrobić. Utknąłem właśnie na tym rozłączaniu z serwerem i do szczęścia brakuje mi tylko pełnego obrazu pamięci odpalonego WarRocka, przy czym żadnym debuggerem nie mogę tego ruszyć (wtedy mógłbym wyszukać brakujące referencje). Kombinowałem już z różnymi aplikacjami do dumpingu pamięci i nic. Chwilowo dałem sobie z tym spokój.

Opublikowano

Wlasciwie to juz z tym probowalem, zanopowalem 'running hack-tool detected', pojawia sie blad warrocka, ale zostawiam go i probuje dalej, jak zalacze CE do warrocka, mam crasha Windowsa =F. Za kazdym razem. Sprobuje tym adresem.

Teraz tak poza tematem, nie chcialem odswiezac tamtego, w sprawie bypassa.

Poczytalem na roznych forach i dowiedzialem sie, ze te nasze NOP'y sa wykrywalne przez hs nawet gdy nopujemy jakies tam skoki, skuteczna metoda jest zhookowanie funkcji skanujacej przez hs i podmienie jej na swoja-ktora nic nie bd robila. Dowiedzialem sie tez, ze ta funkcja jest w ehsvc.dll.:P. Pozostaje jescze kwestia jak odpakowac dll'ke.Ktos pisal, ze widzi ja bez odpakowywania, ale z wlaczonym warrockiem. Trzeba jescze pokombinowac :P.

@up

Dzieki, przeszukalem dll'ke tak na szybko i pierwsze co znalazlem to scanf, moze to wlasnie to ;P.

.text:1000DA65 loc_1000DA65:                          ; CODE XREF: sub_1000D970+117j
.text:1000DA65                 lea     edx, [esp+13h]
.text:1000DA69                 push    edx
.text:1000DA6A                 push    offset a02x    ; "%02x"
.text:1000DA6F                 push    edi            ; char *
.text:1000DA70                 call    _sscanf
.text:1000DA75                 mov     al, [esp+11BCh+var_119D]
.text:1000DA79                 add     esp, 0Ch
.text:1000DA7C                 mov     [esp+esi+11B0h+var_119C], al
.text:1000DA80                 inc     esi
.text:1000DA81                 add     edi, 2
.text:1000DA84                 cmp     esi, 0Ch
.text:1000DA87                 jl      short loc_1000DA65
.text:1000DA89                 lea     ecx, [esp+11B0h+var_1054]
.text:1000DA90                 call    sub_1002B080
.text:1000DA95                 lea     ecx, [esp+11B0h+var_1188]

  • 3 tygodnie później...
Opublikowano

@Propagandhi

 

Reupload'ął byś tego Address Finder? to zrobię porządny logger do WR. Dzięki

"There is no other...then Tibia"
00034718xn1.gif
"Obama r0xi"
Opublikowano

Już biore sie do pracy ^_^

- zaraz ide

- gdzie ?

- jeszcze nie wiem.. :DD

 

 

- odpowiedzi zaznaczajcie ptaszkiem

- a długopisem można ?

 

OWNED xD

Opublikowano

Bylo tu sporo linkow, prosze o jeden dobry adress finder ;p Wystarczy mi esp i antykick

Czy wiesz, że użytkownik, który napisał post wyżej...

-Lubi traktować świat z przymrużeniem oka?
-Nie wstawia prośby o gwiazdki do podpisu, bo lubi doceniać userów, którzy sami dadzą mu te gwiazdki?
-Interesuje się aferami w polityce?
-Nie jest spamerem, przez co ma żenująco mało napisanych postów?
-Jest fajny?
Opublikowano

Czy można prosić o reupa programu?

CE mi wykrywa zanim dobrze uruchomię WR, a w googlach albo ja jestem przytępawy albo nie ma coś ostatnio adresów aktualnych :/

 

@Down

Spam? Eee, nie pomyślałem o PW jak to pisałem :)

Co do ByPassa to napisałem ten post albo jak jeszcze ByPassa nie było, albo go nie zauważyłem.

A umiesz może znajdować adresy używając CE? Nie umiem sam jakoś do tego dojść... A ciężko znaleźć to jakoś jasno objaśnione.

o.O
Gość mlody22pl
Opublikowano

@up

Do czego jest Bypass Naszego moderatora ;>

2x Up

Fajnie ze bierzesz sie do pracy ,ale po co spam ^^

  • 1 miesiąc temu...

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...