HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 16.04.2019, 00:21
CleanLegend
Постоянный
Регистрация: 28.03.2013
Сообщений: 495
С нами: 6908018

Репутация: 213
По умолчанию

Привет, сегодня мы будем вызывать игровую функцию из exe.
Пример вызова в dll:

C++:





Код:
#define FUNC_CMessages__AddMessageJumpQ 0x69F1E0
void
AddMessageJumpQ
(
char
*
text
,
unsigned
int
time
,
unsigned
short
flag
,
bool
bPreviousBrief
)
{
(
(
void
(
__cdecl
*
)
(
char
*
,
unsigned
int
,
unsigned
short
,
bool
)
)
FUNC_CMessages__AddMessageJumpQ
)
(
text
,
time
,
flag
,
bPreviousBrief
)
;
}
AddMessageJumpQ
(
"hello"
,
500
,
NULL
,
false
)
;
// вызываем


Для вызова из exe мы будем использовать:

-OpenProcess

-VirtualAllocEx

-WriteProcessMemory

-CreateRemoteThread

Создаем структуру для передачи аргументов в удаленный поток(CreateRemoteThread):

C++:





Код:
struct
Struct
{
char
text
[
256
]
;
unsigned
int
time
;
unsigned
short
flag
;
bool
bPreviousBrief
;
DWORD pAdr
;
}
FuncArgs
;


Создаем прототип:

C++:





Код:
typedef
void
(
__cdecl
*
_SendMSG
)
(
char
*
,
unsigned
int
,
unsigned
short
,
bool
)
;


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

C++:





Код:
DWORD __stdcall
RemoteThread
(
Struct
*
sArg
)
{
_SendMSG msg
=
(
_SendMSG
)
sArg
->
pAdr
;
// передаем адрес
msg
(
sArg
->
text
,
sArg
->
time
,
sArg
->
flag
,
sArg
->
bPreviousBrief
)
;
// вызываем
return
0
;
}
void
__stdcall
RemoteThread_end
(
)
{
}


Заполняем структуру:

C++:





Код:
strcpy
(
FuncArgs
.
text
,
"Hello world!"
)
;
FuncArgs
.
time
=
500
;
FuncArgs
.
flag
=
NULL
;
FuncArgs
.
bPreviousBrief
=
false
;
FuncArgs
.
pAdr
=
0x69F1E0
;


Функция для получения id процесса:

C++:





Код:
DWORD
GetProcId
(
const
char
*
procname
)
{
PROCESSENTRY32 pe
;
HANDLE hSnap
;
pe
.
dwSize
=
sizeof
(
PROCESSENTRY32
)
;
hSnap
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPPROCESS
,
NULL
)
;
if
(
Process32First
(
hSnap
,
&
pe
)
)
{
do
{
if
(
strcmp
(
pe
.
szExeFile
,
procname
)
==
0
)
break
;
}
while
(
Process32Next
(
hSnap
,
&
pe
)
)
;
}
return
pe
.
th32ProcessID
;
}


C++:





Код:
// получаем хэндл процесса
HANDLE hProcess
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
GetProcId
(
"gta_sa.exe"
)
)
;
// Выделяем память под наш поток в gta_sa
LPVOID pRemoteThread
=
VirtualAllocEx
(
hProcess
,
NULL
,
(
DWORD_PTR
)
RemoteThread_end
-
(
DWORD_PTR
)
RemoteThread
,
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_EXECUTE_READWRITE
)
;
// Записываем его
WriteProcessMemory
(
hProcess
,
pRemoteThread
,
(
LPVOID
)
RemoteThread
,
(
(
DWORD_PTR
)
RemoteThread_end
-
(
DWORD_PTR
)
RemoteThread
)
,
0
)
;
// Выделяем память для нашего объекта в gta_sa
Struct
*
myArg
=
(
Struct
*
)
VirtualAllocEx
(
hProcess
,
NULL
,
sizeof
(
Struct
)
,
MEM_COMMIT
,
PAGE_READWRITE
)
;
// Записываем его
WriteProcessMemory
(
hProcess
,
myArg
,
&
FuncArgs
,
sizeof
(
Struct
)
,
NULL
)
;
// Запускаем наш поток pRemoteThread с аргументами myArg
HANDLE hThread
=
CreateRemoteThread
(
hProcess
,
0
,
0
,
(
LPTHREAD_START_ROUTINE
)
pRemoteThread
,
myArg
,
0
,
0
)
;
// Закрываем дескриптор потока
CloseHandle
(
hThread
)
;
// Освобождаем выделенную память
VirtualFreeEx
(
hProcess
,
myArg
,
sizeof
(
Struct
)
,
MEM_RELEASE
)
;
// Закрываем дескриптор процесса
CloseHandle
(
hProcess
)
;


Получаем:

Цитата:
Сообщение от Спойлер  




Пример с WinAPI(Beep):

Создаем структуру и прототип:

C++:





Код:
typedef
BOOL
(
__stdcall
*
__Beep
)
(
DWORD
,
DWORD
)
;
struct
sBeep
{
DWORD Freq
;
DWORD Duration
;
DWORD pAdr
;
}
myBeep
;


Заполняем структуру:

C++:





Код:
myBeep
.
Freq
=
500
;
myBeep
.
Duration
=
50
;
HMODULE kernel
=
LoadLibrary
(
"Kernel32.dll"
)
;
// Получаем адрес kernel32
myBeep
.
pAdr
=
(
DWORD
)
GetProcAddress
(
kernel
,
"Beep"
)
;
// получаем адрес функции Beep
FreeLibrary
(
kernel
)
;


C++:





Код:
DWORD __stdcall
RemoteThread
(
sBeep
*
sArg
)
{
__Beep msg
=
(
__Beep
)
sArg
->
pAdr
;
msg
(
sArg
->
Freq
,
sArg
->
Duration
)
;
return
0
;
}
void
__stdcall
RemoteThread_end
(
)
{
}


C++:





Код:
HANDLE hProcess
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
GetProcId
(
"gta_sa.exe"
)
)
;
// Выделяем память под наш поток в gta_sa
LPVOID pRemoteThread
=
VirtualAllocEx
(
hProcess
,
NULL
,
(
DWORD_PTR
)
RemoteThread_end
-
(
DWORD_PTR
)
RemoteThread
,
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_EXECUTE_READWRITE
)
;
// Записываем его
WriteProcessMemory
(
hProcess
,
pRemoteThread
,
(
LPVOID
)
RemoteThread
,
(
(
DWORD_PTR
)
RemoteThread_end
-
(
DWORD_PTR
)
RemoteThread
)
,
0
)
;
// Выделяем память для нашего объекта в gta_sa
sBeep
*
myArg
=
(
sBeep
*
)
VirtualAllocEx
(
hProcess
,
NULL
,
sizeof
(
sBeep
)
,
MEM_COMMIT
,
PAGE_READWRITE
)
;
// Записываем его
WriteProcessMemory
(
hProcess
,
myArg
,
&
myBeep
,
sizeof
(
sBeep
)
,
NULL
)
;
// Запускаем наш поток pRemoteThread с аргументами myArg
HANDLE hThread
=
CreateRemoteThread
(
hProcess
,
0
,
0
,
(
LPTHREAD_START_ROUTINE
)
pRemoteThread
,
myArg
,
0
,
0
)
;
// Закрываем дескриптор потока
CloseHandle
(
hThread
)
;
// Освобождаем выделенную память
VirtualFreeEx
(
hProcess
,
myArg
,
sizeof
(
sBeep
)
,
MEM_RELEASE
)
;
// Закрываем дескриптор процесса
CloseHandle
(
hProcess
)
;
 
Ответить с цитированием

  #2  
Старый 16.04.2019, 10:28
SR_team
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами: 6603505

Репутация: 183


По умолчанию

а самое интересное не написал. Переключение процессов планировщиком происходит в момент вызова CreateRemoteThread или по истечению кванта? Т.е. поток выполняется сразу или отложено, при переключение процесса?
 
Ответить с цитированием

  #3  
Старый 16.04.2019, 11:24
CleanLegend
Постоянный
Регистрация: 28.03.2013
Сообщений: 495
С нами: 6908018

Репутация: 213
По умолчанию

Цитата:
Сообщение от SR_team  

а самое интересное не написал. Переключение процессов планировщиком происходит в момент вызова CreateRemoteThread или по истечению кванта? Т.е. поток выполняется сразу или отложено, при переключение процесса?
Сразу
 
Ответить с цитированием

  #4  
Старый 16.04.2019, 12:17
CleanLegend
Постоянный
Регистрация: 28.03.2013
Сообщений: 495
С нами: 6908018

Репутация: 213
По умолчанию

Обновил. Изменил реализацию, добавил пример с WinAPI
 
Ответить с цитированием

  #5  
Старый 16.04.2019, 13:05
SR_team
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами: 6603505

Репутация: 183


По умолчанию

Цитата:
Сообщение от CleanLegend  

Обновил. Изменил реализацию, добавил пример с WinAPI
вот это уже выглядит круто, но компилятор может расположить функции в ином порядке
 
Ответить с цитированием

  #6  
Старый 16.04.2019, 20:32
iAmerican
Постоянный
Регистрация: 17.02.2014
Сообщений: 611
С нами: 6438231

Репутация: 133


По умолчанию

клёвый гайд , взял себе
 
Ответить с цитированием

  #7  
Старый 25.04.2019, 08:39
#Rin
Познавший АНТИЧАТ
Регистрация: 09.08.2015
Сообщений: 1,213
С нами: 5663255

Репутация: 183


По умолчанию

Цитата:
Сообщение от CleanLegend  

HMODULE kernel = LoadLibrary("Kernel32.dll"); // Получаем адрес kernel32 myBeep.pAdr = (DWORD)GetProcAddress(kernel,"Beep"); // получаем адрес функции Beep FreeLibrary(kernel);
Может windows и гарантирует загрузку такой системной библиотеки по одинаковому адресу. Но адрес библиотеки в разных процессах может и будет отличаться.

Поэтому что бы найти адрес функции относительно другого процесса, нужно:

Использовать CreateToolhelp32Snapshot, Module32First, Module32Next для нахождения адреса библиотеки в чужом процессе.

Затем загрузить туже библиотеку в свой процесс через LoadLibrary.

А после найти адрес функции относительно своего процесса через GetProcAddress.

Затем просто вычисляем: адрес_библиотеки_в_чужом процессе + адрес_функции_в_нашем_проце ссе - адрес_библиотеки_в_нашем_пр оцессе.
 
Ответить с цитированием

  #8  
Старый 28.04.2019, 14:53
SR_team
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами: 6603505

Репутация: 183


По умолчанию

Цитата:
Сообщение от Rinat_Namazov  

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

  #9  
Старый 28.04.2019, 15:03
#Rin
Познавший АНТИЧАТ
Регистрация: 09.08.2015
Сообщений: 1,213
С нами: 5663255

Репутация: 183


По умолчанию

Цитата:
Сообщение от SR_team  

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

Но в Виндоусе на каждый процесс свой экземпляр библиотеки.
 
Ответить с цитированием

  #10  
Старый 01.05.2019, 22:15
SR_team
Флудер
Регистрация: 26.10.2013
Сообщений: 4,924
С нами: 6603505

Репутация: 183


По умолчанию

Цитата:
Сообщение от Rinat_Namazov  

Я читал что в Линуксе, библиотека загруженная в память, используется всеми процессами.
Но в Виндоусе на каждый процесс свой экземпляр библиотеки.
1. на*** они тогда нужны в винде?

2. Почему тогда фокус с получением адреса библиотечной функции из своего процесса работает?
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.