Нужна ваша помощь боле опытные кодеры ...
хочу выделить блок памяти что бы внедрить свой код (тк как делает СЕ)
Пишу на Delphi вот сам код :
Код:
begin
WindowName := FindWindow(nil,'Tomb Raider');
If WindowName = 0 then
begin
MessageDlg('Игра должна быть запущена до трейнера', mtwarning,[mbOK],0);
Exit;
end;
ThreadId := GetWindowThreadProcessId(WindowName,@pid);
proces := OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
ptr := VirtualAllocEx(proces, nil, 2049, MEM_RESERVE, PAGE_READONLY);
// Поч не работает ?
// И как вернуть адрес созданного блока памяти
end;
Что у тебя не работает? У тебя адрес в переменную ptr функция возвращает. Лучше её конечно обозвать просто как p, потому что ptr в delphi - это название функции преобразования значения в указатель.
Тебе вывести надо или что? Или возвращает Nil? Если вывести - то:
var:
s: string;
begin
s := IntToHex(DWord(ptr), 8);
ShowMessage(s);
end;
Добавлено через 2 минуты
MEM_RESERVE, PAGE_READONLY
Атрибуты тоже неверные. Вместо MEM RESERVE советую MEM_COMMIT. А насчет PAGE_READONLY - ты же туда потом писать будешь, так почему READONLY? PAGE_EXECUTE_READWRITE надо!!
Если копируешь откуда-то код - то хотя бы гугли описание функций:
Что у тебя не работает? У тебя адрес в переменную ptr функция возвращает. Лучше её конечно обозвать просто как p, потому что ptr в delphi - это название функции преобразования значения в указатель.
Тебе вывести надо или что? Или возвращает Nil? Если вывести - то:
var:
s: string;
begin
s := IntToHex(DWord(ptr), 8);
ShowMessage(s);
end;
Добавлено через 2 минуты
MEM_RESERVE, PAGE_READONLY
Атрибуты тоже неверные. Вместо MEM RESERVE советую MEM_COMMIT. А насчет PAGE_READONLY - ты же туда потом писать будешь, так почему READONLY? PAGE_EXECUTE_READWRITE надо!!
Если копируешь откуда-то код - то хотя бы гугли описание функций:
И Правда большое спасибо что указал на ошибки
кому интересно вот хоть и сырой ну робочий код :
Код:
begin
WindowName := FindWindow(nil,'Form1');
If WindowName = 0 then
begin
MessageDlg('Игра должна быть запущена до трейнера', mtwarning,[mbOK],0);
Exit;
end;
ThreadId := GetWindowThreadProcessId(WindowName,@pid);
proces := OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
pd := VirtualAllocEx(proces, nil, 2049, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
s := IntToHex(DWord(pd), 8);
ShowMessage(s);
end;
Добавлено через 1 час 25 минут
Блок памяти создается отлично только вот столкнулся с проблемой
Не могу понять как создать jmp на нужный мне адрес (в моем случаи это адрес с переменной pd) + если взять байты (код) с СЕ скрипта конечный jmp который должен нас вернуть на основной участок кода не возвращает нас на нужный адрес
Код:
begin
WindowName := FindWindow(nil,'Plants vs. Zombies');
If WindowName = 0 then
begin
MessageDlg('Игра должна быть запущена до трейнера.', mtwarning,[mbOK],0);
Exit;
end;
ThreadId := GetWindowThreadProcessId(WindowName,@pid);
proces := OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
pd := VirtualAllocEx(proces,nil, 2048, MEM_COMMIT,PAGE_EXECUTE_READWRITE);
s := IntToHex(DWord(pd), 8);
GWrite(pid,pd,'C7 47 24 99 99 09 00 83 47 24 01 8B 47 24 E9 50 B3 2C',0);
Edit1.Text:= s;//Выводим адресс
//VirtualFreeEx(proces, pd, 2048,MEM_DECOMMIT);
end;
Чернетка :
Код:
Plants vs zombies v
Растения без перезарядки : 83 ?? ?? 01 8B ?? ?? ?? ?? ?? ?? ?? C7 ?? ?? ?? ?? ?? ?? C6 ?? ?? ?? C6 ?? ?? ?? ??
Protect : Execute/Read only
Adress Start Jump : game.exe+8B35C [0048B35C] - E9 9F 4C D3 FF 90 90 - jmp 001C0000
0048B35C - 83 47 24 01 - add dword ptr [edi+24],01
0048B360 - 8B 47 24 - mov eax,[edi+24]
0048B363 - 3B 47 28 - cmp eax,[edi+28]
0048B366 - 7E 14 - jle 0048B37C
0048B368 - C7 47 24 00 00 00 00 - mov [edi+24],00000000
End Jump : PD
mod.bytes : C7 47 24 99 99 09 00 83 47 24 01 8B 47 24 E9 50 B3 2C
001C0000 - C7 47 24 99 99 09 00 - mov [edi+24],00099999 : [00000000]
001C0007 - 83 47 24 01 - add dword ptr [edi+24],01
001C000B - 8B 47 24 - mov eax,[edi+24]
001C000E - E9 50 B3 2C 00 - jmp game.exe+8B363 [0048B363]
СЕ - скрипт -
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)
newmem:
mov [edi+24],99999
originalcode:
add dword ptr [edi+24],01
mov eax,[edi+24]
exit:
jmp returnhere
"game.exe"+8B35C:
jmp newmem
nop
nop
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"game.exe"+8B35C:
add dword ptr [edi+24],01
mov eax,[edi+24]
//Alt: db 83 47 24 01 8B 47 24
Последний раз редактировалось dark; 25.12.2017 в 17:17.
Лень разбираться в СЕ коде. Если я правильно понимаю, тебе нужно пропатчить код игры, поставив там где-то перенаправление на твой код?
Тогда где-то так:
PHP код:
var
bBuf: byte;
dBuf: DWord;
pMem: Pointer;
OldProtect: Cardinal;
NumberOfBytesWritten: SIZE_T;
const
oldAddress: DWord = $0051040; // здесь "$0051040" - это адрес, по которому собираешься патчить
begin
pMem := Pointer(oldAddress);
if VirtualProtectEx(proces, pMem, 1024, PAGE_EXECUTE_READWRITE, OldProtect) then
begin
// jmp
bBuf := $E9;
// У WPM желательно проверять result и число записанных байт, я опустил этот момент
WriteProcessMemory(proces, pMem, @bBuf, 1, NumberOfBytesWritten);
// Расчитываем адрес для jmp
// Предполагается, что указатель PD уже получил от фукнкции VirtualAllocEx значение выделенной памяти
dBuf := DWord(pd) - oldAddress - 5;
// Восстанавливаем атрибуты защиты памяти по умолчанию
VirtualProtectEx(proces, pMem, 1024, OldProtect, OldProtect);
end else
begin
ShowMessage('Не удалось изменить защиту участка памяти :(' + #13#10 +
'Код ошибки: ' + IntToStr( GetLastError() ));
end;
end;
Не забудь потом из кода, на который перенаправляешь, вернуться назад или вернуть управление (ret) (смотря что за код ты внедряешь).
В 32-битных процессах для call и jmp адрес для вызова\прыжка высчитывается так:
address := (NewAddress - OldAddress - 5);
Вот что получается -
Решил не танцевать с бубном и пойти путем нуба и так указал адрес для создание пространства $06E80000 и туда веду запись инструкций
только вот это глупо ну для начала хватит ...
Хочу реализовать как в СЕ скрипты только мне нужно что бы создавалось пустое пространство в игре и по нужно мне адресу прописывался jump на ту пустоту дальше идут куча байт и возврат на нужный мне адрес
Код:
var
bBuf: byte;
dBuf: DWord;
pMem: Pointer;
OldProtect: Cardinal;
NumberOfBytesWritten: DWORD_PTR;
adreg:Cardinal;
const
oldAddress: DWord = $0048D90B; // здесь "$0051040" - это адрес, по которому собираешься патчить
begin
WindowName := FindWindow(nil,'Plants vs. Zombies');
ThreadId := GetWindowThreadProcessId(WindowName,@pid);
proces := OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
pd := VirtualAllocEx(proces,Ptr($06E80000), 2048, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
s := IntToHex(DWord(pd), 8);
pMem := Pointer(oldAddress);
if VirtualProtectEx(proces, pMem, 1024, PAGE_EXECUTE_READWRITE, OldProtect) then
begin
// jmp
bBuf := $E9;
// У WPM желательно проверять result и число записанных байт, я опустил этот момент
WriteProcessMemory(proces, pMem, @bBuf, 1, NumberOfBytesWritten);
// Расчитываем адрес для jmp
// Предполагается, что указатель PD уже получил от фукнкции VirtualAllocEx значение выделенной памяти
dBuf := DWord(pd) - oldAddress - 5;
WriteProcessMemory(proces, pMem, @dBuf, 4, NumberOfBytesWritten);
// Восстанавливаем атрибуты защиты памяти по умолчанию
VirtualProtectEx(proces, pMem, 1024, OldProtect, OldProtect);
end else
begin
ShowMessage('Не удалось изменить защиту участка памяти :(' + #13#10 +
'Код ошибки: ' + IntToStr( GetLastError() ));
end;
end;
Последний раз редактировалось dark; 25.12.2017 в 17:17.
тьфу, наморосил чутка. Ща через пол часика к компу вернусь - покажу где я косячнул.
Ты в VirtualAllocEx не указывай лучше адрес, он далеко не факт что таким будет, это значение как рекомендация, а винда даст память там, где сама захочет
Добавлено через 25 минут *** скрытый текст ***
Огромное тебе спасибо помог от души ))
Все прекрасно работает
Позже выложу исходник - чернетка ))
Я не оказываю услуги гаранта!
База данных кидал: blacklist.rf-cheats.ru
Обязательно проверяйте человека через чёрный список прежде чем совершать с ним сделку.
Кто то уже сталкивался в данной проблемой только на C#..
Как и обещал выкладываю чернетку.
Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 300 сообщение(ий)):
У вас нет прав чтобы видеть скрытый текст, содержащейся здесь.
Чтобы его прочитать, вы должны заработать сообщения. Как это сделать бесплатно, описано в правилах форума. Как купить доступ, описано в Платных услугах.
@Dark - Ну как быть с х64 процессах ?
Код HTML:
В 32-битных процессах для call и jmp адрес для вызова\прыжка высчитывается так:
address := (NewAddress - OldAddress - 5);
Прыжок я то создаю только вот не туда куда нужно.
Скачать Исходник
Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 300 сообщение(ий)):
У вас нет прав чтобы видеть скрытый текст, содержащейся здесь.
Чтобы его прочитать, вы должны заработать сообщения. Как это сделать бесплатно, описано в правилах форума. Как купить доступ, описано в Платных услугах.