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;
}
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 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
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.
I have been working on an application to set the desktop background basing of another application I found here: http://www.optimumx.com/downloads.html#SetWallpaper. The idea is to set the background to a wallpaper every 10 minutes, so it launches the SetWallpaper.exe with the command 'SetWallpaper.exe /D:S Wallpaper.jpg' but when I launch my application it creates a console window that doesn't automatically close and when I manually close it, it kills the exe.
#include <windows.h>
int main() {
int i = 1;
int j = 3;
// refresh = time until refresh in minutes
int refresh = 10;
// 1000 milliseconds = 1 second
int second = 1000;
int minute = 60;
int time = second * minute * refresh;
while (i < j) {
system("cmd /c start /b SetWallpaper.exe /D:S Wallpaper.jpg");
Sleep(time);
}
return 0;
}
I tried using 'sleep.exe' that comes with MinGW Msys but that creates a new process each team, eventually hogging all the processes.
Thanks in advance!
The first problem you're having is that you've created your program as a console application with a main method. Instead, create it as a Win32 Project with a WinMain entry point. This will be invoked directly without creating a console window.
EDIT: The second issue is addressed by Ferruccio's answer in that you're invoking another console application from yours which will also result in a console window being created.
You're going about it the hard way. It's fairly simple to change the Windows wallpaper in a program:
#include <windows.h>
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID) "path/to/wallpaper.jpg", SPIF_UPDATEINIFILE);
In any case, if you insist on launching an external program to do it. Use CreateProcess. It has the ability to launch console mode apps without a visible window, by setting the dwCreationFlags parameter to CREATE_NO_WINDOW.
Set ShowWindow to false and don't forget to FreeConsole at the end.
#include <windows.h>
int main(void)
{
ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
// put your code here
system("cmd /c start /b SetWallpaper.exe /D:S Wallpaper.jpg");
FreeConsole();
return 0;
}
And as Ferruccio mentioned, You can use SetTimer and SystemParametersInfo to trigger a change periodically.
#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 = change every 2 seconds
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;
}
I am trying to do some dll injection. I think I tried everything I could but cound not solve the problem unfortunately. I always get ERROR CODE 127 which means ERROR_PROC_NOT_FOUND. I am using Windows 7 64 bit.
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
using namespace std;
char FileToInject[] = "theDll.dll";
char ProcessName[] = "calc.exe";
typedef HINSTANCE (*fpLoadLibrary)(char*);
bool InjectDLL(DWORD processId);
int main() {
DWORD processId = NULL;
PROCESSENTRY32 pre32 = {sizeof(PROCESSENTRY32)};
HANDLE hProcSnap;
cout << "BEFORECreateToolhelo32Snapshot:" << GetLastError() <<endl;
while(!processId) {
system("CLS");
cout << "Searching..." << endl;
hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
cout << "CreateToolhelo32Snapshot:" << GetLastError() <<endl;
if(Process32First(hProcSnap, &pre32)) {
do {
if(!(strcmp(pre32.szExeFile, ProcessName))) {
processId = pre32.th32ProcessID;
break;
}
}
while(Process32Next(hProcSnap, &pre32));
}
Sleep(1000);
}
cout << GetLastError() <<endl;
while(!InjectDLL(processId)) {
cout << "DLL Injection failed" << endl;
Sleep(1000);
}
cout << "DLL Injected successfully" << endl;
getchar();
CloseHandle(hProcSnap);
return 0;
}
bool InjectDLL(DWORD processId) {
HANDLE hProc;
LPVOID paramAddr;
cout << "START:" << GetLastError() <<endl;
HINSTANCE hDll = LoadLibrary("KERNEL32");
cout << "LoadLibrary:" << GetLastError() <<endl;
fpLoadLibrary LoadLibraryAddr = (fpLoadLibrary)GetProcAddress(hDll, "LibraryLoadA");
cout << "LoadLibraryArr:" << GetLastError() <<endl;
hProc = OpenProcess(PROCESS_ALL_ACCESS, false, processId);
cout << "OpenProcess:" << GetLastError() <<endl;
char DllPath[250] = "C:\\Hacks\test.dll";
paramAddr = VirtualAllocEx(hProc, 0, strlen(DllPath) + 1, MEM_COMMIT, PAGE_READWRITE);
cout << "VirtualAlloxEx:" <<GetLastError() <<endl;
bool MemoryWritten = WriteProcessMemory(hProc, paramAddr, DllPath, strlen(DllPath) + 1, NULL);
cout << "WriteProcessMemory:" << GetLastError() <<endl;
CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, paramAddr, 0, 0);
cout << "CreateRemoteThread:" <<GetLastError() <<endl;
CloseHandle(hProc);
return MemoryWritten;
}
The output is the following:
Searching...
CreateToolhelp32Snapshot: 18 ERROR_NO_MORE_FILES
LoadLibrary:18 ERROR_NO_MORE_FILES
LoadLibraryArr:127 ERROR_PROC_NOT_FOUND
OpenProcess:127 ERROR_PROC_NOT_FOUND
VirtualAlloxEx:127 ERROR_PROC_NOT_FOUND
WriteProcessMemory:127 ERROR_PROC_NOT_FOUND
CreateRemoteThread:5 ACCESS DENIED
DLL Injected successfully
The program finds the calc.exe as a process with no problem, but after that something goes wrong. Could someone please help me with this?
Thank you,
Tamas
This is one problem:
char DllPath[250] = "C:\\Hacks\test.dll";
The last backslash is not escaped. Change to:
char DllPath[250] = "C:\\Hacks\\test.dll";
The function is called LoadLibraryA(), not LibraryLoadA():
fpLoadLibrary LoadLibraryAddr =
(fpLoadLibrary)GetProcAddress(hDll, "LibraryLoadA");
A few other suggestions:
Only check GetLastError() if the previous WINAPI function failed.
Only continue processing if the previous WINAPI code (or other code) succeeded.
In
fpLoadLibrary LoadLibraryAddr = (fpLoadLibrary)GetProcAddress(hDll, "LibraryLoadA");
you should rather resolve the string LoadLibraryA. The
OpenProcess:127 ERROR_PROC_NOT_FOUND
VirtualAlloxEx:127 ERROR_PROC_NOT_FOUND (<-- sic)
WriteProcessMemory:127 ERROR_PROC_NOT_FOUND
errors are caused because you're using GetLastError even though these functions maybe didn't even fail. So before calling GetLastError, make sure that these functions yield an error return value (NULL or the like).