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

Иньекция своего кода на VC#


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

Все таки узнал как внедрить свой код с помощью c# спасибо тем кто помог разобраться с кодом.

Создаем новое приложение WinForms. Добавляем кнопку.

Добавляем имена (Смотрите подключаем имена), и под класс формы добавим

 Inject Mem = new Inject();

Так:


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;

namespace // имя формы
{
public partial class Form1 : Form
{

Inject Mem = new Inject();
public Form1()
{
InitializeComponent();
}

Добавляем класс по имени ingect.

Подключаем имена:


using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;

Начало класса:


class Inject
{

protected Process[] Proc;
protected bool iActive;
protected List<IntPtr> Cave = new List<IntPtr>();

Обработка процесса:


public void GetProc(string Process_Name)
{
if (!iActive)
{
Proc = Process.GetProcessesByName(Process_Name.Replace(".exe", ""));
iActive = Proc.Length != 0;
}
try
{iActive = !Proc[0].HasExited;}
catch{iActive = false;}
if (!iActive) MessageBox.Show("Process Not Found!", "Get Process");
}

Api:


[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flAllocationType, uint flProtect);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
private static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, byte dwSize, uint dwFreeType);

[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesRead);

[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesWritten);

Чтение и Запись.


private byte[] rBytes(int iAddress, int iSize)
{
byte[] buff = new byte[iSize];
if (iActive)
ReadProcessMemory(Proc[0].Handle, (IntPtr)iAddress, buff, iSize, 0);
return buff;
}

private void wBytes(int iAddress, byte[] pBytes)
{
if (iActive)
WriteProcessMemory(Proc[0].Handle, (IntPtr)iAddress, pBytes, pBytes.Length, 0);
}

public byte ReadByte(int iAddress)
{
byte[] buff = new byte[1];
if (iActive)
ReadProcessMemory(Proc[0].Handle, (IntPtr)iAddress, buff, 1, 0);
return buff[0];
}

выделяем новое память:


IntPtr Allocate(IntPtr Addy)
{
if (iActive)
{
if (RetCave(Addy) == IntPtr.Zero)// Проверка, если адрес был введен.Чтобы не создавать другой Cave.
{
IntPtr iCave = VirtualAllocEx(Proc[0].Handle, IntPtr.Zero, 512, 0x1000, 0x40);// Создаем Cave
if (iCave != IntPtr.Zero)
{
Cave.Add(iCave);//If its successful, it gets added to storage.
return iCave;
}
MessageBox.Show("Unable to allocate memory.\nCode Error " + Marshal.GetLastWin32Error());
return IntPtr.Zero;
}
}
return IntPtr.Zero;
}

IntPtr RetCave(IntPtr Address)
{
for (int i = 0; i < Cave.Count; i++)
if (HPool(rBytes(Address.ToInt32() + 1, 4), BitConverter.GetBytes((int)Cave[i] - (int)Address - 5)) != -1)
return Cave[i];
return IntPtr.Zero;
}

static int HPool(byte[] SearchIn, byte[] SearchFor)
{// Поиск массив для значения и возвращает индекс
int[] sBytes = new int[256]; int Pool = 0;
int End = SearchFor.Length - 1;
for (int i = 0; i < 256; i = i + 1)
sBytes[i] = SearchFor.Length;
for (int i = 0; i < End; i = i + 1)
sBytes[SearchFor[i]] = End - i;
while (Pool <= SearchIn.Length - SearchFor.Length)
{
for (int i = End; SearchIn[Pool + i] == SearchFor[i]; i = i - 1)
if (i == 0) return Pool;
Pool += sBytes[SearchIn[Pool + End]];
}
return -1;
}

Освобождаем выделенн.. память:


private void DeAllocate(IntPtr Addy, string Instruction)
{
if (iActive)
{
IntPtr iCave = RetCave(Addy);
byte[] pBytes = HX2Bts(Instruction);
if (iCave != IntPtr.Zero)
{
wBytes((int)Addy, pBytes);
Cave.Remove(iCave);
if (!VirtualFreeEx(Proc[0].Handle, iCave, 0, 0x8000))
MessageBox.Show("Unable to deallocate memory.\r\nCode Error " + Marshal.GetLastWin32Error());
return;
}
if (ReadByte(Addy.ToInt32()) == 0xe9 | ReadByte(Addy.ToInt32()) == 0xc3)
{
wBytes((int)Addy, pBytes);
return;
}
MessageBox.Show("Integrity Check not passed. Your game version might be different.\r\nNothing was written to avoid a crash", "Errorz");
}
}

Возвращает модуль + смещение:



int Module(string Name)
{
if (iActive)
{
int iOffset;
string[] S = Name.Replace("+", " ").Split(' ');
try
{
iOffset = int.Parse(S[1], NumberStyles.AllowHexSpecifier);
}
catch { return 0; }
ProcessModuleCollection ProcMod = Proc[0].Modules;
CompareInfo Case = CultureInfo.CurrentCulture.CompareInfo;
for (int i = 0; i < ProcMod.Count; i++)
if (Case.IndexOf(ProcMod[i].FileName, S[0], CompareOptions.IgnoreCase) != -1)
return ProcMod[i].BaseAddress.ToInt32() + iOffset;
}
return 0;
}

string Jmp_Call(IntPtr iCave, int JumpFrom, int iNext, bool JC)
{// Возвращает байт при прыжке / Вызов Cave из исходного местоположения.
string Ins = GetIns(BitConverter.GetBytes(iCave.ToInt32() - JumpFrom - 5));
for (int i = 5; i < iNext - JumpFrom; i++)
Ins += "90";
return JC ? "E9" + Ins : "E8" + Ins;
}

string GetIns(byte[] BTS)
{// Преобразует инструкции в шестнадцатеричную строку
string Temp = string.Empty;
for (int i = 0; i < BTS.Length; i++)
Temp += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(BTS[i]));
return Temp;
}

string Ret_Jmp(int Cave, int NextInstruc, bool JC)
{// Возвращает байт при прыжке, возвращение обратно из cave на следующую инструкцию
return JC ? "E9" + GetIns(BitConverter.GetBytes(NextInstruc - Cave - 5)) : "C3";
}

private static byte[] HX2Bts(string hexString)
{
hexString = System.Text.RegularExpressions.Regex.Replace(hexString, "[^a-fA-F0-9]", "");
int length = hexString.Length / 2;
byte[] buf = new byte[length];
for (int i = 0; i < length; i++)
buf[i] = byte.Parse(hexString.Substring(i * 2, 2), NumberStyles.HexNumber);
return buf;
}

public bool Integrity(int iAddress, string iBytes)
{
return HPool(rBytes(iAddress, iBytes.Length / 2), HX2Bts(iBytes)) != -1;
}

Инекция кода:


public void Patch(int Address, string CodeInjection, string Default_Bts)
{
if (iActive)
{
if (!Integrity(Address, CodeInjection) && !Integrity(Address, Default_Bts))
{
MessageBox.Show("Integrity Check not passed. Your game version might be different.\r\nNothing was written to avoid a crash", "Errorz");
return;
}
byte[] pBytes = Integrity(Address, Default_Bts) ? HX2Bts(CodeInjection) : HX2Bts(Default_Bts);
wBytes(Address, pBytes);
}
}

public void Patch(string Name_Offset, string CodeInjection, string Default_Bts)
{
if (iActive)
{
int iAddy = Module(Name_Offset);
if (iAddy != 0)
{
if (!Integrity(iAddy, CodeInjection) && !Integrity(iAddy, Default_Bts))
{
MessageBox.Show("Integrity Check not passed. Your game version might be different.\r\nNothing was written to avoid a crash", "Errorz");
return;
}
byte[] pBytes = Integrity(iAddy, Default_Bts) ? HX2Bts(CodeInjection) : HX2Bts(Default_Bts);
wBytes(iAddy, pBytes);
return;
}
MessageBox.Show("Module not found. Check the spelling", "Errorz");
}
}

public void Inject_Jmp(string Name_Offset, string CodeInjection, string Default_Bytes)
{
int iAddy = Module(Name_Offset);
if (iAddy != 0)
{
int iLength = Default_Bytes.Length / 2;
Write_Cave((IntPtr)iAddy, (IntPtr)(iAddy + iLength), CodeInjection, Default_Bytes, true);
return;
}
MessageBox.Show("Module not found. Check the spelling", "Errorz");
}

public void Inject_Jmp(int JumpFrom, string CodeInjection, string Default_Bytes)
{
int iLength = Default_Bytes.Length / 2;
Write_Cave((IntPtr)JumpFrom, (IntPtr)(JumpFrom + iLength), CodeInjection, Default_Bytes, true);
}

public void Inject_Call(string Name_Offset, string CodeInjection, string Default_Bytes)
{
int iAddy = Module(Name_Offset);
if (iAddy != 0)
{
int iLength = Default_Bytes.Length / 2;
Write_Cave((IntPtr)iAddy, (IntPtr)(iAddy + iLength), CodeInjection, Default_Bytes, false);
return;
}
MessageBox.Show("Module not found. Check the spelling", "Errorz");
}

public void Inject_Call(int JumpFrom, string CodeInjection, string Default_Bytes)
{
int iLength = Default_Bytes.Length / 2;
Write_Cave((IntPtr)JumpFrom, (IntPtr)(JumpFrom + iLength), CodeInjection, Default_Bytes, false);
}

private void Write_Cave(IntPtr iFrom, IntPtr iNext, string Code, string D_Bs, bool JC)
{
if (iActive)
{
IntPtr iCave = Integrity((int)iFrom, D_Bs) ? Allocate(iFrom) : IntPtr.Zero;
if (iCave != IntPtr.Zero)
{
byte[] Inj = JC ? HX2Bts(Code + Ret_Jmp(iCave.ToInt32() + HX2Bts(Code).Length, iNext.ToInt32(), JC)) : HX2Bts(Code + "C3");
wBytes((int)iCave, Inj);
byte[] Org = HX2Bts(Jmp_Call(iCave, iFrom.ToInt32(), iNext.ToInt32(), JC));
wBytes((int)iFrom, Org);
return;
}
DeAllocate(iFrom, D_Bs);
}
}

Теперь все ключи у нас есть к бою.

Запускаем СЕ я выбрал игрушку Вампиры против Зомби.

Находим адрес денег, далее Точка Останова на Доступ, получаем инструкцию.

cmp dword ptr [esi+24],0A

Далее переходим в отладчик СЕ по этому адресу, смотрим.

рис1. post-1568-1324523318,14_thumb.jpg

Пишем скрипт по этому адресу:


[ENABLE]
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem:
mov [esi+24],(int)999999

originalcode:
cmp dword ptr [esi+24],0A
jnge 0041C6E9

exit:
jmp returnhere

"VampiresVSZombies.exe"+1C6D4:
jmp newmem
nop
returnhere:

[DISABLE]
"VampiresVSZombies.exe"+1C6D4:
cmp dword ptr [esi+24],0A
jnge 0041C6E9
dealloc(newmem)
//Alt: db 83 7E 24 0A 7C 0F

Сохраняем скрипт, смотрим в рис1 до включение скрипта, байты начиная с 83 до 0F сохраняем.

837E240A7C0F

это у нас де-активация кода.

Включаем скрипт далее переходим в новую память рис2

рис2.post-1568-1324524128,39_thumb.jpg

Смотрим.

рис3post-1568-1324524168,24_thumb.jpg

Тут будем брать байты до прыжка до jmp 0041C6DA начиная с С7 до FE. смотрим рис3.

C746243F420F00837E240A0F8CD8C695FE

это у нас Активация кода

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


Mem.GetProc("VampiresVSZombies"); //имя процесса
Mem.Inject_Jmp(0x41C6D4, "C746243F420F00837E240A0F8CD8C695FE", "837E240A7C0F"); //Активация и деактивация смотрите ри2,3
//0x00416CD4 адрес инструкции

Теперь запускаем приложение нажимаем на кнопку получаем результат как на рис2,3 и естественно получаем бесконеч.. деньги.

Чтоб поставить хоткей к кнопке в свойстве кнопки переходим в События (значок молния) там находим KeyDown два раза кликаем и пишем код.


if (e.KeyCode == Keys.F1)
{
Mem.GetProc("VampiresVSZombies");
Mem.Inject_Jmp(0x41C6D4, "C746243F420F00837E240A0F8CD8C695FE", "837E240A7C0F");
}

Теперь нажимаем F1 активация и повторное нажатие деактивация.

Исходный код:inject code.rar

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

Круто! icon_e_biggrin.gif

Можешь, кстати, чуть подробнее написать, почему мы берём не всю цепочку байт для инъекции - вдруг кому непонятно.

PS: Очень рекомендую скачать и поставить чудо-прогу под названием Resharper (если ещё нету) - сильно поможет писать код лучше\быстрее. laugh.gif

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

А нам лишние не нужны, через прог СЕ нам стало известно что брать а что нет, при включение скрипта на СЕ и отключение и после освобождение код кейва.

Нам знакомо писать скрипт на СЕ там пишем новое условие и восстанавливаем при деактивации, орг. инструкции. такой же принцип

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

Еще один момент: перед затиранием оригинальной инструкции прыжком на инъекцию, желательно (или, можно сказать, почти обязательно) снять защиту со страницы памяти функцией VirtualProtectEx, а после записи ею же восстановить защиту. Попадалось мне немало игр, которые вылетали, если пытаться писать без снятия защиты.

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

  • 4 месяца спустя...

Нормально, а вот это

Добавляем класс по имени ingect.

Подключаем имена:

using System.Windows.Forms;

using System.Diagnostics;

using System.Runtime.InteropServices;

using System.Globalization;

Начало класса:

class Inject

{

protected Process[] Proc;

protected bool iActive;

protected List<IntPtr> Cave = new List<IntPtr>();

Обработка процесса:

public void GetProc(string Process_Name)

{

if (!iActive)

{

Proc = Process.GetProcessesByName(Process_Name.Replace(".exe", ""));

iActive = Proc.Length != 0;

}

try

{iActive = !Proc[0].HasExited;}

catch{iActive = false;}

if (!iActive) MessageBox.Show("Process Not Found!", "Get Process");

}

Api:

[DllImport("kernel32.dll", SetLastError = true)]

public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flAllocationType, uint flProtect);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]

private static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, byte dwSize, uint dwFreeType);

[DllImport("kernel32.dll")]

public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesRead);

[DllImport("kernel32.dll")]

public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesWritten);

Чтение и Запись.

private byte[] rBytes(int iAddress, int iSize)

{

byte[] buff = new byte[iSize];

if (iActive)

ReadProcessMemory(Proc[0].Handle, (IntPtr)iAddress, buff, iSize, 0);

return buff;

}

private void wBytes(int iAddress, byte[] pBytes)

{

if (iActive)

WriteProcessMemory(Proc[0].Handle, (IntPtr)iAddress, pBytes, pBytes.Length, 0);

}

public byte ReadByte(int iAddress)

{

byte[] buff = new byte[1];

if (iActive)

ReadProcessMemory(Proc[0].Handle, (IntPtr)iAddress, buff, 1, 0);

return buff[0];

}

выделяем новое память:

Скрытый текст

Освобождаем выделенн.. память:

Скрытый текст

Скрытый текст

Инекция кода:

Скрытый текст

Один раз добавить в класс inject и всё? Можно делать сколько влезет функций????

Я имею ввиду #Region "Allocate"

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

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

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

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