Access the whole video memory through OpenGL programming
Asked Answered
V

3

5

How to access the video memory of graphics card through OpenGL programming, specifically, to get all contents of video memory?

I have tried the following two methods, but failed. With attaching them down, I hope you could point out the error in my program or in my understanding of the structure of video memory. Thanks in advance!

My basic idea is to continue allocating an uninitialized area in the video memory until exploring all the contents of video memory.

(1) In the main function, I create a window with double buffers (see following codes).

int main(int argc,char ** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); // double buffers
    glutInitWindowPosition(0,0);
    glutInitWindowSize(windowWidth, windowHeight);
    glutCreateWindow("Hope to be successful!");
    glutDisplayFunc(myDisplay); // call back function "myDisplay"
    glutKeyboardFunc(keyboard);
    glutMainLoop();

    free(PixelData);
    return 0;
}

Then, in the "myDisplay" function, firstly I call glReadPixels() function to read out a given-size rectangle of pixels out of the back framebuffer, save these pixels information in an array "PixelData", and finally display those pixel information on the screen by calling glDrawPixels() function. After executing this program, only a black window appears. Black is the default color. So it means the window contains nothing. Then I have tried to read other areas out of the back framebuffer, and all of them contain nothing.

The conclusion from the above is that nothing is contained in the back framebuffer. However, this is unreasonable because the front buffer should only contain the current screen content/window, and thus other windows opened and minimized at the bottom of the screen should have their contents in the back framebuffer, but the back framebuffer is empty. So where are those windows (opened and minimized by me at the bottom) stored?

I guess the framebuffers (back and front) allocated for my program only occupy a small part of the whole video memory. Thus those minimized windows content should be stored in other places of video memory.

After some time, I read an introduction to OpenGL frameBuffer object (FBO), and there is a sentence: By default, OpenGL uses the framebuffer as a rendering destination that is created and managed entirely by the window system. This default framebuffer is called window-system-provided framebuffer. This seemingly verifies my above guess.

(2) Then I begin to work on FBO with the hope that FBO can help me to explore the whole video memory content.

In the below main function, I create a FBO and 7 renderbuffer objects (RBO), and then attach these 7 RBOs to this FBO through color attachment points.

const int RBO_COUNT = 7; //how many renderBuffer objects are created to attach to the frameBuffer object

int main(int argc, char **argv)
{
    ....
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_ALPHA); // display mode
    ...  

    // create a framebuffer object
    glGenFramebuffers(1, &fboId);
    glBindFramebuffer(GL_FRAMEBUFFER, fboId);

    //Create several 7 render buffer objects and attach all of them to the FBO.
    glGenRenderbuffers(RBO_COUNT, rbo);
    for (int i = 0; i < RBO_COUNT; i++)
    {
        glBindRenderbuffer(GL_RENDERBUFFER, rbo[i]);
        glRenderbufferStorage(GL_RENDERBUFFER, PIXEL_FORMAT, SCREEN_WIDTH, SCREEN_HEIGHT);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, colorAttach[i], GL_RENDERBUFFER, rbo[i]);
    }

   // check FBO status
   bool status = checkFramebufferStatus();
   if(!status) fboUsed = false;

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    ...

    glutMainLoop(); /* Start GLUT event-processing loop */
    return 0;
}

The below is the main part of my display callback function. Its function is to use the space key to control which renderBuffer object to read from, and then display its content on the screen.

void displayCB()
{
glBindFramebuffer(GL_FRAMEBUFFER, fboId);

//read this FBO attached RBO, save its content to fboContent
//"count" is a global variable, and is incremented by 1 (mod )every time pressing the space key of the keyboard.
glReadBuffer(colorAttach[count]); 
glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, PIXEL_FORMAT, GL_UNSIGNED_BYTE, fboContent);

// back to normal window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind

// render to the default framebuffer //////////////////////////
glClear(GL_COLOR_BUFFER_BIT); // clear buffer
glClearColor(1, 0, 0, 1);
glDrawBuffer(GL_BACK);
glRasterPos2i(-1, -1);  
glDrawPixels(SCREEN_WIDTH, SCREEN_HEIGHT, PIXEL_FORMAT, GL_UNSIGNED_BYTE, fboContent);
glutSwapBuffers();
}

The final result is disappointing. The contents of all the renderBuffer objects are empty. I don't know the cause of this, because I thought that all these RBOs were never initialized and should contain some remaining contents.

Verso answered 11/5, 2012 at 17:22 Comment(4)
"I thought that all these RBOs were never initialized and should contain some remaining contents." Then you should re-read the spec. It says that their contents are undefined. Undefined could mean "remaining contents". It could also mean "zeroed memory". It could mean "memory set to some arbitrary color to make it easier to catch bugs." Undefined means undefined.Crista
The spec (opengl.org/wiki/Renderbuffer_Object) says that "the renderbuffer is created uninitialized." I think you are right. Whether uninitialized RBOs are empty or contain some remaining contents is determined by when those RBOs are created. If all the video memory have once been used and some of them are now unallocated, newly created RBOs will probably contain some previous contents.Verso
That is not the spec; that is a Wiki article. The spec is found on the OpenGL registry. But thanks for pointing the error out; I'll fix it.Crista
Thanks for the spec link. Do you think that OpenGL is qualified for accessing the whole video memory? The answer provided by SigTerm seems reasonable. He said only video driver could do that thing, but OpenGL couldn't.Verso
L
6

How to access the video memory of graphics card through OpenGL programming, specifically, to get all contents of video memory?

You cannot do that. Raw video memory cannot be accessed via OpenGL or DirectX. OpenGL only has various "buffers". The only thing that can access it is video driver, which is proprietary on windows platform. Free video memory is managed by video driver, and certain objects in video memory might exist only temporarily - driver can store copies in system memory, move them around and in offload them to disk when necessary. So your idea of managing free memory manually has no practical application.

You should be able to access video memory directly on OLD hardware - thing EGA/CGA/VGA, also on cards that support VESA, however you'll have no hardware acceleration, and you'll need to run something similar to MS-DOS or have kernel/driver access privilegies. You might be able to access memory contents on Linux, but i think it won't be helpful.

I'd recommend to forget about this idea.

Do you mean OpenGL cannot do such task? Actually, I have worked on this problem for nearly two months.

Something like that normally happens when you start a grandiose project without doing sufficient amount of research first. I'd recommend to learn from this experience. Before you start coding, always remember to check if you app hasn't been already written, has any practical application, can be created, there's a need for that app, and that you possess sufficient resources to create it.

Currently managing objects stored in video memory is driver's job.

If you want to see objects created by other applications, it'll be probably easier to hijack OpenGL api using proxy dlls, dll-injection or similar techniques and intercept relevant calls.

Lifelong answered 11/5, 2012 at 19:43 Comment(2)
Thanks for your detailed explanation! Very useful! It will be a terrible thing for me if all you said turns out to be true.Verso
doesn't have to be old hardware; can just put a bios application on a cd/floppy. all pcs support this.Brauer
G
2

How to access the video memory of graphics card through OpenGL programming, specifically, to get all contents of video memory?

Talk to the operating system, not OpenGL.

Gregoire answered 11/5, 2012 at 17:32 Comment(1)
Do you mean OpenGL cannot do such task? Actually, I have worked on this problem for nearly two months. If OpenGL cannot, I will have to restart my work. In addition, could you say more about "talking to OS"?Verso
C
-1

It is not clear why you want to do this, and what is your end-game, but it seems to me that you are trying to access graphic information that is produced by 3rd party applications.

In case you are trying to accomplish what FRAPS does, keep in mind that it uses a technique completely different from what you are trying to do (a much simpler one): it intercept calls to graphic libraries like OpenGL and DirectX.

Cataplasia answered 11/5, 2012 at 19:38 Comment(3)
I am trying to verify if a kind of potential attack is really feasible. And accessing the whole video memory is part of the verification process. Thanks for the reply.Verso
Your link is broken. Can you try to fix it (I mean, can you find an updated URL?) since I'm currently interested in "how FRAPS works" in order to implement something similar...Chasechaser
2 minutes of internet search. :( It's fixed.Cataplasia

© 2022 - 2024 — McMap. All rights reserved.