Noticias(creo
)
Originally Posted by Fanjita
In layman's terms, here's how buffer overflows work, from the basics.
In coding, it's common to organise your program into functions. A function is just a set of instructions for doing some task, e.g. to print something to the screen. Because a function can be called from anywhere in your program, there needs to be a way of remembering where the program was before it called the function, so it can return there once the function is finished. The way this is done varies, but typically (and on the PSP) it's done by recording the current program position in a part of memory called the stack, then calling the function, then retrieving that position and going back there once the function is done.
It also happens that a lot of code uses memory space on the stack to store working variables and other temporary data.
What normally happens with image-viewing code is that the flow of the program is tightly defined - it opens the image, decompresses it, and displays it, then exits. All of this time it is running code, but it is running code written by Sony. What we want to do is to somehow intercept the program, and make it run our code instead.
Image exploits do this by giving the image viewer code a 'broken' image to view. The way in which it is 'broken' is chosen carefully, by understanding the behaviour of the image viewer code that we're targetting. What we aim to do is to get the image viewer to unpack bits of the image into its data space (the 'buffer') on the stack, in such a way that it unpacks more data than can fit in the space that has been set aside for it.
The trick that makes all this work, is that the place in memory where it recorded where to return after the function, is often close to the place where the buffer is located. Therefore, we can get the program to overwrite its own record of where to go back to. By very careful design of the data that we're stuffing into the buffer, we can fool the program into thinking that the return location is actually somewhere completely different, which just so happens to be a place where we've loaded our own code. So, when it finishes the function and tries to return from it, it actually jumps into our code, and BINGO! we're running our code.
This is a slightly simplified description of how all this works, and obviously there's a lot more detail in the actual process of designing an exploit like this. The art of it lies in several areas:
* Working out which code might be vulnerable in the first place
* Working out how it might be vulnerable
* Figuring out exactly where the different parts of memory that are involved are.
* Designing input data that overflows the correct data into the correct locations in memory
* Getting code loaded into some known place in memory so that you can actually call it
* Dealing with many quirks in the hardware, such as caching, and also restrictions of your exploit (sometimes the data you provide gets changed during the copying process, so you need to adapt to that)
* Working out how to get your code to get a sufficient foothold on the system that it can actually start to do some stuff - that gets increasingly harder on the later firmwares.
It's a really tricky process, and requires a lot of ingenuity, hard work and testing to get to the point of running something useful, especially because Sony keeps inventing new countermeasures to make the whole process harder. Some of the tricks in 2.5 are just evil... But it's also tremendous fun, which is why we do it