I posted a little earlier with a sendmessage issue and we came to the conclusion that it would be extremely hard to get the chat window from Xchat. I have now moved to ThrashIRC and using spy++ was able to find the chat window(highlighted):
As you can see it does have a caption which means that it does see the text. Here is the code that I am using to get the HWND's and the text:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
#include <strsafe.h>
using namespace std;
void FindThrash()
{
cout << "[ThrashIRC]" << endl;
cout << "| find ThrashIRC window" << endl;
HWND hwndThrashIRC = FindWindow(L"ThrashIRC", NULL);
if (NULL != hwndThrashIRC)
{
cout << " + found ThrashIRC window" << endl;
cout << "| find MDIClient window" << endl;
HWND hwndMDIClient = FindWindowEx(hwndThrashIRC, NULL, L"MDIClient", NULL);
if (NULL != hwndMDIClient)
{
cout << " + found MDIClient window" << endl;
cout << "| find DefChannel window" << endl;
HWND hwndDefChannel = FindWindowEx(hwndMDIClient, NULL, L"DefChannel", NULL);
if (NULL != hwndDefChannel)
{
cout << " + found MDIClient window" << endl;
cout << "| find RichEdit20W window" << endl;
HWND hwndRichEdit20W = FindWindowEx(hwndDefChannel, NULL, L"RichEdit20W", NULL);
if (NULL != hwndRichEdit20W)
{
cout << " + found RichEdit20W window" << endl << endl;
cout << "- get text " << endl;
const int bufferSize = 32768;
char textBuffer[bufferSize] = "";
SendMessage(hwndRichEdit20W, WM_GETTEXT, (WPARAM)bufferSize, (LPARAM)textBuffer);
cout << "[begin text]" << endl;
cout << textBuffer << endl;
cout << "[end text]" << endl;
}
else
{
cerr << "RichEdit20W not found." << endl;
}
}
else
{
cerr << "DefChannel not found." << endl;
}
}
else
{
cerr << "MDIClient not found." << endl;
}
}
else
{
cerr << "ThrashIRC not open." << endl;
}
}
void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
int main()
{
FindThrash();
if (!GetProcessId(NULL))
ErrorExit(TEXT("GetProcessId"));
return 0;
}
The buffer is only that large because 1: I thought it might have been an error where the buffer was to small, and 2: the buffer is going to have to be large because of the amount of text. Any suggestions / code would be greatly appreciated! Thanks!
GetProcessID expects to be passed a valid process handle, as is clearly stated in the MSDN documentation. You're calling it with NULL as the argument:
if (!GetProcessId(NULL))
Why would you expect it to return anything but an invalid handle error when you're clearly providing it an invalid process handle?
Just to make sure you're aware, an HWND is a window handle, not a process handle. FindWindow and FindWindowEx return a window handle.
Related
I decided to create my own dll injector but the problem is that almost when I finished my code a problem occurs, in the following code my dll does not inject correctly, I tried everything like checking if my dll was good or even my code in general but nothing works. (I want to specify that for my processId if I use GetCurrentProcessId() my dll is injected correctly but not where I want so it is imperative for me to use GetProcessIdByName.) Thank you to all those who will help me!
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>
#include <string>
#include <iostream>
using namespace std;
DWORD GetProcessIdByName(const char* processName)
{
DWORD processId = 0;
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(snap, &pe))
{
do
{
if (!_stricmp(pe.szExeFile, processName))
{
processId = pe.th32ProcessID;
break;
}
} while (Process32Next(snap, &pe));
}
CloseHandle(snap);
}
return processId;
}
int main()
{
const char* processName = "OLLYDBG.exe";
DWORD processId = GetProcessIdByName(processName);
LPCSTR dllPath = "C:\\Users\\Alban\\source\\repos\\Cheat\\Cheat\\testdll.dll";
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if (hProcess == NULL)
{
cout << "Error with 'OpenProcess', error code : " << GetLastError() << endl;
return 1;
}
cout << "process id : " << processId << endl;
LPVOID pdllPath = VirtualAllocEx(hProcess, NULL, strlen(dllPath) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pdllPath == NULL)
{
cout << "failed to allocate dll path, error code : " << GetLastError() << endl;
return 1;
}
cout << "path to memory : " << hex << pdllPath << endl;
BOOL writedMemory = WriteProcessMemory(hProcess, pdllPath, LPVOID(dllPath), strlen(dllPath) + 1, NULL);
if (writedMemory == 0)
{
cout << "failed to write memory, error code : " << GetLastError() << endl;
return 1;
}
HANDLE hloadThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "LoadLibraryA"), pdllPath, 0, NULL);
if (hloadThread == NULL)
{
cout << "Can not create remote thread, error code : " << GetLastError() << endl;
return 1;
}
WaitForSingleObject(hloadThread, INFINITE);
BOOL virtualFree = VirtualFreeEx(hProcess, pdllPath, 0, MEM_RELEASE);
if (virtualFree == 0)
{
cout << "Can not release memory, error code : " << GetLastError() << endl;
}
CloseHandle(hProcess);
}
#include <Windows.h>
#include <iostream>
#include <vector>
#include <TlHelp32.h>
#include <tchar.h>
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 (DWORDLONG)lpModuleEntry.modBaseAddr;
}
bModule = Module32Next( hSnapShot, &lpModuleEntry );
}
CloseHandle( hSnapShot );
return NULL;
}
int main() {
DWORD pID;
DWORDLONG off1, off2;
DWORDLONG baseAddress;
char moduleName[] = _T("AoE2DE_s.exe");
HWND hGameWindow;
HANDLE pHandle;
//Get Handles
hGameWindow = FindWindow(NULL, "Age of Empires II: Definitive Edition");
cout << "Game Window: " << hGameWindow << std::endl;
GetWindowThreadProcessId(hGameWindow, &pID);
cout << "Process ID: " << pID << std::endl;
pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
cout << "Process Handle: " << std::hex << pHandle << std::endl;
//Get Client Base Addy
DWORDLONG clientBase = GetModuleBase(moduleName, pID);
cout << "Client Base: " << clientBase << std::endl;
ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &baseAddress, sizeof(DWORDLONG), NULL);
DWORD lastError = GetLastError();
cout << "Error: " << lastError << std::endl;
cout << "Base Address: " << std::hex << baseAddress << std::endl;
ReadProcessMemory(pHandle, (LPCVOID)(baseAddress + 0x18), &off1, sizeof(DWORDLONG), NULL);
cout << "After Offset 1: " << std::hex << off1 << std::endl;
ReadProcessMemory(pHandle, (LPCVOID)(off1 + 0x9230), &off2, sizeof(DWORDLONG), NULL);
cout << "After Final Offset: " << off2 << std::endl;
cin.get();
}
The error occurs on this line:
ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &baseAddress, sizeof(DWORDLONG), NULL);
Application output for debugging purposes:
Game Window: 0x1307c2
Process ID: 11988
Process Handle: 0xec
Client Base: cc640000
Error: 12b
Base Address: 0
After Offset 1: 401519
After Final Offset: 8
Not sure how it is failing here, I'm somewhat new to this. Everything else goes through perfectly without error's but fails on the first ReadProcessMemory() if someone can help bring the solution for this to light I would be grateful.
ReadProcessMemory is defined like this:
BOOL ReadProcessMemory(
HANDLE hProcess,
LPCVOID lpBaseAddress,
LPVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesRead
);
If it returns zero then there has been an error, and only in that case GetLastError will return a meaningfull error number.
So correct usage would be:
SIZE_T readBytes;
if (!ReadProcessMemory(pHandle, (LPCVOID)(clientBase + 0x2BFCA18), &baseAddress, sizeof(DWORDLONG), &readBytes)) {
DWORD lastError = GetLastError();
cout << "ReadProcessMemory failed: Error: " << lastError << " read " << readBytes << std::endl;
}
else
{
cout << "ReadProcessMemory succeeded"; << std::endl;
cout << "Base Address: " << std::hex << baseAddress << std::endl;
}
This is all the source code for a program i'm trying to make, and I can't get WriteProcessMemory to work at all. It returns the correct messages, saying that everything went successfully, but nothing actually changes in the game. Does anyone know of a fix?
#include <iostream>
#include <Windows.h>
using namespace std;
// variables
int plcHold = 1;
string hlthLoop = "OFF";
string ammoLoop = "OFF";
DWORD pid;
DWORD playerAddr;
DWORD hlthOffs = 0xF8;
// main function
int main()
{
// finding pid, opening proc, finding player address
HWND hwnd = FindWindowA(NULL, "AssaultCube");
if(hwnd == NULL)
{
cout << "Error; Couldn't find window" << endl;
} else{
GetWindowThreadProcessId(hwnd, &pid);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(pHandle == NULL)
{
cout << "Error; Couldn't open process" << endl;
} else{
ReadProcessMemory(pHandle, (LPCVOID)0x50F4F4, &playerAddr, sizeof(playerAddr), 0);
if(ReadProcessMemory != FALSE)
{
cout << "Health successfully read!" << endl;
} else{
cout << "Error code " << GetLastError << endl;
}
}
while(plcHold == 1){
cout << "========== *****'s Assault Cube Trainer ==========\n" << endl;
cout << "=============== Health Loop - " << hlthLoop << " ================" << endl;
Sleep(1500);
system("cls");
if(GetAsyncKeyState(0x5A))
{
cout << "Health successfully edited!" << endl;
WriteProcessMemory(pHandle, LPVOID(playerAddr + hlthOffs), 0, sizeof(999), 0);
CloseHandle(pHandle);
}
}
}
return 0;
}
You're passing a null pointer to WriteProcessMemory for the third (lpBuffer) parameter. You have to pass the address of the actual value, not the value itself. If you want to write an integer value, try this:
DWORD val = 0; // or 999?
WriteProcessMemory(
pHandle, static_cast<LPVOID>(playerAddr + hlthOffs),
&val, sizeof(val), 0);
The task of getting the PID of the process that I'm starting, CreateProcess() ProcessInformation.dwProcessId does a great job of this, but in my case, the process that I start opens the child processes and then closes, and I need to get all the PIDs that creates the process I am opening.
I found this code, it receives the child PIDs but they do not match the final Firefox window, what am I doing wrong
Source:
CreateProcess returns handle different than launched Chrome.exe
Update 1
After Drake Wu - MSFT comment, I used the following code
int test(const wchar_t* programPath) {
HANDLE Job = CreateJobObject(nullptr, nullptr);
if (!Job) {
std::cout << "CreateJobObject, error " << GetLastError() << std::endl;
return 0;
}
HANDLE IOPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
if (!IOPort) {
std::cout << "CreateIoCompletionPort, error " << GetLastError() << std::endl;
return 0;
}
JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
Port.CompletionKey = Job;
Port.CompletionPort = IOPort;
if (!SetInformationJobObject(Job,
JobObjectAssociateCompletionPortInformation,
&Port, sizeof(Port))) {
std::cout << "SetInformation, error " << GetLastError() << std::endl;
return 0;
}
PROCESS_INFORMATION ProcessInformation;
STARTUPINFOW StartupInfo = { sizeof(StartupInfo) };
LPWSTR szCmdline = const_cast<LPWSTR>(programPath);
if (!CreateProcessW(
programPath,
nullptr,
nullptr,
nullptr,
FALSE,
CREATE_SUSPENDED,
nullptr,
nullptr,
&StartupInfo,
&ProcessInformation))
{
std::cout << "CreateProcess, error " << GetLastError() << std::endl;
return 0;
}
std::cout << "PID: " << ProcessInformation.dwProcessId << std::endl;
if (!AssignProcessToJobObject(Job, ProcessInformation.hProcess)) {
std::cout << "Assign, error " << GetLastError() << std::endl;
return 0;
}
ResumeThread(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
DWORD CompletionCode;
ULONG_PTR CompletionKey;
LPOVERLAPPED Overlapped;
while (GetQueuedCompletionStatus(IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE))
{
switch (CompletionCode)
{
case JOB_OBJECT_MSG_NEW_PROCESS:
std::cout << "New PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_EXIT_PROCESS:
std::cout << "Exit PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
std::cout << "JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO" << std::endl;
break;
default:
break;
}
if (CompletionCode == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO)
break;
}
std::cout << "All done" << std::endl;
}
and I got the following results:
standart Firefox
test(L"C:\\Program Files\\Mozilla Firefox\\firefox.exe");
portable edition Firefox
test(L"D:\\FirefoxPortable\\FirefoxPortable.exe");
As before, PIDs are incorrectly returned. In the case of the portable version, the process hangs on the while loop, in the case of the standard version of firefox, GetQueuedCompletionStatus() returns JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO. Why am I getting the wrong result?
Update 2
I ran Visual Studio as an administrator and, but on standard startup everything displays correctly
I tested that the process of Firefox is not new and exit in order(the pid obtained by CreateProcess will exit), and your code will not receive the new Firefox process if there is any new process created later.
You could use swtich-case statement, the following sample work for me:
int openProgram(const wchar_t* programPath) {
HANDLE Job = CreateJobObject(nullptr, nullptr);
if (!Job) {
std::cout << "CreateJobObject, error " << GetLastError() << std::endl;
return 0;
}
HANDLE IOPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1);
if (!IOPort) {
std::cout << "CreateIoCompletionPort, error " << GetLastError() << std::endl;
return 0;
}
JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
Port.CompletionKey = Job;
Port.CompletionPort = IOPort;
if (!SetInformationJobObject(Job,
JobObjectAssociateCompletionPortInformation,
&Port, sizeof(Port))) {
std::cout << "SetInformation, error " << GetLastError() << std::endl;
return 0;
}
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
LPTSTR szCmdline = _tcsdup(programPath);
if (!CreateProcessW(
nullptr,
szCmdline,
nullptr,
nullptr,
FALSE,
CREATE_SUSPENDED,
nullptr,
nullptr,
&StartupInfo,
&ProcessInformation))
{
std::cout << "CreateProcess, error " << GetLastError() << std::endl;
return 0;
}
std::cout << "PID: " << ProcessInformation.dwProcessId << std::endl;
if (!AssignProcessToJobObject(Job, ProcessInformation.hProcess)) {
std::cout << "Assign, error " << GetLastError() << std::endl;
return 0;
}
ResumeThread(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
DWORD CompletionCode;
ULONG_PTR CompletionKey;
LPOVERLAPPED Overlapped;
while (GetQueuedCompletionStatus(IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE))
{
switch (CompletionCode)
{
case JOB_OBJECT_MSG_NEW_PROCESS:
std::cout << "New PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_EXIT_PROCESS:
std::cout << "Exit PID: " << (int)Overlapped << std::endl;
break;
case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
std::cout << "JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO" << std::endl;
break;
default:
break;
}
if (CompletionCode == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO)
break;
}
std::cout << "All done" << std::endl;
}
Result:
I am developing a small cash hack for GTA V and I found that when I use
WriteProcessMemory(hp, (LPVOID)0x1417C4C18, &cashVal, (DWORD)sizeof(cashVal), 0)
that the WriteProcessMemory returns 0. Here is the full source code of my small hack.
#include <Windows.h>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int cashVal = 0;
cout << "Enter the amount of cash you want: " << endl;
cin >> cashVal;
HWND hwnd = FindWindow(0, "Grand Theft Auto V");
if (hwnd == 0) {
cout << "Cannot find the GTAV window. Make sure its running in Windowed mode!" << endl;
}
else {
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hp) {
cout << "Could not get a handle to GTAV. Try again :(" << endl;
}
else {
int success = WriteProcessMemory(hp, (LPVOID)0x1417C4C18, &cashVal, (DWORD)sizeof
(cashVal), 0);
if (success > 0) {
cout << "You now have " << cashVal << " money!" << endl;
}
else {
cout << "Writing the memory failed!" << endl;
cout << "Error code: " << success << endl;
}
CloseHandle(hp);
}
}
cin.get();
return 0;
}
I basically ask the user to input the cash they want, and it's meant to set it in the game, but it returns a code of 0 and fails. It doesn't fail trying to find the game window because it doesn't print that message to the standard output. Please help me!
NOTE: The hack will be used on single player
First, don't use PROCESS_ALL_ACCESS. Only request what you actually need. WriteProcessMemory() only needs PROCESS_VM_WRITE and PROCESS_VM_OPERATION access, so request only that.
Like many other API functions, when WriteProcessMemory() fails, GetLastError() will tell you why. Your code is assuming that WriteProcessMemory() itself returns an error code directly, but it does not. It returns a BOOL (not an int) to indicate success or failure, and then GetLastError() returns the error code if failure. This is documented behavior:
Return value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError. The function fails if the requested write operation crosses into an area of the process that is inaccessible.
Try this:
#include <windows.h>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int cashVal = 0;
cout << "Enter the amount of cash you want: " << endl;
cin >> cashVal;
HWND hwnd = FindWindow(0, "Grand Theft Auto V");
if (hwnd == 0) {
cout << "Cannot find the GTAV window. Make sure its running in Windowed mode!" << endl;
}
else {
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hp = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
if (!hp) {
cout << "Could not get a handle to GTAV. Try again :(" << endl;
}
else {
BOOL success = WriteProcessMemory(hp, (LPVOID)0x1417C4C18, &cashVal, sizeof(cashVal), 0);
if (success) {
cout << "You now have " << cashVal << " money!" << endl;
}
else {
DWORD errCode = GetLastError();
cout << "Writing the memory failed!" << endl;
cout << "Error code: " << errCode << endl;
}
CloseHandle(hp);
}
}
cin.get();
return 0;
}
You are most likely trying to write to a memory path where you don't have access to... probably you are using a 32-bit program to write to a 64-bit memory address(that's if u use a 64-bit computer), I think I had this problem a few years back porting solved my problem then forgive me if I am wrong atleast that was what I thought.
Try the code on a 32-bit address and if it works... that solves your problem.
And for the Getting_Last_Error you can add this lil' bit of functionality I use.
void PrintLastErrorMsg(){
LPTSTR pTmp = NULL;
DWORD errnum = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
errnum,
LANG_NEUTRAL,
(LPTSTR)&pTmp,
0,
NULL
);
cout << "Error(" << errnum << "): " << pTmp << endl;
}
Be free to make changes.