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

Проблема с FASM


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

Здравствуйте! Как в FASM подключиться к процессу по его имени (war3.exe)?

Или по его классу?

format PE GUI 4.0
entry start
include 'd:\Coding\fasm\include\win32a.inc'
section '.data' data readable writable
error_message db 'Access denited!',0
caption db 'Fasm Trainer',0
pid dd 0
Poke dd _Poke
windowcap db 'Warcraft III',0
addr dd адрес
godmode_on db байты вкл
godmode_off db байты выкл

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
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,2
jmp .finish
.wmclose:
invoke Poke,[addr],godmode_off,2
invoke EndDialog,[hwnddlg],0
.move:
invoke SendMessage,[hwnddlg],WM_NCLBUTTONDOWN,2,0
.finish:
ret
endp
proc _Poke,memadd,memval,bytes
invoke FindWindow, windowcap, 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
section '.idata' import data readable writeable
library kernel,'kernel32.DLL',\
user,'user32.DLL'
import kernel,\
GetModuleHandle,'GetModuleHandleA',\
ExitProcess,'ExitProcess',\
OpenProcess,'OpenProcess',\
WriteProcessMemory,'WriteProcessMemory'
import user,\
DialogBoxParam,'DialogBoxParamA',\
EndDialog,'EndDialog',\
MessageBox,'MessageBoxA',\
FindWindow,'FindWindowA',\
GetWindowThreadProcessId,'GetWindowThreadProcessId',\
SendMessage,'SendMessageA'
section '.rsrc' resource data readable
directory RT_DIALOG,dialogs
resource dialogs,37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration
dialog demonstration,'WarCraft +1 trainer',70,70,190,175,WS_POPUP
dialogitem 'STATIC','Press OK for toggle godmone on.',-1,0,0,163,188,SS_LEFT + WS_VISIBLE+ SS_CENTER
dialogitem 'BUTTON','OK',1,85,150,45,15,WS_VISIBLE
dialogitem 'BUTTON','Exit',2,135,150,45,15,WS_VISIBLE
enddialog

Так как подключиться по имени окна не получается, та же самая проблема возникла и при написании данного трейнера на C#, проблема при подключении к процессу.

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

Реально подключиться к окну, когда игра в оконном режиме.

Так можно как-нибудь иным способом подключиться к процессу?

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

На форуме нашем проскакивали способы подключения к процессу. Даю подсказку. Используй снятие снимка системы с последующим перебором процессов. В этом тебе помогут три WinAPI фуникции:

CreateToolhelp32Snapshot

Process32First

Process32Next

Описания функций найдешь в MSDN.

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

Сейчас попробую запилить.

Вроде бы понял как работают эти функции. Но тогда возникает вопрос, а как я узнаю что функция остановилась на моём процессе? И собственно остановлюсь на своём процессе.

Кое-что написал, но при компиляции ошибка на линии 58 ( invoke OpenProcess,PROCESS_ALL_ACCESS,0,[pe32.th32ProcessID] )

format PE GUI 4.0
entry start
include 'd:\Coding\fasm\include\win32a.inc'
section '.data' data readable writable
error_message db 'Access denited!',0
caption db 'Fasm Trainer',0
pid dd 0
Poke dd _Poke
windowcap db 'Warcraft III',0
addr dd адрес
mh_on db байты вкл
mh_off db байты выкл
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
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],mh_on,4
jmp .finish
.wmclose:
invoke Poke,[addr],mh_off,4
invoke EndDialog,[hwnddlg],0
.move:
invoke SendMessage,[hwnddlg],WM_NCLBUTTONDOWN,2,0
.finish:
ret
endp
proc _Poke,memadd,memval,bytes
invoke CreateToolhelp32Snapshot,0fh,NULL
mov edx, eax
mov [pe32.dwSize],sizeof.PROCESSENTRY32
cmp eax,0
je .error
invoke Process32First,edx,pe32
test eax,eax
jz .error
invoke Process32Next,edx,pe32
test eax,eax
jz .error
invoke lstrcmpi,pe32.szExeFile,'war3.exe'
test eax,eax
jz .error
invoke OpenProcess,PROCESS_ALL_ACCESS,0,[pe32.th32ProcessID]
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
struct PROCESSENTRY32

dwSize dd MAX_PATH
cntUsage dd NULL
th32ProcessID dq NULL
th32DefaultHeapID dq NULL
th32ModuleID dd NULL
cntThreads dd NULL
th32ParentProcessID dd NULL
pcPriClassBase dd NULL
dwFlags dd NULL
szExeFile db MAX_PATH dup NULL
ends
pe32 PROCESSENTRY32
section '.idata' import data readable writeable
library kernel,'kernel32.DLL',\
user,'user32.DLL'
import kernel,\
GetModuleHandle,'GetModuleHandleA',\
ExitProcess,'ExitProcess',\
OpenProcess,'OpenProcess',\
WriteProcessMemory,'WriteProcessMemory',\
CreateToolhelp32Snapshot,'CreateToolhelp32Snapshot',\
Process32First,'Process32First',\
Process32Next,'Process32Next '
import user,\
DialogBoxParam,'DialogBoxParamA',\
EndDialog,'EndDialog',\
MessageBox,'MessageBoxA',\
FindWindow,'FindWindowA',\
GetWindowThreadProcessId,'GetWindowThreadProcessId',\
SendMessage,'SendMessageA'
section '.rsrc' resource data readable
directory RT_DIALOG,dialogs
resource dialogs,37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration
dialog demonstration,'Trainer by Coder',70,70,190,175,WS_POPUP
dialogitem 'STATIC','Press OK for toggle godmode on.',-1,0,0,163,188,SS_LEFT + WS_VISIBLE+ SS_CENTER
dialogitem 'BUTTON','OK',1,85,150,45,15,WS_VISIBLE
dialogitem 'BUTTON','Exit',2,135,150,45,15,WS_VISIBLE
enddialog

Изменено пользователем Kvazimado
В твиттере чтоли пересидел, каждое движение тут описываешь?
Ссылка на комментарий
Поделиться на другие сайты

Сделал вещь, процесс видит, но запись в код игры не происходит, в чём проблема?

format PE GUI 4.0
include 'd:\Coding\fasm\include\win32ax.inc'

struct PROCESSENTRY32
.dwSize dd ?
.cntUsage dd ?
.th32ProcessID dd ?
.th32DefaultHeapID dd ?
.th32ModuleID dd ?
.cntThreads dd ?
.th32ParentProcessID dd ?
.pcPriClassBase dd ?
.dwFlags dd ?
.szExeFile rb 260
ends

TH32CS_SNAPPROCESS = 0x2

;------------------------------------------------
;Declares
;------------------------------------------------
.data
SnapHandle dd ?
Poke dd _Poke
ProcessEntry PROCESSENTRY32
szProcessName db "war3.exe", 0
addr dd адрес
godmode_on db байты
proc _Poke,memadd,memval,bytes
invoke OpenProcess,PROCESS_ALL_ACCESS,0,[ProcessEntry..th32ProcessID]
invoke WriteProcessMemory,eax,[memadd],[memval],[bytes],0
cmp eax,0
je Exit
ret
endp
.code
Main:
;------------------------------------------------
;Create Snapshot of Processes
;------------------------------------------------
mov dword [ProcessEntry..dwSize], sizeof.PROCESSENTRY32
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
cmp eax, 0
je Exit
mov dword [SnapHandle], eax
invoke Process32First, dword [SnapHandle], ProcessEntry

;------------------------------------------------
;Loop Through All Processes
;------------------------------------------------
NextProcess:
cmp eax, 0
je Exit
invoke lstrcmpi, ProcessEntry..szExeFile, szProcessName
cmp eax, 0
je Found
invoke Process32Next, dword [SnapHandle], ProcessEntry
jmp NextProcess
;------------------------------------------------
;Show a messagebox if found
;------------------------------------------------
Found:
invoke MessageBox, 0, "Patch Sucessful!", szProcessName, MB_ICONQUESTION
invoke Poke,addr,godmode_on,4;
;jmp Exit

;------------------------------------------------
;Exit the loader when done
;------------------------------------------------
Exit:
invoke ExitProcess, 0
.end Main

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

Первая и самая грубая ошибка - после того, как процесс найден, или же перебор процессов закончен (в случае, если игра не запущена), надо обязательно закрывать хэндл снимка системы. Это раз. Ну а по поводу записи в память - большинство игр сейчас идут с защитой от подобных изменений, поэтому, прежде чем записать что-либо в память процесса, надо сначала получить права на запись, а точнее, сменить тип защиты нужного адреса. Делается это функцией VirtualProtectEx. Далее, сразу же после записи нужных данных в память процесса, нужно восстановить старые настройки защиты (их можно сохранить при первом запуске упомянутой функции - МСДН объяснит) вызовом этой же самой функции. Это неоднократно рассматировалось в разных статьях и разных тредах нашего форума, надо не лениться и пользоваться поиском. Если в каждой теме обмусоливать одни и те же вопросы - мы все погрязнем в куче однотипной информации, в которой что-то полезное будет найти весьма проблематично.

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

Первая и самая грубая ошибка - после того, как процесс найден, или же перебор процессов закончен (в случае, если игра не запущена), надо обязательно закрывать хэндл снимка системы. Это раз. Ну а по поводу записи в память - большинство игр сейчас идут с защитой от подобных изменений, поэтому, прежде чем записать что-либо в память процесса, надо сначала получить права на запись, а точнее, сменить тип защиты нужного адреса. Делается это функцией VirtualProtectEx. Далее, сразу же после записи нужных данных в память процесса, нужно восстановить старые настройки защиты (их можно сохранить при первом запуске упомянутой функции - МСДН объяснит) вызовом этой же самой функции. Это неоднократно рассматировалось в разных статьях и разных тредах нашего форума, надо не лениться и пользоваться поиском. Если в каждой теме обмусоливать одни и те же вопросы - мы все погрязнем в куче однотипной информации, в которой что-то полезное будет найти весьма проблематично.

Потратив пол дня, на изучение рассказанных Вами функций, я смог написать программу без ошибок, но проблема та же не могу просто открыть процесс, пожалуйста просмотрите мой исходник, я перепробовал уже множество вариантов.

format PE GUI 4.0
entry start
include 'd:\Coding\fasm\include\win32a.inc'
struct PROCESSENTRY32
dwSize dd ?
cntUsage dd ?
th32ProcessID dd ?
th32DefaultHeapID dd ?
th32ModuleID dd ?
cntThreads dd ?
th32ParentProcessID dd ?
pcPriClassBase dd ?
dwFlags dd ?
szExeFile rd 260
ends
section '.data' data readable writable
file_name db 'war3.exe',0
handle_snap dd ?
handle_proc dd ?
error_message db 'Access denited!',0
caption db 'Fasm Trainer',0
Poke dd _Poke
addr dd адрес
godmode_on db байты
godmode_off db байты

pe32 PROCESSENTRY32
section '.text' code readable executable
start:
invoke CreateToolhelp32Snapshot, 0fh, 0
mov [handle_snap], eax
invoke Process32First, eax, pe32
invoke GetModuleHandle,0
invoke DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
invoke ExitProcess,0
@next:
nop
invoke Process32Next, [handle_snap], pe32
test eax, eax
jz @error
invoke lstrcmp, pe32.szExeFile, file_name
test eax, eax
jnz @next
@error:
invoke MessageBox,HWND_DESKTOP,error_message,caption,MB_OK
proc DialogProc hwnddlg,msg,wparam,lparam
cmp [msg],WM_CLOSE
je .wmclose
cmp [msg],WM_COMMAND
je .wmcommand
cmp [msg],WM_LBUTTONDOWN
je .move
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,4
jmp .finish
.wmclose:
invoke Poke,[addr],godmode_off,4
invoke EndDialog,[hwnddlg],0
.move:
invoke SendMessage,[hwnddlg],WM_NCLBUTTONDOWN,2,0
.finish:
ret
endp
proc _Poke,memadd,memval,bytes
invoke OpenProcess, PROCESS_ALL_ACCESS, 0, [pe32.th32ProcessID]
cmp eax,0
je .error
invoke WriteProcessMemory,eax,[memadd],[memval],[bytes],0
cmp eax,0
je .error
invoke CloseHandle, [handle_snap]
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',\
CreateToolhelp32Snapshot,'CreateToolhelp32Snapshot',\
Process32First,'Process32First',\
Process32Next,'Process32Next',\
lstrcmp,'lstrcmp',\
CloseHandle,'CloseHandle'
import user,\
DialogBoxParam,'DialogBoxParamA',\
EndDialog,'EndDialog',\
MessageBox,'MessageBoxA',\
SendMessage,'SendMessageA'
section '.rsrc' resource data readable
directory RT_DIALOG,dialogs
resource dialogs,37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration
dialog demonstration,'Trainer by Coder',70,70,190,175,WS_POPUP
dialogitem 'STATIC','Press OK for toggle godmode on.',-1,0,0,163,188,SS_LEFT + WS_VISIBLE+ SS_CENTER
dialogitem 'BUTTON','OK',1,85,150,45,15,WS_VISIBLE
dialogitem 'BUTTON','Exit',2,135,150,45,15,WS_VISIBLE
enddialog

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

 Coder, пользуйся пошаговой отладкой в каком-нибудь отладчике для выявления проблемных мест. Когда не знаешь почему программа не работает пользуются отладчиком и документацией WinAPI функций под рукой.

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

Тут вообще допущена такая ошибка, о которой и говорить-то не стоит. В этом исходнике у тебя не отрабатывает даже поиск процесса, ибо после вызова ExitProcess твоя программа завершается. Цикл поиска и внедрения в процесс надо заталкивать в диалоговую процедуру. И, если хочешь по хоткею - заталкиваешь эту процедуру в сообщениия нажатия клавиш, а если же хочешь, чтобы сразу при запуске проги отрабатывала - в обработчик сообщения WM_INITDIALOG внутри диалоговой процедуры. Далее, PROCESS_ALL_ACCESS тебе совсем не нужен. Тебе достаточно PROCESS_VM_READ и PROCESS_VM_WRITE (это флаги, их надо сочетать). В каком направлении копать - я тебе подсказал, дальше давай сам.

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

Я всё-таки Coder-у предлагаю сначала написать рабочий вариант на языке высокого уровня (С++) + WinAPI. Это нужно для того чтобы в упрощённом виде смотреть на жизненный цикл программы. И кстати его хорошо бы сначала спланировать.

1) Спланировать жизненный цикл программы на WinAPI

2) Написать по примерам на C++ желаемую программу

3) Написать на FASM

На С++ будет нагляднее, а на FASM код становится довольно ёмким.

План:

1) Создаём окно

2) Цепляем к окну диалоговую функцию

3) В диалоговой функции продуманно обрабатываем сообщения горячих клавиш и закрытие формы. При закрытии закрываем созданные дескрипторы(хендлы).

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

5) Продумать логику поиска процесса. Ведь если процесс найден, то искать его вновь не нужно...

Если по своему плану написать что-то на С++, то на FASM это будет переписать гораздо проще чем писать сразу на нём не имея ранее опыта ;)

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

Спасибо за подсказки, получилось сделать трейнер на C++.

#include <windows.h>
#include <conio.h>
#include <dos.h>
#include <tlhelp32.h>
#include <stdio.h>

LPVOID gm_addr1 = (void*) адрес; // memory address of the stamina value in the WarRock process
LPVOID gm_addr2 = (void*) адрес;
LPVOID gm_addr3 = (void*) адрес;
LPVOID gm_addr4 = (void*) адрес;
LPVOID gm_off1 = (void*) байт кода;
LPVOID gm_off2 = (void*) байт кода;
LPVOID gm_off3 = (void*) байт кода;
LPVOID gm_off4 = (void*) байт кода;
LPVOID gm_on1 = (void*) байт кода;
LPVOID gm_on2 = (void*) байт кода;
LPVOID gm_on3 = (void*) байт кода;
LPVOID gm_on4 = (void*) байт кода;

void screen() // output
{
system("cls"); // clear the screen
printf("WarCraft 3 Map Hack \n");
printf("Press NumPad1 to enable MapHack \n");
printf("Press NumPad2 to disable MapHack \n");
printf("Created by Coder, connect with me ICQ: 222932 \n");

}

int main(int argc, char* argv[])
{
HANDLE hProcessSnap; // will store a snapshot of all processes
HANDLE hProcess = NULL; // we will use this one for the WarRock process
PROCESSENTRY32 pe32; // stores basic info of a process, using this one to read the ProcessID from

hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); // make process snapshot

pe32.dwSize = sizeof( PROCESSENTRY32 ); // correct size

Process32First(hProcessSnap, &pe32); // read info about the first process into pe32

do // loop to find the WarRock process
{
if(strcmp(pe32.szExeFile, "war3.exe") == 0) // if WarRock was found
{
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); // open it, assigning to the hProcess handle
break; // break the loop
}
}
while(Process32Next(hProcessSnap, &pe32)); // loop continued until Process32Next deliver NULL or its interrupted with the "break" above

CloseHandle( hProcessSnap ); // close the handle (just fuckin do it)

if(hProcess == NULL) // self explanatory tbh
{
printf("WarCraft is not running!");
getch(); // wait for a key press. otherwise the app will just close so fast when the process is not found, you wont know wtf happened.
}
else
{
screen(); // print the display

char key = ' '; // make a key variable to store pressed keys

while(key != VK_ESCAPE) // loop until user presses Escape
{

if(kbhit()) // if a key was pressed
{
key = getch(); // it is saved into "key"

switch(key) // here the commands are handled depending on the key that was pressed
{ // case '1': ... break; case '2': ... break; and so on
case '1':
WriteProcessMemory(hProcess, gm_addr1, &gm_on1, 1, NULL); // read the stamina value from the memory into the "stamina" variable
WriteProcessMemory(hProcess, gm_addr2, &gm_on2, 1, NULL);
WriteProcessMemory(hProcess, gm_addr3, &gm_on3, 1, NULL);
WriteProcessMemory(hProcess, gm_addr4, &gm_on4, 1, NULL);
break;
case '2':
WriteProcessMemory(hProcess, gm_addr1, &gm_off1, 1, NULL); // read the stamina value from the memory into the "stamina" variable
WriteProcessMemory(hProcess, gm_addr2, &gm_off2, 1, NULL);
WriteProcessMemory(hProcess, gm_addr3, &gm_off3, 1, NULL);
WriteProcessMemory(hProcess, gm_addr4, &gm_off4, 1, NULL);
break;
}

screen(); // print the display after each key press

}

CloseHandle(hProcess); // close the handle

}

return 0; // THE END
}
}

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

Во-первых, таки функцией VirtualProtectEx ты не воспользовался. Во-вторых, зачем делать консольное приложение? В-третьих, зачем для каждого байта вызывать функцию записи в память отдельно? Можно записать сразу цепочку байтов.

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

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

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

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