PDA

Просмотр полной версии : [Руководство] Пишем свой тренер для игр на c#


object
22.01.2011, 23:35
Создание трейнера на C#
Всем привет, довольно часто задают вопросы: "Как в CиШарп читать/писать память клиента", и так далее.
Сегодня мы будем пробывать написать простенький трейнер для "Сапёр" на XP SP3, не забываем что на другой OC оффсеты другие :D.
Что нам понадобиться:

1. Cheat Engine (для поиска оффсетов).
2. Компилятор кода, я использую MVS 2008.
3. И как всегда руки, мозг и точные действия по гайду.
4. Библиотека VAMemory, СКАЧАТЬ ([Ссылки могут видеть только зарегистрированные и активированные пользователи]")
И так, поехали...
1. Для начала создадим проэкт, обязательно поставить .net framework 3.5 для будущего проэкта.
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
2. Добавим .dll VAMemory.

[Ссылки могут видеть только зарегистрированные и активированные пользователи]
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
3. Запускаем CE, Сапёра, в CE процесс сапёр, ищем текущее значение флажков, юзаем 1 флажок, отсеиваем в CE и так пока не получим 1 значение.
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
4. Теперь добавим 2 лабела и 1 кнопку
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
5. Теперь после
public partial class ИМЯВАШЕЙФОРМЫ : Form
{
Добавим:
VAMemory VAM;
6. На кнопку "обновить" кинем код:
VAM = new VAMemory("winmine"); //Имя процесса, без .exe!
label2.Text = (Convert.ToString(VAM.ReadByte((IntPtr)0x01005194) )); //label2 принимает значение по адрессу 01005194 не забываем про 0x********!
адрес что идёт после 0x, можно узнать в CE
[Ссылки могут видеть только зарегистрированные и активированные пользователи]
7. Запускаем, видим профит

[Ссылки могут видеть только зарегистрированные и активированные пользователи]
8. Теперь научимся редактировать, для этого кинем 1 текст бокс и 1 буттон
и на буттон кинем код:

VAM = new VAMemory("winmine"); // Имя процесса, без .exe!
VAM.WriteByte((IntPtr)0x01005194, byte.Parse(textBox1.Text.ToString())); // Изменяем значение по адресу 01005194, не забываем про 0x********!
9. Запускаем, вводим желаемое количество и жмём буттон

[Ссылки могут видеть только зарегистрированные и активированные пользователи]
10. Спасибо за внимание!

Учтите!На разных Осях разные адреса!
А точнее, на 7ке например Сапер отличается чем на ХП, поэтому адреса будут разные! :)

С ув, обжа! :)

dickens011
23.01.2011, 14:32
вот какраз самое важное и не выложил...
а самое важное это исходник VAMemory.dll, а в уроке описан только прототип функции из этой длл...
если есть исходник, плиз, кинь в личку или сюда ссылку

((((Zloy))))
23.01.2011, 15:47
омг, у меня нету сапёра:)
Скиньте кто-то, в гугле искал - не ищет такой. Вернее нашёл, но ошибка при установке

dickens011
23.01.2011, 16:21
((((Zloy)))),
любую другую игру попробуй, например косынку, все равно вероятность того, что адрес у тебя совпадет с адресом в примере крайне мала.

((((Zloy))))
23.01.2011, 16:23
dickens011,
сделал на примере косынки, работает, но адресс действительно другой:)

VolniyStalker
23.01.2011, 18:29
спасибо, урок замечательный.
dickens011 исходники и список функций в гугле:)

dickens011
23.01.2011, 19:03
Может кому поможет, видео версия данного урока.
В первом видео описывается как искать значения:
Первое видео. ([Ссылки могут видеть только зарегистрированные и активированные пользователи])
Во втором, собственно, сам процесс программирования, разжеванный до нельзя с описанием всех шагов, правда на английском:
Второе видео. ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

Думаю даже у начинающих не возникнет вопросов.

Добавлено через 28 минут
VolniyStalker, прототипы функций действительно можно найти, но ведь я спрашивал об исходнике. Если ты даш ссылку именно на исходник (!), то с меня 3 спасибки.

reraider
24.01.2011, 13:58
У меня проблема решил сделать на Darksiders трейнер на деньги неполучилось , а тоесть информацию при обновлении выдает ложную у меня к примеру там 100000000
мне выдает 123 вообщем как мне сделать это , если значение байта Float.
Жду видео туториала или простеньгого обьяснения "с меня СПАСИБО"

reraider
24.01.2011, 14:46
Sapper v 1.2

reraider
25.01.2011, 16:36
Как сделать так чтобы на кнопку нажмая менялось на определённое число?

nokia03
26.01.2011, 20:41
супер работает
ВОТ МОИ ФЕИК ([Ссылки могут видеть только зарегистрированные и активированные пользователи])

KeepirTee
26.01.2011, 20:47
У меня проблема решил сделать на Darksiders трейнер на деньги неполучилось , а тоесть информацию при обновлении выдает ложную у меня к примеру там 100000000
мне выдает 123 вообщем как мне сделать это , если значение байта Float.
Жду видео туториала или простеньгого обьяснения "с меня СПАСИБО"
Во избежании вопросов, вылаживаю всё что умеет VAMemory:

public VAMemory();
public VAMemory(string pProcessName);

public long getBaseAddress { get; }
public string processName { get; set; }

public bool CheckProcess();
public bool ReadBoolean(IntPtr pOffset);
public byte ReadByte(IntPtr pOffset);
public byte[] ReadByteArray(IntPtr pOffset, uint pSize);
public char ReadChar(IntPtr pOffset);
public double ReadDouble(IntPtr pOffset);
public float ReadFloat(IntPtr pOffset);
public short ReadInt16(IntPtr pOffset);
public int ReadInt32(IntPtr pOffset);
public long ReadInt64(IntPtr pOffset);
public int ReadInteger(IntPtr pOffset);
public long ReadLong(IntPtr pOffset);
public short ReadShort(IntPtr pOffset);
public string ReadStringASCII(IntPtr pOffset, uint pSize);
public string ReadStringUnicode(IntPtr pOffset, uint pSize);
public ushort ReadUInt16(IntPtr pOffset);
public uint ReadUInt32(IntPtr pOffset);
public ulong ReadUInt64(IntPtr pOffset);
public uint ReadUInteger(IntPtr pOffset);
public long ReadULong(IntPtr pOffset);
public ushort ReadUShort(IntPtr pOffset);
public bool WriteBoolean(IntPtr pOffset, bool pData);
public bool WriteByte(IntPtr pOffset, byte pData);
public bool WriteByteArray(IntPtr pOffset, byte[] pBytes);
public bool WriteChar(IntPtr pOffset, char pData);
public bool WriteDouble(IntPtr pOffset, double pData);
public bool WriteFloat(IntPtr pOffset, float pData);
public bool WriteInt16(IntPtr pOffset, short pData);
public bool WriteInt32(IntPtr pOffset, int pData);
public bool WriteInt64(IntPtr pOffset, long pData);
public bool WriteInteger(IntPtr pOffset, int pData);
public bool WriteLong(IntPtr pOffset, long pData);
public bool WriteShort(IntPtr pOffset, short pData);
public bool WriteStringASCII(IntPtr pOffset, string pData);
public bool WriteStringUnicode(IntPtr pOffset, string pData);
public bool WriteUInt16(IntPtr pOffset, ushort pData);
public bool WriteUInt32(IntPtr pOffset, uint pData);
public bool WriteUInt64(IntPtr pOffset, ulong pData);
public bool WriteUInteger(IntPtr pOffset, uint pData);
public bool WriteULong(IntPtr pOffset, ulong pData);
public bool WriteUShort(IntPtr pOffset, ushort pData);

Тебе надо читать не Byte1/2/4/8... а Float, и вместо ReadByte, пишем ReadFloat.

reraider
27.01.2011, 01:38
Спасибо тебе

Добавлено через 47 минут
а не скажеш как сделать так чтобы на button1 уже выполнялось определённое число)

VolniyStalker
28.01.2011, 11:08
а не скажеш как сделать так чтобы на button1 уже выполнялось определённое число)
вместо textBox1.Text.ToString() в строке редактирования памяти пиши нужное число
___________________
ИМХО тема супер, громадное спасибо за либу!)))

anime-kawai
31.01.2011, 14:34
А как сделать что бы тренер ждал пока запустится процесс?
Например я сделал checkBox, поставил галочку и что бы тренер ждал пока запуститься процесс и потом внес изменение

VolniyStalker
01.02.2011, 20:46
А как сделать что бы тренер ждал пока запустится процесс?
Например я сделал checkBox, поставил галочку и что бы тренер ждал пока запуститься процесс и потом внес изменение

тут нужно в winApi лезть, что делать в C# все равно что штаны через голову надевать...

а если вообще - winApi функция FindWindow если окна нету возвратит ошибочное значение =>

[DLLimport("user32.dll", charset = charset.Auto)]
public extern IntPtr FindWindow(
string windowtype, string window name);

импортирует либу user32.dll и описывает находяшуюся в ней функцию FindWindow, в идеале там типы другие но в C# их нет, обойдемся аналогами - IntPtr вместо HWND и string вместо LPCSTR...
в функции прописываешь 1 аргумент ""=пустой, второй- "имяПроцесса" (1 аргумент- тип окна может быть к примеру D3D Window, второй- имя процесса)
как юзать:
создаешь переменную (в идеале типа HWND но в C# е нету - аналог IntPtr)
IntPtr wnd;
wnd = FindWindow("", "windowName");
//теперь проверяем есть ли процесс
if(wnd)
{
//код Hook'а
}

все это помещаешь в таймер и ставишь интервал эдак 100мсек (раза 4 в секунду)
//возможно есть и лучше варианты рассказал что знаю.... /facepalm
//все это если что надо помещать к примеру в обработчике change чекБокса

anime-kawai
01.02.2011, 21:05
VolniyStalker, спс буду пытатся

Bagernyi
03.02.2011, 19:19
А можете написать гайд?
"как создавать трейнер для DMA игр....очень нужно)

VolniyStalker
03.02.2011, 22:12
А можете написать гайд?
"как создавать трейнер для DMA игр....очень нужно)

во первых вариант создать цикл в котором адрес будет увеличиваться на 1 и по этому адресу будет читаться буффер, далее буффер сравнивается с искомым значением и если значения совпали то добавить скажем адрес в массив и копать дальше пока адрес не достигнет максимального установленного тобой значения... потом создать цикл который будет менять по адрессам из массива значения на нужные тебе....
___
плюс в DMA играх должны быть указатели адреса которых всегда одинаковы, или указатели на указатели и тд. Т.е. надо прочитать этот указатель, прочитать адрес, на который ссылается указатель, проверить значение заменить значение
___
если что не так говорю - строго не суди

*Rakim*
20.02.2011, 22:34
А для этого подойдёт С++ Builder ???

link2142(2)
21.02.2011, 13:05
А для этого подойдёт С++ Builder ???
а название темы тебе лень прочесть пишем тренер на с#
а не С++

( синтаксис немного отличается )

*Rakim*
22.02.2011, 02:51
Киньте плиз сылку на установленную С# только на установленну оч прошу

☣Antibiotik☣
22.02.2011, 08:51
У меня вот это выдаёт хотя игра запущина [Ссылки могут видеть только зарегистрированные и активированные пользователи]

OnSidePB
06.03.2011, 15:18
а почему я максимум могу взломать 255 ??

xxxPixelxxx
07.03.2011, 21:21
а почему я максимум могу взломать 255 ??

Потому что шестнадцати-ричная система счисление, максимальное значение 255=FF

Добавлено через 16 часов 57 минут
Как сделать заморозку?

Добавлено через 21 час 2 минуты
Изменение значение на число больше чем 255
Меняем

VAM.WriteByte((IntPtr)0x01005194, byte.Parse(textBox1.Text.ToString()));


на


VAM.WriteULong((IntPtr)0x01005194, ulong.Parse(textBox1.Text.ToString()));

ZaNGiF
15.03.2011, 19:33
а как сделать, чтобы при нажатии на кнопку выполнялась консольная команда игры?

pashtet232
09.04.2011, 21:34
Большего гона я еще не видел. Я встречал самые безумные идеи куда пытались присобачить C#, но писать на Managed языке софт который будет управлять UnManaged Memory и писать туда это полный бред. И если уж нато пошло то адресация в памяти меняется не от платформе к платформе, а от запуска к запуску. Основная задача тренера не записать в память, а по косвенным признакам точно определить в какое место в памяти писать. А реклама библиотеки обертки поверх неуправляемого кода это не гайд по тому как сделать свой тренер это просто не самая удачная попытка порисоваться. Все нужно делать теми инструментами которые для этого предназначены.

metalin
06.05.2011, 16:17
как мне изменить этот код чтобы он менял на нужное мне знаение
VAM.WriteByte((IntPtr)0x046DF5F8, byte.Parse(156 ))

moony80
10.05.2011, 09:17
спасибо ))))))))))))

rocket-ua
30.05.2011, 19:23
а ссылку на исходники можно?
может я где-то провтыкал и уже ответ на мой вопрос был...

ятру2
22.01.2012, 08:31
подскажите в чём может быть проблема
при попытки создать Тренер на деньги пишет
"Значение было недопустимо малым или недопустимо большим для беззнакового байта."

весь код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
VAMemory VAM;
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button1_Click(object sender, EventArgs e)
{
VAM = new VAMemory("game");
label2.Text = (Convert.ToString(VAM.ReadByte((IntPtr)0x00CA2E6C) ));
}

private void button2_Click(object sender, EventArgs e)
{
VAM = new VAMemory("game");
VAM.WriteByte((IntPtr)0x00CA2E6C, byte.Parse(textBox1.Text.ToString()));
}
}
}

ZxCL_xak
25.01.2012, 15:05
Извините , но как найти число , которое с каждым запуском меняет свой оффсет?

Pahafl
25.01.2012, 18:22
подскажите в чём может быть проблема
при попытки создать Тренер на деньги пишет
"Значение было недопустимо малым или недопустимо большим для беззнакового байта."

весь код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
VAMemory VAM;
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void button1_Click(object sender, EventArgs e)
{
VAM = new VAMemory("game");
label2.Text = (Convert.ToString(VAM.ReadByte((IntPtr)0x00CA2E6C) ));
}

private void button2_Click(object sender, EventArgs e)
{
VAM = new VAMemory("game");
VAM.WriteByte((IntPtr)0x00CA2E6C, byte.Parse(textBox1.Text.ToString()));
}
}
}

Нужно изменить VAM.WriteByte((IntPtr)0x00CA2E6C, byte.Parse(textBox1.Text.ToString())); на VAM.WriteULong((IntPtr)0x00CA2E6C, ulong.Parse(textBox1.Text.ToString()));

саня питерский
25.01.2012, 19:21
вот у меня офсет на кроссфаер (0x21A2) как мне и че сним делать на с# я пробывал по аналогии сапера ни че не получается одни ошибки ( кто поможет? а вот начальный офсет 0x2244 это перезарядка

coffee2
11.03.2012, 17:31
Подскажите как сделать
1. Как замораживать значение , в моей игре оно сразу меняется на исходное
и
2.Как сделать так я читаю адрес с помощью ReadLong получаю значение
и мне надо найти в процессе все адреса со значением и поменять на мое.

VeTaL_UA
11.03.2012, 21:35
Как замораживать значение , в моей игре оно сразу меняется на исходное
Писать в значение циклом. Именно так сделано в Cheat Engine. А лучше, конечно, найти функцию, которая пишет в этот адрес, в памяти и изменить её "под себя".

coffee2
11.03.2012, 21:53
Писать в значение циклом. Именно так сделано в Cheat Engine. А лучше, конечно, найти функцию, которая пишет в этот адрес, в памяти и изменить её "под себя".

Циклом сделал но это немного не то что надо.
Еще такой вопрос
в Cheat Engine нашел 10 адресов с нужным мне значением
9 адресов серого цвета а 1 зеленого так вот вопрос в том почему я могу прочитать или записать значение только в адрес зеленого цвета со стальными серыми адресам работать библиотека не хочет программа вылетает с критом. А в Cheat Engine все значения адресов правятся на ура

Adspros
19.03.2012, 11:11
как изменить этот код чтобы он менял на нужное мне значение
То есть одной кнопкой например на 20

ashipko
26.03.2012, 22:24
Сабж , а можно ли использовать этот метод к браузерной игре (большинство действий осуществляются на стороне ПК )

Nickitee
27.03.2012, 10:57
вот у меня офсет на кроссфаер (0x21A2) как мне и че сним делать на с# я пробывал по аналогии сапера ни че не получается одни ошибки ( кто поможет? а вот начальный офсет 0x2244 это перезарядка
И что, что у тебя есть оффсет?
Как минимум нужно прибавить бейсадресс+твойоффсет, или (бейсадресс+адрес структуры) +твойоффсет.

vovik147
07.04.2012, 01:56
Почему в textBox нельзя ввести значение больше 250 ? И как это исправить?

Nickitee
07.04.2012, 18:23
Почему в textBox нельзя ввести значение больше 250 ? И как это исправить?
Потому что byte (0-255,0x00-0xFF)
юзай

WriteULong

NexusBlackHeart
24.04.2012, 13:34
Как получить и изменить значение я понял. А как его заморозить с помощью checkBox и т.д.?
И что делать если адрес значения меняется?
Заранее спасибо.

VeTaL_UA
24.04.2012, 16:33
А как его заморозить с помощью checkBox и т.д.?
Всем известный Cheat Engine делает это с помощью цикла, который постоянно пишет в адрес "замороженное" значение.
И что делать если адрес значения меняется?
Если я правильно понял вопрос, то тебе нужно из адреса сделать цепочку оффсетов, по которым ты будешь всегда добираться до правильного адреса.

саня питерский
24.04.2012, 19:51
может кто нибудь подскажет как создать трейнер с динамическим адрессом ??? поинтеры и смещения у меня есть, а как их прописать не знаю...

Maxsimus+
02.05.2012, 19:15
Это работает только на DMA играх?

Nickitee
02.05.2012, 19:20
может кто нибудь подскажет как создать трейнер с динамическим адрессом ??? поинтеры и смещения у меня есть, а как их прописать не знаю...
Конечный адрес = бейс адрес + адрес/смещение. Ну цепочка может продолжатся.
прим.

int base = 0x000001;
int adres1 = 0x000002;
int finishadres1 = base+=adres1;

Anоnymоus
07.05.2012, 22:55
Cheat Engine (для поиска оффсетов).
Как оффсеты искать то е?

VeTaL_UA
08.05.2012, 13:52
Как оффсеты искать то е?
Прочитайте темы в разделе разработки для игры Perfect World. Там всё описано более чем подробно :)

gastraler
15.05.2012, 11:02
может кто нибудь подскажет как создать трейнер с динамическим адрессом ??? поинтеры и смещения у меня есть, а как их прописать не знаю...

ProcessModule myProcessModule = null; //
IntPtr MemoryAddress = IntPtr.Zero; // вводишь базовый адрес модуля
if (myProcess.Length > 0) //
{
ProcessModuleCollection myProcessModuleCollection;
try
{
myProcessModuleCollection = myProcess[0].Modules;
}
catch
{
return;
}
for (int i = 0; i < myProcessModuleCollection.Count; i++)
{
myProcessModule = myProcessModuleCollection[i];
if (myProcessModule.ModuleName.Contains("hw.dll"))
{
MemoryAddress = (myProcessModule.BaseAddress + 0x7BBD9C);
break;
}
}
}

Более подробно тут: [Ссылки могут видеть только зарегистрированные и активированные пользователи] 1%82%D1%8C%D1%81%D1%8F-%D0%BA-%D0%B1%D0%B0%D0%B7%D0%BE%D0%B2%D0%BE%D0%BC%D1%83-%D0%B0%D0%B4%D1%80%D0%B5%D1%81%D1%83/#entry8936

НitBit
18.05.2012, 14:32
почему C# мой ругается на DllImport?
Сама ошибка:
Атрибут DllImport должен быть указан для метода, который помечен как "static" и "extern"
вот код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Threading;

namespace WindowsFormsApplication9
{
public partial class Form1 : Form

{



[DllImport("user32.dll",CharSet=CharSet.Auto)]
public extern IntPtr FindWindow(string windowtype, string windowname);
VAMemory VAM;
public Form1()
{

InitializeComponent();
}



private void button2_Click(object sender, EventArgs e)
{
IntPtr wnd;
wnd = FindWindow("", "windowName");
if (Convert.ToBoolean(wnd))
{
VAM = new VAMemory("ElementClient");
VAM.WriteByte((IntPtr)0x00A57F3C, 1);
}
else
{
label2.Text = "Нету проги";
}
}





}
}

cthulhu217
18.05.2012, 22:10
public extern IntPtr FindWindow(string windowtype, string windowname);
Вот этот метод должен быть статическим.
То есть должен выглядеть так:
public static extern IntPtr FindWindow(string windowtype, string windowname);

НitBit
19.05.2012, 14:23
вот почти правильный код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Threading;

namespace WindowsFormsApplication9
{
public partial class Form1 : Form

{



[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern Boolean FindWindow(string windowtype, string windowname);
VAMemory Vam;
public Form1()
{

InitializeComponent();
}



private void button2_Click(object sender, EventArgs e)
{
Boolean wnd;

wnd = FindWindow("", "ElementClient");


if (!wnd)
{
Vam = new VAMemory("ElementClient");
Vam.WriteByte((IntPtr)0x00A57F3C, 1);
}
}


}
}

XRASER
03.07.2012, 17:07
У меня тип данных: Text
И нужно переходить в память по адресам: FDA4782D, FDA4783D, FDA4784D, FDA4785D, FDA4786D и изменять их hex код.
Такое возможно?

Yukikaze
03.07.2012, 21:05
XRASER, предположим что я понял о чем речь, и собственно даже понял, что такое хекс код /facepalm
byte[] buffer = Encoding.ASCII.GetBytes(text);
IntPtr writen;
WriteProcessMemory(pHandle, (IntPtr)0xFDA4782D, buffer, (uint)buffer.Length, out writen);
Зависит от кодировки, может придется инвертировать буфер

Gogi_2012
07.08.2012, 23:37
Можно ли использовать этот способ для flash игр ? В игре почти все действий идут на стороне клиента .

LetsKaktus
06.09.2012, 14:37
Так, трейнер у меня сделать получилось, но при перезаходе в игру значение меняется. Что с этим делать?

Nickitee
06.09.2012, 21:47
Так, трейнер у меня сделать получилось, но при перезаходе в игру значение меняется. Что с этим делать?
Это проделки DMA.
(Dynamic Memory Allocation)