Adding functionality to Stick-it v.6

In this essay I'm going to add a function that I thought would be very useful and that would perfectly fit into this neat little tool. If I had asked nicely visionz probably could have added this function for me in 5 mins since he has the source code, I like a challenge though so I figured what the hell. My idea is to allow stick-it to change the title of windows. Stick-it already gets hold of window handles to alter properties like 'on top' and it already gets hold of the windows title and has another text box that could be used to change it. It just doesn't do it - yet! I have used the following techniques/steps to complete my mission.

  1. Changed the dialogs resources to add my new button
  2. Added a function to the programs imports
  3. Created a snippet of code to add to the event handler for button presses
  4. Coded my own function to change the title using stick-it's already existing variables

I've just started learning more about the PE file format, starting with reversing the Happy99 virus I have spent many hours recently trying to get my head round it's layout. Adding functionality to this excellent program is a great way to learn a bit more. The program is tightly coded and has no nasty surprises hidden away and is small enough to be manageable for a starting point.

Changing the resources

For this part I didn't concern myself with learning about the resources structure in the PE file, instead I loaded up a program that could do it for me. I first tried BRW but this didn't seem to be able to display the dialog correctly so I turned to protools - the Resource Hacker by Angus Johnson was the tool I downloaded. I simply cranked up the executable into it, moved the 'add to tray' button to a new position to the side of where it once was to work out the offset and added the code for a new button, 'change title'. I set the id of this button to 3006 because I didn't feel like altering the code to shift up the textfields. This was pure laziness, if you want to do it properly feel free. The Resource Hacker allows you to recompile the resource data and save the new information to a new executable, do this and you have now completed your first step to the FBJ stick-it variant.

Adding the exported function

We are going to use the SetWindowText API function to change the window title. Stick-it doesn't import this function yet so we will have to change this. If you don't understand how functions are imported by executables then I suggest you go read up how it works. Matt Pietrek has done a couple of documents explaining how it all works very well which I would personally recommend. Once you understand how it works my essay on how the data in an exe is structured may help. Now we encounter the first problems, the import data is so tightly packed that we are going to have to move something. For ease I suggest the following actions, I cannot see any harm in doing things in this manner. There doesn't after all seem to be any consistency between compilers so it should be okay. Another point to remember is that this data only gets used at startup so if we cause the loader to have to do some work it won't have any major effect, especially with such a small executable.

Presently the data is located like this,

The Thunk arrays are arranged like this at the moment,

-------------------------------
: kernel32 : shell32 : user32 :
-------------------------------
One of the key aims while adding this import is to create the least amount of impact on the program possible, we don't want to have to make thousands of changes to just add a function. The main two items that need to remain unmoved to prevent massive change are the Thunk arrays and the Function names. If we move the thunks then every call to those functions in the program needs to be altered, this is not desirable. We will have to modify one call, but that should be it. If we move the function names we end up with an even nastier situation, every single thunk array entry and original thunk array entry will have to be updated for the new positions. These are the motivations that compelled me to come up with the following method of adding our function. By the end we will have arranged the order of the thunk tables to be in the following order.
-------------------------------
: kernel32 : user32 : shell32 :
-------------------------------
To achieve this effect these are the steps I followed. This isn't the cleanest solution and it does for some strange reason seem to break wdasm's ability to read the import table but this does seem to be the only detrimental effect.
  1. Add the function name to the end of the list of names, just behind SHELL32.DLL
  2. Moving the Import Directory entries to behind the function and DLL names.
  3. Move the Shell32 Thunk to behind the existing thunks, do this for the original thunks too.
  4. Blank out the gap created by moving the thunks.
  5. Add the new function to the start of the User32 thunks. Simply add the RVA of the function name to the start of the list. There should now be enough room there after moving shell32 function.
  6. Now you need shift all the original thunks forwards, from starting at offset 0abc to 0ab4. Then the same procedure as before can happen, the original thunk table should look identical to the thunk table. In fact so much so that I simply cut and pasted the thunk table into place.
  7. Fixing the Import Directory entries to reflect new position of the Thunk array for shell32. Also shift the user32 position to point to the new function that we added to the start of the array.
  8. Shift the OriginalThunk arrays to their new positions
  9. Alter the data dictionary to point to the new location of the ImportDirectory
  10. Alter the section header for this section to reflect new phat ass size
  11. Alter all the functions called by shell32 to point to new thunks

The event handler

Now we are ready to add our code to the .text section. The .text section has plenty of space left at the end, this was caused by the compiler liking to align all the sections and works to our benefit. First we need to add our event handling code, fortunately the event handler routine is located at the end of code so it doesn't take much work. Now to write the code to handle the events, I have put in my own labels and haven't left any addresses so you'll have to analyse the code yourself but it's very simple to figure out. We will insert this snippet into the middle of the event handler so we will have to shift the back part of the code out further and then fix up the jumps that pass over our inserted code. There are several jumps that will have to be fixed, the amount the back end has been pushed out by is the number to add to each of these jumps. There are also some relational calls behind the new event handler that will need to be fixed.

   jz    short notTop
   dec   eax
   jz    short addTray
   sub   eax, 3
   jnz   short finishUp
   call  setTitle
   jmp   short finishUp
addTray:
   call	 addToTray
   jmp	 short finishUp

The call to setTitle will be the end of code at the moment, that will be where we insert the procedure.

Creating the procedure to set the title

This requires an analysis of the stick-it code. You need to find the handle of the window that has been selected and stick-it's own handle. I'm going to assume that you are perfectly capable of doing this your self and simply write my little piece of code using that information. We can get the thunk for the api call from the import we have already inserted to stick-it.

setTitle proc near

   ; alloc memory for the string
   ; locally                               
   ; e.g. char title[100];
   push  ebp                               
   mov   ebp, esp                          
   sub   esp, 100h                         
   
   lea   eax, [ebp-100h]                   
   push  eax                               
   push  0FFh                              
   push  eax                               
   push  0BBDh ; CAPTION_ID                
   push  ds:our_handle                     
   call  GetDlgItemTextA                   
   
   push  ds:targetWindowHan                
   call  SetWindowTextA                    
   
   ; clears up all the memory we have
   ; alloced earlier, not used with
   ; enter because enter is pointless,
   ; there is no nesting here

   leave                                   
   retn                                    
   
setTitle endp

All that needs to be done now is to insert this piece of code at the end of the .text section right after the event handler. Now all you need to do is run up stick-it!

Conclusion

This has been an interesting exercise in adding functionality to an executable for me certainly. The program is nice and small so we can really see what is going on and I have done a lot of the process by hand. This method may be rather inefficient and completely un scalable but it does help to increase the understanding. In actual fact it's a pain to do even this small a mod by hand so I would recommend the use of tools to do this in the future. I must also confess to having been slightly light on detail with this essay, my guess is that if you are capable of doing this then the filling in of the blanks will be a nice light warmup before making the changes. I hope you enjoy this little exercise.

As usual comments/suggestions etc. can be mailed to me at the ImmortalDescendants