I googled a bit but can't seem to make this work.
privileges();
int pid = getPid("test.exe");
cout << "Process ID :" << pid << endl;
const char* prename;
HANDLE pHandle = OpenProcess(PROCESS_VM_READ , FALSE, pid);
if (pHandle)
{
cout << "Handle Open Success" << endl;
//SIZE_T bytesRead;
if (ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, strlen(prename), NULL))
{
cout << "Read Success" << endl;
cout << prename << endl;
}
else
cout << GetLastError() << endl;
}
return 0;
It prints "Read Success" but does not print the variable just blank. The address(address of a string in another process) I got is from ollydbg and verified it using a function as well.
I also wanted to replace the string using writeprocessmemory but before i get to that i needed to make sure reading is correct.
Any idea?
Your problem lies here:
const char* prename;
ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, strlen(prename), NULL)
Your char pointer is not initialized and neither is the random memory it points to. When you call strlen on it, it's trying to get the length of a random memory location.
Secondly you're using the address of the pointer &prename, that's the address of the pointer not the char array it should point to.
To fix do it like this:
char prename[100];
ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, sizeof(prename), NULL)
sizeof() will return 100, so you will be reading 100 bytes of memory
Related
I have been experimenting with various aspects of the Windows API and thought I would give process memory manipulation a try. Previously I had been trying to do this in native C++ using this method: C++ - Get value of a particular memory address
However, this method does not work and I found a response somewhere on the Cplusplus forum that told me to use ReadProcessMemory. I found that WriteProcessMemory works just fine when attempting to edit values, but ReadProcessMemory either fails (returning error code 299) or crashes the application.
Here is my code:
#include <iostream>
#include <cstdint>
#include <Windows.h>
#include <cstdio>
using namespace std;
int main()
{
LPVOID bytes;
DWORD pid;
SIZE_T *num_bytes_read;
int temp;
SIZE_T size = sizeof(temp);
LPCVOID address = reinterpret_cast<int*>(0x404004);
HWND hwnd = FindWindow(NULL, "C:\\Users\\Delkarix\\Desktop\\memory_edit_test.exe");
GetWindowThreadProcessId(hwnd, &pid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
BOOL worked = ReadProcessMemory(hProcess, address, bytes, size, num_bytes_read);
cout << "ERROR: " << GetLastError() << endl;
cout << "PROCESS: " << hProcess << endl;
cout << "BYTES: " << bytes << endl;
cout << "BASE ADDRESS: " << address << endl;
cout << "FUNCTION SUCCESS: " << worked << endl;
cout << "BYTES READ: " << *num_bytes_read << endl;
CloseHandle(hProcess);
}
I have noticed that the application crashes when the num_bytes_read variable is a pointer (the 5th parameter of ReadProcessMemory is the num_bytes_read variable) and it throws error 299 when it is not a pointer (the 5th parameter of ReadProcessMemory is the pointer to the num_bytes_read variable).
Here is the code for the memory_edit_test.cpp:
#include <iostream>
using namespace std;
int test = 6;
int main() {
string input;
cout << &test << endl; // Where I got the address 0x404004
getline(cin, input);
cout << test << endl; // Used to check the value against the one I got from ReadProcessMemory
getline(cin, input);
}
How can I get ReadProcessMemory to succeed? Answers to similar questions on StackOverflow either do nothing or they just make the problem worse.
The problem is very simple, third parameter to ReadProcessMemory is meant to point to a buffer, where the memory read will be written to. You just give it an unintialised pointer. Similar problem with the fifth parameter as well.
Your code should look something like this
int temp;
SIZE_T num_bytes_read;
BOOL worked = ReadProcessMemory(hProcess, address, &temp, sizeof temp, &num_bytes_read);
Note third and fifth parameters are pointers to already existing memory. Declare a variable and use & to get its address.
I`m struggling for the past many hours with the following problem: I try to read a file using CreateFile and ReadFile methods.
Here is the code:
char* Utils::ReadFromFile(wchar_t* path) {
HANDLE hFile = CreateFile(
path, // long pointer word string file path (16 bit UNICODE char pointer)
GENERIC_READ, // access to file
0, // share mode ( 0 - prevents others from opening/readin/etc)
NULL, // security attributes
OPEN_EXISTING, // action to take on file -- returns ERROR_FILE_NOT_FOUND
FILE_ATTRIBUTE_READONLY, // readonly and offset possibility
NULL // when opening an existing file, this parameter is ignored
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cout << "File opening failed" << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
}
LARGE_INTEGER largeInteger;
GetFileSizeEx(hFile, &largeInteger);
LONGLONG fileSize = largeInteger.QuadPart;
if (fileSize == 0) {
std::cout << "Error when reading file size" << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
}
cout << "File size: " << fileSize << endl;
char* bytesRead;
bytesRead = new char(fileSize);
int currentOffset = 0;
int attempts = 0;
int nBytesToBeRead = BYTES_TO_READ;
//DWORD nBytesRead = 0;
OVERLAPPED overlap{};
errno_t status;
while (currentOffset < fileSize) {
overlap.Offset = currentOffset;
if (fileSize - currentOffset < nBytesToBeRead)
nBytesToBeRead = fileSize - currentOffset;
status = ReadFile(
hFile, // file handler
bytesRead + currentOffset, // byted read from file
nBytesToBeRead, // number of bytes to read
NULL, // number of bytes read
&overlap // overlap parameter
);
if (status == 0) {
std::cout << "Error when reading file at offset: " << currentOffset << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
attempts++;
std::cout << "Attempt: " << attempts << endl;
if (attempts == 3) {
cout << "The operation could not be performed. Closing..." << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
}
continue;
}
else {
cout << "Read from offset: " << currentOffset;// << " -- " << overlap.InternalHigh << endl;
currentOffset += nBytesToBeRead;
if (currentOffset == fileSize) {
cout << "File reading completed" << endl;
break;
}
}
}
CloseHandle(hFile);
return bytesRead;
}
When running this method I get some weird results:
One time it worked perfectly
Very often I get Access violation reading location for currentOffset variable and overlap.InternalHigh ( I commented last one), with last method from CallStack being
msvcp140d.dll!std::locale::locale(const std::locale & _Right) Line 326 C++
Sometimes the function runs perfectly, but I get access violation reading location when trying to exit main function with last method from CallStack being
ucrtbased.dll!_CrtIsValidHeapPointer(const void * block) Line 1385 C++
I read the windows documentation thoroughly regarding the methods I use and checked the Internet for any solution I could find, but without any result. I don't understand this behaviour, getting different errors when running cod multiple times, and therefore I can`t get to a solution for this problem.
Note: The reason I am reading the file in repeated calls is not relevant. I tried reading with a single call and the result is the same.
Thank you in advance
You are allocating a single char for bytesRead, not an array of fileSize chars:
char* bytesRead;
bytesRead = new char(fileSize); // allocate a char and initialize it with fileSize value
bytesRead = new char[fileSize]; // allocate an array of fileSize chars
Currently I am making a C/C++ program for the Linux Operating system.
I want to use a named pipe to communicate a PID (process ID) between two programs.
The pipe has been created and is visible in the directory.
The Get PID program says that the file descriptor returns 3, while it should return 0 if it could open the pipe. What am I doing wrong?
Get PID
// Several includes
using namespace std;
int main(int argc, char *argv[]) {
pid_t pid;
int sig = 22;
int succesKill;
int iFIFO;
char sPID[5] = {0,1,2,3,'\0'};
iFIFO = open("IDpipe" , O_RDONLY);
if(iFIFO != 0)
{
cerr << "File descriptor does not return 0, but: " << iFIFO << endl;
return EXIT_FAILURE;
}
read(iFIFO, sPID, strlen(sPID));
cerr << "In sPID now is: " << sPID << endl;
close(iFIFO);
pid = atoi(sPID);
cout << "The PID I will send signals to is: " << pid << "." << endl;
while(1)
{
succesKill = kill(pid, sig);
cout << "Tried to send signal" << endl;
sleep(5);
}
return EXIT_SUCCESS;
}
Send PID
// Several includes
using namespace std;
void catch_function(int signo);
volatile sig_atomic_t iAmountSignals = 0;
int main(void) {
pid_t myPID;
int iFIFO;
char sPID[5] = {'l','e','e','g','\0'};
myPID = getpid();
sprintf(sPID, "%d",myPID);
cout << "My PID is: " << sPID << endl;
iFIFO = open("IDpipe" , O_WRONLY);
if(iFIFO == -1)
{
cerr << "Pipe can't be opened for writing, error: " << errno << endl;
return EXIT_FAILURE;
}
write(iFIFO, sPID, strlen(sPID));
close(iFIFO);
if (signal(22, catch_function) == SIG_ERR) {
cerr << "An error occurred while setting a signal handler." << endl;
return EXIT_FAILURE;
}
cout << "Raising the interactive attention signal." << endl;
if (raise(22) != 0) {
cerr << "Error raising the signal." << endl;
return EXIT_FAILURE;
}
while(1)
{
cout << "iAmountSignals is: " << iAmountSignals << endl;
sleep(1);
}
cout << "Exit." << endl;
return EXIT_SUCCESS;
}
void catch_function(int signo) {
switch(signo) {
case 22:
cout << "Caught a signal 22" << endl;
if(iAmountSignals == 9)
{iAmountSignals = 0;}
else
{++iAmountSignals;}
break;
default:
cerr << "Thats the wrong signal.." << endl;
break;
}
}
Terminal output
Output
open() returns the newly created file descriptor. It cannot return 0 for the simple reason that the new process already has a file descriptor 0. That would be standard input.
The return value of 3 is the expected result from open(), in this case, because that would be the next available file descriptor after standard input, output, and error. If open() couldn't open the file descriptor, it would return -1.
But besides that, your code also has a bunch of other bugs:
sprintf(sPID, "%d",myPID);
// ...
write(iFIFO, sPID, strlen(sPID));
If your process ID happens to be only 3 digits long (which is possible), this will write three bytes to the pipe.
If your process ID happens to be five digits long (which is even more possible), this will write 5 bytes plus the '\0' byte, for a total of six bytes written to the five byte-long sPID buffer, overrunning the array and resulting in undefined behavior.
The actual results are, of course, are undefined, but a typical C++ implementation will end up clobbering the first byte of whatever is the next variable on the stack, which is:
int iFIFO;
which is your file descriptor. So, if your luck runs out and your new process gets a five-digit process id, and this is a little-endian C++ implementation, there is no padding, then the low order byte of iFIFO gets set to 0, and if the code got compiled without any optimizations, the iFIFO file descriptor gets set to 0. Hillarity ensues.
Furthermore, on the other side of the pipe:
char sPID[5] = {0,1,2,3,'\0'};
// ...
read(iFIFO, sPID, strlen(sPID));
Because the first byte of SPID is always set to 0, this will always execute read(iFIFO, sPID, 0), and not read anything.
After that:
pid = atoi(sPID);
atoi() expects a '\0'-terminated string. read() only reads whatever it reads, it will not '\0'-terminate whatever it ends up reading. It is your responsibility to place a '\0' that terminates the read input (and, of course, making sure that the read buffer is big enough), before using atoi().
Your logic appears to be incorrect.
if(iFIFO != 0)
should be
if(iFIFO == -1)
since open returns -1 on error. Otherwise it returns a valid file descriptor.
Been stuck for a few hours making a (simple) dll injector that takes a .dll file and a process as arguments and then injects said .dll into the process, and I'm about to start tearing my hair out.
It doesn't function properly, and for no obvious reason either. The dll simply won't load into the process, but without any error messages being displayed. I did the exact same thing but with ANSI functions instead of Unicode and it worked like a charm, which after some testing is leading me to believe it's PROBABLY a problem with the file path not being loaded properly but I have no idea why.
I've attached my entire source code below and added some comments to hopefully clarify somewhat. And like I said, if I'm right, then the important part should start somewhere around:
//Get the full path of our dll and store it in a variable
Help a bro out.
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
using namespace std;
int main()
{
HANDLE hSnapshot, hProc = NULL;
PROCESSENTRY32 PE32;
PE32.dwSize = sizeof(PROCESSENTRY32);
WCHAR injProcName[100] = {NULL}, injDllName[100] = {NULL};
//Let user input options
cout << "Dll injector started!" << endl << "Please enter the name of the dll you would like to inject: ";
wcin >> injDllName;
cout << "Enter the name of the target process: ";
wcin >> injProcName;
//Create snapshot
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
Process32First(hSnapshot, &PE32);
//Load the first process into PE32 and loop to see if target process is running
do {
if(wcscmp(PE32.szExeFile, injProcName) == 0) {
wcout << PE32.szExeFile << " found!" << endl;
wcout << "Attempting to open " << injProcName << ".." << endl;
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PE32.th32ProcessID);
if(!hProc)
{
cout << "Failed to open process!" << endl;
return 1;
}
break;
}
}
while(Process32Next(hSnapshot, &PE32));
if(!hProc) {
cout << "Unable to locate process!" << endl;
return 1;
}
cout << "Process successfully opened!" << endl;
//Get the full path of our dll and store it in a variable
WCHAR DllPath[MAX_PATH] = {NULL};
GetFullPathName(injDllName, MAX_PATH, DllPath, NULL);
wcout << DllPath << endl;
//Allocate memory in target process
cout << "Allocating memory.." << endl;
LPVOID DllMemAddr = VirtualAllocEx(hProc,
NULL,
wcslen(DllPath),
MEM_COMMIT|MEM_RESERVE,
PAGE_READWRITE);
//Write our path into target process memory
wcout << "Writing dll to target process.." << endl;
WriteProcessMemory(hProc,
DllMemAddr,
DllPath,
wcslen(DllPath),
NULL);
//Get the memory address of LoadLibraryW
LPVOID LoadAddr = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
//Finally, start a new thread with the address of LoadLibraryW and our dll path as argument
cout << "Executing dll in remote process.." << endl;
CreateRemoteThread(hProc,
NULL,
NULL,
(LPTHREAD_START_ROUTINE)LoadAddr,
DllMemAddr,
NULL,
NULL);
cout << "Dll sucessfully injected!" << endl;
cin.get();
return 0;
}
wcslen returns length in wchar_t units. But VirtualAllocEx and WriteProcessMemory receive a length in byte units. So you only write half the string, because wchar_t is two bytes wide. And you did not write the null terminator.
You need to pass (wcslen(DllPath)+1)*sizeof(wchar_t).
Incidentally, your ANSI code was probably broken too because, presumably, it also missed the null terminator. But you probably got away with it by chance.
A little error checking would not go amis, while we are in the business of looking at your code. And initialising DllPath is a little pointless when you follow it with the call to GetFullPathName.
I am having a really hard time with some API calls to the Wininet dll. I am trying to read cookies client side set by IE 9. Here's the code.
#include "stdafx.h"
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
LPTSTR lpData = NULL;
DWORD dwSz = 500;
std::cout << "Hello Chris" << std::endl;
lpData = new TCHAR[dwSz];
std::wcout << "Arg 0: " << argv[1] << std::endl;
bool val = InternetGetCookieEx(argv[1], argv[2], lpData, &dwSz, INTERNET_COOKIE_THIRD_PARTY | INTERNET_FLAG_RESTRICTED_ZONE, NULL);
if (!val)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
std::cout << "Insufficent Buffer size" << std::endl;
lpData = new TCHAR[dwSz];
val = InternetGetCookieEx(argv[1], argv[2], lpData, &dwSz, INTERNET_COOKIE_THIRD_PARTY | INTERNET_FLAG_RESTRICTED_ZONE, NULL);
if (val)
{
std::cout << "Cookie Data: " << lpData << std::endl;
}
else
{
std::cout << "ERROR Code: " << GetLastError() << std::endl;
}
}
else
{
int err = GetLastError();
std::cout << "ERROR Code: " << err << std::endl;
}
}
else
{
std::cout << "Cookie Data: " << lpData << std::endl;
}
//}
return 0;
}
The problem that I am having is that when I call InternetGetCookeEx I always return false and get an error code of 259, which means no more data available. When you consult the API essentially what that means is that it couldn't find my cookie.
Because I am using IE 9 the names for files that the cookie is being stored in are obviously mangled , which is why I am trying to read my cookie data that way.
I have removed the company name to protect the company. Essentially what I am trying to do is. Find the lUsrCtxPersist cookie value. Therefore I am calling the code as such CookieReader.ext http://[CompanyDomain].com lUsrCtxPersist.
However I always get a false and an error code of 259. Any light you might be able to shed on this would be greatly appreciated.
http://msdn.microsoft.com/en-us/library/ms537312%28v=vs.85%29.aspx
Try to use IEGetProtectedModeCookie
Assuming the cookie name is correct, then try removing the INTERNET_COOKIE_THIRD_PARTY and/or INTERNET_FLAG_RESTRICTED_ZONE flags and see what happens. Or try calling InternetGetCookie() instead, which has no such flags available.
On a separate note, when InternetGetCookieEx() returns ERROR_INSUFFICIENT_BUFFER, you are leaking memory. You need to delete[] your existing buffer before then calling new[] to allocate a new buffer.