Calling a Codecave

Sep 17, 2008 at 1:39pm
I'm creating a code that modifies live memory on a function, the offset where the data structure is held has a buffer that's too small to handle the data I write though. I figured the easiest and most effective way (not to mention I've tried EVERYTHING else) would be to jmp to a codecave instead of the current offset where the structure is held. Here is the assembly (not the whole function, just where the structure is held.)

IDA View:
1
2
3
4
1. push    offset word_97F2B8
2. push    4
3. mov     word_97F2B8, ax
4. call    sub_64A430


Explanation:
1
2
3
4
5
6
/*
*   1. Pushes offset where the data for the function is held
*   2. Unknown, not used and not needed
*   3. Moves register ax (containing the data) into the previous declared buffer
*   4. Calls the function that carries out the execution of this data
*/


My current working C++ code works and carries out this function with my edits flawlessly, but the buffer is too small to accept sizes greater than 128. The current function I'm using has parameters Data and Size.

What it then does is use a WriteProcessMemory type function to edit the BYTE of memory where size is held (right above Data, but I didn't include that in the IDA View because I don't need help with it) with whatever you set the size parameter to. Size parameter is always set as sizeof(Data) with "Data" being the data structure your passing as a parameter.

Then for Data, you will use a typedef struct's data in a pointer when calling this function and it will write 0x97F2B8 (data locations address) with the data that was contained in the structure you pointed to. That will effectively replace whatever the previous data and size was so that when you call the function in the exe it gets passed with your parameters and not the normal ones.

Unfortunately, the buffer in which the data is held for this function has a size of 128 and many of the structures I declare are larger, resulting in a crash. I have tried such a ridiculous amount of methods, many of which I think are really smart at the time and then turn out to be nothing more than another waste of time on fixing this.

I decided it may be a good idea to use a codecave. For those that don't know what a codecave is, it is basically an area somewhere in the exe with enough space for whatever function you need to carry out that is either never called or called very little so as to not interrupt any normal functions that may call it.

What you do once you find this codecave (unused space in the exe) is you write whatever data you want in it that you couldn't write anywhere else due to protected code or small buffer in my case. Then you use a jmp or some other method to call that codecaves data, which is usually always coded in assembly when it is in the exe.

You can also write a set of code in your DLL and call it from the exe, which is usually a more reliable method. You must inject your DLL into the exe before calling the codecave, I am not sure if I'll put it in the exe or a DLL at this point but I'm just looking for some advice on how I would go about doing this either way. For more information about codecaves for those that are good programmers but have never heard of it (if your a good programmer it'll take you a few minutes to fully understand) click the link below.

http://www.codeproject.com/KB/cpp/codecave.aspx

Now what I need help with finally after that huge write up! I need to know exactly how I can write my data to this codecave (DLL preferred, but it honestly makes not the slightest difference to me) and then call it from the exe. I have a general idea of how I would go about it, but not quite sure for sure.

I assume that I would first find a codecave in the exe to be a faster method and to test it easier. Then I would write up my structure and use WriteProcessMemory to copy the data into my new codecave. Then I assume I would replace the line
mov word_97F2B8, ax
with
mov pNewCodeCaveOffset, ax

I imagine I would also have to change the
 
push    offset word_97F2B8

with
 
push    offset pNewCodeCaveOffset


Or perhaps an easier, more effective method is staring me in the face and I'm missing it? All I really need help with right now is increasing the size of this buffer, if you have a better idea than a codecave then shoot, I'm all ears! Any help would be great, I've been struggling on this for a week or so now.

Thanks!!
Last edited on Sep 17, 2008 at 1:41pm
Sep 17, 2008 at 11:05pm
I still don't follow why you need to use a codecave. It is a rather esoteric solution for something. I am particularly confused as to why you are trying to make changes to an executing process. (Frankly it doesn't sound very kosher.)

If all you want to do is get a bigger buffer, you can do that by playing around with the PE32 directly. Find the data segment, increase its size by however-big you want the new buffer to be, then search through all the code sections for the address of the old buffer and replace it with the address of the new buffer. Write the new relocatable segments out to a new PE and the program now has a larger buffer --in the same address space as before-- and with all the necessary relocations being done by the OS --just as before.

However, just increasing the size is not necessarily sufficient: the original exe probably has the original size of the buffer hard-coded in there somewhere. So even if you do increase the buffer size it is uncertain (read: unlikely) that the old code would know what to do with it beyond what it did with the old buffer. In other words, you can write all you want into a new buffer, but the original code may always just think of it as a 128-byte buffer.

If the old buffer is being dynamically allocated, you'll have it easier since all you have to do is modify the instruction(s) that call the memory allocation routine (instead of having to re-link the PE32 together). But again, how you inform the old code of the new size is at best a shot in the dark, and at worst a fruitless endeavor --the difference is entirely on how the original code kept track of the buffer size.

I don't want to be discouraging, but this really is a deep pit you are getting into.
Sep 18, 2008 at 9:10pm
All I'm doing is calling a function in the exe that sends a packet with the variables in the function being the packet opcode, data structure, size, and true/false boolean. The actual "send packet" function is called dynamically in the exe whenever a packet is supposed to be sent. For example, if I click a button that opens a help browser then the location in the exe that handles that function will call the "send packet" function.

What I do is use a function that contains a packet that is NEVER sent (may be old, may be something that was going to be used but never went live, I dont know). I then have a function in my code that changes the memory of the packet opcode, data structure, size and boolean true/false's data. Then I just let the function call the "send packet" function as it normally would with my data, this is MUCH simpler than calling the actual function which contains much more complicated data and encryption.

Anyway, there are several packets that are unsigned such as text messages which are unsigned char for message contents. I have used packet sniffing on various packets and I am absolutely positive that there are packets with a higher size than 128, as a matter of fact most of them are. I believe the highest size possible (from dissasembling it, not tested) is 1028 but I am positive it is higher than 128.

I wanted to call a codecave for the simple reason that it's an easy way to increase the size of the buffer. I would be more than happy to PM you the assembly (it's not a big function at all) if your willing to take a look at it for me. I can also send you the assembly of a different function that sends higher sizes (such as text messaging) so you can see the difference. I don't want to actually "edit" the exe, I'm looking for a code to do this and I'm not quite sure what you mean with your explanation of playing around with PE32.
Sep 18, 2008 at 9:51pm
I'm sorry, but like I said, this really is black magic and I really don't have that much interest in dinking with it a gratis.

From what you have posted, it appears that you are trying to modify the program in-memory (while it is running), instead of just changing the executable file (EXE file format is "PE32"). There are advantages to both methods, but the main advantage to the second is that you only need to dink around with the executable's internals one time.
Sep 19, 2008 at 1:49am
All I'm really asking is how do I replace the buffer of a mov buffer, structure with buffer being the address that holds the data structure and structure is actually the "ax" assembly register containing the structure. I want to replace the "buffer" part with data that I hold in a DLL which I inject or a code cave in the exe. At the VERY least if you could just tell me how to replace that one bit of code then I can figure out the part of the codecave/DLL injection.

The reason I choose to use C++ memory modification over exe modification is that this application is regularly patched, replacing the old exe. I have a program I have that automatically updates offsets - all you do is plugin the old exe and the new exe, followed by the old offsets header file. That way it takes 2 seconds to update offsets, instead of having to remodify the entire exe. It will port an old header file with defined offsets
(#define offset1 0x3432424)
With a new header file with the same names but updated offsets in a new file name that you declare, looking like this..
(#define offset1 0x3432554)
Last edited on Sep 19, 2008 at 1:49am
Sep 19, 2008 at 2:36am
I understood that much. What I am saying is that it isn't that simple.

If the program is regularly patched, why don't you just put in a feature request to increase the size of the buffer?

If you want to PM me more info about exactly what is supposed to be happening I'll take a look through it, but no promises.
Topic archived. No new replies allowed.