|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Harambe132 How do I cheat? Reputation: 0
Joined: 19 Feb 2017 Posts: 3
|
Posted: Sun Feb 19, 2017 10:48 pm Post subject: c++ basic memory scanner |
|
|
I am trying to read the string in this process i made, bb = "stringstuff", with len of 11.
Code: |
#include <iostream>
#include <windows.h>
struct stuff {
int i = 0;
int b = 1;
const char* bb = "stringstuff";
stuff() { std::cout << "stuff created\n" << "i: " << i << "\nb: " << b << "\nbb: " << bb << "\n" << std::endl; }
};
int main() {
stuff *stuffPtr = new stuff();//creates a stuff thing with its default values set
while ((*stuffPtr).bb == "stringstuff") {
std::cout << "i: " << stuffPtr->i << "\n";
std::cout << "b: " << stuffPtr->b << "\n";
std::cout << "bb: " << stuffPtr->bb << "\n\n";
std::cout << &stuffPtr->bb << std::end;
Sleep(10000);
if (stuffPtr->bb != "stringstuff") {
std::cout << "bb has been changed to: " << stuffPtr->bb << std::endl;
Sleep(30000);
}
}
delete stuffPtr;
return 1;
}
|
i am using this other process
[spoiler]
Code: |
#include "windows.h"
#include "Tlhelp32.h"
#include <iostream>
#include <vector>
class Memory {
private:
DWORD _processID = 0;
DWORD _processAddress = 0;
HANDLE _snapshot=0;
HANDLE _handle=0;
const char* _processName=0;
public:
Memory(const char* processName);
~Memory();
void getProcessID();
void getModuleAddress();
template<typename TYPE>
TYPE read(DWORD address);
char* query(const char *data, size_t len);
};
int main()
{
Memory *Mem = new Memory("process1.exe");//processID Address and handle PROCESS_QUERY_INFORMATION.
const char* hey = Mem->query("stringstuff",11);
std::cout << hey << std::endl;
system("PAUSE");
delete Mem;
return 0; //Mem.read<int>(0x0);
}
Memory::Memory(const char* processName)
{
_processName = processName;
getProcessID();
getModuleAddress();
_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, _processID);//PROCESS_QUERY_INFORMATION, PROCESS_VM_READ
if (_handle == NULL) {
std::cout << "handle error\n";
}
}
Memory::~Memory()
{
CloseHandle(_handle);
}
void Memory::getProcessID()
{
PROCESSENTRY32 _processEntry;
_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
while (!_processID)
{
if (Process32First(_snapshot, &_processEntry))
{
do
{
if (!strcmp((const char*)_processEntry.szExeFile, _processName))
{
_processID = _processEntry.th32ProcessID;
break;
}
} while (Process32Next(_snapshot, &_processEntry));
}
if (!_processID)
{
std::cout << _processName << " not found.\n";
break;
}
}
CloseHandle(_snapshot);
}
void Memory::getModuleAddress()
{
MODULEENTRY32 _moduleEntry;
_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, _processID);
_moduleEntry.dwSize = sizeof(MODULEENTRY32);
while (_processAddress == 0)
{
do
{
if (!strcmp((const char*)_moduleEntry.szModule, _processName))
{
_processAddress = (unsigned int)_moduleEntry.modBaseAddr;
break;
}
} while (Module32Next(_snapshot, &_moduleEntry));
if (_processAddress == 0)
{
std::cout << "Failed to find module " << _processName << std::endl;
break;
}
}
std::cout << "Base Address: " << std::hex << _processAddress << std::dec << std::endl;
CloseHandle(_snapshot);
}
template<typename TYPE>
TYPE Memory::read(DWORD address)
{
TYPE _buffer = -1;
ReadProcessMemory(_handle, (void*)address, &_int, sizeof(_buffer), 0);
return _buffer;
}
char* Memory::query(const char *data,size_t len)
{
_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, _processID);//PROCESS_QUERY_INFORMATION, PROCESS_VM_READ
DWORD dwProtectionMask = PAGE_READONLY | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOMBINE;
SYSTEM_INFO si;
GetSystemInfo(&si);
MEMORY_BASIC_INFORMATION memoryInfo;
char* p = 0;
int page = 0;
while (p < si.lpMaximumApplicationAddress)
{
if (VirtualQueryEx(_handle, p, &memoryInfo, sizeof(memoryInfo)) == sizeof(memoryInfo))
{
p = (char*)memoryInfo.BaseAddress;
char *buffer = new char[memoryInfo.RegionSize];
SIZE_T bytesRead;
if (ReadProcessMemory(_handle, p, &buffer[0], memoryInfo.RegionSize, &bytesRead))
{
for (size_t i = 0; i < (bytesRead - len); ++i)
{
if (memcmp(data, &buffer[i], len) == 0)
{
std::cout << page << " end\n";
return (char*)p + i;
}
}
}
p += memoryInfo.RegionSize;
delete[] buffer;
}
page++;
std::cout << page << ":pages read.\n";
Sleep(50);
}
return "no find";
}
|
[/spoiler]
specifically
Code: |
int main()
{
Memory *Mem = new Memory("process1.exe");//processID Address and handle PROCESS_QUERY_INFORMATION.
const char* hey = Mem->query("stringstuff",11);
std::cout << hey << std::endl;
system("PAUSE");
delete Mem;
return 0; //Mem.read<int>(0x0);
}
char* Memory::query(const char *data,size_t len)
{
_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, _processID);//PROCESS_QUERY_INFORMATION, PROCESS_VM_READ
DWORD dwProtectionMask = PAGE_READONLY | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOMBINE;
SYSTEM_INFO si;
GetSystemInfo(&si);
MEMORY_BASIC_INFORMATION memoryInfo;
char* p = 0;
int page = 0;
while (p < si.lpMaximumApplicationAddress)
{
if (VirtualQueryEx(_handle, p, &memoryInfo, sizeof(memoryInfo)) == sizeof(memoryInfo))
{
p = (char*)memoryInfo.BaseAddress;
char *buffer = new char[memoryInfo.RegionSize];
SIZE_T bytesRead;
if (ReadProcessMemory(_handle, p, &buffer[0], memoryInfo.RegionSize, &bytesRead))
{
for (size_t i = 0; i < (bytesRead - len); ++i)
{
if (memcmp(data, &buffer[i], len) == 0)
{
std::cout << page << " end\n";
return (char*)p + i;
}
}
}
p += memoryInfo.RegionSize;
delete[] buffer;
}
page++;
std::cout << page << ":pages read.\n";
Sleep(50);
}
return "no find";
}
|
the program finds process1 gets the handle and searches its virtualqueryex (3 pages) it must find a match because "end" is cout, but it throws a read access violation and will not return (char*)p + i, then has a bunch of errors about
e.g. Hack.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
anyone else have similar experience or can help? thank.
[spoiler]
another problem i had was when reading 30-50 pages of virtual memory a bad memory allocation exception would be thrown but hopefully i never have to read that much...
[/spoiler]
|
|
Back to top |
|
|
Viloresi Expert Cheater Reputation: 0
Joined: 02 Feb 2017 Posts: 149
|
Posted: Mon Feb 20, 2017 9:47 am Post subject: |
|
|
You must get an access violation becausw you aren't checking if the pages you are reading are accesible... You've declared thedwProtectionMask but you are not using it... You are just checking if the virtualqueryex function fails or not, so you have to add an if condition to see if the "returned" (it's not actually returned since it's stored into you memorybasicinformation) values are matching the dw protection mask, also you should start from a very simple program tha reads just the numbers inside the addresses so you can understand this better
|
|
Back to top |
|
|
Harambe132 How do I cheat? Reputation: 0
Joined: 19 Feb 2017 Posts: 3
|
Posted: Mon Feb 20, 2017 3:19 pm Post subject: |
|
|
edit: i changed the query function to DWORD and return (DWORD)p+i, now the program returns an address.
just got to figure out why my write is failing and if it works ill get back.
Code: |
DWORD Memory::query(const char *data, size_t len)
{
DWORD dwProtectionMask = PAGE_READONLY | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOMBINE;
SYSTEM_INFO si;
GetSystemInfo(&si);
MEMORY_BASIC_INFORMATION memoryInfo;
unsigned char* p = (unsigned char*)_processAddress;
int page = 0;
while (p < si.lpMaximumApplicationAddress)
{
if (VirtualQueryEx(_handle, p, &memoryInfo, sizeof(memoryInfo)) == sizeof(memoryInfo))
{
if ((memoryInfo.AllocationProtect & dwProtectionMask) && (memoryInfo.State & MEM_COMMIT))
{
//p = (char*)memoryInfo.BaseAddress;
unsigned char *buffer = new unsigned char[memoryInfo.RegionSize];
SIZE_T bytesRead;
if (ReadProcessMemory(_handle, p, &buffer[0], memoryInfo.RegionSize, &bytesRead))
{
for (size_t i = 0; i < (bytesRead - len); ++i)
{
if (memcmp(data, &buffer[i], len) == 0)
{
std::cout << page << " end\n";
const char* writeValue = "stringNew";
LPVOID writeAddress = p + i;
if (WriteProcessMemory(_handle, writeAddress, &writeValue, sizeof(writeValue), 0)!=0) {
std::cout << "write success!\n";
}
else {
std::cout << "write failure\n";
}
return (DWORD)writeAddress;
}
}
}
p += memoryInfo.RegionSize;
delete[] buffer;
}
}
page++;
std::cout << page << ":pages read.\n";
Sleep(50);
}
return 0;
}
|
|
|
Back to top |
|
|
Viloresi Expert Cheater Reputation: 0
Joined: 02 Feb 2017 Posts: 149
|
Posted: Mon Feb 20, 2017 4:22 pm Post subject: |
|
|
Edit: sorry I've messed with your variables before, since I didn't see you've called the structure as memoryInfo...
You're doing it wrong, if you are not sure just put a cout just next to the virtualqueryex and see what values are stored inside tje memorybasicinformation structure...
Aniway you have to change tha allocationprotect to (memoryInfo.Protect & dwProtectionMask) .
Maybe this code will help you (the first one, bevause the others have some errors)
http://www.cplusplus.com/forum/general/202725/
And take a look how that structure is (i guess you already did, but who knows)
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366775(v=vs.85).aspx
|
|
Back to top |
|
|
Harambe132 How do I cheat? Reputation: 0
Joined: 19 Feb 2017 Posts: 3
|
Posted: Mon Feb 20, 2017 10:24 pm Post subject: |
|
|
i converted the query function to search for an int (69) in process1, figured out the address to be (base address += regionSize) + i*sizeof(int).
read the address to confirm this, and my process1 struct on the heap will not allow me access to write. feelsbadman.
_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, TRUE, _processID);
Code: |
#include <iostream>
#include <windows.h>
struct stuff {
int i = 69;
};
int main() {
int temp = 0;
stuff *stuffPtr = new stuff();//creates a stuff thing with its default values set
while (1) {
std::cout << "i: " << stuffPtr->i << "\n";
Sleep(5000);
}
delete stuffPtr;
return 1;
}
|
|
|
Back to top |
|
|
ulysse31 Master Cheater Reputation: 2
Joined: 19 Mar 2015 Posts: 324 Location: Paris
|
Posted: Tue Feb 21, 2017 10:13 am Post subject: |
|
|
Any reason you don't open process with all access?
Code: | DebuggedProc.hwnd = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); |
Or even better, dbug privileges ?
Code: | BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL))
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError());
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
int ProcessPriv()
{
// get process handle
HANDLE hProc = GetCurrentProcess();
// get access token of process
HANDLE hToken = NULL;
if (!OpenProcessToken(hProc, TOKEN_ADJUST_PRIVILEGES, &hToken))
fout << "Failed to open access token" << endl;
// set token privileges to SE_DEBUG_NAME to able to access OpenProcess() with PROCESS_ALL_ACCESS
if (!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE))
fout <<"Failed to set debug privilege" << endl;
return 0;
} |
Why are you doing a monologue ? It appears to me that Viloresi makes valid points.
Quote: | process1 struct on the heap will not allow me access to write |
See if you can write with Cheat Engine but considering you do not even check the memory page rights, there is not much to say. Obviously someone already told you to check for those rights but then again.
Code: | MEMBLOCK * QueryMemoryAddrress(int64_t addr)
{
MEMORY_BASIC_INFORMATION meminfo;
MEMBLOCK *mb = nullptr;
DWORD error = GetLastError();
if (DebuggedProc.hwnd)
{
if (VirtualQueryEx(DebuggedProc.hwnd, (LPCVOID)addr, &meminfo, sizeof(meminfo)) == 0)
{
fout << "Virtual Query failed" << endl;
}
#define WRITABLE (PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE | PAGE_EXECUTE_READ)
if ((meminfo.State & MEM_COMMIT))// && (meminfo.Protect & WRITABLE))
{
fout << "Memory pages are writable and commited" << endl;
mb = create_memblockInsertDisas(DebuggedProc.hwnd, &meminfo, 1);
fout << "base add : " << hex << meminfo.BaseAddress << endl;
fout << "wanted add : " << hex << addr << endl;
fout << "regionsize : " << meminfo.RegionSize << endl;
addr += meminfo.RegionSize;
}
else
{
fout << "Memory pages are not writable and/or not MEM comit" << endl;
}
}
else
fout << "no process handle" << endl;
DebuggedProc.basePageAddress =(int64_t) meminfo.BaseAddress;
fillEachMemblock(mb);
return mb;
} |
1/ Your protection masks DWORD dwProtectionMask = PAGE_READONLY |..
So if the protection is readonly you'll still try to write to it.
2/You check the allocation with the member allocation state instead of state (because current memory page state is not necessarily the same state as when it was allocated), that's a mistake
Quote: | memoryInfo.AllocationProtect | instead of
meminfo.Protect
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|