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..
Related
I want to list all the file type associations app names. My code:
#include <windows.h>
#include <shlwapi.h>
#include <ShlObj.h>
#include <iostream>
#pragma comment(lib, "shlwapi.lib")
int main()
{
IQueryAssociations *iQueryAssoc = nullptr;
HRESULT assocHRes = AssocCreate(CLSID_QueryAssociations, IID_IQueryAssociations, reinterpret_cast<void**>(&iQueryAssoc));
if (assocHRes == S_OK) {
HWND hWnd = GetConsoleWindow();
LPCWSTR pszAssoc = L".xls";
HRESULT initAssocHRes = iQueryAssoc->Init(NULL, pszAssoc, NULL, hWnd);
if (initAssocHRes == S_OK) {
TCHAR buffer[1024];
DWORD bufferSize = 1024;
HRESULT getStrAssocHRes = iQueryAssoc->GetString(ASSOCF_NONE, ASSOCSTR_FRIENDLYAPPNAME, NULL, buffer, &bufferSize);
if (getStrAssocHRes == S_OK) {
std::wcout << "App name: " << std::wstring(buffer).c_str() << std::endl;
} else {
std::wcout << "iQueryAssoc GetString failed!" << std::endl;
}
} else {
std::wcout << "iQueryAssoc Init failed!" << std::endl;
}
} else {
std::wcout << "AssocCreate failed!" << std::endl;
}
iQueryAssoc->Release();
system("PAUSE");
return 0;
}
My code works but it displays app name only for the ".xls" extension. I think, I need to use the while (iQueryAssoc->QueryInterface()) to get all of them. Is there any example how to use it? Should I call init method first and then QueryInterface method or just call QueryInterface method without init method?
Additionally, I have found the SHAssocEnumHandlers method:
IEnumAssocHandlers *pEnumHandlers = nullptr;
IAssocHandler *assocHandler = nullptr;
HRESULT initAssocHRes = SHAssocEnumHandlers(NULL, ASSOC_FILTER_NONE, &pEnumHandlers);
if (initAssocHRes == S_OK) {
while (pEnumHandlers->Next(1, &assocHandler, nullptr) == S_OK) {
std::cout << "Test..." << std::endl;
}
} else {
std::cout << "Failed: " << initAssocHRes << std::endl;
}
But for me, it fails with the following error: Failed: -2147024882 E_OUTOFMEMORY - Failed to allocate necessary memory. I think, the issue with: IEnumAssocHandlers are null and not initialized. What method should I use to initialize the IEnumAssocHandlers? Thank you.
I have found, these lines of code leads to E_OUTOFMEMORY issue:
IEnumAssocHandlers *pEnumHandlers = NULL;
HRESULT initAssocHRes = SHAssocEnumHandlers(NULL, ASSOC_FILTER_RECOMMENDED, &pEnumHandlers);
Also, I got this warning:
Any ideas? Thank you.
Updated code:
#include <windows.h>
#include <shlwapi.h>
#include <ShlObj.h>
#include <iostream>
#include "hresinfo.h"
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "shell32.lib")
int main()
{
IEnumAssocHandlers *pEnumHandlers = nullptr;
HRESULT initAssocHRes = SHAssocEnumHandlers(NULL, ASSOC_FILTER_NONE, reinterpret_cast<IEnumAssocHandlers**>(&pEnumHandlers));
if (initAssocHRes == S_OK) {
IAssocHandler *pAssocHandler = nullptr;
LPWSTR pszName = nullptr;
while (pEnumHandlers->Next(1, &pAssocHandler, NULL) == S_OK) {
if (pAssocHandler) {
pAssocHandler->GetUIName(&pszName);
printf_s("%S \n", pszName);
}
}
if (pAssocHandler) {
pAssocHandler->Release();
}
} else {
HRESInfo::getErrorMsg(initAssocHRes);
}
if (pEnumHandlers) {
pEnumHandlers->Release();
}
system("PAUSE");
return 0;
}
Screenshot:
You don't say which call is actually failing (so please do so), but if you look at the documentation for IEnumAssocHandlers::Next, it doesn't say anywhere that the third parameter (pceltFetched) can be nullptr, so I would change your code to:
if (initAssocHRes == S_OK) {
ULONG handlers_retrieved = 0;
while (pEnumHandlers->Next(1, &assocHandler, &handlers_retrieved) == S_OK) {
...
Also first parameter to SHAssocEnumHandlers must not be null:
wchar_t *extension = L".jpg";
HRESULT initAssocHRes = SHAssocEnumHandlers(extension, ...
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'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 have been developing an application that uses winapi to get administrator group members. I used NetLocalGroupGetMembers method for that purpose. My problem is when i try to free buffer's heap space i get ERROR_INVALID_PARAMETER (Error Code 87) from NetApiBufferFree method. I have administrator privileges for the application.
Here is the code:
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <lm.h>
#include <time.h>
#include <assert.h>
#define SLEEP_TIME 2000
#define OS_GROUP_NAME L"administrators"
void createServiceThread();
DWORD WINAPI mainServiceThread( LPVOID lpParam );
char** getUsersByLocalGroup();
void freeNetApiBuffer(LPVOID buffer);
int localGroupUserCount;
int WriteToLog(char* str)
{
printf("%s\n", str);
return 0;
}
int main()
{
createServiceThread();
}
void createServiceThread(){
WriteToLog("Application Started...");
while(TRUE){
mainServiceThread(NULL);
Sleep(SLEEP_TIME);
}
WriteToLog("Application Closed...");
}
//-------------------------------------------
// A function that represents Main Service Thread
//-------------------------------------------
DWORD WINAPI mainServiceThread( LPVOID lpParam )
{
time_t startTime;
time (&startTime);
char startTimeText[30];
sprintf(startTimeText, "Service Loop Started %s", ctime(&startTime));
WriteToLog(startTimeText);
localGroupUserCount = 0;
char** localGroupUsers = getUsersByLocalGroup();
WriteToLog("User not found...");
time_t endTime;
time (&endTime);
char endTimeText[30];
sprintf(endTimeText, "Service Loop Ended %s", ctime(&endTime));
WriteToLog(endTimeText);
}
char** getUsersByLocalGroup(){
WriteToLog("getUsersByLocalGroup started");
LOCALGROUP_MEMBERS_INFO_3 *pBuf;
DWORD dwLevel = 3;
DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
DWORD dwEntriesRead = 0;
DWORD dwTotalEntries = 0;
DWORD dwResumeHandle = 0;
NET_API_STATUS nStatus;
WriteToLog("Call NetLocalGroupGetMembers");
nStatus = NetLocalGroupGetMembers(
NULL,
OS_GROUP_NAME,
dwLevel,
(LPBYTE *) &pBuf,
dwPrefMaxLen,
&dwEntriesRead,
&dwTotalEntries,
NULL
);
// nStatus = ERROR_SUCCESS;
WriteToLog("NetLocalGroupGetMembers called");
//
// If the call succeeds,
//
if (nStatus == ERROR_SUCCESS || nStatus == ERROR_MORE_DATA)
{
DWORD i;
DWORD dwTotalCount = 0;
WriteToLog("Correct Status");
if (pBuf != NULL)
{
//
// Loop through the entries.
//
for (i = 0; (i < dwEntriesRead); i++)
{
assert(pBuf != NULL);
if (pBuf == NULL)
{
char bufError[] = "";
sprintf(bufError, "An access violation has occurred %d", stderr);
WriteToLog(bufError);
break;
}
LPWSTR userNameOnBuffer = pBuf->lgrmi3_domainandname;
pBuf++;
dwTotalCount++;
}
localGroupUserCount = dwTotalCount;
char totalCount[] = "";
sprintf(totalCount, "Entries enumerated: %d", dwTotalCount);
WriteToLog(totalCount);
}
//
// Otherwise, print the system error.
//
else{
char systemError[] = "";
sprintf(systemError, "An system error has occurred %d - %d", stderr, nStatus);
WriteToLog(systemError);
}
}
//
// Free the allocated buffer.
//
if (pBuf != NULL)
{
NET_API_STATUS nBufferFreeStatus = NetApiBufferFree((LPVOID)pBuf);
if(nBufferFreeStatus == NERR_Success){
WriteToLog("Succesfully freed buffer");
}
else{
WriteToLog("Error occured freeing buffer");
}
pBuf = NULL;
}
WriteToLog("getUsersByLocalGroup finished");
return NULL;
}
In your loop you have the line pBuf++;. This modifies pBuf which means that the value you are freeing is not the value that was allocated. Hence the invalid parameter.
Also, these lines
char totalCount[] = "";
sprintf(totalCount, "Entries enumerated: %d", dwTotalCount);
create a stack buffer overflow, which is probably corrupting your pBuf variable. There is another instance of it a few lines later.
In general, here's how you debug it: Set a breakpoint as soon as NetLocalGroupGetMembers returns. Look at the value in pBuf and write it down in a safe place. Set another breakpoint when you are about to call NetApiBufferFree. Look at the value of pBuf you are passing. Is it equal to the value you wrote down earlier? If not, then you have a bug. Use the debugger to find out why you are passing the wrong value.
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;
}