PDA

Просмотр полной версии : Адрес DLL из стороннего процесса с++


Gafask
22.03.2021, 02:34
Пробыв год в одном месте и потеряв все исходники и знания я задам теперь вопрос который меня щас мучает ооочень сильно !

Пример: У нас есть адрес в формате samp.dll+0x12D8F8 который был найден в Cheat Engine и адрес 0xS3FSFD + 0х9201 который нам кто-то дал ( ну или нашли где-то ) .

😘🤓😘😇Практика : 😘🤓😘😇​


ReadProcessMemory(process, (LPCVOID)(0xS3FSFD), &TestS, sizeof(TestS), NULL)[/COLOR][/CENTER][/HEADING]
[HEADING=2][CENTER][COLOR=rgb(0, 0, 0)]ReadProcessMemory(process, (LPCVOID)(TestS+0х9201 ), &TestD, sizeof(TestD), NULL);
​Значит адрес 0xS3FSFD + 0х9201 мы вроде как можем прочитать и вроде все верно или нет то посоветуйте как правильнее 🙂, так дальше .🙂

Адрес формата : samp.dll+0x12D8F8 я не могу прочитать так как я не знаю как правильно прочитать samp.dll что-бы к нему 🙂добавить смещение 0x12D8F8 . 🙂

Вопрос : Как прочитать адрес samp.dll+0x12D8F8 а точнее samp.dll что бы к примеру его прочитать и вывести в консоль или 🙂наоборот изменить его . 🙂

Я пишу на языке с++ , использую консольно приложение , редактирую адреса памяти не через DLL ! а используя консольое 😘🤓😘😇приложение .exe тоесть из левой программы пытаюсь взаимодействовать с гта са . 😘🤓😘😇

Надеюсь я правильно все вам написал и вы правильно мой вопрос поняли , даже если не знаете на него ответ ) . 😘

😘🤓😘😇Спасибо за внимание жду ваших ответов с примерами желательно . 😇 😇 😇

🥰🥰Всем удачи ! Денег , дачи .🥰🥰​

Gafask
22.03.2021, 11:04
Может всё-таки кто-то поможет ?

Vintik
22.03.2021, 12:22
Привет-привет.

Давай все по порядку.

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 pID
,
TCHAR
*
szModuleName
)
// функция, которая получает этот адрес "samp.dll". её трогать не надо
{
DWORD dwModuleBaseAddress
=
0
;
HANDLE hSnapshot
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPMODULE
|
TH32CS_SNAPMODULE32
,
pID
)
;
if
(
hSnapshot
!=
INVALID_HANDLE_VALUE
)
{
MODULEENTRY32 ModuleEntry32
;
ModuleEntry32
.
dwSize
=
sizeof
(
MODULEENTRY32
)
;
if
(
Module32First
(
hSnapshot
,
&
ModuleEntry32
)
)
{
do
{
if
(
strcmp
(
ModuleEntry32
.
szModule
,
szModuleName
)
==
0
)
{
dwModuleBaseAddress
=
(
DWORD_PTR
)
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



3) А вот что ты писал про сумму – это не совсем сумма. Это указатель. То есть по одному адресу памяти хранится значение другого адреса памяти, уже который хранит именно нужные тебе данные (обычно это число).

[CODE]
0x3FBFD –> 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



Надеюсь, что я ответил на все поставленные тобой вопросы. Удачи.

Gafask
22.03.2021, 21:35
[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

Vintik
22.03.2021, 22:57
Да вы ответили на мои вопросы , я вам очень благодарен за это и удивлён что на этот вопрос отреагировал сам ДаркПиксель охохо🤩 , ладно не буду терять голову 🧐 ) .

Есть еще 4 вопроса , думаю вы не затруднитесь ответить на него , я буду вам благодарен😇 .

Вопросы :🤔🤔🤔🤔🤔🤔

1. Для чего менять уровень защиты через VirtualProtectEx ?🤔

2. Где необходимо/рекомендуется применять VirtualProtectEx при работе с памятью ?🤔

3. Если не использовать VirtualProtectEx то какие последствия могу быть ?🤔

4. Ошибка E0020 идентификатор "_tcscmp" не определен , я исправлял с помощью подключения библиотеки она исправила эту ошибку , то есть компилятор перестал кричать на нее но при попытке запустить код для тестов в режиме отладчика я понял что getModuleBaseAddress не работает тесть она не находит не samp.dll , nvd3dum.dll и тд. и почему то мне кажется что в этом вся проблема , что мне нужно поменять в проекте что-бы исправить эту ошибку так как я подозреваю что это в этом проблема или в том что библиотека "stdafx.h" не видна у меня а точнее не определяется . В чем же проблема и как ее решить ?


Отвечаю на вопросы 1, 2 и 3.

VirtualProtectEx нужен для того, чтобы установить нужному кусочку памяти необходимый уровень защиты для того, чтобы читать и записывать данные. Условно: сказать программе, что есть разрешение на запись/чтение этого участка памяти.

Использовать стоит везде, где ты её читаешь или записываешь.

Последствия, с которыми сталкивался я, – краш от античита с причиной "Нарушение прав доступа к памяти". Пример:

1616438552482.pngVintik · 22 Мар 2021 в 21:57' data-fancybox="lb-post-696556" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="https://www.blast.hk/attachments/90314/" style="cursor: pointer;" title="1616438552482.png">
https://forum.antichat.xyz/attachments/27696556/

Это из краш-лога одного пользователя, который воспользовался моим скриптом (https://www.blast.hk/threads/76962/page-2#post-684791) без VirtualProtectEx.

Теперь по поводу вопроса 4.

Измени ту функцию на вот эту. Вероятно, у тебя возникнет ошибка, просто надо поставить многобайтовую кодировку. В VS это делается вот так (https://www.blast.hk/redirect/aHR0cHM6Ly9xbmEuaGFici5jb20vcS8zODIxNjM).

C++:






DWORD
getModuleBaseAddress
(
DWORD pID
,
TCHAR
*
szModuleName
)
// функция, которая получает этот адрес "samp.dll". её трогать не надо
{
DWORD dwModuleBaseAddress
=
0
;
HANDLE hSnapshot
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPMODULE
|
TH32CS_SNAPMODULE32
,
pID
)
;
if
(
hSnapshot
!=
INVALID_HANDLE_VALUE
)
{
MODULEENTRY32 ModuleEntry32
;
ModuleEntry32
.
dwSize
=
sizeof
(
MODULEENTRY32
)
;
if
(
Module32First
(
hSnapshot
,
&
ModuleEntry32
)
)
{
do
{
if
(
strcmp
(
ModuleEntry32
.
szModule
,
szModuleName
)
==
0
)
{
dwModuleBaseAddress
=
(
DWORD_PTR
)
ModuleEntry32
.
modBaseAddr
;
break
;
}
}
while
(
Module32Next
(
hSnapshot
,
&
ModuleEntry32
)
)
;
}
CloseHandle
(
hSnapshot
)
;
}
return
dwModuleBaseAddress
;
}

Gafask
22.03.2021, 23:29
Отвечаю на вопросы 1, 2 и 3.
VirtualProtectEx нужен для того, чтобы установить нужному кусочку памяти необходимый уровень защиты для того, чтобы читать и записывать данные. Условно: сказать программе, что есть разрешение на запись/чтение этого участка памяти.
Использовать стоит везде, где ты её читаешь или записываешь.
Последствия, с которыми сталкивался я, – краш от античита с причиной "Нарушение прав доступа к памяти". Пример:

Это из краш-лога одного пользователя, который воспользовался моим скриптом (https://www.blast.hk/threads/76962/page-2#post-684791) без VirtualProtectEx.

Теперь по поводу вопроса 4.
Измени ту функцию на вот эту. Вероятно, у тебя возникнет ошибка, просто надо поставить многобайтовую кодировку. В VS это делается вот так (https://www.blast.hk/redirect/aHR0cHM6Ly9xbmEuaGFici5jb20vcS8zODIxNjM).

C++:






DWORD
getModuleBaseAddress
(
DWORD pID
,
TCHAR
*
szModuleName
)
// функция, которая получает этот адрес "samp.dll". её трогать не надо
{
DWORD dwModuleBaseAddress
=
0
;
HANDLE hSnapshot
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPMODULE
|
TH32CS_SNAPMODULE32
,
pID
)
;
if
(
hSnapshot
!=
INVALID_HANDLE_VALUE
)
{
MODULEENTRY32 ModuleEntry32
;
ModuleEntry32
.
dwSize
=
sizeof
(
MODULEENTRY32
)
;
if
(
Module32First
(
hSnapshot
,
&
ModuleEntry32
)
)
{
do
{
if
(
strcmp
(
ModuleEntry32
.
szModule
,
szModuleName
)
==
0
)
{
dwModuleBaseAddress
=
(
DWORD_PTR
)
ModuleEntry32
.
modBaseAddr
;
break
;
}
}
while
(
Module32Next
(
hSnapshot
,
&
ModuleEntry32
)
)
;
}
CloseHandle
(
hSnapshot
)
;
}
return
dwModuleBaseAddress
;
}











Спасибо за ответ , я вам очень признателен , теперь буду юзать VirtualProtectEx ну или просто переделаю ReadProcessMemory c встроенным VirtualProtectEx в нее🥸🤠 это должно уменьшить код ) .

Про стиль общения это маска дабы общение было приятным ( 🥷я не такой🥷 ) . 🤩 🥰 😀

Vintik
22.03.2021, 23:41
Спасибо за ответ , я вам очень признателен , теперь буду юзать VirtualProtectEx ну или просто переделаю ReadProcessMemory c встроенным VirtualProtectEx в нее🥸🤠 это должно уменьшить код ) .
Про стиль общения это маска дабы общение было приятным ( 🥷я не такой🥷 ) . 🤩 🥰 😀


Вот такое есть готовое решение с использованием шаблонов (template). Просто в начало кода закинуть эти функции.

C++:






template

T
readMem
(
DWORD address
)
{
T buffer
;
DWORD oldProtect
=
0
;
VirtualProtectEx
(
process
,
(
void
*
)
address
,
sizeof
(
buffer
)
,
PAGE_EXECUTE_READWRITE
,
&
oldProtect
)
;
ReadProcessMemory
(
process
,
(
void
*
)
address
,
&
buffer
,
sizeof
(
buffer
)
,
0
)
;
VirtualProtectEx
(
process
,
(
void
*
)
address
,
sizeof
(
buffer
)
,
oldProtect
,
NULL
)
;
return
buffer
;
}
template

void
writeMem
(
DWORD address
,
T value
)
{
DWORD oldProtect
=
0
;
VirtualProtectEx
(
process
,
(
void
*
)
address
,
sizeof
(
value
)
,
PAGE_EXECUTE_READWRITE
,
&
oldProtect
)
;
WriteProcessMemory
(
process
,
(
void
*
)
address
,
&
value
,
sizeof
(
value
)
,
0
)
;
VirtualProtectEx
(
process
,
(
void
*
)
address
,
sizeof
(
value
)
,
oldProtect
,
NULL
)
;
}




Использовать его вот так:

C++:






auto
money
=
readMem

(
0xB6F5F0
)
;
// int – тип данных. обязательно надо указывать




(этот код запишет в moneyтвоё состояние, в смысле сколько денег)

Или вот так:

C++:






auto
CPed
=
readMem

(
0xB6F5F0
)
;
// DWORD указывать, чтобы знать какой тип данных надо считать.
float
health
=
55.0
;
writeMem

(
CPed
+
0x540
,
health
)
;
// float так же обязательно надо указывать.




(а этот изменит твоё здоровье до 55 единиц)



Просто и со вкусом

kin4stat
23.03.2021, 00:26
Просто и со вкусом


А зачем для записи в свой процесс использовать WPM?

Vintik
23.03.2021, 00:37
А зачем для записи в свой процесс использовать WPM?


Чё в свой то? Прочитай заголовок темы, и задай вопрос повторно, но уже себе.

Gafask
23.03.2021, 00:56
Вот такое есть готовое решение с использованием шаблонов (template). Просто в начало кода закинуть эти функции.

C++:






template

T
readMem
(
DWORD address
)
{
T buffer
;
DWORD oldProtect
=
0
;
VirtualProtectEx
(
process
,
(
void
*
)
address
,
sizeof
(
buffer
)
,
PAGE_EXECUTE_READWRITE
,
&
oldProtect
)
;
ReadProcessMemory
(
process
,
(
void
*
)
address
,
&
buffer
,
sizeof
(
buffer
)
,
0
)
;
VirtualProtectEx
(
process
,
(
void
*
)
address
,
sizeof
(
buffer
)
,
oldProtect
,
NULL
)
;
return
buffer
;
}
template

void
writeMem
(
DWORD address
,
T value
)
{
DWORD oldProtect
=
0
;
VirtualProtectEx
(
process
,
(
void
*
)
address
,
sizeof
(
value
)
,
PAGE_EXECUTE_READWRITE
,
&
oldProtect
)
;
WriteProcessMemory
(
process
,
(
void
*
)
address
,
&
value
,
sizeof
(
value
)
,
0
)
;
VirtualProtectEx
(
process
,
(
void
*
)
address
,
sizeof
(
value
)
,
oldProtect
,
NULL
)
;
}




Использовать его вот так:

C++:






auto
money
=
readMem

(
0xB6F5F0
)
;
// int – тип данных. обязательно надо указывать




(этот код запишет в moneyтвоё состояние, в смысле сколько денег)
Или вот так:

C++:






auto
CPed
=
readMem

(
0xB6F5F0
)
;
// DWORD указывать, чтобы знать какой тип данных надо считать.
float
health
=
55.0
;
writeMem

(
CPed
+
0x540
,
health
)
;
// float так же обязательно надо указывать.




(а этот изменит твоё здоровье до 55 единиц)



Просто и со вкусом




1.Данный вариант лучше того ?

2. Или есть свои плюсы и минусы ?

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

Vintik
23.03.2021, 01:21
1.Данный вариант лучше того ?

2. Или есть свои плюсы и минусы ?

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


Лучше чего? Это один и тот же код.

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

Я сделал то, что хотел ты



Спасибо за ответ , я вам очень признателен , теперь буду юзать VirtualProtectEx ну или просто переделаю ReadProcessMemory c встроенным VirtualProtectEx в нее🥸🤠 это должно уменьшить код ) .

Gafask
23.03.2021, 01:44
Лучше чего? Это один и тот же код.
Просто в этом я объединил чтение/запись в память и установку защиты на адрес в одну функцию, отсюда и "визуальный эффект перспективности".

Я сделал то, что хотел ты


А да ? Круто , я уже сонный и так как ты мне дал инфу которую я долго ждал , я сижу и пишу универсальную дичь , хотя она мне не нужна будет но чисто что-то меня двигает ее писать ) . Лучше бы в доту поиграл ей богу . 🙄

kin4stat
23.03.2021, 01:45
Чё в свой то? Прочитай заголовок темы, и задай вопрос повторно, но уже себе.


у тебя в асишнике та же дичь была

Vintik
23.03.2021, 03:28
у тебя в асишнике та же дичь была


В асишке не было дичи. Там было *(float*)0xb6f600 и т. д.

rumboorumboo
15.11.2021, 06:47
В асишке не было дичи. Там было *(float*)0xb6f600 и т. д.


Доброго времени суток! Если не затруднит, поясните пожалуйста. Выдаёт несколько ошибок, по приведению типов переменных...

В плюсах ноль, понимаю что это просто из за типизации, но как с этим быть не понимаю..



аргумент типа "WCHAR *" несовместим с параметром типа "const char *"

аргумент типа "TCHAR *" несовместим с параметром типа "const char *" mBYTE

"int strcmp(const char *,const char *)": невозможно преобразовать аргумент 1 из "WCHAR [256]" в "const char *"





аргумент типа "const wchar_t *" несовместим с параметром типа "TCHAR *" 53

"DWORD getModuleBaseAddress(DWORD,TCHAR *)": невозможно преобразовать аргумент 2 из "const wchar_t [11]" в "TCHAR *"





=: преобразование "DWORD_PTR" в "DWORD", возможна потеря данных





#include

#include

#include

#include

#include

#include

using namespace std

Vintik
15.11.2021, 15:35
Доброго времени суток! Если не затруднит, поясните пожалуйста. Выдаёт несколько ошибок, по приведению типов переменных...
В плюсах ноль, понимаю что это просто из за типизации, но как с этим быть не понимаю..


аргумент типа "WCHAR *" несовместим с параметром типа "const char *"

аргумент типа "TCHAR *" несовместим с параметром типа "const char *" mBYTE

"int strcmp(const char *,const char *)": невозможно преобразовать аргумент 1 из "WCHAR [256]" в "const char *"




аргумент типа "const wchar_t *" несовместим с параметром типа "TCHAR *" 53

"DWORD getModuleBaseAddress(DWORD,TCHAR *)": невозможно преобразовать аргумент 2 из "const wchar_t [11]" в "TCHAR *"




=: преобразование "DWORD_PTR" в "DWORD", возможна потеря данных




#include

#include

#include

#include

#include

#include

using namespace std


Поставь в настройках многобайтовую кодировку.