На досуге просматривал читерские форумы и набрёл на исходники бота для 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 это можно было сделать гораздо быстрее.
В итоге могу сказать, что задумка неплохая, а вот реализация подкачала, либо, повторюсь, код намеренно был испорчен.
Если кому надо, могу выложить исправленный вариант.
тыды репост.
Numlock не горит - бот вкл
Capslock горит - жмет левую кнопку мыши при красном курсоре (значение в условии поставил только для моба, врага не выделит)
ScrollLock горит - юзает скиллы с F1 по F10 (я маг и мне нуна все 10 скилофф, кому мешает, могут сами там закомментировать).
Радар вкл - лут подбирает\выкл - не подбирает.
Последний раз редактировалось Fij; 30.04.2007 в 00:31.