How to make a program portable the hacker way (the hardest way/the fun way)

Davide De Gennaro Tutorials

If you frequently move and you don’t want to take your laptop with you all time, or if you simply can’t use your computer it’s really useful to bring with you a usb flash drive filled with your favourite/most useful programs.
A start point to download free and already prepared apps is portableapps.com they have even a custom menu to easily launch your programs and is ready to accept user-made apps.
There are tons of softwares ready to pack your programs in a sandbox to make them portable (cameyo.com , enigmaprotector.com, www.evalaze.de, spoon.net, vmware.com), so why someone should do this work by hand?
-These apps makes your program bigger
They add an inevitable overhead for the sandbox code.
-These apps usually makes your program slower
Apps created this way must intercept all calls to disk access and registry access to redirect them in a sandbox.
-Sometimes these Apps are flagged as viruses by your antivirus
Bad coded Antivirus flag your programs as viruses thanks to the runtime decompression of the app’s code.
-It’s Fun!
Who don’t like challenges? This is definitevly a hard goal to reach.

Required knowlege:
You must be a programmer, or at least you must be able to think like one, and you should definitevly know Assembly language or be prepared to use a lot of your time digging a manual for opcodes meanings!
You must also know Windows common files location, like user directories and how Registry works and how is used by programs to store configurations.

Tools Used:

Process Monitor v3.1 – http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
A program that log file and registry usage by programs, used to spot registry and file access.

UPX 3.91 – http://upx.sourceforge.net/
A program used to compress executables and libraries, used to shrink the total size of the app executables.

OllyDbg 2.01 – http://www.ollydbg.de/version2.html
It’s a debugger and a disassembler it’s extendable with plugins and widely used in the decompiler and Cracker scene, we will use it to find and change file load and read location.

An x86 app to make portable, for this example I’ll use the game Braid, I’ve buyed a DRM-free version on the humblebundle store http://www.humblebundle.com/store .
You can use the knowledge gathered on this particular example on any piece of software, but I suggest when avaible DRM-free version of games/programs or you first need to crack them in order to make them portable.

Step 0:
Sometimes programs are already portable-ready, try to dig in readme files located in the installation folder or search into configuration files for save files paths, also remember to have a look into Windows Registry, and if those three methods fail try to search on google, you’ll be surprised by the results, but keep away from cracked and packed piece of software, usually they hide malware.

Don't try this at home!

First step: Play it!

In order to generate a savegame or some configuration you must try the program while executing Process Monitor.
First start Process Monitor, then click on the filter button

Process monitor start

Now you must add a filter on process name

Process Monitor Filters

Finally you can play your game or run your app to generate configuration files!

Finally Play it!

Second Step: Spot files location
After you’re sure that configurations files/savegames were created, exit the game and open Process Monitor window.
Filter only for File System Activity ant start looking for a possible configuration file/savegame path.

Spot your target

Third Step: Find the save location in the executable
Start OllyDbg and open the executable of your program.

Start OllyDbg ———————————————————————————————

Right click the code and select “Search for->All referenced strings”, in the following window search into the list of all recognized strings the name of the savegame folder, in our case “Braid”.

Find the right one

This is the hardest part, you should find the right string, so follow each one with a double click and look for file access code.

Seems good enough

This is definitely the right place!

Fourth step: Understand what’s appening
In this small function some things are appening:
CALL DWORD PTR DS:[<&SHELL32.SHGetFolderPathA>]

After a fast google search we can find the meaning of this CALL:
Gets the path of a folder identified by a CSIDL value.
HRESULT SHGetFolderPath(_In_ HWND hwndOwner, _In_ int nFolder, _In_ HANDLE hToken, _In_ DWORD dwFlags, _Out_ LPTSTR pszPath);
In this case the Value 1A passed as dwFlags parameter means CSIDL_APPDATA <user name>\AppData\Roaming in windows 8, and this is the basic path found in the second step that we must replace with the current directory
The second CALL seems suspiciously like a sprintf that concatenate the 2 input string: “C:\Users\<username>\AppData\Roaming” and “Braid” with a “\” in the middle
So this must be the function that generate the value that is then returned.
If you don’t get what’s appening in the function I suggest to set a breakpoint at the start an then run the program. In Braid’s case you will see a black screen cause it’s a fullscreen program, to return to OllyDbg you should use ctrl + alt + del combination and start the Task Manager or start Braid in windowed mode by adding “-windowed” to the Arguments passed By OllyDBG when starting the program.

Use windowed mode

As you can see at the end of the function the value 00BB47C8 that point to a memory region that contain the string: “C:\Users\Dege\AppData\Roaming\Braid” is in the EAX register, so our changed path sould also be passed this way!

Try to debug your function to understand what's going on

Fifth step: Make the magic happen
Now we’re gonna finally edit some code!
First we’ll fill the function with NOPs by selecting all commands and Right Click->Edit->Fill with NOPs, now we have plenty of space to work with.
The first instruction will be a short JMP that uses 2 Bytes so we’ll copy the third NOP addres by Right click on it->Edit->Copy address
Now we can use the space inside the cleaned function to store the new string that we’ll replace.
Start By rightclicking in the hex-dump section of the window then Go to->Expression… and paste the address of the third NOP that we copied before.
Now we’ll select some of these 90 values and we’ll inject our string.
In this case we’ll use the replacement string “.\savegames”, the point is a reference to the current directory, so the program will create the savegames in his own folder under a savegames directory.
The string is long 11 characters, we’ll add a bynary 00 character as string terminator so we can select 12 of the “90” red values.

Select the right chars

Then right click on them->Edit->Binary edit…
In the ASCII input write “.\savegames” and in the HEX input replace the last 90 with a 00.

Add your replacement text

Now back to the assembly section we must select te last five NOPs Right Click->Assemble… in the following window we must write the command “MOV EAX, ” and paste the address of the third byte of the function, the one in wich we put the new string, that should still be in our clipboard.

This is the new return value

Now for the last part of code edit we must copy the address of the command that we have just inserted with our usual Right Click->Edit->Copy Address.
Then after the selection of the first two NOPs Right Click->Assemble… it and write “JMP ” followed by the address that you copied.

This JMP will move the execution to the MOV used to return the right value

The final result should be this one:

Final result

Now to save our changes to the exe file “Right Click->Edit->Copy all modifications to executable” and then in the following window “Right Click->Save File…” and save it.

Sixth step: Unused files removal
Every portable program should be as small as possible, this isn’t a step that you can skip.
We’ll start by copying all files of the Braid installation into a working directory.

Folder content before cleaning

By examinating the contents of the folder we can choose to remove some files:
unins000.dat and unins000.exe are needed by windows to uninstall the game and can go away.
READ_ME.txt is a readme file and isn’t necessary to make the game run so it can go away too.
braid.bak is a backup done by OllyDbg, and after a test to make sure that our modification works we should remove it.
The licenses folder contains various licenses, we will not redistribuite the game so it can go too.
The folder DirectX_Redist contains a redistributable version of the directX library, if you think that some of your target computers will need it you should keep it on your usb flash drive, but not on your Braid folder so we’ll move it away.
After the first clening the situation will be this one:

Folder content after cleaning

Now by entering in the data folder we’ll discover some archives and some folders with languages and fonts, if you plan to never play in an asiatic language you can delete the fonts directory. You can also remove from the strings folder all languages that you’ll never play, but I suggest to leave english anyway to have a fallback.

Seventh step: Archive recompression
Usually when you see archives you can try to recompress them with a highter compression rate, unfortunately Braid don’t support zip compression, probably to keep low load times, so we can’t apply this step on the game.

Eighth step: Reduce images quality
It’s optional and I won’t do it in this case, because it would be terrible to the quality of the game, but when you do this step remember to test all of your modification and keep a backup copy of the entire untouched folder, errors always happens when you are doing something that the original creator haven’t considered!

Nineth step: Compress executables and libraries
By using UPX you can compress even the executables, you just need to drag and drop the desired executable onto the upx.exe file.
On Braid I got a 50% compression ratio, with bigger executables it will significantly reduce total size. If you want to play with command line parameters you can even try to reach a higher compression ratio.

Results:
Start size: 165.342.514 bytes
End size: 123.325.587 bytes
We got a 40MB file reduction and now our program will keep savegames in his own directory

Davide De GennaroHow to make a program portable the hacker way (the hardest way/the fun way)