Ещё один небольшой, но ответственный и важный шажок в создании трейнера - работа с указателями. В [видео] кратко пересказана суть этого явления, а так же живой пример вместе с пошаговой отладкой в OllyDbg. Смотрим, задаём вопросы. Извините, что сбиваюсь - хотелось спать. :)
Полный исходный код трейнера (жирным синим шрифтом - новое) из этого урока на Flat Assembler:
PS: Как вы уже могли догадаться, квадратные скобки означают содержимое переменной, а их отсутствие - адрес этой переменной. :)
Полный исходный код трейнера (жирным синим шрифтом - новое) из этого урока на Flat Assembler:
format PE GUI 4.0;Необходимо для вызова процедуры чтения указателя через invoke
entry start
include 'c:\fasm\include\win32a.inc'
section '.data' data readable writable
error_message db 'Error! :(',0
caption db 'Fasm Trainer',0
pid dd 0
Poke dd _Poke
ReadPointer dd _ReadPointer
windowcap db 'Minesweeper',0
addr dd 0x004256BF
godmode_on db 0x90,0x90,0x90,0x90,0x90,0x90
godmode_off db 0xD9,0x9F,0xC4,0xE5,0x48,0x00
;Новые переменные
;Базовый адрес указателя
pointer_base dd 0xFFD9AA38
buffer dd ? ;Буфер для чтения байт из памяти
phandle dd ? ;Переменная для хранения хэндла процесса
section '.text' code readable executable
start:
invoke GetModuleHandle,0
invoke DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
invoke ExitProcess,0
proc DialogProc hwnddlg,msg,wparam,lparam
cmp [msg],WM_CLOSE
je .wmclose
cmp [msg],WM_COMMAND
je .wmcommand
cmp [msg],WM_LBUTTONDOWN
je .move
cmp [msg],WM_INITDIALOG
je .init
cmp [msg],WM_TIMER
je .timer
xor eax,eax
jmp .finish
.wmcommand:
cmp [wparam],BN_CLICKED shl 16 + 1
je .poke
cmp [wparam],BN_CLICKED shl 16 + 2
je .wmclose
.poke:
invoke Poke,[addr],godmode_on,6
jmp .finish
.wmclose:
;invoke Poke,[addr],godmode_off,6
invoke EndDialog,[hwnddlg],0
.move:
invoke SendMessage,[hwnddlg],WM_NCLBUTTONDOWN,2,0
ret
.init:
invoke SetTimer,[hwnddlg],0,100,0
ret
.timer:
invoke GetAsyncKeyState,VK_F11
cmp eax,0
je .finish
invoke ReadPointer,[pointer_base] ;Читаем указатель
.finish:
ret
endp
proc _Poke,memadd,memval,bytes
invoke FindWindow, 0, windowcap
cmp eax,0
je .error
invoke GetWindowThreadProcessId,eax,pid
cmp [pid],0
je .error
invoke OpenProcess,PROCESS_ALL_ACCESS,0,[pid]
cmp eax,0
je .error
invoke WriteProcessMemory,eax,[memadd],[memval],[bytes],0
cmp eax,0
je .error
ret
.error:
invoke MessageBox,HWND_DESKTOP,error_message,caption,MB_OK
ret
endp
proc _ReadPointer,address ;Процедура чтения указателя
invoke FindWindow,0,windowcap
cmp eax,0
je .error
invoke GetWindowThreadProcessId,eax,pid
cmp [pid],0
je .error
invoke OpenProcess,PROCESS_ALL_ACCESS,0,[pid];Сохраняем хэндл процесса после его открытия
cmp eax,0 mov [phandle],eax
je .error;Читаем содержимое базового адреса указателя в буфер
invoke ReadProcessMemory,[phandle],[address],buffer,4,0
cmp eax,0
je .error;Прибавляем к содержимому буфера первое смещение
add [buffer],0x18;Читаем полученный адрес
invoke ReadProcessMemory,[phandle],[buffer],buffer,4,0
cmp eax,0
je .error;Прибавляем второе смещение
add [buffer],0x20;Читаем полученный адрес
invoke ReadProcessMemory,[phandle],[buffer],buffer,4,0
cmp eax,0
je .error
ret
.error:
invoke MessageBox,HWND_DESKTOP,error_message,caption,MB_OK
ret
endp
section '.idata' import data readable writeable;Объявляем новую функцию для работы с ней
library kernel,'kernel32.DLL',\
user,'user32.DLL'
import kernel,\
GetModuleHandle,'GetModuleHandleA',\
ExitProcess,'ExitProcess',\
OpenProcess,'OpenProcess',\
WriteProcessMemory,'WriteProcessMemory',\
ReadProcessMemory,'ReadProcessMemory'
import user,\
DialogBoxParam,'DialogBoxParamA',\
EndDialog,'EndDialog',\
MessageBox,'MessageBoxA',\
FindWindow,'FindWindowA',\
GetWindowThreadProcessId,'GetWindowThreadProcessId',\
SendMessage,'SendMessageA',\
SetTimer,'SetTimer',\
GetAsyncKeyState,'GetAsyncKeyState'
section '.rsrc' resource data readable
directory RT_DIALOG,dialogs
resource dialogs,37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration
dialog demonstration,'Crimsonland +1 trainer by keng',70,70,190,175,WS_POPUP
dialogitem 'STATIC','Press OK for toggle godmone on. Visit me at: www.gamehacklab.ru',-1,0,0,163,188,SS_LEFT + WS_VISIBLE+ SS_CENTER
dialogitem 'BUTTON','OK',1,85,150,45,15,WS_VISIBLE
dialogitem 'BUTTON','Cancel',2,135,150,45,15,WS_VISIBLE
enddialog
PS: Как вы уже могли догадаться, квадратные скобки означают содержимое переменной, а их отсутствие - адрес этой переменной. :)
Комментариев нет:
Отправить комментарий
Не люблю мат и низкий уровень грамотности. Чем конкретнее поставите свой вопрос и чем лучше он будет выглядеть - тем большая вероятность на мой ответ. :)