Made in C++
I kinda burned out on making it, but it's a mostly-done pixel aimbot. Takes a screenshot of the game, reads the pixels, looks for a player, moves and shoots them.
I got it done up to detecting the colors correctly.
How it works: Grab the player's colors before aimbotting, saves them to a text file to be searched for later (best done with friends). Then, every time you click, it screenshots and reads the pixels, looking for colors grouped close enough to signify a player, then moves the crosshairs to the center of the grouping.
Code:
#include <windows.h>
#include <iostream>
#define Winver 0x500
#include <tlhelp32.h>
#include <stdio.h>
#include <winable.h>
#include <fstream>
#include <istream>
#include <string>
#include <time.h>
#include <sys/timeb.h>
#include <vector>
#include <algorithm>
#include <sstream>
#include <iterator>
using namespace std;
int ScreenWidth; //the width of the screen
int ScreenHeight; //the height of the screen
RECT ava_rect;
HWND ava_wind;
ofstream pixel_file; //to-be-written to file that will hold the pixel colors
ifstream pixel_check; //to-be-read from file that holds the pixel colors
bool operator == (vector<unsigned int> const& v1, vector<unsigned int> const& v2){ //for comparing 2 vectors
return (v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]);
}
int getMilliCount(){ //timing function, used to test speed
timeb tb;
ftime(&tb);
int nCount = tb.millitm + (tb.time & 0xfffff) * 1000;
return nCount;
}
int getMilliSpan(int nTimeStart){ //timing function, used to test speed
int nSpan = getMilliCount() - nTimeStart;
if(nSpan < 0)
nSpan += 0x100000 * 1000;
return nSpan;
}
void mouseMove(float x_coord, float y_coord) //moves the mouse x and y amounts
{
//x_coord *= (65335/ScreenWidth);
//y_coord *= (65335/ScreenWidth);
//cout << x_coord << endl;
//cout << y_coord << endl;
INPUT mouse;
memset(&mouse, 0, sizeof(INPUT));
mouse.type = INPUT_MOUSE;
// flag for the mouse hook to tell that it's a synthetic event.
mouse.mi.dwExtraInfo = 0x200;
//POINT p;
//p.x = x_coord;
//p.y = y_coord;
//ClientToScreen(ava_wind, &p);
mouse.mi.dx = x_coord;
mouse.mi.dy = y_coord;
mouse.mi.dwFlags = mouse.mi.dwFlags | MOUSEEVENTF_MOVE;
SendInput(1, &mouse, sizeof(mouse));
}
int curr_color[2]; //the current pixel color
unsigned int pix_data[1000][2]; //reference radius for specific size
unsigned int found_pix[100][2]; //to avoid repeat colors
int found_pix_counter = 0;
int pix_pos_piece[1]; //a pixel x, y coordinate
int pix_pos_counter = 0; //the counter for all of the positions
void get_bitmap_ava(HWND ava_hwnd, int size_x, int size_y, bool get_pixel_color){ //grabs the bitma
int pix_pos_full[size_x * size_y][1]; //use max possible positions just in case
if(get_pixel_color){ //if the user pressed enter to grab pixels
pixel_file.open("pixels.dat"); //open the write-to file
}
int pos_x, pos_y; //the starting x and y position
pos_x = size_x / 2; //crosshairs are always center screen
pos_y = size_y / 2;
//POINT p; //used for special testing
//GetCursorPos(&p);
//pos_x = p.x;
//pos_y = p.y;
int radius = 10; //the amount of pixels to grab if saving pixel colors
//int start = getMilliCount(); //track screenread speed in milliseconds
HDC ava_dc = GetDC(ava_hwnd); //get the device context of the window
HDC ava_dc_cap = CreateCompatibleDC(ava_dc); //create a compatible dc out of that
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(ava_dc, size_x, size_y); //make a bitmap
SelectObject(ava_dc_cap, hCaptureBitmap); //select it in memory
BitBlt(ava_dc_cap, 0, 0, size_x, size_y, ava_dc, 0, 0, SRCCOPY); //and bitblt it
//getting the size of the picture
BITMAP bm;
GetObject(hCaptureBitmap, sizeof(bm), &bm);
int width(bm.bmWidth), height(bm.bmHeight);
//creating a bitmapheader for getting the dibits
BITMAPINFOHEADER bminfoheader;
::ZeroMemory(&bminfoheader, sizeof(BITMAPINFOHEADER));
bminfoheader.biSize = sizeof(BITMAPINFOHEADER);
bminfoheader.biWidth = width;
bminfoheader.biHeight = -height;
bminfoheader.biPlanes = 1;
bminfoheader.biBitCount = 32;
bminfoheader.biCompression = BI_RGB;
bminfoheader.biSizeImage = width * 4 * height;
bminfoheader.biClrUsed = 0;
bminfoheader.biClrImportant = 0;
//ALL THAT IS COMMENTED OUT BELOW IS TO SAVE THE PICTURE TO A FILE
/*DWORD dwBmpSize = ((size_x * bminfoheader.biBitCount + 31) / 32) * 4 * size_y;
HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
// Gets the "bits" from the bitmap and copies them into a buffer
// which is pointed to by lpbitmap.
GetDIBits(CreateCompatibleDC(0), hCaptureBitmap, 0,
(UINT)bm.bmHeight,
lpbitmap,
(BITMAPINFO *)&bminfoheader, DIB_RGB_COLORS);
// A file isz3 created, this is where we will save the screen capture.
HANDLE hFile = CreateFile("captureqwsx.bmp",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
// Add the size of the headers to the size of the bitmap to get the total file size
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
BITMAPFILEHEADER bmfh;
//Offset to where the actual bitmap bits start.
bmfh.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
//Size of the file
bmfh.bfSize = dwSizeofDIB;
//bfType must always be BM for Bitmaps
bmfh.bfType = 0x4D42; //BM
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)&bmfh, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)&bminfoheader, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);
//Close the handle for the file that was created
CloseHandle(hFile);*/
//FILE SAVING PROCESS ENDS HERE
//create a buffer and let the GetDIBits fill in the buffer
unsigned char* pPixels = new unsigned char[(width * 4 * height)];
if( !GetDIBits(CreateCompatibleDC(0), hCaptureBitmap, 0, height, pPixels, (BITMAPINFO*) &bminfoheader, DIB_RGB_COLORS)) // load pixel info
{
//return if fails but first delete the resources
DeleteObject(hCaptureBitmap);
delete [] pPixels; // delete the array of objects
cout << "fail" << endl;
return;
}
int x, y; // fill the x and y coordinate for grabbing pixels
x = 0;
y = 0;
int total_found = 0; //the total amount of pixels matching pixels being searched for
int previous_x = -1; //set the initial prev_x and y to -1 to avoid issues
int previous_y = -1;
for(int iter = 0; iter < (size_x * size_y); iter++){ //loop through all of the pixels in the screen
if(x < size_x){ //if the pixels have not reached the right of the screen
x++; //keep going
}
else{
x = 0; //if they do reach the right, reset to the left
y++; //and go down one row
}
unsigned int r = pPixels[(width*y+x) * 4 + 2]; //the pixel color in r g b color format
unsigned int g = pPixels[(width*y+x) * 4 + 1];
unsigned int b = pPixels[(width*y+x) * 4 + 0];
curr_color[0] = r; //set the current color array values
curr_color[1] = g; //old values wrote over with each new pixel
curr_color[2] = b;
pix_pos_piece[0] = x; //set the current position
pix_pos_piece[1] = y; //wrote over with each new pixel
if(!get_pixel_color){ //if we are looking for pixels (not saving them)
bool done = false; //a bool to check if we have gone through the entire set of pixels to look for
for(unsigned int iter2 = 0; iter2 < sizeof(pix_data)/sizeof(pix_data[0]); iter2++){
if(abs(int(curr_color[0] - pix_data[iter2][0])) < 1 && abs(int(curr_color[1] - pix_data[iter2][1])) < 1 && abs(int(curr_color[2] - pix_data[iter2][2])) < 1){
found_pix[found_pix_counter][0] = curr_color[0];
found_pix[found_pix_counter][1] = curr_color[1];
found_pix[found_pix_counter][2] = curr_color[2];
found_pix_counter++;
//if all of the current pixel colors are within 1 color difference of the pixels being searched for
break; //exit the loop
}
if(sizeof(pix_data)/sizeof(unsigned int) - 1 == iter2){ //if it reaches the end of the loop
done = true;
}
}
if((abs(int(previous_x - x)) < 10 || abs(int(previous_y - y)) < 10) && (!done)){
//cout << "incr" << endl;
//cout << x << endl;
//cout << y << endl;
//cout << endl;
//if the found pixel was within 10 pixels of the last found one
total_found++; //increment the total found
pix_pos_full[pix_pos_counter][0] = pix_pos_piece[0]; //fill in the pix_pos array
pix_pos_full[pix_pos_counter][1] = pix_pos_piece[1]; //with the x, y values of the current pixel
}
else{ //if it was not found within 10 pixels or not the right color
//cout << "Reset" << endl;
total_found = 0; //reset the total found (needs to be a grouping to match a pattern)
pix_pos_counter = 0; //reset the pix_pos_counter
}
if(total_found > 6){
break;
}
}
if(get_pixel_color){ //if the user wants to save pixels
if((abs(int(100-r)) > 10) && (abs(int(100-g)) > 10) && (abs(int(100-b)) > 10)){
if(abs(x - pos_x) < radius && abs(y - pos_y) < radius){ //if the x and y positions of the pixels are within radius amount of the center of the screen
pixel_file << r << " " << g << " " << b << "\n"; //write the r g b to the file
}
}
}
}
//cout << total_found << endl; //for testing purposes, to see how many were found. Currently, either 0 or all of them are "found"
if(!get_pixel_color){ //make sure the user did not want to save pixels
if(total_found > 6){ //if more than 6 were found (arbitrary number, will be worked into percentage later)
int other_x_pos = pix_pos_full[(sizeof(pix_pos_full)/sizeof(int))/2][0]; //grab the center position
int other_y_pos = pix_pos_full[(sizeof(pix_pos_full)/sizeof(int))/2][1]; //of the pixel positions
//I am having trouble determining how much to move
//the mouse moves by x amount (the distance between pos_x and other_pos_x)
//but I can't determine it correctly
cout << other_x_pos - pos_x << endl;
cout << other_y_pos - pos_y << endl;
mouseMove(other_x_pos - pos_x, other_y_pos - pos_y);
}
}
total_found = 0; //reset the variables
pix_pos_counter = 0; //for the next screen grab
found_pix_counter = 0;
if(get_pixel_color){ //if the save-to file was opened
pixel_file.close(); //close it
}
//clean up the bitmap and buffer unless you still need it
DeleteObject(hCaptureBitmap);
delete [] pPixels; // delete the array of objects
ReleaseDC(ava_hwnd, ava_dc);
DeleteDC(ava_dc_cap);
DeleteObject(hCaptureBitmap);
//int end = getMilliSpan(start);
//cout << end << endl;
}
int main()
{
//use for testing
/*RECT desktop_rect;
HWND desktop_hwnd;
desktop_hwnd = GetDesktopWindow();
GetWindowRect(desktop_hwnd, &desktop_rect);
while(true){
if((GetKeyState(VK_RETURN) & 0x80) != 0){
get_bitmap_ava(desktop_hwnd, desktop_rect.right, desktop_rect.bottom, true);
Sleep(500);
}
if((GetKeyState(VK_LBUTTON) & 0x80) != 0){
get_bitmap_ava(desktop_hwnd, desktop_rect.right, desktop_rect.bottom);
}
if((GetKeyState(VK_END) & 0x80) != 0){
pixel_file.close();
break;
}
}
return 0;*/
pixel_check.open("pixels.dat"); //the file that contains pixels to look for
string line; //a line to hold each set up numbers
if(pixel_check.is_open()){ //if the file open ok
vector<string> tokens; //to hold the 3 numbers as strings
unsigned int tokints[2]; //to hold the 3 numbers as ints
int counter = 0; //indexing for the pix_data array
while(getline(pixel_check,line)){ //get each line in the file
istringstream iss(line); //create a stringstream
copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter<vector<string> >(tokens)); //copy the sstream elements into tokens
for(unsigned int it = 0; it < sizeof(tokints)/sizeof(tokints[0]); it++){
tokints[it] = atoi(tokens.at(it).c_str()); //and convert/ copy tokens into tokints as ints
}
pix_data[counter][0] = tokints[0]; //fill pix_data
pix_data[counter][1] = tokints[1];
pix_data[counter][2] = tokints[2];
counter++;
}
}
pixel_check.close(); //close the file
ifstream ava_settings("C:/AeriaGames/AVA/avaGame/Config/AVAOptionSettings.ini");
size_t found;
int file_counter = 0;
if(ava_settings.is_open()){
while(getline(ava_settings,line) && file_counter < 3){
found = line.find("=");
if(found != string::npos){
line.replace(0, found+1,"");
if(file_counter == 1){
ScreenWidth = int(atof(line.c_str()));
}
else if(file_counter == 2){
ScreenHeight = int(atof(line.c_str()));
}
}
file_counter++;
}
ava_settings.close();
}
TCHAR title[500];
while(true){
if(GetWindowText(GetForegroundWindow(), title, 500) == 24){
ava_wind = GetActiveWindow();
break;
}
Sleep(100);
}
while(true){
if((GetKeyState(VK_RETURN) & 0x80) != 0){ //if the user presses enter
get_bitmap_ava(ava_wind, ScreenWidth, ScreenHeight, true); //screen read and save the pixels the center of the screen is on
Sleep(500);
}
if((GetKeyState(VK_LBUTTON) & 0x80) != 0){ //if the user left-clicks
get_bitmap_ava(ava_wind, ScreenWidth, ScreenHeight, false); //screen read and search for pixels
Sleep(100);
}
if((GetKeyState(VK_END) & 0x80) != 0){ //killswitch
break;
}
}
return 0;
}
There's some commented-out code to save the bitmap to a file, to prove it works. There's also come commented-out code for testing it on the desktop. I made this myself, but there's stuff in there I didn't personally write. The timing functions are not mine, nor is the save bitmap to file.
NOTE: Run AVA in windowed mode for this to work. Something about graphic acceleration and Overlays prevents fullscreen from working.
ALSO NOTE: The 0x200 flag for the mouse movement, and making it relative, rather than absolute, are how it works. The crosshairs will not move otherwise.
LAST NOTE: Undetectable (kinda). Since it does not actually inject into the game, it is harder for XIGN to detect it.
If anyone wants to finish this (fix the actual color detection), be my guest. Just credit the main part to me (if you use my code).