I'm attempting to use ReadProcessMemory to read a dynamic amount of bytes into an array and then return it. I simply can't get it to work properly. My current code is...
byte *Application::readMemory(DWORD address, int length) {
byte *buffer = new byte[length];
SIZE_T bytesRead;
ReadProcessMemory(piProcessInfo.hProcess, (void *)address, &buffer, length, &bytesRead);
return buffer;
}
Any help would be appreciated.
Shouldn't it be
ReadProcessMemory(piProcessInfo.hProcess, (void *)address, buffer, length, &bytesRead);
? If you give buffer-pointer address as input parameter, then ReadProcessMemory copies it where buffer pointer lies (not to the buffer but into buffer pointer vatiable and beyond) - and sice it is on the stack, stack gets corrupted.
Related
I'm confused with a size issue. Running the following code throws an exception at runtime. Specifically it seems to appear at end, and the text still be pasted with success. Due to my limited skills I'm not able to interpret the exception clearly.
It started when I decided to use the wcscpy_s function due to depreciation of wcscpy which worked fine in my noob program.
#define _CRT_SECURE_NO_WARNINGS
#include <afxwin.h>
int main() {
wchar_t wcSource[7] = L"Testeu"; // Throws an exception error. However, wcSource[8] doesn't
//wchar_t wcSource[9] = L"TestCopy"; // Runs fine
UINT iSize = sizeof(wcSource);
if (OpenClipboard(NULL)) {
EmptyClipboard();
HGLOBAL hClipboardData;
hClipboardData = GlobalAlloc(GMEM_DDESHARE, iSize);
wchar_t *wpchData;
wpchData = (wchar_t*)GlobalLock(hClipboardData);
//wcscpy(wpchData, wcSource); // Works fine
wcscpy_s(wpchData, iSize, wcSource);
GlobalUnlock(hClipboardData);
SetClipboardData(CF_UNICODETEXT, hClipboardData);
CloseClipboard();
}
return 0;
}
wcscpy_s() expects a CHARACTER count, but you are passing it a BYTE count instead. On Windows, sizeof(wchar_t) is 2 bytes.
You need a BYTE count when allocating memory for the clipboard buffer (which in your example will require 14 bytes), but since you are passing the BYTE count as a CHARACTER count to wcscpy_s(), you are telling it that the clipboard buffer can hold up to 14 wchar_t elements, when in actuality it can hold only 7. You are giving wcscpy_s() permission to go out of bounds of the clipboard buffer (for instance, if it wants to pre-fill the buffer memory before then filling it with actual characters). Doing so would corrupt the call stack, which could easily cause an exception when main() exits.
You need to pass wcscpy_s() the max number of CHARACTERS that the clipboard buffer can hold. Not the max number of BYTES it can hold.
You can do that by dividing iSize by sizeof(wchar_t), eg:
wcscpy_s(wpchData, iSize / sizeof(wchar_t), wcSource);
Alternatively, since you are using the exact BYTE size of the source array to allocate the clipboard buffer, you can use _countof() to get the number of CHARACTERS in the array (you cannot pass the allocated clipboard buffer to _countof()), eg:
wcscpy_s(wpchData, _countof(wcSource), wcSource);
Alternatively, you can use wsclen() instead, eg:
wchar_t wcSource[] = L"Testeu";
int iLen = wcslen(wcSource) + 1;
UINT iSize = iLen * sizeof(wchar_t);
...
hClipboardData = GlobalAlloc(GMEM_DDESHARE, iSize);
...
wcscpy_s(wpchData, iLen, wcSource);
I'm using RAW socket to capture udp packets. After capturing I want to parse the packet and see what's inside.
The input I get from the socket is an unsigned char* buffer and it's length. I tried to put the buffer into a string but I guess I did it wrong because when I checked the string it was empty.
Any advice?
I don't know what you want to parse, but your have the buffer and it's length. So you can do everything you want with this memory. Look for pointer arithmetic. If you want to make an C-String out of the content, simply add an '\0' to the end of the memory block. But this assumes, that no other 0x00 are inside the buffer. So maybe you have to check that. Like πάντα ῥεῖ said.
Steps:
1: receive UDP package
2: cast like:
unsigned char* buffer;
char* cString = (char*) buffer;
3: check casted cString if an '\0' occurred before buffer size was reached. If it does, then create a new char* pointer to the byte after the '\0', but be aware of the buffer size. Save the pointer in an vector.
I made an code example, but haven't checked if it is runnable!
char* firstPtr = (char*) buffer;
size_t indexer = 0;
std::vector<char*> pointerVec;
pointerVec.push_back(firstPtr);
while(indexer < bufferSize) {
if(*(buffer + indexer) == '\0') {
if(indexer + 1 < bufferSize) {
char* cString = (char*) (buffer + indexer);
pointerVec.push_back(cString);
}
}
} // end while
After that you should have the positions of the different strings saved with the pointers inside of the vector. Now you can handle them to an copy mechanism which takes every C-String pointer and saves it's content to one C-String or String.
Hope you searched for something like that, because you question was unclear.
There is a function, I want to call
(void) get_bytes (void * ptr, int length)
function takes two arguments
the first is buffer (by that argument data will be recieved)
second length of the data that I want to read.
The task is to reading 10 bytes using this function, and print buffer on the screen (in the form of hexadecimal).
I tried this way
char *buffer = malloc(sizeof(char) * 10);
get_bytes (buffer, sizeof(buffer));
for (int i = 0; i < 10; i++) {
printf("%s", buffer[i]);
}
but I get exception of execution bad access on printf line,
Please provide a right way of passing buffer to this function
You probably meant to write
printf("%02x", (unsigned char)buffer[i]);
As is you are passing characters as addresses for strings which won't quite work.
get_bytes (buffer, sizeof(buffer)); isn't right... instead of sizeof(buffer) which returns the size of your char pointer, you want the size of what it's pointing to, 10 in this case.
I'm writing on c++ in VS2010 Windows 7. I try to read file of size 64 bytes. Here's the code:
BYTE* MyReadFile(FILE *f)
{
size_t result;
BYTE *buffer;
long lSize;
if (f == NULL)
{
fputs ("File error", stderr);
exit (1);
}
fseek (f, 0, SEEK_END);
lSize = ftell (f);
rewind (f);
//buffer = (BYTE*) malloc (sizeof(char)*lSize);
buffer = new BYTE[lSize];
if (buffer == NULL)
{
fputs ("Memory error", stderr);
exit (2);
}
result = fread (buffer, 1, lSize, f);
if (result != lSize)
{
fputs ("Reading error",stderr);
exit (3);
}
fclose (f);
return buffer;
}
When I get file size it is 64, but when I allocate memory for it with new BYTE[lSize] I get 80 bytes of space and thus strange sequence ээээ««««««««оюою is added to the end of buffer. Can you please tell me how to handle this?
There is an important difference between the number of bytes you have allocated, and the number of bytes that you see.
If lsize is 64, you have indeed allocated yourself 64 bytes. This does not mean that behind the screen the C++ run time will have asked exactly 64 bytes to Windows. In practice memory managers ask slightly more memory so they are able to do their own homework. Often these extra bytes are allocated BEFORE the pointer you get back from new/malloc so you will never see them.
However, that is not your problem. The problem is that you read 64 bytes from file using fread. There is no way that fread knows what kind of data you are reading. It could be a struct, a char buffer, a set of doubles, ... It just reads these bytes for you.
This means that if the file contains the characters "ABC" you will get exactly "ABC" back. BUT, in C, strings should be nul-terminated, so if you pass this buffer to printf, it will continue to scan memory until it finds a nul-character.
So, to solve your problem, allocate 1 byte more, and set the last byte to the nul character, like this:
buffer = new BYTE[lSize+1];
buffer[lSize] = '\0';
What is behind and above is called sentinel.It is used to check if your code does not exceed boundary of allocated memory.When your program overwrite this values, CRT library will report debug messages when you release your buffer.
Look here : http://msdn.microsoft.com/en-us/library/ms220938%28v=vs.80%29.aspx
Although this may look like a memory problem, its actually a printing problem (as #Mystical pointed out). You need to put a null termination if you are going to print out anything as a string, else memory will be wildy read till one is encountered (which is UB).
Try this instead:
buffer = new BYTE[lSize + 1];
if (buffer == NULL)
{
fputs ("Memory error", stderr);
exit (2);
}
result = fread (buffer, 1, lSize, f);
if (result != lSize)
{
fputs ("Reading error",stderr);
exit (3);
}
buffer[lSize] = '\0';
It'll ensure there is a null terminator at the end of the returned buffer.
When memory is allocated, it is not on a per byte basis. Instead it is allocated in aligned blocks of 8 or 16 bytes (possibly with a header at the start, before the pointer). This is usually not a problem unless you create lots (many millions) of little objects. This doesn't have to be a problem in C and isn't even a major problem in Java (which doesn't support array of objects or objects allocated on the stack).
I am trying to read memory addresses from an executable running in memory, and then use those memory addresses to walk the PE structure.
I am having trouble because I'm unsure how to convert a 4 byte char array to it's int equivalent.
Here is my code so far:
char buffer[4];
int e_lfanew = 60;
if(!ReadProcessMemory(pHandle, (me32.modBaseAddr + e_lfanew), buffer, 4, NULL))
{
printf("ReadProcessMemory # %x Failed (%d)\n", me32.modBaseAddr, GetLastError());
}
The address i'm reading in, in this case 0xE0000000, is the offset of the PE Header. I want to take the memory address I just read and use it as an offset to read from process memory again, but I cannot figure out how to convert it to an int properly.
Any help would be greatly appreciated.
buffer[0] |
(buffer[1] << 8) |
(buffer[2] << 16) |
(buffer[3] << 24)
or the other way around, depending on whether your high-order byte is buffer[0] or buffer[3]
int MemoryBufferToInt(char* buffer, int buffer_size) {
int result;
assert(buffer_size == sizeof(result));
memcpy(&result, &buffer[0], sizeof(result));
return result;
}
The code above assumes that this buffer was obtained from the process, so that the byte order of the memory buffer is the same as the byte order of a regular int on your platform. Otherwise, you can easily contruct the integer for a specific byte order if you know what the byte order of the buffer is.
NOTE that you could just use static_cast<char*>(&result) in place of your buffer as the parameter to the function that retrieves the buffer contents.