I was learning how to interact with processes from a channel called "null". I wrote his program and tried to understand how everything worked. But when i executed it the wpm function did work but then the target program immediately closed after it incremented the same variable I was writing to.
Anyways here's the code.
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
HANDLE hProc = NULL;
DWORD ProcId;
bool attatchProc(const char* ProcName)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(PROCESSENTRY32);
auto hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcSnap == INVALID_HANDLE_VALUE)
return false;
while (Process32Next(hProcSnap, &procEntry)) {
std::cout << procEntry.szExeFile << std::endl;
if (!strcmp(ProcName, procEntry.szExeFile)) {
std::cout << "Process Found!\n Heres the Process ID" << procEntry.th32ProcessID << std::endl;
ProcId = procEntry.th32ProcessID;
hProc = OpenProcess(PROCESS_ALL_ACCESS, false, ProcId);
if (hProc == NULL)
std::cout << "Sike you thought lmao" << std::endl;
CloseHandle(hProcSnap);
return true;
}
}
std::cout << "Process not found or other issue";
}
template <class DataType>
void wpm(DataType VarToWrite, DWORD addressToWrite)
{
WriteProcessMemory(hProc, (PVOID)addressToWrite, &VarToWrite, sizeof(DataType), 0);
}
int main()
{
DWORD memAddr = 0x012FF848;
attatchProc((char*)"Testing.exe");
while (1)
{
wpm<int>(68, memAddr);
}
}
You are not using Process32First to get the first entry in the snapshot. Microsoft Docs has a tutorial on how to do it correctly here
If you use the tutorial you can come up with your own version like mine, which includes exactly what you need and nothing else. I use TCHAR in this example so you can either include tchar.h or you can change it to match your coding style.
#include
DWORD GetProcId(const TCHAR* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_tcsicmp(procEntry.szExeFile, procName))
{
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
After calling this function you would check if the return is nonzero and then call OpenProcess() using the process id and the memory access permissions you require. If the process handle is nonzero you may then continue to write to the process memory. If you write to the incorrect memory address you will crash the program, so ensure you have the correct address by using the Visual Studio Debugger and comparing what you see against what you see in the target process using another debugger like Cheat Engine.
Related
I am making a DLL injector. A really simple one: console app, input DLL, input process. But I'm getting an error on line 26:
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
Can someone help me?
#include<Windows.h> //DWORD
#include <iostream>
#include <string>
#include <psapi.h> //EnumProcessModules
#include <VersionHelpers.h>
#include <atlstr.h> // CString
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
BOOL InjectDLL(DWORD ProcessID)
{
LPCSTR DLL_PATH = "dll file here";
LPVOID LoadLibAddy, RemoteString;
if (!ProcessID)
return false;
HANDLE Proc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, ProcessID);
if (!Proc)
{
std::cout << "OpenProcess() failed: " << GetLastError() << std::endl;
return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_PATH) + 1, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, RemoteString, (LPVOID)DLL_PATH, strlen(DLL_PATH)+1, NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
...
You did not say what kind of error you are getting. But I suspect you are getting a compile-time error on GetModuleHandle("kernel32.dll"). If your project is set to use the Unicode character set, you would need to use GetModuleHandle(L"kernel32.dll") instead. Or better, since GetModuleHandle() is a TCHAR-based macro, use TEXT("kernel32.dll") to match:
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
Otherwise, use GetModuleHandleA() or GetModuleHandleW() instead:
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryA");
That being said, you are also not doing any error handling when allocating memory or creating the remote thread. And your logic is incomplete as you are leaking allocated memory and resources. You need to wait for the remote thread to finish, and then free the virtual memory you allocate, and close the handle to the thread.
Try this instead:
#include <Windows.h> //DWORD
#include <iostream>
#include <string>
#include <psapi.h> //EnumProcessModules
#include <VersionHelpers.h>
#include <atlstr.h> // CString
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
bool InjectDLL(DWORD ProcessID)
{
LPCSTR DLL_PATH = "dll file here";
int DLL_PATH_SIZE = strlen(DLL_PATH) + 1;
if (ProcessID == 0)
return false;
FARPROC LoadLibAddy = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
if (!LoadLibAddy)
{
DWORD err = GetLastError();
std::cout << "Can't find LoadLibraryA: " << err << std::endl;
return false;
}
HANDLE Proc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, ProcessID);
if (!Proc)
{
DWORD err = GetLastError();
std::cout << "OpenProcess() failed: " << err << std::endl;
return false;
}
LPVOID RemoteString = VirtualAllocEx(Proc, NULL, DLL_PATH_SIZE, MEM_COMMIT, PAGE_READWRITE);
if (!RemoteString)
{
DWORD err = GetLastError();
std::cout << "VirtualAllocEx() failed: " << err << std::endl;
CloseHandle(Proc);
return false;
}
if (!WriteProcessMemory(Proc, RemoteString, DLL_PATH, DLL_PATH_SIZE, NULL))
{
DWORD err = GetLastError();
std::cout << "WriteProcessMemory() failed: " << err << std::endl;
VirtualFreeEx(Proc, RemoteString, 0, MEM_RELEASE);
CloseHandle(Proc);
return false;
}
HANDLE Thread = CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, RemoteString, NULL, NULL);
if (!Thread)
{
DWORD err = GetLastError();
std::cout << "CreateRemoteThread() failed: " << err << std::endl;
VirtualFreeEx(Proc, RemoteString, 0, MEM_RELEASE);
CloseHandle(Proc);
return false;
}
WaitForSingleObject(Thread, INFINITE);
// If the target process is 32bit, you can use GetExitCodeThread()
// to find out if LoadLibraryA() was successful or not.
//
// If the target process is 64bit, it is much harder to determine
// that. You would have to allocate an entire function containing
// shellcode that calls LoadLibraryA() and saves the result in
// memory that you can then read via ReadProcessMemory(). Or,
// you would have to enumerate the target process's modules list
// looking for the DLL that you just injected.
CloseHandle(Thread);
VirtualFreeEx(Proc, RemoteString, 0, MEM_RELEASE);
CloseHandle(Proc);
return true;
}
This program enumerate all handles and get their names.
For pID 4 OpenProcess gets error 5 with SeDebugPrivilege.
UAC off. Running from Admin.
Enable SeDebugPrivilege
BOOL EnableDebugPrivilege(BOOL bEnable)
{
HANDLE hToken = nullptr;
LUID luid;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) return FALSE;
TOKEN_PRIVILEGES tokenPriv;
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luid;
tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) return FALSE;
_tprintf(_T("Privileges error: %d\n", GetLastError()));
return TRUE;
}
Enumerate handles
DWORD EnumerateFileHandles(ULONG pid)
{
HINSTANCE hNtDll = LoadLibrary(_T("ntdll.dll"));
assert(hNtDll != NULL);
PFN_NTQUERYSYSTEMINFORMATION NtQuerySystemInformation =
(PFN_NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,
"NtQuerySystemInformation");
assert(NtQuerySystemInformation != NULL);
PFN_NTQUERYINFORMATIONFILE NtQueryInformationFile =
(PFN_NTQUERYINFORMATIONFILE)GetProcAddress(hNtDll,
"NtQueryInformationFile");
DWORD nSize = 4096, nReturn;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)
HeapAlloc(GetProcessHeap(), 0, nSize);
while (NtQuerySystemInformation(SystemExtendedHandleInformation, pSysHandleInfo,
nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
nSize += 4096;
pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION*)HeapAlloc(
GetProcessHeap(), 0, nSize);
}
DWORD dwFiles = 0;
_tprintf(_T("Handles Number: %d\n"), pSysHandleInfo->NumberOfHandles);
for (ULONG i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
{
PSYSTEM_HANDLE pHandle = &(pSysHandleInfo->Handles[i]);
if (pHandle->ProcessId == 4)
{
HANDLE hProcess = OpenProcess(
PROCESS_DUP_HANDLE, FALSE, pHandle->ProcessId);
if (hProcess == NULL)
{
_tprintf(_T("OpenProcess failed w/err 0x%08lx\n"), GetLastError());
continue;
}
HANDLE hCopy;
if (!DuplicateHandle(hProcess, (HANDLE)pHandle->Handle,
GetCurrentProcess(), &hCopy, MAXIMUM_ALLOWED, FALSE, 0))
continue;
TCHAR buf[MAX_PATH];
if (GetFinalPathNameByHandle(hCopy, buf, sizeof(buf), VOLUME_NAME_DOS))
wprintf(L"p%d:h%d:t%d:\t%s\n", pHandle->ProcessId, pHandle->Handle, pHandle->ObjectTypeNumber, buf);
CloseHandle(hProcess);
CloseHandle(hCopy);
}
}
HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
return dwFiles;
}
On windows 7 x64 it's work fine.
But on Windows 10 x64 OpenProcess returns error 5 with SeDebugPrivilege.
How open system process(pID 4) on windows 10.
You can't open a handle for it as the documentation for OpenProcess specifically says it'll fail:
If the specified process is the Idle process or one of the CSRSS
processes, this function fails and the last error code is
ERROR_ACCESS_DENIED because their access restrictions prevent
user-level code from opening them.
If you want to get system process names, you could try to use CreateToolhelp32Snapshot() to get the snapshot of the process, then use Process32First() and Process32Next() to enumerate the all process.
Here is an example:
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <string>
#include <TlHelp32.h>
using namespace std;
int main()
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//get the snapshot
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
cout << "CreateToolhelp32Snapshot Error!" << endl;
return false;
}
BOOL bResult = Process32First(hProcessSnap, &pe32);
int num(0);
while(bResult)
{
cout << "[" << ++num << "] : " << "Process Name:"<< pe32.szExeFile << " " << "ProcessID:" << pe32.th32ProcessID << endl;
bResult = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
}
Hope it could help you!
there's something wrong with this api. i already check return function. no error. but output nothing.
HANDLE hSnapProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
PROCESSENTRY32 process;
process.dwSize = sizeof(PROCESSENTRY32);
Process32First(hSnapProcess, &process);
do
{
if (process.th32ProcessID != 0)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process.th32ProcessID);
if (hProcess != NULL)
{
wchar_t filePath[MAX_PATH];
if (!GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH))
{
std::wcout << filePath << std::endl;
}
}
CloseHandle(hProcess);
}
} while (Process32Next(hSnapProcess, &process));
CloseHandle(hSnapProcess);
Two clear mistakes can be seen in your code, both can be understood by reading the documentation.
Firstly, in GetModuleFileNameEx:
The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights.
Your handle only has PROCESS_QUERY_INFORMATION.
Secondly, again in GetModuleFileNameEx:
If the function succeeds, the return value specifies the length of the string copied to the buffer.
If the function fails, the return value is zero.
Your logic is back-to-front. Replace:
if (!GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH))
with
if (GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH))
Nothing is wrong with this API, the only thing that's wrong here is your code.
The documentation clearly states that the return value of GetModuleFileNameExW is the length of the string copied to the buffer.
If the return value is 0, the function has failed.
So you simply need to write this:
...
if (GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH) != 0)
{
// handle "success" case
}
...
BTW CloseHandle(hProcess); should be inside the if (hProcess != NULL) block.
Full working example with error checks
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
int main()
{
HANDLE hSnapProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (hSnapProcess != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 process;
process.dwSize = sizeof(PROCESSENTRY32);
Process32First(hSnapProcess, &process);
do
{
if (process.th32ProcessID != 0)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process.th32ProcessID);
if (hProcess != NULL)
{
wchar_t filePath[MAX_PATH];
if (GetModuleFileNameExW(hProcess, NULL, filePath, MAX_PATH))
{
std::wcout << filePath << std::endl;
}
else
{
std::wcout << L"GetModuleFileNameExW failed with error" << GetLastError() << std::endl;
}
CloseHandle(hProcess);
}
}
} while (Process32Next(hSnapProcess, &process));
CloseHandle(hSnapProcess);
}
else
{
std::wcout << L"CreateToolhelp32Snapshot failed with error" << GetLastError() << std::endl;
}
}
With DLL injection, grabbing the base address of the process was as easy as using
GetModuleHandleW(0);
So I'm trying to grab the address without injection and I can't seem to get it to work. I've Googled some solutions and found others from stackoverflow but they don't seem to work. Here's what I'm using right now. I have the right headers and it compiles. It just doesn't work.
DWORD_PTR dwGetModuleBaseAddress(DWORD dwProcID, TCHAR *szModuleName)
{
DWORD_PTR dwModuleBaseAddress = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcID);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &ModuleEntry32))
{
do
{
if (_tcsicmp(ModuleEntry32.szModule, szModuleName) == 0)
{
dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
}
I try to cout this address and it just gives me 0. I think it might be the fact that I don't understand the second parameter. I'm just copying what I saw. Here's my main function.
int main() {
HWND hwnd = FindWindowA(NULL, gameName);
int x;
if (hwnd == NULL) {
cout << "Cannot find " << (string)gameName << " window" << endl;
cin >> x;
exit(-1);
}
DWORD procID;
GetWindowThreadProcessId(hwnd, &procID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
DWORD playerAddr = 0;
playerAddr = dwGetModuleBaseAddress(procID, _T("starbound.exe"));
cout << hex << playerAddr;
}
Some of this may be redundant because I'm just adding it to what I had before. I'm just not sure why it's not working.
Your code is correct, there is nothing wrong with it, I just tested it on x86 and x64.
Your problem is you need to run as administrator so you have correct security permissions to access the other process and you also should build your project as the same architecture, x86 or x64, as the target process.
If neither of those solutions fix it, then your 'gameName' variable or your module name are defined incorrectly.
If you use your dwModuleBaseAddress as a debug tool, it may be easier to spot the call that fails...
DWORD_PTR dwGetModuleBaseAddress(DWORD dwProcID, TCHAR *szModuleName)
{
DWORD_PTR dwModuleBaseAddress = (DWORD_PTR)-1; // unlikely value...
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcID);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
dwModuleBaseAddress = (DWORD_PTR)-2;
if (Module32First(hSnapshot, &ModuleEntry32))
{
do
{
--dwModuleBaseAddress;
if (_tcsicmp(ModuleEntry32.szModule, szModuleName) == 0)
{
dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
}
You can also check the error that caused the issue using GetLastError()
void PrintLastError()
{
LPTSTR psz;
DWORD dwError = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwError,
0,
(LPTSTR)&psz,
1024,
NULL);
_tprintf(_T("Windows reports error: (0x%08X): %s\n"), dwError, (psz) ? psz : _T("(null)"));
if (psz)
{
LocalFree(psz);
}
}
If all else fails, try running this example from msdn https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms686849(v=vs.85).aspx
It will print the exact string you want to match, the problem may come from there.
I am trying to fiddle around with CounterStrike in order to learn something about memory editing in C++. I used an offset dumper in order to obtain the static pointers and offsets that will lead to the temporary adresses of the dw_LocalPlayer, m_fFlags and dw_ForceJump. I am not using any memory editing classes like VAMemory.dll, just ReadProcessMemory. I found out that when the player is in the air, the value of m_fFlags is "256". When he is on the ground it is "257". However, I am not able to read these to values once I obtained a temporary adress. Here is the code:
// ConsoleApplication1.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <cstdint>
#define dwLocalPlayer 0xAB06EC
#define dwForceJump 0x4D6A684
#define fFlags 0x100
int main()
{
HWND hwnd = FindWindowA(NULL, "Counter-Strike: Global Offensive");
if (hwnd == NULL)
{
std::cout << "Error!" << std::endl;
exit(-1);
system("PAUSE");
}
else
{
DWORD pid = GetWindowThreadProcessId(hwnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
DWORD tempadress;
ReadProcessMemory(pHandle, (PBYTE*)dwLocalPlayer, &tempadress, sizeof(tempadress), NULL);
DWORD fl_Onground = tempadress + fFlags;
std::cout << fl_Onground << "\n" << &fl_Onground << std::endl;
system("PAUSE");
}
return 0;
}
I would really appreciate some help and suggestions to the code since Im stuck on this since a few days. I am only trying to gain knowledge on C++ here, I do not want to code any cheats or whatnot...
You are not using the offsets correctly. The offsets that are supplied by the dumper need to be added to other addresses, such as the base address of the module.
dwLocalPlayer is not a pointer to the local player, it's an offset. You have to add it to the address of client_panorama.dll.
Secondly:
DWORD fl_Onground = tempadress + fFlags;
This gives you the address of fl_Onground but you never read it's value, your subsequent std::cout will print the address not the value.
Fixed code here:
#include <iostream>
#include <Windows.h>
#include <cstdint>
#include <TlHelp32.h>
#define dwLocalPlayer 0xD30B94
#define dwForceJump 0x51EE680
#define m_fFlags 0x104
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (!_wcsicmp(modEntry.szModule, modName))
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
int main()
{
HWND hwnd = FindWindowA(NULL, "Counter-Strike: Global Offensive");
if (hwnd == NULL)
{
std::cout << "Error!\n" << std::endl;
exit(-1);
system("PAUSE");
}
else
{
DWORD pid = GetWindowThreadProcessId(hwnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
uintptr_t dllBaseAddress = 0;
dllBaseAddress = GetModuleBaseAddress(pid, L"client_panorama.dll");
DWORD tempadress;
ReadProcessMemory(pHandle, (BYTE*)(dllBaseAddress + dwLocalPlayer), &tempadress, sizeof(tempadress), NULL);
BYTE fl_Onground = 0;
ReadProcessMemory(pHandle, (BYTE*)(tempadress + m_fFlags), &fl_Onground, sizeof(fl_Onground), NULL);
std::cout << fl_Onground << "\n" << &fl_Onground << std::endl;
getchar();
}
return 0;
}