It changes the value while it's ran inside of Visual studio, but if I build the program and run the executable it does not actually change the value. Here is the code:
using namespace std;
DWORD pid;
DWORD players = 0x00883D70;
int playerCount = 0;
int readValue = 0;
int firstTime = 0;
int main()
{
HWND hWnd = FindWindowA(0, ("Diablo II"));
GetWindowThreadProcessId(hWnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
if (firstTime == 0)
{
cout << "This is a tool to set the player count in Diablo II: Lord of Destruction v1.14D" << endl;
cout << "This tool was made by xElite_V." << endl;
cout << "You can set a number between 0 and 255 for player difficulty:" << endl;
}
else {
cout << "You can set a number between 0 and 255 for player difficulty:" << endl;
}
firstTime = 1;
cin >> playerCount;
WriteProcessMemory(pHandle, (LPVOID)players, &playerCount, sizeof(playerCount), 0);
main();
}
So I don't understand why it wouldn't do the same thing as it would while it's in visual studio.
You almost certainly have a permissions problem, but since your code doesn't check for errors properly, nobody can actually tell you for sure.
There's actually a bunch of stuff you need to do to get this to work, and there's some code that does that here:
https://stackoverflow.com/a/51346951/5743288
Note that this is calling ReadProcessMemory but the idea is the same.
Related
I am trying to change the value of minerals in Starcraft II to learn win32.
I am not into gaming at all. but chose my childhood game to leearn win32 and operating systems.
Here is my code.
everything works, I can get the handle and its process id.
however reading the value does not work.
From cheat engine, I can change the value of minerals to whatever I like.
Here is the memory address of the minerals.
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
int newMineral = 2000;
int readMineral = 0;
HWND hwnd = FindWindowA(NULL, "Brood War");
if (hwnd == NULL)
{
cout << "Cannot find window." << endl;
Sleep(30000);
exit(-1);
}
else
{
DWORD procID;
GetWindowThreadProcessId(hwnd, &procID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
if (procID == NULL)
{
cout << "Cannot find procssID." << endl;
Sleep(30000);
exit(-1);
}
else
{
cout << "process exists." << endl;
cout << procID << endl;
//WriteProcessMemory(handle, (LPVOID)0x57F0F0, &newMineral, sizeof(newMineral), 0);
ReadProcessMemory(handle, (PBYTE*)0x57F0F0, &readMineral, sizeof(int), 0);
cout << readMineral << endl;
}
}
return 0;
I think it is the format of my memory address maybe since the handle and processID are obtainable.
i'm trying to make a little program to my university that can change values in the memory of another process. With the exact address value that the Cheat Engine give me i can do this, but not ever the value is the same then my problem is with the memory pointers. In the following image i has the every offset that i found in the pointer scan map:
I already make a program but it not work and ever gives me 299 error code, i Run it as administrator. The code is the following:
#include <iostream>
#include <Windows.h>
#include <Psapi.h>
#include <TlHelp32.h>
#include <queue>
using namespace std;
int main() {
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(PROCESSENTRY32);
// Snapshot to list all process
HANDLE pHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (pHandlers == NULL) {
cout << "Error 1";
return 1;
}
// Listing process
if (Process32First(pHandlers, &pEntry)) {
while (Process32Next(pHandlers, &pEntry)) {
// Convert value to string
wstring wstr(pEntry.szExeFile);
string str(wstr.begin(), wstr.end());
// Check if is the process that i wan't
if (str == "Playgroundd.exe") {
MODULEENTRY32 mEntry;
mEntry.dwSize = sizeof(MODULEENTRY32);
// Snapshot to list all modules inside process
HANDLE mHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pEntry.th32ProcessID);
if (mHandlers == NULL) {
cout << "Error 2";
return 1;
}
// Usually the first process is the main module
if (Module32First(mHandlers, &mEntry)) {
// Convert the name to string
wstring wstrr(mEntry.szExePath);
string strr(wstrr.begin(), wstrr.end());
if (strr.find("Playgroundd.exe")) {
// Get the base address of module
DWORD moduleBaseAddress = (DWORD)mEntry.modBaseAddr;
// Append initial value
moduleBaseAddress += (DWORD)0x000000E8;
// Offsets defined
DWORD offsets[] = {0x88,0x98,0x90,0x20,0x10,0x48,0x904};
// Open process with the right process id
cout << "process id: " << pEntry.th32ProcessID << endl << endl;
HANDLE processHandler = OpenProcess(PROCESS_ALL_ACCESS, 0, pEntry.th32ProcessID);
if (processHandler == NULL) {
cout << "Can't open the process";
return 1;
}
// Sum offsets
for (int i = 0; i < 7;i++) {
moduleBaseAddress += offsets[i];
}
int receive = 0;
size_t bytesRead = 0;
bool resultStatus = ReadProcessMemory(processHandler,
(LPCVOID)moduleBaseAddress, &receive, sizeof(receive), &bytesRead);
cout << "result status :" << resultStatus << endl;
cout << "Received : " << receive << endl;
cout << "Bytes read : " << bytesRead << endl;
cout << "Possible error code : " << GetLastError() << endl;
}
else {
cout << "Can't find module";
return 1;
}
}
}
}
}
};
This is the output of the above program, the error code can be ignored if the result status be non-zero
result status :0
Received : 0
Bytes read : 0
Possible error code : 299
What i am doing wrong?
As pointed by the comment above, your calculation of the target address is questionable.
Your use of GetLastError is unsafe - you should call it immediately after FAILED call to ReadProcessMemory. However, in this case, cout << ... doesn't change that code, so you are OK.
According to docs
ERROR_PARTIAL_COPY
299 (0x12B)
Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
And this post states
ReadProcessMemory would return FALSE and GetLastError would return ERROR_PARTIAL_COPY when the copy hits a page fault.
I am trying to get the money adress to change to whatever i want , but when i try doing so i get 998 error which is ERROR_NOACCESS . I have visual studio ran as administrator.
#include <windows.h>
using namespace std;
int main()
{
HWND hWnd = FindWindowA(NULL, "PC Building Simulator");
if (hWnd == NULL)
{
cout << "App not found" << endl;
Sleep(3000);
exit(-1);
}
else
{
DWORD proccess_ID;
GetWindowThreadProcessId(hWnd, &proccess_ID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proccess_ID);
if (hProcess==NULL)
{
cout << "App not found" << endl;
Sleep(3000);
exit(-1);
}
else
{
int newdata = 500;
DWORD newdatasize = sizeof(newdata);
WriteProcessMemory(hProcess, (LPVOID)0x1B13B498FB0, &newdata, newdatasize, 0);
cout << GetLastError() << endl;
}
}
return 0;
}
The problem for me had an easy fix ,but not that easy to find it . I had to go to configuration manager and changed the platform from Win32 to x64 and that made it work
I'm learning StackWalk API provided by "DbgHelp" in Windows 7. I wrote an exception filter that uses StackWalk64. The intention is to back trace at most 50 lines with function name and line number. "StackWalk64" iterates through each stack frame. The address(AddrPC) retrieved from Stack Frame is used in "SymGetSymFromAddr64" and "SymGetLineFromAddr64" to retrieve Symbol name and Line number respectively. But, though "SymGetSymFromAddr64" works successfully, "SymGetLineFromAddr64" fails. The Last Error returned is 487. How can the address work successfully for the former but not for the latter?
Am I missing something? Any Help?
LONG WINAPI TestStackWalker (EXCEPTION_POINTERS* lpFilter)
{
STACKFRAME64 st;
CONTEXT cc;
HANDLE hProcess = ::GetCurrentProcess();
HANDLE hThread = ::GetCurrentThread();
vector<IMAGEHLP_SYMBOL64> vectSymbs(50);
vector<IMAGEHLP_LINE64> vectLines(50);
if (!SymInitialize(hProcess, NULL, TRUE))
{
cout << "Issue with SymInitialize ! " << ::GetLastError() << endl;
return 1;
}
cc = *(lpFilter->ContextRecord);
printContext(cc);
::ZeroMemory(&st, sizeof(st));
st.AddrStack.Mode = AddrModeFlat;
st.AddrStack.Offset = cc.Esp;
st.AddrFrame.Mode = AddrModeFlat;
st.AddrFrame.Offset = cc.Ebp;
st.AddrPC.Mode = AddrModeFlat;
st.AddrPC.Offset = cc.Eip;
for (int i = 0; i < 50; i++)
{
if (!::StackWalk64(IMAGE_FILE_MACHINE_I386,
hProcess,
hThread,
&st,
&cc,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
NULL))
{
cout << "Issue with StackWalkFailed: " << ::GetLastError () <<endl;
return 1;
}
if (st.AddrReturn.Offset == st.AddrPC.Offset)
{
cout << "i think it's done!" << endl;
break;
}
if (st.AddrPC.Offset != 0)
{
vectSymbs[i].SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
vectSymbs[i].MaxNameLength = 1024;
if (!SymGetSymFromAddr64 (hProcess, st.AddrPC.Offset, 0, &vectSymbs[i]))
{
cout << "Issue with Getting Symbol From Address " << ::GetLastError() << endl;
break;
}
SymSetOptions(SYMOPT_LOAD_LINES);
vectLines[i].SizeOfStruct = sizeof(IMAGEHLP_LINE64);
if (!SymGetLineFromAddr64 (hProcess, st.AddrPC.Offset, 0, &vectLines[i]))
{
cout << "Issue with Getting Line from Address " << ::GetLastError() << endl;
break;
}
cout << vectSymbs[i].Name << " at " << vectLines[i].LineNumber <<endl;
}
if (st.AddrReturn.Offset == 0)
{
cout << "seems finished " << endl;
break;
}
}
return 1;
}
The pdwDisplacement parameter is not optional:
DWORD dis;
if (!SymGetLineFromAddr64 (hProcess, st.AddrPC.Offset, &dis, &vectLines[i]))
{
cout << "Issue with Getting Line from Address " << ::GetLastError() << endl;
break;
}
I had the same problem. My symbols were on a symbol server. The solution was to put symsrv.dll (from the Windows SDK) next to dbghelp.dll, so it can be loaded. Everything worked after that. In practice, the solution was to distribute both dbghelp.dll and symsrv.dll with my application (together with dbgcore.dll and srcsrv.dll). See the Modules list in Visual Studio, to verify that both symsrv.dll and dbghelp.dll are being loaded from where you expect.
More info here:
https://learn.microsoft.com/en-us/windows/desktop/Debug/using-symsrv
(See "Installation" section)
https://learn.microsoft.com/en-us/windows/desktop/Debug/dbghelp-versions (regarding obtaining and distributing those dlls)
I've been trying to write an application, using Qt and mingw32, to download images and set them as the background Wallpaper. I have read several articles online about how to do this, in VB and C#, and to some extent how to do it in c++. I am currently calling the SystemParametersInfo with what seems to be all the correct arguments (no compiler errors) and it fails. No great crash of cymbals, just a 0 returned. GetLastError() returns an equally enlightening 0.
Below is the code I am using (In a slightly modified form, so you do not have to view the object internals).
#include <windows.h>
#include <iostream>
#include <QString>
void setWall()
{
QString filepath = "C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
char path[150];
strcpy(path, currentFilePath.toStdString().c_str());
char *pathp;
pathp = path;
cout << path;
int result;
result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, pathp, SPIF_UPDATEINIFILE);
if (result)
{
cout << "Wallpaper set";
}
else
{
cout << "Wallpaper not set";
cout << "SPI returned" << result;
}
}
It could be that SystemParametersInfo is expecting an LPWSTR (a pointer to wchar_t).
Try this:
LPWSTR test = L"C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, test, SPIF_UPDATEINIFILE);
If this works (try it with a few different files just to make sure), you'll need to convert your char * to a LPWSTR. I'm not sure if Qt offers these services, but one function that may help is MultiByteToWideChar.
"C:\Documents and Settings\Owner\My Documents\Wallpapers\wallpaper.png";
shouldn't this be:
"C:\\Documents and Settings\\Owner\\My Documents\\Wallpapers\\wallpaper.png";
You cn use SetTimer to trigger a change.
#define STRICT 1
#include <windows.h>
#include <iostream.h>
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
LPWSTR wallpaper_file = L"C:\\Wallpapers\\wallpaper.png";
int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallpaper_file, SPIF_UPDATEINIFILE);
cout << "Programmatically change the desktop wallpaper periodically: " << dwTime << '\n';
cout.flush();
}
int main(int argc, char *argv[], char *envp[])
{
int Counter=0;
MSG Msg;
UINT TimerId = SetTimer(NULL, 0, 2000, &TimerProc); //2000 milliseconds
cout << "TimerId: " << TimerId << '\n';
if (!TimerId)
return 16;
while (GetMessage(&Msg, NULL, 0, 0))
{
++Counter;
if (Msg.message == WM_TIMER)
cout << "Counter: " << Counter << "; timer message\n";
else
cout << "Counter: " << Counter << "; message: " << Msg.message << '\n';
DispatchMessage(&Msg);
}
KillTimer(NULL, TimerId);
return 0;
}