简体   繁体   中英

Using ReadFile function to read data from a process

I am trying to read data from a process using the Win32 API function ReadFile() . I am not using the standard library function because I'm using a source code from a public repo. Here I provide the specific snippet I have trouble with..

//Those are Globals
HANDLE pipin_w, pipin_r, pipout_w, pipout_r;
DWORD write, read, available;
BYTE buffer[2048];

std::string myFunction(){
    std::string out="";
    PeekNamedPipe ( pipout_r, buffer, sizeof(buffer), &read, &available, NULL);
    sleep(300);
    do {
        ZeroMemory(*buffer, sizeof(buffer));
        ReadFile( pipout_r, buffer, sizeof(buffer), &read, NULL);

        if (!read) { return std::string("error"); }
        buffer[read]=0;
        out += (char*)buffer;
    } while(read >= sizeof(buffer));
    return out;
}

The first two calls respond correctly, than "error" gets returned.

I wasn't able to use and understand the standard library function because I have no experience in C++ programming. What I'm trying to do is to fill the BYTE buffer that has size 2048.

This code works for the first two calls, then the read variable gets corrupted. I know that my initialization is correct because I am able to connect with the process which opens itself in the Task Manager, and also I am able to retrieve data from it, but after a pair of calls the read variable gets corrupted.

That causes hangs or crashes in my code. There are a few things which I don't like about this code. For example, I was not able to use the standard library functions like fstream , so I have decided to stick with this setting for now. Also, I don't know if it is correct to read from the process with the ReadFile() function, but that sort of works. And the while loop feels quiet uncomfortable for me, I can't understand why I need it.

Anyone who wants to know how I have initialized this code, feel free to ask, I will provide every missing info, but I don't think that is an issue because I am able to make a couple of readings from the process itself. I can provide a link to the source code that I am using since that's a public source code repository.

Maybe Asked Questions (from you):

  1. Does your process support reading?

    Yes It does

  2. Do you have enough permissions to run and read the process?

    Yes I have

  3. Maybe you need to write some data to tell the process to start the communication..

    That's not the case, I have another function to write data, and I use it before this call, but I still receive data even if I don't write to it

  4. How do you create your process?

    I can provide that snippet, just ask me, but essentialy I create two pipes, one for Reading and another for writing, then I start the process by calling CreateProcess, and that works.

  5. What are you trying to do with your code?

    I am trying to build a class which can handle the creation, the writing, and the reading of a process in a Windows platform environment with c++, nothing more..

What can possibly cause the corruption of the read variable? I am struggling to understand that, and how I can avoid it. Also, if someone can explain to me good practices for this kind of situations, I really appreciate that, or at least to have a link to some resources I can look at, or to study how that works.

  • ZeroMemory(*buffer, sizeof(buffer)); should be ZeroMemory(buffer, sizeof(buffer));
    In it's current state, you read the first BYTE in buffer and use that as the address to start zeroing at. This causes undefined behavior.
  • buffer[read]=0; is potentially writing out of bounds. If you've read 2048 BYTE s, you have undefined behavior.
  • out += (char*)buffer; reads buffer until it finds \0 - but there's no need for that since you already know how many BYTE s you've read.

Fixes:

  • Remove ZeroMemory - you will only read memory that's been filled by ReadFile so it's just a waste of time to zero it out first.
  • Replace
    buffer[read]=0; out += (char*)buffer;
    with
    out.append(reinterpret_cast<char*>(buffer), read);

Also, check the return value of the functions you call. ReadFile may fail for example.

The crashes all gone, after i reverted the casting to a char pointer, i did not understand quite well cast conversion, but since i allocated memory by first initializing the char pointer to nullptr, then i used memset to allocate a bigger buffer, somehow my approce works with this kind of situation, as i do not use it anywhere else in my code, if i need it, i just copy it to a new initialized string using std::string, so that solved the continous crash problem, and onestly i cant figure out a better approch to this.

Next, what i premused was also a crash, it was really an infinite loop by the ReadFile function, and it occures in two kind of situation.

  1. when i pass a "wrong" string to communicate with it, some kind of special caharcters (such as \ or /)

  2. When the buffer has nothing to read from the application, and the application returns empty output

Still not sure how to handle the second case:( but at least i can continue debugging... :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM