vector<PBYTE> getting corrupted c++ - c++

I understand PBYTE is unsigned char* from Windows Data Types.
I am calling a function which updates data and dataSize.
I print the data after I call the function, but once I print the vector that stores all the data, I am not getting the same value.
Is it possible that the data is getting corrupted?
This is a function written internally, not open-source.
SerializeEvent(__in_z PCWSTR EventName,
__out_bcount(DataSize) PBYTE & Data,
__out ULONG & DataSize){}
This function takes in a field and serializes it and data is basically the buffer where the serialize event name is stored, and dataSize is the size for the same.
PBYTE data=NULL;
ULONG dataSize=0;
int main(){
vector<PBYTE> dataVector;
vector<ULONG> dataSizeVector;
for(int i=0;i<10;i++){
serializeData(event,data,dataSize);
printf("%02x ",data); ///----->a
dataVector.push_back(data);
dataSizeVector.push_back(dataSize);
}
//just want to print the contents of this vector to verify
for(int i=0;i<dataVector.size();i++){
printf("%02x ",dataVector.at(i)); ----> b
}
}
The print from the first for loop is not matching the print from the second for loop. Am I missing something?
But doing the same for dataSizeVector is printing similar values...

Both loops are printing out incorrect data.
printf("%02x ", ...); is being given a BYTE* pointer as the input value for %x, but %x expects an integer not a pointer.
As I already showed you in your previous question, you can print out individual bytes using %x, and print out pointers using %p instead.
Try something more like this:
int main() {
vector<PBYTE> dataVector;
vector<ULONG> dataSizeVector;
for(int i = 0; i < 10; ++i) {
PBYTE data = NULL;
ULONG dataSize = 0;
SerializeEvent(event, data, dataSize);
printf("%p", data);
for(ULONG j = 0; j < dataSize; ++j) {
printf(" %02x", data[j]);
}
printf("\n");
dataVector.push_back(data);
dataSizeVector.push_back(dataSize);
}
//just want to print the contents of this vector to verify
for(size_t i = 0; i < dataVector.size(); ++i) {
PBYTE data = dataVector[i];
ULONG dataSize = dataSizeVector[i];
printf("%p", data);
for(ULONG j = 0; j < dataSize; ++j) {
printf(" %02x", data[j]);
}
printf("\n");
}
}
I suggest you read this printf() reference on how printf() actually works.

Related

Vector returning NULL values

I'm having an issue with getting my vector to return with data. I'm passing in a vector to getAudioStreams that'll hold the data I want, but when I print out the values, they're all empty. In getAudioStreams, I have a pointer for an array of the values, but after each loop the value in the vector becomes NULL.
I'm pretty sure this is an issue of scope, but I'm not sure how to resolve it.
Thanks for any help!
Main.cpp
std::vector<WCHAR*> names;
mvc.getAudioStreams(names);
for (int i = 0; i < names.size(); i++)
{
printf("Main I: %d | %ls\n", i, names.at(i));
}
MainVolumeControl.cpp
void MainVolumeControl::getAudioStreams(std::vector<WCHAR*>& o_streams)
{
...
WCHAR* progName;
int nSessionCount = 5;
for (int n = 0; n < nSessionCount; n++)
{
...
WCHAR wsImageName[MAX_PATH + 1];
DWORD nSize = MAX_PATH;
if (QueryFullProcessImageNameW(hProcess, NULL, wsImageName, &nSize))
{
printf("\nImage: %ls\n", wsImageName);
progName = extractName(wsImageName);
printf("Prog: %ls\n\0", progName);
o_streams.push_back(progName);
}
...
}
...
printf("\n");
for (int i = 0; i < o_streams.size(); i++)
{
printf("I: %d | %ls\n", i, o_streams.at(i));
printf("\n");
}
}
WCHAR* MainVolumeControl::extractName(WCHAR i_imageName[])
{
constexpr u_int LEN_IMAGE_MAX = MAX_PATH + 1;
WCHAR o_progName[LEN_IMAGE_MAX];
... // Extracting the name from a longer string
return o_progName;
}
Thank you #JaMit & #Richard Critten!
Returning a value instead of using pointers/references solved the issue.
Using std::wstring instead of WCHAR* cleaned up my code a decent bit too

Read int through char * binary data from a file with std::ifstream::read()

Background: This question is a follow up of this one.
The given answer suggesting to access the data through unsigned char * instead of char* worked successfully.
Main question: But how can we do if we have no choice ? (i.e. if char* imposed by a function prototype).
Context:
Let's assume that we have written an int array in binary format into a file.
It may look as (without errors checking):
const std::string bin_file("binary_file.bin");
const std::size_t len(10);
int test_data[len] {-4000, -3000, -2000, -1000, 0, 1000, 2000, 3000, 4000, 5000};
std::ofstream ofs(bin_file, std::ios::trunc | std::ios::binary);
for(std::size_t i = 0; i < len; ++i)
{
ofs.write(reinterpret_cast<char*>(&test_data[i]), sizeof test_data[i]);
}
ofs.close();
Now I want to open the file, read it and print the previously written data one by one.
The opening is performed as follows (without errors checking):
std::ifstream ifs(bin_file, std::ios::binary); // open in binary mode
// get the length
ifs.seekg(0, ifs.end);
std::size_t byte_size = static_cast<std::size_t>(ifs.tellg());
ifs.seekg(0, ifs.beg);
At this point, byte_size == len*sizeof(int).
Possible solutions:
I know that I can do it either by:
int val;
for(std::size_t i = 0; i < len; ++i)
{
ifs.read(reinterpret_cast<char*>(&val), sizeof val);
std::cout << val << '\n';
}
or by:
int vals[len];
ifs.read(reinterpret_cast<char*>(vals), static_cast<std::streamsize>(byte_size));
for(std::size_t i = 0; i < len; ++i)
std::cout << vals[i] << '\n';
Both of these solutions work fine but none of them are the purpose of this question.
Problem description:
I consider here the case where I want to get the full binary file contents into a char* and handle it afterwards.
I cannot use an unsigned char* since std::ifstream::read() is expecting a char*.
I tried:
char * buff = new char[byte_size];
ifs.read(buff, static_cast<std::streamsize>(byte_size));
int val = 0;
for(std::size_t i = 0; i < len; ++i)
{
// Get the value via std::memcpy works fine
//std::memcpy(&val, &buff[i*sizeof val], sizeof val);
// Get the value via bit-wise shifts fails (guess: signedness issues)
for(std::size_t j = 0; j < sizeof val; ++j)
val |= reinterpret_cast<unsigned char *>(buff)[i*sizeof val + j] << CHAR_BIT*j; // For little-endian
std::cout << val << '\n';
}
delete[] buff;
ifs.close();
With std::memcpy to copy the 4 bytes into the int, I got the expected results (the printed vals are the same values than the original ones).
With bit-wise shifting, even with reinterpret_cast<unsigned char*>ing the buffer, I got trash values resulting in failing to get back the original int value (the printed vals are "garbage" values: not the same values than the original ones).
My question is: What does std::memcpy to be able to get the right values back from a char* instead of an unsigned char* while it is not possible with my bit-wise shifting ?
And how could I solve it without using std::memcpy (for general interest purposes) ? I could not figure it out.
Ok, this was a really stupid error, shame on me.
Actually, I forgot to reset val to zero before each next iteration...
The problem was not related to the bit-wise shifting, and the reinterpret_cast<unsigned char *> worked successfully.
The corrected version should be:
char * buff = new char[byte_size];
ifs.read(buff, static_cast<std::streamsize>(byte_size));
int val = 0;
for(std::size_t i = 0; i < len; ++i)
{
for(std::size_t j = 0; j < sizeof val; ++j)
val |= reinterpret_cast<unsigned char *>(buff)[i*sizeof val + j] << CHAR_BIT*j; // For little-endian
std::cout << val << '\n';
val = 0; // Reset the val
}
delete[] buff;
ifs.close();
For those who don't like casting, we can replace it with a mask as follows:
char * buff = new char[byte_size];
ifs.read(buff, static_cast<std::streamsize>(byte_size));
int val = 0;
for(std::size_t i = 0; i < len; ++i)
{
int mask = 0x000000FF;
for(std::size_t j = 0; j < sizeof val; ++j)
{
val |= (buff[i*sizeof val + j] << CHAR_BIT*j) & mask; // For little-endian
mask = mask << CHAR_BIT;
}
std::cout << val << '\n';
val = 0; // Reset the val
}
delete[] buff;
ifs.close();
Perfect example when the issue comes from between the keyboard and the chair :)

RingBuffer for data collection

I have a Ring Buffer implementation that I like to use to process an incoming data. Is the following approach safe and efficient to use considering synchronizations needed?.
void CMyDlg::MyButton1()
{
RingBuffer BufRing(10000);
unsigned char InputBuf[100];
unsigned char OutBuf[100];
for (int ii = 0; ii < 1000; ++ii)
{
for (int i = 0; i < 100; ++i)
{
InputBuf[i] = i;
}
BufRing.Write(InputBuf,100);
BufRing.Read(OutBuf,100);
AfxBeginThread(WorkerThreadProc,OutBuf,THREAD_PRIORITY_NORMAL,0,0,NULL);
}
}
UINT WorkerThreadProc( LPVOID Param )
{
unsigned char* pThreadBuf = (unsigned char*)Param;
for (int c = 0; c < 100; ++c)
{
TRACE("Loop %d elemnt %x\n",c,pThreadBuf[c]);
}
return TRUE;
}
Looks hazardous to me...
void CMyDlg::MyButton1()
{
// ...
unsigned char OutBuf[100];
for (int ii = 0; ii < 1000; ++ii)
{
// ...
BufRing.Read(OutBuf,100);
AfxBeginThread(WorkerThreadProc,OutBuf,THREAD_PRIORITY_NORMAL,0,0,NULL);
}
}
The problem that I see is that you're using a single buffer (OutBuf) to store data in, passing it to a worker thread, and then modifying that same buffer in the next iteration of your loop.
Your test code won't reveal this, because you're simply repopulating OutBuf with the same values in every iteration (as far as I can tell, anyway). If you changed InputBuf[i] = i; to InputBuf[i] = ii; and included a unique thread ID in your TRACE output, you'd probably see suspicious behaviour.

Treating an unsigned int address as a pointer and dereferencing it as a byte array

So, I have an unsigned int variable with a decimal value address stored on it, let's say unsigned int var = 1232342, what I am trying to do is, without knowing the type of the variable but knowing the size of it and the address where it is stored, get the values as a byte array. For example, let's say I have an int var = 20 with its address and bytesize. I want to be able to go to that address and return a byte array, in this case [00001100] and the same for char variables and data members of a struct.
A little bit of pseudocode would be something like:
for var.address until var.address = var.address + bytesize
do
byte_array = *var.address
var.address++
I am encountering some problems though, I am kind of new to C so I don't know how to treat an unsigned int as an address/pointer. Second, I don't know how to get the actual bytes out of the address, whenever I dereference the address what I get is the actual value of it, but that is if I know the type for the variable.
A little bit of background: I am working on a tool called Pin which gives me the option to hook into a running process, then I am using the DWARF and ELF info. So I do have access to the virtual memory space I am trying to access
Take a look at the hexdump function by epatel here
Off-the-Shelf C++ Hex Dump Code
In spite of the title it's really C code. I'll copy it here for your convenience
#include <ctype.h>
#include <stdio.h>
void hexdump(void *ptr, int buflen) {
unsigned char *buf = (unsigned char*)ptr;
int i, j;
for (i=0; i<buflen; i+=16) {
printf("%06x: ", i);
for (j=0; j<16; j++)
if (i+j < buflen)
printf("%02x ", buf[i+j]);
else
printf(" ");
printf(" ");
for (j=0; j<16; j++)
if (i+j < buflen)
printf("%c", isprint(buf[i+j]) ? buf[i+j] : '.');
printf("\n");
}
}
"a" is the address from where you want to get 4 bytes. "bytes" is where you want to store your results. I assigned the address of "i" to "a", then read 4 bytes from that address.
#include <stdio.h>
int main(int argc, char *argv[]) {
unsigned char bytes[4];
int i = 65535, j;
unsigned long a = (unsigned long) &i;
for (j = 0; j < 4; j++) {
bytes[j] = *((unsigned char*) a + j);
}
for (j = 0; j < 4; j++) {
printf("bytes[%d]: %d\n", j, bytes[j]);
}
}

fwrite, fread - problems with fread

I have following code:
int main()
{
char* pedal[20];
char* pedal2[20];
for (int i = 0; i < 20; i++)
{
pedal[i] = "Pedal";
}
FILE* plik;
plik = fopen("teraz.txt","wb");
for (int i = 0; i < 20; i++)
{
fwrite(pedal[i],strlen(pedal[i]),1,plik);
}
system("pause");
fclose(plik);
plik = fopen("teraz.txt","rb");
for (int i = 0; i < 20; i++)
{
fread(pedal2[i],5,1,plik); //I know for now that every element has 5 bytes
}
for (int i = 0; i < 20; i++)
{
std::cout << pedal2[i] << std::endl;
}
fclose(plik);
system("pause");
return 0;
}
It's crashing at reading and second question let's assume that I have structure where I keep like integers, floats and also char* array and how can I easly write whole structure to the file? Normal fwrite with sizeof structure is not working
Your problem that you didn't allocate buffer for reading. In fact line
fread(pedal2[i],5,1,plik)
reads to unknown place. You need allocate memory (in your case it is 5 + 1 bytes for zero terminated string).
pedal2[i] = malloc(5+1);
fread(pedal2[i],5,1,plik)
Don't forget to release it after usage.
You can't read into pedal2 without first having allocated space for it.
You need something like this:
for (int i = 0; i < 20; ++i) {
pedal[i] = malloc(100); //allocate some space
}
Your first question seem to have already been answered by Simone & Dewfy.
For your second question about how to write structure values into the file, you will have to write member by member.
Please check fprintf. You can probably use it for writing different data types.