Перейти к содержанию

Нужен совет, с++


Рекомендуемые сообщения

В общем попытался написать трейнер на с++ для кримсона

Вот, что у меня получилось, но не работает, можете подсказать где ошибся?


#include <windows.h>
#include <iostream>
HWND hWnd = NULL; // заголовок окна нужного процесса
HANDLE process = NULL;
DWORD pid = 0; // номер процесса в списке
int Health; // буфер
int PatchHealth = 100;
int main() // создаём точку входа в процесс трейнера
{
while(1)
{
if(FindWindow(NULL, "Crimsonland")) // проверяем наличие окна с заголовком Crimsonland
{
hWnd = FindWindowA(NULL, "Crimsonland");
GetWindowThreadProcessId(hWnd,&pid); // запоминаем номер в переменную pid
std::cout<<hWnd<<'\n';
if (process == NULL && pid != 0)
process = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
//*=== Статический адрес ===*
ReadProcessMemory(process, (LPVOID)(0x0048E5C4), &Health, 4, NULL);
if (Health < 100.0)
WriteProcessMemory(process, (LPVOID)(0x0048E5C4), &PatchHealth, 4, NULL);
}
Sleep(200);
}

}

Ссылка на комментарий
Поделиться на другие сайты

1). Хэндл процесса за тебя Страуструп закрывать должен?

2). при использовании iostream конструкция


std::cout<<hWnd<<'\n';

- бред.

Надо


std::cout<<hWnd<<endl;

3). Уверен ли, что адрес статичен? Если да, то

4). Уверен ли, что он однозначно хранит здоровье, а не является указателем на адрес здоровья, или вообще указателем на указатель?

5). Уверен ли в правильности заголовка окна (хэндл окна правильный берется?)?.

6). В принципе, тут iostream ну нафиг не сдался. Но это дело вкуса.

7). Из бесконечного цикла нужно предусматривать выход по условию, но это так, правила грамотного программирования, в принципе, ими можно в данном случае пренебречь, ибо при закрытии окна консоли цикл и так прервется.

8). Логика кода несколько кривовата, видимо, ты совсем новичок. Условие (if) лучше организовать примерно так:


hwnd = FindWindow(NULL, "Crimsonland");
if (hwnd)
{
...
}

Объясняю почему - ты задаешь напрасную работу процессору, получая хендл окна два раза (функция FindWindow в условии и дальше при получении положительного результата).

9). Необязательно использовать функции с суффиксом "А" (FindWindowA), достаточно в свойствах проекта указать, что используется ASCII-кодировка (MultiByte), а не юникод.

10). int PatchHealth = 100; - это значение у тебя не меняется, поэтому лучше объявить его как константу: const int PatchHealth = 100;

11). Судя по этому куску


if (Health < 100.0)

ты сравниваешь здоровье с float значением. Следовательно, тебе надо определиться - либо в игре значение здоровья - float, и тогда тебе переменную для записи здоровья надо поменять на const float PatchHealth = 100; или же в игре у тебя int, и тогда тебе надо поменять условие сравнения. А еще проще - сравнивай здоровье с константой PatchHealth, ибо видно, что она у тебя соответствует (не равна в твоей реализации, ибо типы разные) значению, которое ты сравниваешь. Поэтому лучше сразу записать так:

if (Health < PatchHealth)

и тогда тебе будет проще изменить тип константы (PatchHealth) и принимающего значения (Health), ибо менять их нужно будет только в одном месте.

Больше очевидных ошибок и недочетов пока не вижу. Игры у меня этой нет, поэтому более конкретно с проблемой помочь не могу.

ЗЫ. И вообще, "не работает" - это слишком общий термин. Нужно более конкретно пояснять, что именно не работает в твоем случае - неверно возвращается хэндл окна, не удается открыть процесс, не удается считать значение, не удается записать значение, или что-то еще. В общем, больше конкретики - выше вероятность более быстрой и более конкретной помощи с нашей стороны. Меньше конкретики - меньше вероятность быстрой и четкой помощи, и больше вероятность неудачных попыток включения режима телепата (телепатов среди нас, увы, нет)...

Ссылка на комментарий
Поделиться на другие сайты

Ого, спасибо за советы)

Не работало из за последнего пункта, значение float точкой, а искал int

Про сиаут - не обращай внимания, это я для теста сделал, какое значение возвращает, с брейкпоинтами не очень ещё дружу.

Ссылка на комментарий
Поделиться на другие сайты

Вот, постарался учесть все замечания


#include <windows.h>
HWND hWnd = NULL; // заголовок окна нужного процесса
HANDLE process = NULL;
DWORD pid = 0; // номер процесса в списке
const float patchH(100.0), patchA(20.0);
float Health, Ammo;
int main() // создаём точку входа в процесс трейнера
{
while(1)
{
hWnd = FindWindow(NULL, "Crimsonland");
GetWindowThreadProcessId(hWnd,&pid);
if(hWnd){
if (process == NULL && pid != 0)
{
process = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
}
ReadProcessMemory(process, (LPVOID)(0x0048E5C4), &Health, 4, NULL);
ReadProcessMemory(process, (LPVOID)(0x0048E860), &Ammo, 4, NULL);
if (Health<patchH || Ammo<patchA)
WriteProcessMemory(process, (LPVOID)(0x0048E5C4), &patchH, 4, NULL);
WriteProcessMemory(process, (LPVOID)(0x0048E860), &patchA, 4, NULL);

}
Sleep(200);
}

}

Ссылка на комментарий
Поделиться на другие сайты

А первое замечание не учел. Перед выходом из программы надо закрыть хэндл открытого процесса.


CloseHandle(process);

И условие не совсем правильное. По этому условию у тебя если патроны уменьшились, в здоровье тоже запишется значение, ибо стоит || - логическое или.

Если ты хочешь эти условия проверять и выполнять по отдельности - тебе нужно их в разные конструкции if убрать.

Ссылка на комментарий
Поделиться на другие сайты

А зачем закрывать хэндл?

И если их по отдельности делать, то это не будет долше или более ресурсоёмким?


#include <windows.h>
HWND hWnd = NULL;
HANDLE process = NULL;
DWORD pid = 0;
const float patchH(100.0), patchA(20.0);
float Health, Ammo;
int main()
{
hWnd = FindWindow(NULL, "Crimsonland");
GetWindowThreadProcessId(hWnd,&pid);

while(hWnd)
{
if (process == NULL && pid != 0)
{
process = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
}
ReadProcessMemory(process, (LPVOID)(0x0048E5C4), &Health, 4, NULL);
ReadProcessMemory(process, (LPVOID)(0x0048E860), &Ammo, 4, NULL);
if (Health<patchH)
{
WriteProcessMemory(process, (LPVOID)(0x0048E5C4), &patchH, 4, NULL);
}
if (Ammo<patchA)
{
WriteProcessMemory(process, (LPVOID)(0x0048E860), &patchA, 4, NULL);
}

Sleep(50);
}
CloseHandle(process);
return 0;
}

Ссылка на комментарий
Поделиться на другие сайты

А зачем закрывать хэндл?

И если их по отдельности делать, то это не будет долше или более ресурсоёмким?


#include <windows.h>
HWND hWnd = NULL;
HANDLE process = NULL;
DWORD pid = 0;
const float patchH(100.0), patchA(20.0);
float Health, Ammo;
int main()
{
hWnd = FindWindow(NULL, "Crimsonland");
GetWindowThreadProcessId(hWnd,&pid);

while(hWnd)
{
if (process == NULL && pid != 0)
{
process = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
}
ReadProcessMemory(process, (LPVOID)(0x0048E5C4), &Health, 4, NULL);
ReadProcessMemory(process, (LPVOID)(0x0048E860), &Ammo, 4, NULL);
if (Health<patchH)
{
WriteProcessMemory(process, (LPVOID)(0x0048E5C4), &patchH, 4, NULL);
}
if (Ammo<patchA)
{
WriteProcessMemory(process, (LPVOID)(0x0048E860), &patchA, 4, NULL);
}

Sleep(50);
}
CloseHandle(process);
return 0;
}

Вообще странная реализация первый раз такой странный трейнер вижу.

Ну я бы такой реализовал бы так:


#include <windows.h>
void main()
{
DWORD pid = 0;
HANDLE process = NULL;
const float patchH(100.0f);
const float patchA(20.0f);
float Health = 0.f;
float Ammo = 0.f;
for (;;Sleep(50))
{
HWND hWnd = FindWindow(NULL, "Crimsonland");
GetWindowThreadProcessId(hWnd, &pid);
if (process == NULL) process = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
ReadProcessMemory(process, (LPVOID)(0x0048E5C4), &Health, 4, NULL);
ReadProcessMemory(process, (LPVOID)(0x0048E860), &Ammo, 4, NULL);
if (Health < patchH)
{
WriteProcessMemory(process, (LPVOID)(0x0048E5C4), &patchH, 4, NULL);
}
if (Ammo < patchA)
{
WriteProcessMemory(process, (LPVOID)(0x0048E860), &patchA, 4, NULL);
}
if (process == NULL) CloseHandle(process);
}
return;
}

А ещё лучше без -

if (process == NULL)

P.S. твой метод нещадно грузит ЦП.

Поэтому более лояльно по отношению к ЦП будет - внедрение инъекции кода.

Ссылка на комментарий
Поделиться на другие сайты

P.S. твой метод нещадно грузит ЦП.

Поэтому более лояльно по отношению к ЦП будет - внедрение инъекции кода.

Спасибо за совет, но внедрять инъекцию кода я ещё не научился.

Не откажусь от ссылки где можно про это почитать или посмотреть)

Ссылка на комментарий
Поделиться на другие сайты

Спасибо за совет, но внедрять инъекцию кода я ещё не научился.

Не откажусь от ссылки где можно про это почитать или посмотреть)

Мой канал на Youtube - http://www.youtube.com/user/coder1994?feature=mhee думаю тебе будет полезно.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.