C++ ReadProcessMemory buffer always displays 0 - c++

my &pTemp
So I think I'm not understanding this quite well. If I'm not mistaken, the pointer value should be stored in pTemp, right?. So, if the base pointer is 0x00001A, shouldn't pTemp display the same thing? I'm really new to C++ and any help would be appreciated!
DWORD pointer = baseAddress;
DWORD pTemp;
DWORD pointerAddress;
cout << "Base Address: " << (DWORD*) pointer << endl;
for (int i = 0; i < PointerLevel; i++)
{
if (i == 0)
{
ReadProcessMemory(handle, (LPVOID)pointer, &pTemp, sizeof(4), NULL);
cout << "pTemp: " << pTemp << endl;

Try this:
void * src_addr = reinterpret_cast<void *>(baseAddress);
std::size_t n;
if (ReadProcessMemory(handle, src_addr, &pTemp, sizeof pTemp, &n))
{
if (n == sizeof pTemp)
{
std::cout << "Success: pTemp = " << pTemp << "\n";
}
else
{
std::cout << "We only read " << n << " bytes, not the expected "
<< sizeof pTemp << " bytes.\n";
}
}
else
{
std::cout << "Failed to read process memory.\n";
}

Related

How do I get stack call information in an x64 program?

I found a way to get the information of the stack call in an x86 program. The code is not difficult to understand:
#ifdef X86
void TestGetCallStack_X86()
{
std::cout << "Call -> TestGetCallStack_X86" << std::endl;
std::cout << "***************************************" << std::endl;
DWORD _ebp, _esp;
__asm mov _ebp, ebp
__asm mov _esp, esp
for (unsigned int index = 0; index < CALLSTACK_NUM; index++) {
void* pAddr = (void*)ULongToPtr(*(((DWORD*)ULongToPtr(_ebp)) + 1));
if (!pAddr)
return;
IMAGEHLP_LINE64 Line;
Line.SizeOfStruct = sizeof(Line);
memset(&Line, 0, sizeof(Line));
DWORD Offset = 0;
if (fnSymGetLineFromAddr64(s_Process, (DWORD64)pAddr, &Offset, &Line))
{
std::cout << index << " [" << pAddr << "]";
std::cout << " File Name:" << Line.FileName << " " << "Line Count:" << Line.LineNumber << std::endl;
std::cout << std::endl;
}
else
{
DWORD error = GetLastError();
if (error == 487)
{
OutputDebugString(TEXT("No debug info in current module\n"));
}
else if (error == 126)
{
OutputDebugString(TEXT("Debug info in current module has not loaded\n"));
}
else
{
OutputDebugString(TEXT("SymGetLineFromAddr64 failed\n"));
}
std::cout << std::endl;
}
_ebp = *(DWORD*)ULongToPtr(_ebp);
if (_ebp == 0 || 0 != (_ebp & 0xFC000000) || _ebp < _esp)
break;
}
std::cout << "***************************************" << std::endl;
}
#endif // X86
run result
I wrote an x64 version and found that MSVC for x64 does't support inline assembly.
I try to write a .asm file and load the function in C++ code. but it does't work. (Actually I'm not good at Assembly language)
I found many ways. So far, I have used the _ReturnAddress to achieve.
void TestGetCallStack_X64()
{
void* pAddr = _ReturnAddress();
if (!pAddr)
return;
std::cout << "0" << "\t" << pAddr << std::endl;
std::cout << "Use GetLineFromAddress64:" << std::endl;
IMAGEHLP_LINE64 Line;
Line.SizeOfStruct = sizeof(Line);
memset(&Line, 0, sizeof(Line));
DWORD Offset = 0;
if (fnSymGetLineFromAddr64(s_Process, (DWORD64)pAddr, &Offset, &Line))
{
std::cout << "File Name:" << Line.FileName << "\t" << "Line Count:" << Line.LineNumber << std::endl;
std::cout << std::endl;
}
else
{
//Can not find...
}
}
Run Result
But this way cannot fully display the information of the stack call. How should I achieve the same effect as the x86 version?
PS: I can't understand the condition of break in x86's Code. Can anyone answer, Please! Thank you first.
//what's the mean that <_ebp & 0xFC000000>
if (_ebp == 0 || 0 != (_ebp & 0xFC000000) || _ebp < _esp)

why send function return 0 in socket, but clients do have recieve the message?

void SendStr(int connfd, std::string str)
{
uint16_t *len = new uint16_t(str.size());
const char * lenByte = (char *)len;
char *sendByte = new char[*len + 2]{0};
memcpy(sendByte,lenByte,sizeof(*len));
memcpy(sendByte + 2, str.c_str(), *len);
std::cout << "str size " << *len << std::endl;
//std::cout << "len size " << sizeof(len) << std::endl;
size_t nleft = *len + 2;
std::cout << "need to send " << nleft << std::endl;
int nsend = 0;
while (nleft > 0)
{
//std::cout << "sending " << nleft << "bytes" << std::endl;
if (nsend = (write(connfd, sendByte + nsend, nleft)) < 0)
{
if (errno == EINTR)
continue;
ERROR_EXIT("send");
}
else if (nsend == 0)
//continue;
break;
nleft -= nsend;
std::cout << "sended " << nsend << " left " << nleft << std::endl;
}
std::cout << "send complete" << std::endl;
delete[] sendByte;
delete len;
}
The full code is here
I see write and send function return the sum of bytes, while here returns 0, and client seems run normally, it confuses me.
What you see is wrong.
In this statement
if (nsend = (write(connfd, sendByte + nsend, nleft)) < 0)
The comparision result of (write(connfd, sendByte + nsend, nleft)) < 0 is assingned to nsend. This will become 1 if the condition is true and 0 if the condition is false. It seems you are misunderstanding this comparision result as the sum of bytes.
If you want to assign what is returned from write to nsend and then compare, it should be like this:
if ((nsend = write(connfd, sendByte + nsend, nleft)) < 0)
Addendum: The only way for write to return 0 on a socket is if nleft is 0.

NtQuerySystemInformation returns back negative result for a specific core - What does that mean

I am trying to output the performance of each processor on my machine.
I have two groups with 36 processors on each. I am doing something like this
PVOID WLAlloc(DWORD dwSize)
{
PVOID pMem = nullptr;
pMem = HeapAlloc(GetProcessHeap(),NULL,dwSize);
return pMem;
}
void test()
{
int numofGroups = 2;
DWORD uSize = 2 * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
PVOID pMem = WLAlloc(uSize);
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* m_pCoreUsageInfoArray = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)pMem;
NTSTATUS status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, m_pCoreUsageInfoArray, uSize, NULL);
if (status >= 0)
{
for (int i = 0; i < 72; i++)
{
auto t = m_pCoreUsageInfoArray[i];
std::cout << "Core: " << i << " Idle:" << t.IdleTime.QuadPart << " Kernel: " << t.KernelTime.QuadPart << " User :" << t.UserTime.QuadPart << std::endl;
}
}
}
I am getting this as output:
Core: 23 Idle:0 Kernel: -9223358841219038703 User :0
Any idea why I am getting a negative number?
You are allocating only room for 2 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, but then you are trying to iterate up to index 72, which is Undefined Behavior for indexes 2 and higher.
You need to fix your loop to only iterate over items you have pre-allocated, or else query for the actual size first and retry the call with the proper size:
DWORD uSize = 0;
NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL, 0, &uSize);
PVOID pMem = WLAlloc(uSize);
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* m_pCoreUsageInfoArray = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)pMem;
if (NT_ERROR(NtQuerySystemInformation(SystemProcessorPerformanceInformation, m_pCoreUsageInfoArray, uSize, NULL)))
{
return;
}
int numofGroups = uSize / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
for (int i = 0; i < numofGroups; i++)
{
auto t = m_pCoreUsageInfoArray[i];
std::cout << "Core: " << i << " Idle:" << t.IdleTime.QuadPart << " Kernel: " << t.KernelTime.QuadPart << " User :" << t.UserTime.QuadPart << std::endl;
}

How do i read a std::string from memory using RPM

Okay, so recently i've been working witth RPM(ReadProccesMemory). But while doing so i bumped into the issue of not being able to read a string the way i wanted it.
This is what i heard/know:
I know, when reading a std::string, i get the memory adress of the string OBJECT and not the adress that contains the actual text.I am also aware of "Small String Optimization", and what it does in theory.
I'd like to be able to read the contents of varString(DefaultString) without changing the code of my dummy program(if possible).
The dummy program im reading:
int main() {
// Variables & Pointers
int varInt = 123456;
string varString = "DefaultString";
cout << sizeof(varString);
char arrChar[128] = { "Long char array right there ->" };
int* ptr2int = &varInt;
int** ptr2ptr = &ptr2int;
int*** ptr2ptr2 = &ptr2ptr;
// Printing them out
while (true){
cout << "Process ID: " << GetCurrentProcessId() << endl << endl;
cout << "varInt (0x" << &varInt << ") = " << varInt << endl;
cout << "varString (" << reinterpret_cast<const void*>(varString.data()) << ") = " << varString << endl;
cout << "arrChar (0x" << &arrChar << ") = " << arrChar << endl << endl;
cout << "ptr2int (0x" << &ptr2int << ") = " << &varInt << endl;
cout << "ptr2ptr (0x" << &ptr2ptr << ") = " << &ptr2int << endl;
cout << "ptr2ptr2 (0x" << &ptr2ptr2 << ") = " << &ptr2ptr << endl << endl;
break;
}
cin.get();
return 0;
}
What im currently doing(wont work as intended):
void reading_string(HANDLE handle_procces) {
uintptr_t memoryAdress_2 = 0x0;
cout << "Please write down the memory adress of \"varString\" > " << flush;
cin >> hex >> memoryAdress_2;
string read_string_object;
ReadProcessMemory(handle_procces, (LPCVOID)memoryAdress_2, &read_string_object, sizeof(string), NULL);
cout << "The value of this memory adress is: " << read_string_object << endl;
}
std::string is a container, offset 0x14 is the size of the char array which it manages. If the string is less than 15 characters, the second variable (offset 0x4 or 0x8 depending on x86/x64) is the char array itself. If it's more than 15 characters, this variable turns into a pointer to the char array which is allocated dynamically
We can use this information to read the string externally, it's a hack but it works
Here some sample code which shows you how it's done:
#include <windows.h>
#include <iostream>
using namespace std;
void ReadExternalString(HANDLE hProc, uintptr_t addr, char* dstArray)
{
//Get the size of the array, offset 0x14 is the size of the array
//it's 0x14 on x86
uintptr_t sizeoffset = 0x14;
//check if x64
if (sizeof(int*) == 8)
{
//assign correct offset
sizeoffset = 0x18;
}
uintptr_t arraySize;
ReadProcessMemory(hProc, (BYTE*)(addr + sizeoffset), &arraySize, sizeof(arraySize), 0);
if (arraySize > 15)
{
uintptr_t addrOfCharArray;
//dereference the pointer in the second member variable to get the dynamic address of the array
ReadProcessMemory(hProc, (BYTE*)(addr + sizeof(void*)), &addrOfCharArray, sizeof(void*), 0);
char buffer[500];
//Read the array into buffer, +1 to get the null terminator
ReadProcessMemory(hProc, (BYTE*)(addrOfCharArray), &buffer, arraySize + 1, 0);
//copy the buffer into our ouput argument
memcpy(dstArray, &buffer, strlen(buffer) + 1);
}
else
{
ReadProcessMemory(hProc, (BYTE*)(addr + sizeof(void*)), dstArray, arraySize, 0);
}
}
std::string ourStringToRead = "Yolo";
int main()
{
HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, GetCurrentProcessId());
if (hProcess == NULL)
{
cout << "OpenProcess failed. GetLastError = " << dec << GetLastError() << endl;
system("pause");
return EXIT_FAILURE;
}
char* cString = new char[500];
ZeroMemory(cString, 500);
ReadExternalString(hProcess, (uintptr_t)&ourStringToRead, cString);
cout << "string char array = " << cString << endl;
system("pause");
return 0;
}

Why this program gives a Segmentation Fault while calling a function?

This is a part of my program while I run this program I get a segmentation fault. I've narrowed it down to the line:
checkBase(ptr1, ptr2)
i'm passing both of these as pointers. and they are declare as char* and its a runtime error not compile time.
file contains
< a href = "http://www.google.com"> www.spam.google.com < /a >
in this case ptr1 = www.google.com and ptr2 = spam.google.com
while(inf){
count++;
getline(inf, line);
//cout << "*******" << count << "*******" << endl <<line << endl;
p = new char[line.length()+1];
strcpy(p, line.c_str());
if(strstr(p, "href")){
ptr = strstr(p, "href");
while(ptr[0]!='\0'){
ptr += 1;
if(ptr[0] == 'w' && ptr[1] == 'w' && ptr[2] == 'w'){
cout << ptr << endl;
ptr = strtok(ptr, "\"");
cout << "add1 " << ptr << endl;
add1 = ptr;
ptr1 = ptr;
ptr = strtok(NULL, "> ");
add2 = ptr;
ptr2 = ptr;
cout << "ptr1: " << ptr1 << endl << "ptr2: " <<ptr2 << endl;
if(add1 == add2)
cout << "There is an exact match at line: " << count << endl << line << endl;
else{
cout << "in else" << endl;
checkBase(ptr1, ptr2); //THIS GIVES A SEGMENTATION FAULT
}
}
}
}
}
void checkBase(char *add1, char *add2){
cout << "here" << endl;
char *base1[1000000], *base2[1000000];
int count1 = 0, count2 = 0;
base1[count1] = strtok(add1, ".");
while(base1[count1] != NULL){
count1++;
base1[count1] = strtok(NULL, ".");
cout << base1[count1] << endl;
}
base2[count2] = strtok(add2, ".");
while(base2[count2] != NULL){
count2++;
base2[count2] = strtok(NULL, ".");
}
cout << base2[count2-1] << endl;
if(((strcmp(base1[count1-1],base2[count2-1])) != 0) && (strcmp(base1[count1-2], base2[count2-2]) != 0)){
//if((strcmp(base1[count1-1], base2[count2-1]) != 0)){
cout << "Bases do not match: " << endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << endl;
//}
}
else{
cout << "Bases match: " << endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << endl;
}
}
I have no idea why this is giving a segmenation fault.
char *base1[1000000], *base2[1000000];
No doubt this is causing stack overflow. The stack is limited in size, and creating arrays more than a few kb in size is a bad idea. Try allocating them on the heap, for example vector<char *> base1(1000000)
You should also calculate the exact size required and allocate that much, or push_back on the vector.
A couple of problems, beyond the stack overflow already mentioned by #Neil Kirkwell
Those shouldn't be while loops solely conditioned on base1[count1] != NULL; you should also make sure count1 is less than the number of elements in the array.
If either count2 or count1 is 0 or 1 you will be trying to reference index of -1 and -2... not so good.
use strrchr to search backwards and make your life easier
It's wasteful to build those arrays entirely, since you only seem to care about the last two tokens, you only need two pointers in each.
i.e.
char *one_a = NULL, *one_b = NULL, *two_a=NULL, *two_b = NULL;
char *temp = strtok(add1, ".");
while (temp) {
one_b = one_a;
one_a = temp
temp = strtok(NULL, ".");
}
char *temp = strtok(add2, ".");
while (temp) {
two_b = two_a;
two_a = temp
temp = strtok(NULL, ".");
}
//now just compare one_a with two_a and one_b with two_b and you're done.