MasterGH Опубликовано 27 марта, 2010 Поделиться Опубликовано 27 марта, 2010 Windows API (application programming interfaces) — общее наименование целого набора базовых функций интерфейсов программирования приложений операционных систем семейств Windows и Windows NT корпорации «Майкрософт». Является самым прямым способом взаимодействия приложений с Windows. Для создания программ, использующих Windows API, «Майкрософт» выпускает SDK, который называется Platform SDK и содержит документацию, набор библиотек, утилит и других инструментальных средств.Английская WinApi32: скачатьРусская справка:Краткий вариант: перейтиПолный вариант: перейтиЕщё справочник перейтиПредназначение функций сразу видно из названия, вам нужно запомнить только для чего какая функция нужна, а далее лазить только по справочникам для уточнения.Список функций, которые часто используются при создании трейнера:GetAsyncKeyStateTranslateMessageDispatchMessageFindWindowIsWindowGetWindowThreadProcessIdOpenProcessReadProcessMemoryWriteProcessMemoryCloseHandleМенее используемыеGetHandleInformationЭта функция позволит понять иерархию созданных процессов в том случае если у игры есть запускающий процесс, а надо патчить память дочернего.GetLastErrorВозвратит ошибку той или иной операцииCreateRemoteThreadКогда требуется создать поток в чужом процессе выполнив некоторый код. Например, загрузки dll и выполнения её функций внутри чужого процесса. Или выполнение какой-то функции игры по заданным параметрам и т.д.LoadLibraryЗагрузка исполняемого модуля в адресное пространство игры. Хотел также написать функции которые хорошо бы знать “ВООБЩЕ”, а в итоге понял, что надо посоветовать вам читать полный справочник по WinAPI32. Ссылки можете найти в самом верху.А теперь более подробнее с примерами на языке Дельфи. Принцип работы одинаков на других языках программирования для платформы Windows32/64Приминение функций:FindWindowIsWindowGetWindowThreadProcessIdOpenProcessReadProcessMemoryCloseHandleVar hWn: HWND; PID, hProc, dwReaded,StartAddr,i,r:DWord; buf: Byte;begin hWn := HWND(FindWindow(nil, PChar('Сапер'))); If IsWindow(hWn) Then Begin GetWindowThreadProcessId(hWn, PID); hProc := OpenProcess(PROCESS_VM_READ, False, PID); Try If (hProc <> 0) Then Begin ReadProcessMemory(hProc, ptr($10056AC), @buf, 1, dwReaded); SapMap.x := buf; ReadProcessMemory(hProc, ptr($10056A8), @buf, 1, dwReaded); SapMap.y := buf; sg.ColCount := SapMap.x; //sg - таблица sg.RowCount := SapMap.y; sg.Height:=16*sg.RowCount+3; sg.Width:=16*sg.ColCount+3; form1.Height:=16*sg.RowCount+3+48; form1.Width:=16*sg.ColCount+9; For i := 0 To (sg.ColCount - 1) Do For r := 0 To (sg.RowCount - 1) Do sg.Cells[i,r] := ' '; StartAddr := $01005361; For i := 0 To (SapMap.y - 1) Do Begin For r := 0 To (SapMap.x - 1) Do Begin ReadProcessMemory(hProc, ptr((i*$20) + StartAddr + r), @buf, 1, dwReaded); If (buf = $8F) Then sg.Cells[r, i] := 'X'; End; End; End; Finally CloseHandle(hProc); End; End;end;procedure TForm1.Button1Click(Sender: TObject);Создание трейнера на WinAPIСоздание трейнера на WinAPI. Пример 1{$R-} {проверка диапазона} {$S-} {проверка стека} {$A+} {"выравнивание слов"}program FlatOut; uses windows, messages, commctrl; //Используемые модули,только самое нужное!var WinClass : TWndClass; //переменная класса TWndClass для создания главного окна hInst : HWND; //Хендл приложения Handle : HWND; //локальный хендл Com1 : HWND; //TGroupBox Com2 : HWND; //TButton Com3 : HWND; //TButton Com4 : HWND; //TStaticText Com5 : HWND; //TStaticText Com6 : HWND; //TStaticText Msg : TMSG; //сообщения hFont : HWND; //хендл шрифта win : hwnd; //хендл данного окнаvar WindowName : integer; //имя окна ProcessId : integer; //ID процесса ThreadId : integer; //Поток buf : PChar; HandleWindow : Integer; //хендл окна игры write : cardinal;const //id наших контролов id_1 = 1; //TGroupBox id_2 = 2; //TButton id_3 = 3; //TButton id_4 = 4; //TStaticText id_5 = 5; //TStaticText id_6 = 6; //TStaticTextconst WindowTitle = 'Flat-Out'; //конец формы, начало формы, точный заголовок игры Address = $01B40C64; //адрес нашего значения в памяти игры PokeValue = $FFFFFFFF; //значение на которое мы будем менять NumberOfBytes = 4; //кол-во байт{$R XPMan.res} //Здесь у меня лежит иконка моего трейнера и манифес,//это для того что бы все контролы были в стиле XP procedure Cheating; //Собственно сама процедура изменения значения begin WindowName := FindWindow(nil,WindowTitle); //находим окно игры If WindowName = 0 then //или,обьясняем пользователю чтобы он запустил игру MessageBox(win,'Вначале игра,а потом трейнер.','Ошибка',MB_OK or MB_ICONINFORMATION); ThreadId := GetWindowThreadProcessId(WindowName,@ProcessId); HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId); GetMem(buf,1); buf^ := Chr(PokeValue); WriteProcessMemory(HandleWindow,ptr(Address),buf,NumberOfBytes,write);//пишем в наш адресс наше значение FreeMem(buf); CloseHandle(HandleWindow);//конец формы, началоформы, закрываем хэндл, чтобы не вылететь с ошибкойend;procedure ShutDown; //процедура выхода из программыbegin DeleteObject(hFont); //удаляем шрифт UnRegisterClass('Sample Class', hInst); //удаляем окно ExitProcess(hInst); //закрываем окно Halt; //на всякий случай end;procedure About; //наше окно о программеbegin MessageBox(win, ' [C0DED]: bY g-l-u-k [TeaM - X] ' +#13#10+ ' ' +#13#10+ ' GreatZzz....: ' +#13#10+ ' ' +#13#10+ ' Baron_Gede,6aHguT,AllexY ' +#13#10+ ' And all TeaM - X Members ! ' +#13#10+ ' ' +#13#10+ ' Write on pure Delphi (WinAPI) ' +#13#10+ ' Сopyright (g-l-u-k)R 2004-2005 ' +#13#10+ ' ' +#13#10+ ' <!-- m -->[url=http://www.team-x.ru]http://www.team-x.ru[/url]<!-- m --> ' +#13#10+ ' e-mail : <!-- e -->[email=g-l-u-k@rambler.ru]g-l-u-k@rambler.ru[/email]<!-- e --> ' +#13#10+ ' ' +#13#10+ ' GEngine v0.1 ' +#13#10+ ' All Right Reserved ', 'About',MB_OK or MB_ICONINFORMATION);end; function WindowProc(hwnd, msg, wparam, lparam: longint): longint; stdcall; //обработчик сообщенийbegin Result := DefWindowProc(hwnd, msg, wparam, lparam); case Msg of WM_COMMAND: case LoWord(wParam) of id_2 : if HiWord(wParam) = bn_Clicked then About; //если пользователь нажимает на кнопку "About",получат свой About id_3 : if HiWord(wParam) = bn_Clicked then ShutDown; //если выход то...... end; WM_DESTROY: ShutDown; end; end;// НАЧАЛО ПРОГРАММЫ begin hInst := GetModuleHandle(nil); with WinClass do begin Style := CS_PARENTDC; //стиль класса главного окна hIcon := LoadIcon(hInstance, IDI_APPLICATION); //иконка программы lpfnWndProc := @WindowProc; //назначение обработчика сообщений hInstance := hInst; hbrBackground := COLOR_BTNFACE + 1; //цвет окна lpszClassName := 'Sample Class'; //класс окна hCursor := LoadCursor(0, IDC_ARROW); //активный курсор end; InitCommonControls; RegisterClass(WinClass); //регистрация класса в сис-ме {Создание главного окна программы} Handle := CreateWindowEx(0, 'Sample Class', '[FlatOut] Trainer +1', WS_OVERLAPPED or WS_SYSMENU or WS_VISIBLE, 503, 345, 234, 222, 0, 0, hInst, nil); {Создание шрифта} hFont := CreateFont( -12, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, 'Terminal'); Com1:=CreateWindow( 'Button', 'Trainer Options:' , WS_CHILD or BS_GROUPBOX or WS_VISIBLE, 2,2,222,165, Handle, id_1, hInst,nil); SendMessage(Com1,WM_SETFONT,hFont,0); Com2 := CreateWindow( 'Button', 'About', WS_CHILD or BS_TEXT or WS_VISIBLE, 3, 171, 74, 20,Handle, id_2, hInst, nil); SendMessage(Com2,WM_SETFONT,hFont,0); Com3 := CreateWindow( 'Button', 'Quit', WS_CHILD or BS_TEXT or WS_VISIBLE, 148, 171, 74, 20,Handle, id_3, hInst, nil); SendMessage(Com3,WM_SETFONT,hFont,0); Com4 :=CreateWindow( 'Static', '[F1] :...: More Money' , WS_CHILD or SS_LEFT or SS_NOTIFY or WS_VISIBLE, 51,25,117,17,Handle, id_4, hInst,nil); SendMessage(Com4,WM_SETFONT,hFont,0); Com5:=CreateWindow( 'Static', '[C0DED] :...: g-l-u-k [TeaM - X]' , WS_CHILD or SS_LEFT or SS_NOTIFY or WS_VISIBLE or WS_DISABLED, 32,145,180,17,Handle, id_5, hInst,nil); SendMessage(Com5,WM_SETFONT,hFont,0); Com6:=CreateWindow( 'Static', '[R.Mouse] :...: About Box ' , WS_CHILD or SS_LEFT or SS_NOTIFY or WS_VISIBLE, 26,50,190,17,Handle, id_6, hInst,nil); SendMessage(Com6,WM_SETFONT,hFont,0); //Цикл сбора сообщений while(GetMessage(Msg, Handle, 0, 0)) do begin TranslateMessage(Msg); //приём сообщений if (GetAsyncKeyState(vk_f1 ) <> 0) then Cheating; //если нажата клавиша F1,читим игру if (GetAsyncKeyState(vk_RButton) <> 0) then About; //если нажата правая кнопка мыши,то показываем About if (GetAsyncKeyState(vk_Escape ) <> 0) then ShutDown; DispatchMessage(Msg); //удаление сообщений из очереди end;end.//Немного оптимизации Создание трейнера на WinAPI. Пример 2…в блокноте файл trainer.rc,который будет содержать следующие строки:======================trainer.rc============================100 DIALOG 0, 0, 173, 69STYLE DS_SETFONT | DS_CENTER | WS_CAPTION | WS_SYSMENUCAPTION "[FlatOut] Trainer +1"FONT 8, "Terminal"{PUSHBUTTON "About", 102, 2, 52, 36, 15, BS_FLATPUSHBUTTON "Close", 101, 132, 52, 38, 15, BS_FLATGROUPBOX "Trainer options: ", -1, 1, -1, 172, 51LTEXT "[C0DED] <--::--> bY g-l-u-k [TeaM - X]", -1, 7, 36, 164, 12, WS_DISABLEDLTEXT "[F1] :.......: More Money", -1, 7, 9, 126, 12, WS_DISABLED}======================trainer.rc============================useswindows, messages; //Именно по этому наш трейнер должен весить //меньше,если помните то в прошлой части учебника мы использовали //ещё и commctrl.const ID_ABOUT = 102; //Номера контролов нашего ресурса ID_EXIT = 101; Elapse = 10; //Нужен для таймера aboutcap = 'About'; //Наш About Dialog aboutmsg = ' [C0DED]: bY g-l-u-k [TeaM - X] ' +#13#10+ ' ' +#13#10+ ' GreatZzz....: ' +#13#10+ ' ' +#13#10+ ' Baron_Gede,6aHguT,AllexY ' +#13#10+ ' And all TeaM - X Members ! ' +#13#10+ ' ' +#13#10+ ' Write on pure Delphi (WinAPI) ' +#13#10+ ' copyright (g-l-u-k)R 2004-2005 ' +#13#10+ ' ' +#13#10+ ' <!-- m -->[url=http://www.team-x.ru]http://www.team-x.ru[/url]<!-- m --> ' +#13#10+ ' e-mail : <!-- e -->[email=g-l-u-k@rambler.ru]g-l-u-k@rambler.ru[/email]<!-- e --> ' +#13#10+ ' ' +#13#10+ ' GEngine v0.1 ' +#13#10+ ' All Right Reserved '; WindowTitle = 'Flat-Out'; //Название окна игры Address = $01B40C64;//Адресс нашего значения PokeValue = $FFFFFFFF;//наше значение NumberOfBytes = 4;//Кол-во байтvar Msg : TMSG; Win : HWND; WindowName : Integer; ProcessId : Integer; ThreadId : Integer; hInst : Dword; Buf : PChar; HandleWindow : Integer; Write : Cardinal;{$R trainer.res} //Наш ресурс в котором хранится окно трейнера//Вот самая интересная часть нашего трейнера,процедура роверки.//Если TrainerSPY активен,то мы обломим следящего за нашим //трейнером. function IsTrainerSpyActive:bool;var hProcess,hKernel:dword; addr:pointer; b:byte; dummy:cardinal; proc:pchar;begin result:=false; proc:='WriteProcessMemory'; if FindWindowExA(0,0,nil,'Trainer Spy')<>0 then begin result:=true; exit; end; hProcess:=GetCurrentProcess; hKernel:=LoadLibrary('kernel32.dll'); if hKernel<>0 then begin addr:=GetProcAddress(hKernel,proc); ReadProcessMemory(hProcess,addr,@b,1,dummy); FreeLibrary(hKernel); if b=204 then result:=true; end;end;//Процедура взлома игры,описывать полностью не буду,опишу только //самое главное.procedure Cheating;begin if IsTrainerSpyActive then //если TrainerSpy запушен, то вырубаемся begin MessageBox(0,'Выруби шпион.','Ошибка зашиты',MB_OK or MB_ICONERROR); exit; end; WindowName := FindWindow(nil,WindowTitle); If WindowName = 0 then MessageBox(win,'Игра должна быть запушенна до трейнера','Ошибка',MB_OK or MB_ICONINFORMATION); ThreadId := GetWindowThreadProcessId(WindowName,@ProcessId); HandleWindow := OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId); GetMem(buf,1); buf^ := Chr(PokeValue); WriteProcessMemory(HandleWindow,ptr(Address),buf,NumberOfBytes,write); FreeMem(buf); CloseHandle(HandleWindow);end;procedure Quit; //процедура выхода из программыbegin EndDialog(win,0); Halt;end;procedure DoTimer; //Дополнительна зашита от шпионовbegin CreateFileA('C:logwmemory.bin',$40000000,1,nil,2,1,0); hInst:= GetModuleHandle(nil); SetTimer(hInst,1,Elapse,@DoTimer);end;//Обработчик событий нашего окнаfunction SettingsDlgProc(Window : hWnd; Msg,WParam,LParam : Integer): Integer; StdCall;begin case Msg of wm_InitDialog : begin end; wm_Close : DestroyWindow(Win); wm_Destroy : PostQuitMessage(0); end; Result := 0; case Msg of WM_COMMAND : begin if wParam = ID_EXIT then Quit; //Ели нажата кнопка выхода,выходим if wParam = ID_ABOUT then MessageBox(Win,aboutmsg,aboutcap,MB_OK or MB_ICONINFORMATION);//А это наш //about end; end;end;//Процедура создания главного окнаProcedure RunSettings;begin Win := CreateDialog(hInstance,PCHar(100),0,@SettingsDlgProc); Showwindow(Win,SW_SHOW); Updatewindow(Win);end;// Начало программыbeginRunSettings;while GetMessage(Msg,0,0,0) do begin //Цикл сбора сообщений TranslateMessage(Msg); if (GetAsyncKeyState(VK_F1) <> 0) then Cheating;//Горячая клавиша DispatchMessage(Msg); end;end.program FlatOut; //Опять будем ломать FlatOutЗаключение.Можно было заметить как был построен материал. Сначала была дана справочная информация, а затем можно было увидеть применение функций WinApi в коде трейнеров. Как вы понимаете это базовая основа, т.к. некоторые тонкости не освещены. Например, поиск процесса игры по имени процесса, а не по имени окна. Здесь нет функций сканирования сигнатур для поиска адреса внедрения. Нет проверки на повторный запуск трейнера. Нет отмены читов при закрытии трейнера… Читы не выделяются в выделенную память. Байт-код внедряемых игровых инструкций пишется в память игры через байты, которые нужно получать предварительно при компиляции. Я бы эти байты не получал бы таким образом, а получил бы их скомпилировав инструкции в самом трейнере, а затем бы их копировал бы в игровой процесс в выделенную память. Возможно, я ещё что-то забыл указать… Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения