I "copied" a simple code snippet from a site and adjusted it to a game I was trying to hack. An old game with no multiplayer, basically just to practice all this memory editing stuff. Every time my program successfully returns a window handle, but then fails to return the process handle. Here is my code:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
long address = 0x47C0F04;
int newvalue = 200;
DWORD newvaluesize = sizeof(newvalue);
HWND hWnd = FindWindow(0, L"No One Lives Forever");
HANDLE pHandle;
DWORD pid;
if(hWnd != 0) {
cout << "Found windowx.\n";
GetWindowThreadProcessId(hWnd, &pid);
pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
}
else {
cout << "Can't find window\n";
}
if(pHandle !=0) {
WriteProcessMemory(pHandle, (LPVOID)address, (LPVOID)newvalue, newvaluesize, 0);
cout << "Written to memory successfully\n";
}
else {
cout << "Couldn't get handle.\n";
}
CloseHandle(pHandle);
return 0;
}
The game is from 2000 if I recall correctly (really awesome game by the way) so I'm assuming it doesn't have any advanced anti-hack shield, since I can also pretty much edit the value of that address in cheat engine and it works with no hassle.
EDIT: I'll just explain what exactly happens. It always prints "Found window" but then it directly prints "Couldn't get handle". I don't get any compiler errors (I'm compiling in Microsoft Visual C++ 2010 Express)
You must run your program as administrator to get a handle with PROCESS_ALL_ACCESS permissions, this will fix your problem.
As GuidedHacking mentioned you need to run program as Admin ,Use this code to check whether your process is running as Admin rights.
BOOL IsElevatedProcess()
{
BOOL is_elevated = FALSE;
HANDLE token = NULL;
if (GT_IsPrivateMethod(gt_private_method, FUNC_NAME, LINE_NO))
{
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
{
TOKEN_ELEVATION elevation;
DWORD token_sz = sizeof(TOKEN_ELEVATION);
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &token_sz))
{
is_elevated = elevation.TokenIsElevated;
}
}
if (token)
{
CloseHandle(token);
}
}
return is_elevated;
}
Related
So today I decided to mess a bit with windows.h and I thought of a little exercise to practise, this is the code I wrote, but it's giving me headaches.
It keeps returning 0, so no name is being passed into ExecName, and the error I get if I lookup with GetLastError() is Overflow error.
I've tried different methods of getting the executables' names but it always ends the same.
#include <iostream>
#include <Windows.h>
#include <Psapi.h>
TCHAR* ExeToFind = "Discord.exe";
BOOL CALLBACK CB_EW(
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{
TCHAR ExecName[MAX_PATH];
DWORD ProcesID = NULL;
GetWindowThreadProcessId(hwnd, &ProcesID);
HANDLE handle = OpenProcess(NULL, false, ProcesID);
if (GetModuleFileNameEx(handle, NULL, ExecName, MAX_PATH) == 0) {
std::cout << "Error " << GetLastError();
return true;
}
//GetWindowText(hwnd, ExecName, GetWindowTextLength(hwnd)+1);
//GetProcessImageFileName(hwnd, ExecName, MAX_PATH);
std::cout << ExecName;
if (ExecName == ExeToFind) {
std::cout << "Here it is\n";
return false;
}
else {
std::cout << "next\n";
return true;
}
}
int main()
{
//HWND hWnd = FindWindow(0,0);
EnumWindows(CB_EW, NULL);
while (true) {
}
return 0;
}
What am I doing wrong?
It was a permission issue, instead of using NULL for the access permission on OpenProcess, I used MAXIMUM_ALLOWED and it worked
I want to access and edit multiple addresses in memory.
In case it's vague, the question is: If I used memory scanner and the results were a list of addresses, how would I be able to access and edit them all?
I've already been told to try putting all the addresses in an array, how do I do this?
Here's the code so far:
//
#include "stdafx.h"
#include "iostream"
#include "Windows.h"
#include <cstdint>
#include <stdint.h>
using namespace std;
int main()
{
int newValue = 0;
int* p;
p = (int*)0x4F6DCFE3DC; // now p points to address 0x220202
HWND hwnd = FindWindowA(NULL, "Call of Duty®: Modern Warfare® 3 Multiplayer");// Finds Window
if (hwnd == NULL) {// Tests for success
cout << "The window is not open" << endl;
Sleep(3000);
exit(-1);
}
else {
cout << "It's open boss!";
}
else {// If Successful Begins the following
DWORD procID;
GetWindowThreadProcessId(hwnd, &procID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);//Gets handle on process
if (procID == NULL) {
cout << "Cannot obtain process." << endl;
Sleep(3000);
exit(-1);
}
else {//Begins writing to memory
while (newValue == 0) {
/*This Writes*/WriteProcessMemory(handle, (LPVOID)0x04F6DCFE3DC, &newValue, sizeof(newValue), 0);
cout << p;
Sleep(3000);
}
}
}
}
It's fairly easy. Just use a std::vector<std::pair<int*,int>> to contain all these addresses you want to modify along with the value they should achieve:
std::vector<std::pair<int*,int>> changeMap = {
{ (int*)0x4F6DCFE3DC , 0 }
// more address value pairs ...
};
Then you can process them in a loop:
for(auto it = std::begin(changeMap); it != std::end(changeMap); ++it)
{
WriteProcessMemory(handle, (LPVOID)it->first, &(it->second),
sizeof(it->second), 0);
}
Whatever you want to achieve with that1.
I've already been told to try putting all the addresses in an array, how do I do this?
If you want to set all the address contents to 0 you may use a simpler construct:
int newValue = 0;
std::vector<int*> changeAddrList = {
(int*)0x4F6DCFE3DC ,
// more addresses to change ...
};
// ...
for(auto addr : changeAddrList)
{
WriteProcessMemory(handle, (LPVOID)addr , &newValue ,
sizeof(newValue), 0);
}
1Fiddling around in another processes memory is error prone and might lead to all kinds of unexpected behavior!
Your code may fail miserably at a newer version of that program, where you're trying to apply your cheat codez.
I am trying to make a program to store the value 500 into the calculator's memory address for the MR (Memory Restore) button on the calculator application.
I know that the address for this integer is
"calc.exe"+00073320 + 0 + C
If I use a program like cheat engine, I can get the current address for the instance of the calculator.exe i'm running, and write to it just fine that way. However, since this is not a static address, I need a way to get the module base address.
I tried using this GetModuleBase function (see code below) to get the Base Address of the calc.exe, but my issue is that I cannot get the base address. The function always returns 0 instead of the correct address.
I debugged it and found that in the GetModuleBase function, it is not even cycling once through the while loop because bModule is returning 0 from the Module32First function.
#include <tchar.h>
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <Psapi.h>
#include <wchar.h>
#pragma comment( lib, "psapi" )
using namespace std;
DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId)
{
MODULEENTRY32 lpModuleEntry = {0};
HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
if(!hSnapShot)
return NULL;
lpModuleEntry.dwSize = sizeof(lpModuleEntry);
BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
while(bModule)
{
if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
{
CloseHandle( hSnapShot );
return (DWORD)lpModuleEntry.modBaseAddr;
}
bModule = Module32Next( hSnapShot, &lpModuleEntry );
}
CloseHandle( hSnapShot );
return NULL;
}
int main() {
HWND hWnd = FindWindow(0, "Calculator");
DWORD BaseAddr;
if(hWnd == 0){
MessageBox(0, "Error cannot find window.", "Error", MB_OK|MB_ICONERROR);
} else {
DWORD proccess_ID;
GetWindowThreadProcessId(hWnd, &proccess_ID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proccess_ID);
if(!hProcess){
MessageBox(0, "Could not open the process!", "Error!", MB_OK|MB_ICONERROR);
} else {
int newdata = 500;
BaseAddr = GetModuleBase("calc.exe",proccess_ID);
//GetModuleBase is always returning 0, so I am not getting the correct base address
DWORD newdatasize = sizeof(newdata);
if(WriteProcessMemory(hProcess, (LPVOID)0x002413FC, &newdata, newdatasize, NULL)){
cout << "Memory successfully written." << endl;
} else {
cout << "Memory failed to write." << endl;
}
CloseHandle(hProcess);
}
}
return 0;
}
Summary: I cannot get the correct base address using my GetModuleBase function, and I need to figure out what I am doing wrong so that I can get the correct base address for the "calc.exe" process.
You should read the modules like this:
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
//You don't have to use this function if you don't want to..
int strcompare(const char* One, const char* Two, bool CaseSensitive)
{
#if defined _WIN32 || defined _WIN64
return CaseSensitive ? strcmp(One, Two) : _stricmp(One, Two);
#else
return CaseSensitive ? strcmp(One, Two) : strcasecmp(One, Two);
#endif
}
//You read module information like this..
MODULEENTRY32 GetModuleInfo(std::uint32_t ProcessID, const char* ModuleName)
{
void* hSnap = nullptr;
MODULEENTRY32 Mod32 = {0};
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)) == INVALID_HANDLE_VALUE)
return Mod32;
Mod32.dwSize = sizeof(MODULEENTRY32);
while (Module32Next(hSnap, &Mod32))
{
if (!strcompare(ModuleName, Mod32.szModule, false))
{
CloseHandle(hSnap);
return Mod32;
}
}
CloseHandle(hSnap);
return {0};
}
int main()
{
//Change the process ID below..
BYTE* BaseAddr = GetModuleInfo(5172, "calc.exe").modBaseAddr;
std::cout<<"BASE ADDRESS: "<<(void*)BaseAddr<<"\n";
return 0;
}
EDIT: After further investigation, I found that Visual Studio was compiling for an x32 platform but calc.exe is an x64 process..
To get Visual Studio to compile for x64 you need to do the following:
Then click and select "NEW" from the following drop-down menu:
Next in the following drop down, select x64:
Save the settings and rebuild the project and it should work..
I'm having a problem when trying to run the following code:
#include "header.h"
int main()
{
id = GetCurrentProcessId();
EnumWindows(hEnumWindows, NULL);
Sleep(5000);
//MoveWindow(hThis, 450, 450, 100, 100, TRUE);
system("pause");
return 0;
}
//header.h
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <Windows.h>
using namespace std;
DWORD id = 0;
HWND hThis = NULL;
BOOL CALLBACK hEnumWindows(HWND hwnd, LPARAM lParam)
{
DWORD pid = 0;
pid = GetWindowThreadProcessId(hwnd, NULL);
if (pid == id)
{
hThis = GetWindow(hwnd, GW_OWNER);
if (!hThis)
{
cout << "Error getting window!" << endl;
}
else
{
char *buffer = nullptr;
int size = GetWindowTextLength(hThis);
buffer = (char*)malloc(size+1);
if (buffer != nullptr)
{
GetWindowText(hThis, buffer, size);
cout << pid << ":" << buffer << endl;
free(buffer);
}
}
}
return TRUE;
}
When I run this code nothing is output to the screen almost as if the program is not attached. I tried running it under a console and windows subsystem in VS2013.
According to the GetCurrentProcessId docs, the API
Retrieves the process identifier of the calling process.
GetWindowThreadProcessId, on the other hand,
Retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window.
The return value is the identifier of the thread that created the window.
So looking at your call:
pid = GetWindowThreadProcessId(hwnd, NULL);
You're actually getting back a thread ID, not a process ID. So when you compare pid to id, you're comparing a process ID and a thread ID, and that's just not going to work. Try this instead:
GetWindowThreadProcessId(hwnd, &pid);
(Note: I can't actually test whether this works, since EnumWindows requires a top-level window to enumerate and I ran this as a console app. Let me know if this answer doesn't work for you and I'll delete it.)
(As a second note, you don't need to use NULL anymore, even for WinAPI stuff like HWND. nullptr will work perfectly fine.)
I assume you're trying to find the "Main" window from the ProcessID.. In that case, this MAY help:
#include "stdafx.h"
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <Windows.h>
struct WindowHandleStructure
{
unsigned long PID;
HWND WindowHandle;
};
BOOL CALLBACK EnumWindowsProc(HWND WindowHandle, LPARAM lParam)
{
unsigned long PID = 0;
WindowHandleStructure* data = reinterpret_cast<WindowHandleStructure*>(lParam);
GetWindowThreadProcessId(WindowHandle, &PID);
if (data->PID != PID || (GetWindow(WindowHandle, GW_OWNER) && !IsWindowVisible(WindowHandle)))
{
return TRUE;
}
data->WindowHandle = WindowHandle;
return FALSE;
}
HWND FindMainWindow(unsigned long PID)
{
WindowHandleStructure data = { PID, nullptr };
EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&data));
return data.WindowHandle;
}
int main()
{
HWND Window = FindMainWindow(GetCurrentProcessId());
std::wstring Buffer(GetWindowTextLength(Window) + 1, L'\0');
GetWindowText(Window, &Buffer[0], Buffer.size());
std::wcout << Buffer.c_str() << L"\n";
system("pause");
return 0;
}
I am having problems with reading the registry.
This function finds the number of entries in a registry path. It works perfectly, I have tested it:
void findNumberEntries(registryTest &INSTALLKEY) {
char buffer[50];
char size = sizeof(buffer);
int index = 0;
if(RegOpenKeyEx(INSTALLKEY.hKey,(LPTSTR)(INSTALLKEY.regpath.c_str()),0,KEY_ALL_ACCESS,&INSTALLKEY.hKey) == ERROR_SUCCESS) {
DWORD readEntry;
do {
readEntry = RegEnumValue(INSTALLKEY.hKey,index,(LPTSTR)buffer,(LPDWORD)&size,NULL,NULL,NULL,NULL);
index++;
}
while(readEntry != ERROR_NO_MORE_ITEMS);
}
INSTALLKEY.number = index;
RegCloseKey(INSTALLKEY.hKey);
}
now, the main function:
std::string regpath32 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\";
struct registryTest {
HKEY hKey;
std::string regpath;
int number;
};
registryTest INSTALLKEY = {HKEY_LOCAL_MACHINE, regpath32};
findNumberEntries(INSTALLKEY);
printf("%d\n",INSTALLKEY.number);
system("PAUSE");
//until here everything works as it should
HKEY hKey = INSTALLKEY.hKey;
std::string regpath = INSTALLKEY.regpath;
char buffer[50];
char size = sizeof(buffer);
std::string bufferString;
DWORD regOpen = RegOpenKeyEx(INSTALLKEY.hKey,(LPTSTR)INSTALLKEY.regpath.c_str(),0,KEY_READ,&INSTALLKEY.hKey);
if(regOpen == ERROR_SUCCESS) //this is the part that fails.
{
printf("Registry Key was successfully opened\n");
}
else
{
printf("Unable to open registry key\n");
LPVOID message;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), NULL,(LPTSTR) &message, 0, NULL );
MessageBox(NULL,(LPCTSTR)message,"ERROR",MB_OK|MB_ICONINFORMATION);
}
...rest of the code
I always get "Unable to open registry" and the error message I get is "There are no more files". What is the problem??
your problem is that when you first open the registry key ,you assign it to hkey-member of your struct. So the second time this hkey doesn't contain the original basekey anymore.
change :
DWORD regOpen =
RegOpenKeyEx(INSTALLKEY.hKey,(LPTSTR)INSTALLKEY.regpath.c_str(),0,KEY_READ,&INSTALLKEY.hKey);
into
DWORD regOpen = RegOpenKeyEx(
HKEY_LOCAL_MACHINE
,(LPTSTR)INSTALLKEY.regpath.c_str(),0,KEY_READ,&INSTALLKEY.hKey);
or change this:
void findNumberEntries( registryTest &INSTALLKEY)
{
char buffer[50];
char size = sizeof(buffer);
int index = 0;
HKEY hkOpen = 0; // can't use INVALID_HANDLE_VALUE for HKEY's;
if (RegOpenKeyEx( INSTALLKEY.hKey ,(LPTSTR)(INSTALLKEY.regpath.c_str())
,0,&hkOpen ) == ERROR_SUCCESS)
{
// You should use RegQueryInfoKey for below code !
DWORD readEntry;
do {
readEntry = RegEnumValue( hkOpen ,index,(LPTSTR)buffer
,(LPDWORD size,NULL,NULL,NULL,NULL);
index++;
}
while(readEntry != ERROR_NO_MORE_ITEMS); }
INSTALLKEY.number = index;
RegCloseKey( hkOpen );
}
You may need to specify KEY_ALL_ACCESS in the second call as well, rather than just in the first. And on Win7 64-bit you may be running into the registry redirect craziness (http://msdn.microsoft.com/en-us/library/aa384232%28VS.85%29.aspx).
EDIT: ah, you might just be getting an ERROR_CANTWRITE back (error code number 5). You might be able to ignore that and see if it still works.
It's very likely that on Windows 7 64-bit that you are being redirected via Registry Virtualization. You can determine what keys are being redirected by calling RegQueryReflectionKey.
If you modify your code to output the actual integer value that is returned rather than a generic "Unable to open key", then it would be helpful. For example,
long n = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("\\SOFTWARE"),
0,KEY_QUERY_VALUE, &hk );
if ( n == ERROR_SUCCESS ) {
cout << "OK" << endl;
}
else {
cout << "Failed with value " << n << endl;
}