Показать сообщение отдельно

  #4  
Старый 22.03.2021, 21:35
Gafask
Участник форума
Регистрация: 10.12.2018
Сообщений: 137
С нами: 3908139

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

[QUOTE="Vintik"]

Привет-привет.
Давай все по порядку.

1) Что такое адрес? Адрес – это цифра, правда в шестнадцатеричной системе, но все же это обычная цифра. И по каждому адресу находится какое-то значение от 0 до 255 (1 байт). Все типы данных (int; float; char...) складываются из некого массива байт. Ближе к делу.
Поэтому если у тебя адрес такой:

Код:
0x3FBFD + 0x9201
То тебе нужно просто сложить его (0x3FBFD + 0x9201 = 0x48DFE) и прочитать уже значение по адресу, который является найденной суммой. Кстати, не стоит забывать, что нужно установить корректный уровень защиты на память, которую читаешь или в которую записываешь.

C++:





Код:
DWORD bytes
;
// вместо DWORD любой тип данных, который ты хочешь прочитать
DWORD oldProtect
=
0
;
VirtualProtectEx
(
process
,
(
void
*
)
0x48DFE
,
sizeof
(
bytes
)
,
PAGE_EXECUTE_READWRITE
,
&
oldProtect
)
;
ReadProcessMemory
(
process
,
(
void
*
)
0x48DFE
,
&
bytes
,
sizeof
(
bytes
)
,
NULL
)
;
VirtualProtectEx
(
process
,
(
void
*
)
0x48DFE
,
sizeof
(
bytes
)
,
oldProtect
,
NULL
)
;


2) Если у тебя адрес формата:

Код:
samp.dll + 0x12D8F8
То как это вообще понимать? Я ведь говорил, что адрес – число, да? Каждая DLL библиотека, которая присоединяется к процессу, записывает свои данные в память. Но ведь часть памяти уже занята, поэтому она начинает записывать с некоторого свободного адреса (он почти всегда разный). Нам сперва придётся его найти и просто, как уже я написал в пункте 1, сложить "базовый адрес модуля" и наше число. Например, так (простой пример кода):

C++:





Код:
#include "stdafx.h"
#include 
#include 
#include 
DWORD
getModuleBaseAddress
(
DWORD dwProcessID
,
TCHAR
*
lpszModuleName
)
// функция, которая получает этот адрес "samp.dll". её трогать не надо
{
HANDLE hSnapshot
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPMODULE
,
dwProcessID
)
;
DWORD dwModuleBaseAddress
=
0
;
if
(
hSnapshot
!=
INVALID_HANDLE_VALUE
)
{
MODULEENTRY32 ModuleEntry32
=
{
0
}
;
ModuleEntry32
.
dwSize
=
sizeof
(
MODULEENTRY32
)
;
if
(
Module32First
(
hSnapshot
,
&
ModuleEntry32
)
)
{
do
{
if
(
_tcscmp
(
ModuleEntry32
.
szModule
,
lpszModuleName
)
==
0
)
{
dwModuleBaseAddress
=
(
DWORD
)
ModuleEntry32
.
modBaseAddr
;
break
;
}
}
while
(
Module32Next
(
hSnapshot
,
&
ModuleEntry32
)
)
;
}
CloseHandle
(
hSnapshot
)
;
}
return
dwModuleBaseAddress
;
}
int
main
(
)
{
HWND hWnd
=
FindWindow
(
NULL
,
L
"GTA SA:MP"
)
;
DWORD pId
;
GetWindowThreadProcessId
(
hWnd
,
&
pId
)
;
HANDLE process
=
OpenProcess
(
PROCESS_ALL_ACCESS
,
0
,
pId
)
;
DWORD moduleBase
=
getModuleBaseAddress
(
pId
,
L
"samp.dll"
)
;
// вот тут в кавычках имя твоего модуля. и всё, в переменной уже хранится его базовый адрес
int
my_number
;
// опять же, любой тип данных тут может быть. не забывай, что в 4 строках ниже нужно поменять название переменной, если ты захочешь её переименовать тут
DWORD oldProtect
=
0
;
VirtualProtectEx
(
process
,
(
void
*
)
(
moduleBase
+
0x12D8F8
)
,
sizeof
(
my_number
)
,
PAGE_EXECUTE_READWRITE
,
&
oldProtect
)
;
ReadProcessMemory
(
process
,
(
void
*
)
(
moduleBase
+
0x12D8F8
)
,
&
my_number
,
sizeof
(
my_number
)
,
NULL
)
;
VirtualProtectEx
(
process
,
(
void
*
)
(
moduleBase
+
0x12D8F8
)
,
sizeof
(
my_number
)
,
oldProtect
,
NULL
)
;
std
::
cout
 0x9201–> нужное тебе число (или не число, любой тип данных)
Тогда надо поступить вот так:

C++:





[CODE]
DWORD bytes
;
DWORD oldProtect
=
0
;
// читаем данные по адресу 0x3FBFD и записывает в bytes
VirtualProtectEx
(
process
,
(
void
*
)
0x3FBFD
,
sizeof
(
bytes
)
,
PAGE_EXECUTE_READWRITE
,
&
oldProtect
)
;
ReadProcessMemory
(
process
,
(
void
*
)
0x3FBFD
,
&
bytes
,
sizeof
(
bytes
)
,
NULL
)
;
VirtualProtectEx
(
process
,
(
void
*
)
0x3FBFD
,
sizeof
(
bytes
)
,
oldProtect
,
NULL
)
;
// прибавляет к нему наш "оффсет" (смещение)
bytes
+=
0x9201
;
// это и есть наш новый адрес, который хранит нужные данные. читаем его:
float
my_number
;
// например, найдём число с плавающей точкой (нецелое) по этому адресу
VirtualProtectEx
(
process
,
(
void
*
)
bytes
,
sizeof
(
my_number
)
,
PAGE_EXECUTE_READWRITE
,
&
oldProtect
)
;
ReadProcessMemory
(
process
,
(
void
*
)
bytes
,
&
my_number
,
sizeof
(
my_number
)
,
NULL
)
;
VirtualProtectEx
(
process
,
(
void
*
)
bytes
,
sizeof
(
my_number
)
,
oldProtect
,
NULL
)
;
// нашли. теперь делай с ним, что хочешь. для примера: выведу в консоль
std
::
cout
 
Ответить с цитированием