local ffi = require("ffi")
local TH32CS_SNAPPROCESS = 0x00000002
local TH32CS_SNAPMODULE = 0x00000008
local INVALID_HANDLE_VALUE = ffi.cast("void*", -1)
ffi.cdef[[
typedef uint32_t DWORD;
typedef void* HANDLE;
typedef struct {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
uint32_t* th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
int pcPriClassBase;
DWORD dwFlags;
char szExeFile[260];
} PROCESSENTRY32;
typedef struct {
DWORD dwSize;
DWORD th32ProcessID;
DWORD th32ModuleID;
DWORD th32ModuleUsage;
DWORD th32ModuleUsage2;
void* modBaseAddr;
DWORD modBaseSize;
HANDLE hModule;
char szModule[256];
char szExePath[260];
} MODULEENTRY32;
DWORD GetProcessId(HANDLE Process);
HANDLE CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
HANDLE OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId);
int ReadProcessMemory(int hProcess, int lpBaseAddress, char* lpBuffer, int nSize, int* lpNumberOfBytesRead);
int Process32First(HANDLE hSnapshot, void* lppe);
int Process32Next(HANDLE hSnapshot, void* lppe);
int Module32First(HANDLE hSnapshot, MODULEENTRY32* lpme);
int Module32Next(HANDLE hSnapshot, MODULEENTRY32* lpme);
int CloseHandle(HANDLE hObject);
]]
local function getProcessId(processName)
local hSnapshot = ffi.C.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
if hSnapshot == INVALID_HANDLE_VALUE then
error("Failed to create a snapshot of the processes")
end
local pe32 = ffi.new("PROCESSENTRY32")
pe32.dwSize = ffi.sizeof("PROCESSENTRY32")
if ffi.C.Process32First(hSnapshot, pe32) == 0 then
ffi.C.CloseHandle(hSnapshot)
error("Failed to retrieve information about the first process in the snapshot")
end
repeat
if ffi.string(pe32.szExeFile) == processName then
ffi.C.CloseHandle(hSnapshot)
return pe32.th32ProcessID
end
until ffi.C.Process32Next(hSnapshot, pe32) == 0
ffi.C.CloseHandle(hSnapshot)
return nil
end
local function getModuleBaseAddress(processId, moduleName)
local hSnapshot = ffi.C.CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId)
if hSnapshot == INVALID_HANDLE_VALUE then
error("Failed to create a snapshot of the modules")
end
local me32 = ffi.new("MODULEENTRY32")
me32.dwSize = ffi.sizeof("MODULEENTRY32")
if ffi.C.Module32First(hSnapshot, me32) == 0 then
ffi.C.CloseHandle(hSnapshot)
error("Failed to retrieve information about the first module in the snapshot")
end
repeat
if ffi.string(me32.szModule) == moduleName then
ffi.C.CloseHandle(hSnapshot)
return tonumber(ffi.cast("uintptr_t", me32.modBaseAddr))
end
until ffi.C.Module32Next(hSnapshot, me32) == 0
ffi.C.CloseHandle(hSnapshot)
return nil
end
local PROCESS_VM_READ = 0x100010000
local processId = getProcessId("csgo.exe")
local baseAddress = getModuleBaseAddress(processId, "ArcticTech.dll")
local offset = 0x868F
local handle = ffi.C.OpenProcess(PROCESS_VM_READ, false, processId)
if handle == nil then
error("Failed to open the process")
end
local buffer = ffi.new("char[4]")
local bytesRead = ffi.new("DWORD[1]")
if ffi.C.ReadProcessMemory(ffi.cast("uintptr_t", handle), baseAddress + offset, buffer, 4, bytesRead) == 0 then
error("Failed to read process memory")
end
print(buffer)