-
Автор темы
- #1
Мотиувацию я поднял и решил, всё-таки, разобраться с Mcode (Machine code). В прошлом гайде про Fcode, я показывал костыль с загрузкой .dll в AutoHotkey скрипт. Все работало замечательно, но костыли - это не хорошо, нужно исправлять ситуацию. Для ленивых, готовый скрипт со всеми моими функциями в самом конце.
-Почему костыль?
-Лишний .dll файл, который оставляет след.
И так, напомню, Fcode - это .dll файл на языке C++, в котором прописана логика сканирования байт модуля процесса или всех модулей и родительского процесса в целом. Чтобы эта шарманка работала, данную .dll приходилось загружать в AutoHotkey скрипт путём
Как говорит
На компилируемом языке (например. C++) компилятор создает такой Код напрямую.
ЦП непосредственно способен читать такой код.
MCode - это такой скомпилированный код, который можно использовать внутри скрипта AHK."
Вот как выглядит код на C, сканирующий байты на нужную нам последовательность:
Вот как вызывать эту функцию поиска с помощью AutoHotkey:
Допишем немного логики уже внутри AHK, и на выходе получаем функцию поиска паттерна внутри определенного модуля:
Инструмент, который я использовал для создания скомпилированного кода, называется
Как и обещал, моя база, которой пользуюсь лично, работает только в 64-битном режиме, и никак не доходят руки исправить работоспособность в 32-битном режиме. Кто решит эту проблему, с меня цьом в лобик (не в лобок).
Сама база:
Осталось организовать поиск по всем модулям для тех, кому это нужно, но по моим наблюдениям, поиск внутри модуля более удобен. Всем мира!
-Почему костыль?
-Лишний .dll файл, который оставляет след.
И так, напомню, Fcode - это .dll файл на языке C++, в котором прописана логика сканирования байт модуля процесса или всех модулей и родительского процесса в целом. Чтобы эта шарманка работала, данную .dll приходилось загружать в AutoHotkey скрипт путём
#DllLoad "*i Fcode64.dll"
и вызывать с помощью DllCall("Fcode64\module"
. Теперь эту гадость можно выкинуть на помойку, ибо есть Mcode, который в разы удобнее в использовании, так как для его использования не нужно загружать сторонние .dll и другие библиотеки, а скорость, как всегда, осталась прежней, потому что код написан на языке C.Как говорит
Пожалуйста, авторизуйтесь для просмотра ссылки.
- "Сценарии AHK образуют противоположность скомпилированного кода. В сценарии AHK интерпретатор просматривает текст сценария, а затем выполняет соответствующий код.На компилируемом языке (например. C++) компилятор создает такой Код напрямую.
ЦП непосредственно способен читать такой код.
MCode - это такой скомпилированный код, который можно использовать внутри скрипта AHK."
Вот как выглядит код на C, сканирующий байты на нужную нам последовательность:
AOB:
#include <stdio.h>
#include <string.h>
int compareBytes(char *buffer, char *pattern, int bufferLength, int patternLength, int extra) {
int j;
for (int i = 0; i <= bufferLength - patternLength; i++) {
for (j = 0; j < patternLength; j++) {
if (pattern[j] != -1 && buffer[i + j] != pattern[j]) {
break;
}
}
if (j == patternLength) {
return i + extra;
}
}
return -100;
}
AutoHotkey v2:
result := DllCall(MCode("2,x86:VVdWU4tEJCCLbCQci1wkGCnFeEqLdCQUMf+NtgAAAAAx0oXAfiqNtCYAAAAAjXYAD7YME4D5/3QFOgwWdRKDwgE50HXri0QkJFteAfhfXcM50HTxg8cBg8YBOf19wlu4nP///15fXcM=,x64:VlNIidZIicsx0kUpyHhOSYnyMclFhcl+Nw8fgAAAAABFD7YaQYD7/3QLjQQRSJhEOhwDdRuDwQFJg8IBQTnJdd+LRCQ4AdBbXsNmDx9EAABBOcl07IPCAUE50H2yuJz///9bXsM="), "Ptr", byte, "Ptr", create_array_cpp, "Int", byte.Size, "Int", create_array_cpp.Size, "Int", EXTRA, "Cdecl")
MsgBox(result)
MCode(mcode)
{
global
e := [[0x00000004], [0x00000001]]
c := (A_PtrSize == 8) ? "x64" : "x86"
if (!RegExMatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", &m))
{
return
}
if (!DllCall("crypt32\CryptStringToBinary", "Str", m[3], "UInt", 0, "UInt", e[m[1]][1], "Ptr", 0, "UInt*", &s := 0, "Ptr", 0, "Ptr", 0))
{
return
}
p := DllCall("GlobalAlloc", "UInt", 0, "Ptr", s, "Ptr")
if (c == "x64")
{
DllCall("VirtualProtect", "Ptr", p, "Ptr", s, "UInt", 0x40, "UInt*", &op := 0)
}
if (DllCall("crypt32\CryptStringToBinary", "Str", m[3], "UInt", 0, "UInt", e[m[1]][1], "Ptr", p, "UInt*", s, "Ptr", 0, "Ptr", 0))
{
return p
}
DllCall("GlobalFree", "Ptr", p)
}
FAST_SEARCH_SIGNATURE_IN_MODULE:
;Примеры для получения смещений в CS2
;OFFSETS
dwLocalPlayerController := READ_INT32(TempAddress := FAST_SEARCH_SIGNATURE_IN_MODULE("48 8B 05 ?? ?? ?? ?? 48 85 C0 74 4F", 3)) + TempAddress - Client + 4
dwLocalPlayerPawn := READ_INT32(TempAddress := FAST_SEARCH_SIGNATURE_IN_MODULE("48 8D 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 83 EC ?? 8B 0D", 3)) + TempAddress - Client + 0x118 + 4
dwEntityList := READ_INT32(TempAddress := FAST_SEARCH_SIGNATURE_IN_MODULE("48 8B 0D ?? ?? ?? ?? 48 89 7C 24 ?? 8B FA C1 EB", 3)) + TempAddress - Client + 4
;NETVARS
m_fFlags := READ_INT32(FAST_SEARCH_SIGNATURE_IN_MODULE("F6 80 ?? ?? ?? ?? ?? 75 ?? 48 8B 0D", 2))
m_iHealth_Controller := READ_INT32(FAST_SEARCH_SIGNATURE_IN_MODULE("8B 81 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC CC 40 57", 2))
m_iHealth_Pawn := READ_INT32(FAST_SEARCH_SIGNATURE_IN_MODULE("8B 81 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC CC 40 53 48 83 EC ?? 33 C9 E8 ?? ?? ?? ?? 48 8B D8 48 85 C0 0F 84", 2))
FAST_SEARCH_SIGNATURE_IN_MODULE(PATTERN := "", EXTRA := 0, START_ADDRESS := Client, END_ADDRESS := modBaseSize)
{
static MEM_COMMIT := 0x1000
static PAGE_NOACCESS := 0x01
MEMORY_BASIC_INFORMATION := Buffer(A_PtrSize ? 48 : 28, 0)
PATTERN := StrSplit(StrReplace(RegExReplace(StrReplace(" " PATTERN, A_Space, " 0x"), A_Space, "", , 1, 1), "0x??", "-1"), A_Space)
create_array_cpp := Buffer(PATTERN.Length * 1)
loop PATTERN.Length
{
NumPut("Char", PATTERN[A_Index], create_array_cpp.Ptr, (A_Index - 1) * 1)
}
RegionSize := 0
while RegionSize <= modBaseSize
{
if(DllCall("VirtualQueryEx", "Ptr", ProcessHandle, "Ptr", START_ADDRESS += RegionSize, "Ptr", MEMORY_BASIC_INFORMATION, "Ptr", MEMORY_BASIC_INFORMATION.Size))
{
BaseAddress := NumGet(MEMORY_BASIC_INFORMATION, 0, "Ptr")
RegionSize := NumGet(MEMORY_BASIC_INFORMATION, (A_PtrSize = 8 ? 24 : 12), "Ptr")
Protect := NumGet(MEMORY_BASIC_INFORMATION, (A_PtrSize = 8 ? 36 : 20), "Ptr")
if (Protect && MEM_COMMIT and not Protect & PAGE_NOACCESS)
{
byte := Buffer(RegionSize, 0)
if (DllCall("Kernel32\ReadProcessMemory", "Ptr", ProcessHandle, "Ptr", BaseAddress, "Ptr", byte, "Ptr", RegionSize, "UInt*", 0))
{
result := DllCall(MCode("2,x86:VVdWU4tEJCCLbCQci1wkGCnFeEqLdCQUMf+NtgAAAAAx0oXAfiqNtCYAAAAAjXYAD7YME4D5/3QFOgwWdRKDwgE50HXri0QkJFteAfhfXcM50HTxg8cBg8YBOf19wlu4nP///15fXcM=,x64:VlNIidZIicsx0kUpyHhOSYnyMclFhcl+Nw8fgAAAAABFD7YaQYD7/3QLjQQRSJhEOhwDdRuDwQFJg8IBQTnJdd+LRCQ4AdBbXsNmDx9EAABBOcl07IPCAUE50H2yuJz///9bXsM="), "Ptr", byte, "Ptr", create_array_cpp, "Int", byte.Size, "Int", create_array_cpp.Size, "Int", EXTRA, "Cdecl")
if (result != -100)
{
return Format("0x{:02X}", BaseAddress + result)
}
}
}
}
}
return -100
}
Пожалуйста, авторизуйтесь для просмотра ссылки.
, а компилятор, который я использовал, -
Пожалуйста, авторизуйтесь для просмотра ссылки.
(no ad).Как и обещал, моя база, которой пользуюсь лично, работает только в 64-битном режиме, и никак не доходят руки исправить работоспособность в 32-битном режиме. Кто решит эту проблему, с меня цьом в лобик (не в лобок).
Сама база:
AutoHotkey v2:
#SingleInstance Force
CONNECTING_TO_GAME("cs2.exe", "client.dll")
;OFFSETS
dwLocalPlayerController := READ_INT32(TempAddress := FAST_SEARCH_SIGNATURE_IN_MODULE("48 8B 05 ?? ?? ?? ?? 48 85 C0 74 4F", 3)) + TempAddress - Client + 4
dwLocalPlayerPawn := READ_INT32(TempAddress := FAST_SEARCH_SIGNATURE_IN_MODULE("48 8D 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 83 EC ?? 8B 0D", 3)) + TempAddress - Client + 0x118 + 4
dwEntityList := READ_INT32(TempAddress := FAST_SEARCH_SIGNATURE_IN_MODULE("48 8B 0D ?? ?? ?? ?? 48 89 7C 24 ?? 8B FA C1 EB", 3)) + TempAddress - Client + 4
;NETVARS
m_fFlags := READ_INT32(FAST_SEARCH_SIGNATURE_IN_MODULE("F6 80 ?? ?? ?? ?? ?? 75 ?? 48 8B 0D", 2))
m_iHealth_Controller := READ_INT32(FAST_SEARCH_SIGNATURE_IN_MODULE("8B 81 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC CC 40 57", 2))
m_iHealth_Pawn := READ_INT32(FAST_SEARCH_SIGNATURE_IN_MODULE("8B 81 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC CC 40 53 48 83 EC ?? 33 C9 E8 ?? ?? ?? ?? 48 8B D8 48 85 C0 0F 84", 2))
CONNECTING_TO_GAME(NAME_GAME, DLL_GAME)
{
global PID, Client, ProcessHandle
static PROCESS_VM_READ := 0x0010
static PROCESS_QUERY_INFORMATION := 0x0400
static PROCESS_ALL_ACCESS := 0x1F0FFF
if (!PID := ProcessWait(NAME_GAME, 60))
{
MsgBox("Игра не найдена!")
ExitApp()
}
ProcessHandle := DllCall("OpenProcess", "UInt", PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, "UChar", 0, "UInt", PID)
Client := GET_DLL_BASE(DLL_GAME, PID)
}
GET_DLL_BASE(DLL_GAME, PID)
{
static TH32CS_SNAPPROCESS := 0x00000002
static TH32CS_SNAPMODULE := 0x00000008
static TH32CS_SNAPMODULE32 := 0x00000010
global modBaseSize, hModule
while hSnapshot := DllCall("CreateToolhelp32Snapshot", "UInt", (TH32CS_SNAPPROCESS | TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32), "UInt", PID)
{
MODULEENTRY32 := Buffer(A_PtrSize = 8 ? 568 : 548, 0)
NumPut("UInt", MODULEENTRY32.Size, MODULEENTRY32, 0)
result := DllCall("Module32First", "UInt", hSnapshot, "Ptr", MODULEENTRY32.Ptr)
while result
{
if (DLL_GAME == StrGet(MODULEENTRY32.Ptr + (A_PtrSize = 8 ? 48 : 32), 256, "CP0"))
{
modBaseSize := NumGet(MODULEENTRY32, (A_PtrSize = 8 ? 32 : 24), "Ptr")
hModule := NumGet(MODULEENTRY32, (A_PtrSize = 8 ? 40 : 28), "Ptr")
DllCall("CloseHandle", "UInt", hSnapshot)
return modBaseAddr := NumGet(MODULEENTRY32, (A_PtrSize = 8 ? 24 : 20), "Ptr")
}
result := DllCall("Module32Next", "UInt", hSnapshot, "Ptr", MODULEENTRY32.Ptr)
}
DllCall("CloseHandle", "UInt", hSnapshot)
}
}
FAST_SEARCH_SIGNATURE_IN_MODULE(PATTERN := "", EXTRA := 0, START_ADDRESS := Client, END_ADDRESS := modBaseSize)
{
static MEM_COMMIT := 0x1000
static PAGE_NOACCESS := 0x01
MEMORY_BASIC_INFORMATION := Buffer(A_PtrSize ? 48 : 28, 0)
PATTERN := StrSplit(StrReplace(RegExReplace(StrReplace(" " PATTERN, A_Space, " 0x"), A_Space, "", , 1, 1), "0x??", "-1"), A_Space)
create_array_cpp := Buffer(PATTERN.Length * 1)
loop PATTERN.Length
{
NumPut("Char", PATTERN[A_Index], create_array_cpp.Ptr, (A_Index - 1) * 1)
}
RegionSize := 0
while RegionSize <= modBaseSize
{
if(DllCall("VirtualQueryEx", "Ptr", ProcessHandle, "Ptr", START_ADDRESS += RegionSize, "Ptr", MEMORY_BASIC_INFORMATION, "Ptr", MEMORY_BASIC_INFORMATION.Size))
{
BaseAddress := NumGet(MEMORY_BASIC_INFORMATION, 0, "Ptr")
RegionSize := NumGet(MEMORY_BASIC_INFORMATION, (A_PtrSize = 8 ? 24 : 12), "Ptr")
Protect := NumGet(MEMORY_BASIC_INFORMATION, (A_PtrSize = 8 ? 36 : 20), "Ptr")
if (Protect && MEM_COMMIT and not Protect & PAGE_NOACCESS)
{
byte := Buffer(RegionSize, 0)
if (DllCall("Kernel32\ReadProcessMemory", "Ptr", ProcessHandle, "Ptr", BaseAddress, "Ptr", byte, "Ptr", RegionSize, "UInt*", 0))
{
result := DllCall(MCode("2,x86:VVdWU4tEJCCLbCQci1wkGCnFeEqLdCQUMf+NtgAAAAAx0oXAfiqNtCYAAAAAjXYAD7YME4D5/3QFOgwWdRKDwgE50HXri0QkJFteAfhfXcM50HTxg8cBg8YBOf19wlu4nP///15fXcM=,x64:VlNIidZIicsx0kUpyHhOSYnyMclFhcl+Nw8fgAAAAABFD7YaQYD7/3QLjQQRSJhEOhwDdRuDwQFJg8IBQTnJdd+LRCQ4AdBbXsNmDx9EAABBOcl07IPCAUE50H2yuJz///9bXsM="), "Ptr", byte, "Ptr", create_array_cpp, "Int", byte.Size, "Int", create_array_cpp.Size, "Int", EXTRA, "Cdecl")
if (result != -100)
{
return Format("0x{:02X}", BaseAddress + result)
}
}
}
}
}
return -100
}
MCode(mcode)
{
global
e := [[0x00000004], [0x00000001]]
c := (A_PtrSize == 8) ? "x64" : "x86"
if (!RegExMatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", &m))
{
return
}
if (!DllCall("crypt32\CryptStringToBinary", "Str", m[3], "UInt", 0, "UInt", e[m[1]][1], "Ptr", 0, "UInt*", &s := 0, "Ptr", 0, "Ptr", 0))
{
return
}
p := DllCall("GlobalAlloc", "UInt", 0, "Ptr", s, "Ptr")
if (c == "x64")
{
DllCall("VirtualProtect", "Ptr", p, "Ptr", s, "UInt", 0x40, "UInt*", &op := 0)
}
if (DllCall("crypt32\CryptStringToBinary", "Str", m[3], "UInt", 0, "UInt", e[m[1]][1], "Ptr", p, "UInt*", s, "Ptr", 0, "Ptr", 0))
{
return p
}
DllCall("GlobalFree", "Ptr", p)
}
READ_BYTE(ADDRESS)
{
if (DllCall("Kernel32\ReadProcessMemory", "Ptr", ProcessHandle, "Ptr", ADDRESS, "UChar*", &BYTE := 0, "UInt", 1, "UInt*", 0))
return BYTE
}
READ_INT32(ADDRESS)
{
if (DllCall("Kernel32\ReadProcessMemory", "Ptr", ProcessHandle, "Ptr", ADDRESS, "UInt*", &INT32 := 0, "UInt", 4, "UInt*", 0))
return INT32
}
READ_INT64(ADDRESS)
{
if (DllCall("Kernel32\ReadProcessMemory", "Ptr", ProcessHandle, "Ptr", ADDRESS, "Ptr*", &UINT64 := 0, "UInt", 8, "UInt*", 0))
return UINT64
}
WRITE_BYTE(ADDRESS, VALUE)
{
return DllCall("Kernel32\WriteProcessMemory", "Ptr", ProcessHandle, "Ptr", ADDRESS, "UChar*", VALUE, "UInt", 1, "UInt *", 0)
}
WRITE_INT32(ADDRESS, VALUE)
{
return DllCall("Kernel32\WriteProcessMemory", "Ptr", ProcessHandle, "Ptr", ADDRESS, "UInt*", VALUE, "UInt", 4, "UInt *", 0)
}
WRITE_INT64(ADDRESS, VALUE)
{
return DllCall("Kernel32\WriteProcessMemory", "Ptr", ProcessHandle, "Ptr", ADDRESS, "Ptr*", VALUE, "UInt", 8, "UInt *", 0)
}
WRITE_FLOAT(ADDRESS, VALUE)
{
return DllCall("Kernel32\WriteProcessMemory", "Ptr", ProcessHandle, "Ptr", ADDRESS, "float*", VALUE, "UInt", 4, "UInt *", 0)
}
INS:: Pause -1
END:: ExitApp