Показать сообщение отдельно
Старый 10.04.2007, 06:38   #1
dark
Читодел
Аватар для dark
OFFLINE
Регистрация: 09.04.2007
Сообщений: 985
Благодарностей:
36,603 всего
Мнения: + 37890
Репутация: 116472
Отправить сообщение для dark с помощью ICQ Отправить сообщение для dark с помощью Skype™

Миф о Rf-боте


На досуге просматривал читерские форумы и набрёл на исходники бота для RF на си. Вернее их было два, вот один из них:

Код:
#include <windows.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <tlhelp32.h> 


typedef struct _PLAYER_DATA {    
    DWORD baseadd[1];  // base address of this current player 
    DWORD hp[1]; 
    DWORD hpa; 
    DWORD hpmax[1]; 
    DWORD hpmaxa; 
    DWORD mp[1]; 
    DWORD mpa; 
    DWORD endu[1]; 
    DWORD endua; 
    DWORD baseaddar1[1];  //fleches pointer 1 
    DWORD baseaddar2[2]; //fleches pointer 2 
    DWORD arrowa1;      //adresse des fleches 
    DWORD arrowa2; 
    int arrownb1; 
    int arrownb2; 
    char name[15];  // Holds the current players name 
    DWORD namea;  // The address of the current players name 
} PLAYER_DATA; 

typedef int bool; 
int fight; 
bool debug = 0; 
HANDLE hProcess; 
HWND hrfo; 
PLAYER_DATA myp; 


void CheckMP(); 
void CheckHP(); 
void CheckMOB(); 
int GetPidByName ( char * nom ); 
PLAYER_DATA GetMyPlayerData(); 
void PrintMyPlayerData(PLAYER_DATA myp); 



void CheckMP() 
{ 
     int j; 
     j = myp.mp[0]; 
     if (j <= 35) 
     { 
      keybd_event(VK_F9, 0, 0, 0); 
      keybd_event(VK_F9, 0, KEYEVENTF_KEYUP, 0); 
     }                
      
} 

void CheckHP() 
{ 
     int j; 
     j = myp.hp[0]; 
     if (j <= 900) 
     { 
        keybd_event(VK_F8, 0, 0, 0); 
        keybd_event(VK_F8, 0, KEYEVENTF_KEYUP, 0); 
     }          
      
} 


void CheckMOB() 
{ 
   COLORREF mob = 3239810; 
   COLORREF col; 
   HDC wdc; 
   POINT pt; 
   BYTE red, blue, green; 
   GetCursorPos(&pt); 
   wdc = GetDC(hrfo); 
   col = GetPixel(wdc, (pt.x + 4), (pt.y - 8)); 
   if(col == mob) 
   { 
      printf("[+]Couleur detectee...\n"); 
      SetCursorPos(pt.x, pt.y); 
     keybd_event(VK_LBUTTON, 0, 0, 0); 
     keybd_event(VK_LBUTTON, 0, KEYEVENTF_KEYUP, 0); 
   }else 
   { 
         printf("[*]Couleur sous le curseur: %d\n", col); 
         red = GetRValue(col); 
         printf("red: %d\t", red); 
         blue = GetBValue(col); 
         printf("blue: %d\t", blue); 
         green = GetGValue(col); 
         printf("green: %d\n", green); 
    } 
   ReleaseDC(hrfo, wdc); 
} 


int GetPidByName ( char * nom ) 
{ 
    HINSTANCE      hLib;                // Chargement de la DLL 
    PROCESSENTRY32 PEntry;              // Informations sur les processus Win32 
    HANDLE         hTool32;             // Snapshot des processus 
    
    // Type des fonctions 
    HANDLE (WINAPI *pCreateToolhelp32Snapshot)(DWORD,DWORD); 
    BOOL   (WINAPI *pProcess32First)          (HANDLE,LPPROCESSENTRY32); 
    BOOL   (WINAPI *pProcess32Next)           (HANDLE,LPPROCESSENTRY32); 
    
    //Functions addresses : 
    pCreateToolhelp32Snapshot = (HANDLE(WINAPI *)(DWORD,DWORD))             GetProcAddress ( LoadLibrary("kernel32.dll"), "CreateToolhelp32Snapshot" ); 
    pProcess32First           = (BOOL(WINAPI *)  (HANDLE,LPPROCESSENTRY32)) GetProcAddress ( LoadLibrary("kernel32.dll"), "Process32First" ); 
    pProcess32Next            = (BOOL(WINAPI *)  (HANDLE,LPPROCESSENTRY32)) GetProcAddress ( LoadLibrary("kernel32.dll"), "Process32Next" ); 
    
    // On fixe la taille de la structure avant utilisation 
    PEntry.dwSize = sizeof(PROCESSENTRY32); 
    
    // On cr***233;e notre snapshot ( TH32CS_SNAPPROCESS : inclu la liste des processus Win32 ) 
    hTool32 = pCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 
    
    // On r***233;cup***232;re le premier processus 
    pProcess32First ( hTool32, &PEntry ); 
    
    // Si le nom correspond, on retourne le PID ( Processus IDentifiant ) 
    if ( !strcmp ( PEntry.szExeFile, nom ) ) 
        return PEntry.th32ProcessID; 

    // Sinon, on teste les processus suivants 
    while ( pProcess32Next(hTool32,&PEntry) ) 
        if(!strcmp(PEntry.szExeFile,nom)) 
            return PEntry.th32ProcessID; 

    // Sinon, on a rien trouv***233;, on retourne 0 
    return 0; 
} 

PLAYER_DATA GetMyPlayerData(HANDLE hProcess) 
{ 
    DWORD mBase = 0x00B3745C;      //pointer 
    DWORD mBasear1 = 0x08F8E008; 
    DWORD mBasear2 = 0x0903F900; 
    PLAYER_DATA Player;        // Create a blank PLAYER_DATA struct 
    ZeroMemory(&Player, sizeof(PLAYER_DATA));      // Initiate it all to 0 
    ReadProcessMemory(hProcess, (LPCVOID)mBase, (LPVOID)Player.baseadd, 4, NULL);      // Get our players Base Address from the pointer 
    //ReadProcessMemory(hProcess, (LPCVOID)mBasear1, (LPVOID)Player.baseaddar1, 4, NULL); 
    //ReadProcessMemory(hProcess, (LPCVOID)mBasear2, (LPVOID)Player.baseaddar2, 4, NULL); 
    Player.mpa = Player.baseadd[0] + 0x4AFC; 
    Player.hpa = Player.baseadd[0] + 0x4AEC; 
    Player.hpmaxa = Player.baseadd[0] + 0x4AE8; 
    Player.endua = Player.baseadd[0] + 0x4B0C; 
    Player.namea = Player.baseadd[0] + 0x10; 
    //Player.arrowa1 = Player.baseaddar1[0] + 0x1C; 
    //Player.arrowa2 = Player.baseaddar2[0] + 0x1C; 
    
    ReadProcessMemory(hProcess, (LPCVOID)Player.mpa, (LPVOID)Player.mp, 4, NULL);  // Now we got all the addies, read in the info from em all 
    ReadProcessMemory(hProcess, (LPCVOID)Player.hpa, (LPVOID)Player.hp, 4, NULL); 
    ReadProcessMemory(hProcess, (LPCVOID)Player.hpmaxa, (LPVOID)Player.hpmax, 4, NULL); 
    ReadProcessMemory(hProcess, (LPCVOID)Player.endua, (LPVOID)Player.endu, 4, NULL); 
    ReadProcessMemory(hProcess, (LPCVOID)Player.namea, (LPVOID)Player.name, 15, NULL); 
    //ReadProcessMemory(hProcess, (LPCVOID)Player.arrowa1, (LPVOID)Player.arrownb1, 4, NULL); 
    //ReadProcessMemory(hProcess, (LPCVOID)Player.arrowa2, (LPVOID)Player.arrownb2, 4, NULL); 
    
    return Player;      // Give our PLAYER_DATA Player, as the return value 
} 

void PrintMyPlayerData(PLAYER_DATA myp) 
{ 
     printf("[*]hp: %d/%d\n", myp.hp[0], myp.hpmax[0]); 
     printf("[*]mp: %d\n", myp.mp[0]); 
     printf("[*]endu: %d\n", myp.endu[0]); 
     printf("[*]name: %s\n", myp.name); 
     //printf("[*]fleches slot 1: %d\n", myp.arrownb1); 
     //printf("[*]fleches slot 2: %d\n", myp.arrownb2); 
} 

int main() 
{ 

    //int i,j; 
   DWORD pid; 
   pid = (DWORD)GetPidByName("RF_Online.bin"); 
    printf("[*]Recuperation du Handle sur le processus...\n"); 
    //changer le pid ds cette fonction et changer les 2 adresses ds checkmp et checkhp 
   hProcess = OpenProcess(PROCESS_VM_READ, FALSE, pid); 
    
    if (hProcess == NULL) 
    { 
                printf("[-]Ouverture du processus impossible...\n"); 
    } 
    else 
    { 
        hrfo = FindWindow(NULL,"RF Online"); 
       if(hrfo == NULL) 
       { 
              printf("[-]Impossible de trouver le handle de la fen***234;tre!\n"); 
        } 
        printf("[*]le handle de la fenetre de Rf Online est : 0x%X\n",hrfo); 

        
        myp = GetMyPlayerData(hProcess); 
        PrintMyPlayerData(myp); 
        
        while (1 == 1) 
        { 
              Sleep(400); 
              system("cls"); 
              myp = GetMyPlayerData(hProcess); 
              PrintMyPlayerData(myp); 
              CheckMP(); 
              CheckHP(); 
           //CheckMOB(); 
        } 
    } 
}
Вокруг поднилось столько шума, причём, на моё удивление, некоторые люди писали на форуме, что успешно пользуются этим ботом. Так вот, хочу объяснить что и как этот код делает:
1. ищет процесс с игрой и открывает его для чтения
2. в цикле считываются из памяти игры значения hp и mp.
Если hp < 900, то программно нажимает кнопку F8 (очевидно, в слоту должен быть пот).
Если mp < 35, нажимает на F9.
И это всё, что делает данный код именно в том виде, в котором он был выложен на читерских форумах.

Если же раскомментировать пред-пред-пред-последнюю строчку, то помимо hp и mp, в цикле будет проверятся цвет курсора мышки - это как раз самое интересное. А на сколько вы знаете, когда мышка наведена на моба, она переливается красным цветом. Так вот, если мышка оказывается цвета 3239810 (а точнее 0x316F82, а ещё точнее красный - 0x31, зелёный - 0x6f, синий - 0x82, в общем вот так), то программа нажимает левую кнопку мышки, на что клиент должен атаковать этого моба. При этом, мышку программа НЕ ДВИГАЕТ!
Явно, код был задуман для работы в связке с программами вроде AC tools и в идеале всё должно работать. Но тут всплывает два НО:
- либо программа писалась под какой-то другой клиент (не такой какой использует rfonline.ru), либо автор намеренно испортил код, но на самом деле программа берёт цвет не курсора, а того, что на 8 пикселей выше и на 4 пикселя правее него. А это уже далеко не курсор. Соответственно, в данном виде, программа не видит мобов, а просто тупо кликает, если цввет того, что рядом с курсором совпадает с 0x316F82. Честно говоря, побегав с ней минут 5, я ниразу не наткнулся на этот цвет.
- программа работает с памятью игрового клиента и соответственно требует адреса тех переменных, которые она использует (это если вы хотите использовать фишки авто-питья потов, что на rfonline.ru не требуется), а доставать их сложновато. У меня заняло минут 40 через дебаггер, но, имхо, через ArtMoney это можно было сделать гораздо быстрее.

В итоге могу сказать, что задумка неплохая, а вот реализация подкачала, либо, повторюсь, код намеренно был испорчен.
Если кому надо, могу выложить исправленный вариант.
 
Ответить с цитированием
Сказали спасибо:
Недоступно (28.02.2013), Недоступно (28.05.2009), Недоступно (01.03.2009)