Archives

All posts by Dipanjan

Let us get the objective of our mission clear before we spring into action. I plan to reiterate a little bit of rudimentary information on the operations of compiler and linker and their mutual interaction. Following that, we will ask ourselves a couple of questions to practice thinking out-of-the-box and present the obvious answers. Since, we are ‘Truly Tech’, we will perform two quick experiments to justify our hypothesis; surprisingly fail to prove it; take a closer look, i.e. ‘inspect’ what is going on under the hood; redo the experiments with a subtle change and arrive at the expected result. The whole exercise is to show that the test environment of the trivial-most experiment can be quite tricky to set-up.

The compiler (e.g. gcc) compiles a source code (e.g. C file) to an object file (e.g. ELF REL (Relocatable)). Any function/method that is ‘not’ internal or not supplied by the source code is left ‘unresolved’ by the compiler. It’s the linker’s (e.g. ld) responsibility to turn that object file into a fully-functional binary executable (e.g. ELF EXEC (Executable)) resolving all the references to external method calls by linking to either static (e.g. .a archive) or dynamic libraries (.so). Those libraries are either system provided (GNU libc or glibc) or third-party ones (uClibc, libELF). As a practical example, when ld links an object file having a reference to  printf()  method, most likely it will dynamically link to glibc (default linking mode for ld is dynamic) unless a static linking (-static) is requested. When the operating system begins executing a program, the application loader transparently loads the dynamic libraries the application requires and maps those into application’s address space. All the methods a particular library offers/exports are thus made available to the program at run-time. How does the application loader know where to load a library from? It looks in a set of standard locations following a predetermined search order.

This is the platform I will be using throughout.

Question# 1: Let’s say, we have access to the source code of a C program that makes use of pow() method from libm. Is it possible to supply an alternate implementation of the same using a shared library so that our version of pow()overrides the system-provided one? In other words, if we write our own pow(), pack it in a shared library and furnish it to the compiler/linker from the command line during compilation/linking, how are these tools going to behave? Too loosely speaking, our task is to perform a code-injection while we have access to the source code.

As we can see that there are a couple of implementations of the same method (linker treats method names as ‘symbols’) to choose from; of course, the linker will either bring it to the notice of the user or take a decision itself. Can there be any third possibility? No, apparently. Either play ‘dumb and ask’ or be ‘smart and silent’ by falling-back to some default behavior. Shortly it will turn out that our favorite linker ld quietly swallows the fact. Let’s get our hands dirty with experiment# 1.

Here’s the driver program that makes pow() call.

Our implementation of a lazy pow(). It’s declaration mimics the ‘real’ one. But, no matter whatever the arguments are, it always return a b-o-r-i-n-g 10.000000.

Let’s compile (1) the main program, the shared library (2, 3), dynamically link (4) those together and execute (5) the program. To be on the safer side, we will use -O0 to disable all gcc optimizations and -Wall to display all compiler warnings, if any.

What did just take place? ld is silent about duplicate implementations of pow()  method, one appearing in libm, the system library and the other one being present in libpow, the shared library we created. Moreover, ld is ignoring our version of the method while the system-provided one is taking precedence over. Had it been the other way round, the result would be 10.000000 instead of 1024.000000 (= 2^10).

Question# 2: Let’s say, we don’t have access to the source code of a C program that makes use of pow() method from libm linked dynamically. The only artifact in our hand is the compiled executable. Is it possible to supply an alternate implementation of the same using a shared library so that our version of pow()overrides the system-provided one? In other words, if we write our own pow(), pack it in a shared library and ‘somehow’ preload the library before even the execution begins, how is Linux application loader going to behave? Loosely speaking, our task is to perform a code-injection while we don’t have access to the source code.

Linux provides us with a nifty hack, the LD_PRELOAD environment variable, to preload a dynamic library (.so) before even the application loader attempts to resolve the dynamic references . It serves as a handy ‘backdoor’ to intercept dynamically linked method calls. Let’s hijack the pow call.

What did take place now? We observe that LD_PRELOAD does not work with the  pow() call. How come? Our fresh knowledge about LD_PRELOAD says exactly the opposite. Is there anything special about  libm? If the trick works for srand() as shown example, what’s so special about pow()? We are confused now! To probe into the issue, the first step we take is to dissect the object file.

Holy shit! Where is the pow symbol? Wasn’t it supposed to be there? Of course, it was. The type marker “U” beside printf suggests that the symbol is undefined. Quite reasonably, it seems that the compiler has resolved the reference to the pow() method statically from the math library. But…wait. Resolving reference isn’t really the responsibility of the compiler, but the linker. At least, we can expect the pow symbol to be retained as an unresolved one in the object code, if not in the final executable. gcc never fails to surprise us.

To be sure, let’s peek into the relocation section of the object file to find any entry corresponding to pow call. As expected, such a call is missing.

As the last resort, we will disassemble the executable itself to peek into it. The most common tool for that is objdump. In fact,  objdump -M intel -d pow will generate the disassembly of all the executable sections in the binary in Intel assembly format. However, it will include what we need and a l…o…t more. We are interested in the disassembly of main function only. Here’s a nifty shortcut for you.

Can you see something suspicious at  0x0000000000400535 <+8>? It may not be immediately apparent unless you are familiar with IEEE 754 floating point representation, the template to represent a single or double precision floating point number inside computer’s memory. Even if you don’t know what it is, an online converter should tell you that  0x4090000000000000 in IEEE 754 format is equivalent to the floating point number  1024.000000. The instruction  movabs rax,0x4090000000000000 moves the constant to the register rax.

We have been lied so far. A quick googling will bring out numerous post suggesting the use of gcc -O0 to stop all compiler optimizations. GNAT user guide confuses us even more.

‘-O0’

          No optimization (the default); generates unoptimized code but has the fastest compilation time.

          Note that many other compilers do fairly extensive optimization even if  ‘no optimization’ is specified. With gcc, it is very unusual to use -O0 for production if execution time is of any concern, since -O0 really does mean no optimization at all. This difference between gcc and other compilers should be kept in mind when doing performance comparisons.

Why on earth does it comment on gcc’s behavior? gcc, in its present form and shape, falls exactly in the category of “many other compilers” which does extensive optimizations even in the absence of any optimization flags or at gcc -O0. The clue to the discrepancy above hides in these couple of benign statements from gcc doc’s.

Most optimizations are only enabled if an -O level is set on the command line. Otherwise they are disabled, even if individual optimization flags are specified.

Depending on the target and how GCC was configured, a slightly different set of optimizations may be enabled at each -O level than those listed here. You can invoke GCC with ‘-Q –help=optimizers’ to find out the exact set of optimizations that are enabled at each level. See Overall Options, for examples.

Look carefully. The salient point is, “Most optimizations are only enabled…”, most but not all. To rephrase, there are optimizations those are enabled even at gcc -O0. To see what all are the optimization enabled at gcc -O0, we run the following:

Voila! A plethora of optimizers are enabled by default. Let’s try disabling all of them.

For the sake of brevity, though I am not explicitly showing here, take my word that the upshot of repeating of the entire procedure outlined above with the optimizers turned off remains the same. gcc inevitably performs constant folding,  no matter what your optimization level/options are. There seems no way to alter this behavior.

Constant folding requires compiler to know operands apriori. What if we change one of the constant arguments to pow a variable to be supplied by the user?

Recompile the driver program as well as the library.

Unlike the earlier run, now the linker really searches for libpow.so during linking. We are happy to see that the output is as expected. Though both -lpow and -lm switches are passed to the linker, the linker is prioritizing the user supplied library over the system one. Is it so? Are we sure? Let’s swap the order of the libraries and see what happens.

Math library takes over here. To conclude, the behavior of ld is to scan the libraries supplied on the command line from left to right with decreasing priorities.

To check whether our LD_PRELOAD solution works:

Lastly, we may not be able to prevent gcc from folding constants, but it provides -fno-builtin- switch as a means to disable built-in function(s) during compilation. We can exploit this feature to make the original versions of our program work without introducing an user variable.

In either of the case above, both nm and readelf outputs corroborates our expection, too.

 

In Host-only networking mode, VirtualBox creates a virtual network interface called Host-only Ethernet Adapter on the host system. It is particularly useful when VMs not only want to talk to each other, but to the host system, too. Also, the traffic going through such an interface can be intercepted by binding a packet sniffer like Wireshark. Unlike other modes of networking supported, a static or dynamic IP can be set to this adapter.

A bug I stumbled upon in VirtualBox v4.3.20 running on Windows 7 Ultimate x64 is the IP of a freshly created host-only adapter getting reset every time it is configured manually. Surprisingly, I did not experience this bug on Windows 8.1 Enterprise x64 running the same version of VirtualBox. After quick googling, I discovered that bug#8796 and bug#11155 have already been reported. The video records the bug and the solution to it.

You can bind a static IP to the interface from Oracle VM VirtualBox Manager UI => File => Preferences => Network => Host-only Networks tab => Select the adapter => Click on the third button (Edit) on the right sidebar. Here, what you can see is, I have tried setting the IP 192.168.56.1 and netmask 255.255.255.0 to the host-only adapter several times. Every time I confirmed the IP-netmask pair by clicking ‘OK’ twice. Immediately after, when I reopened same dialog box, the IP and netmask get set to some random value.

To solve this issue, you need to set the adapter to obtain its IP address dynamically.

Navigate to Windows 7 Start Menu => Network => Network and Sharing Center => Change Adapter Settings => Right click on the host-only adapter interface => Properties => Select ‘Internet Protocol Version 4 (TCP/IPv4)’ => Click on ‘Properties’ button => Select ‘Obtain IP address dynamically’ radio button => Click ‘OK’. Now, you can set the IP-netmask of the adapter from inside VirtualBox and it won’t get reset any more.

Oracle VirtualBox’s is a robust virtualization solution and pretty much self-complete. So far, most probably you have used its built-in networking support without worrying about setting up an external DHCP server, e.g. TFTPD32 to supply network parameters to dynamic guest interfaces. The virtual machine receives its network address and configuration on the private network from a DHCP server integrated into VirtualBox. The server can be managed using VBoxManage dhcpserver command from command line or from the GUI, too. So far, so good.

Built-in server is a basic one, yet sufficient to meet the need of most of the applications unless you are into some advanced stuffs, viz. you may want to pass a dhcpd-option to the DHCP client sitting inside VM guest. One workaround is to set the VM to use Host-Only Adapter, disable the built-in DHCP server and run an external one. Ideally, the solution should work out-of-the-box. Probably due to a bug in VirtualBox 4.3.10 (on both Windows 7 Professional x64), it does not. Essentially, even after disabling the built-in DHCP server (19.168.56.100) and running a TFTFD32 server bound to VirtualBox Host-Only adapter (192.168.56.1) on host network, Ubuntu VM still receives DHCP OFFER packets from 192.168.56.100, i.e. the built-one. Attached is a transcript of DHCP cycle as captured by Wireshark.

The workaround I found is as follows:

  1. Remove built-in Host-Only Ethernet Adapter from Oracle VM VirtualBox Manager UI => File => Preferences => Network => Host-Only Networks tab => Select the adapter to be removed => Click on the second button on the right sidebar => Confirm removal
  2. Add a new adapter by clicking on the first button on the right sidebar of the same page. If asked, browse  VBoxNetAdp.sys driver. On my system, it is located at C:\Program Files\Oracle\VirtualBox\drivers\network\netadp.
  3. Set appropriate IP (here 192.168.56.1) and netmask (here 255.255.255.0) for the adapter by clicking the third button on the right sidebar of the same page. If you face the problem of IP and/or netmask getting reset, please refer to this post.
  4. Make sure built-in DHCP server bound to newly created interface is disabled from the ‘DHCP Server’ tab. ‘Enable Server’ check-box must be unchecked.
  5. Verify that built-in DHCP server not running from command line by issuing ‘VBoxManage list dhcpservers‘ command.
  6. Set appropriate parameters in TFTPD64 DHCP settings. Don’t forget to bind it to the IP (here 192.168.56.1) of the new adapter.
  7. Boot up VM and verify the IP assigned to the guest interface by running ifconfig ethX (X = appropriate interface number). Also, the DHCP server offering the lease can be identified by running cat /var/lib/dhcp/dhcp/dhclient.ethX.leases | grep dhcp-server-identifier (X = appropriate interface number) command.
  8. Verify the same from the MAC <=> IP binding as displayed by TFTP64 main console.

What is Link2SD?

Link2SD is an app for Android 2.0+ users on their phone to move applications to the SD card by dual-partitioning the card. First partition gets mounted as external SD and remains available for general use, while the second partition (preferably formatted with an *NIX type file-system, e.g. ext2, ext3, ext4 etc.) holds executable(.apk), data, dalvik-cache(.dex) and library files(.so) for linked/moved application.Link2SD mounts the second partition of your SD card as /data/sdext2 and makes OS mounts it at boot time. When you select an application and press “Create Link” button you can select which files of the application will be linked and moved to SD card. Apk, dex and lib files can be moved and you can select all three or any two of three or even only one of them. Depending on what you select, Link2SD moves apk file, dalvik-cache (.dex) file and lib files (.so) to SD card’s second partition and creates symbolic links in original directories. Phone must be Rooted, of course.


How does mounting of second SD partition work?

After the partitioned SD card is put in the phone, Link2SD asks you to select the file-system of the second partition on SD, just chose the one you used. Once /system/etc/init.d/11link2sd script is created, you have to restart the phone.


What is init.d support and why is it needed?

init.d directory is the container of start-up scripts in a *NIX type system. These scripts are execute during system boot.Link2SD relies on the execution of /system/etc/init.d/11link2sd script which, in turn, mounts the second partition of SD card as /data/sdext2.


What is the Boot-Loop problem?

The SD card storage is dual-partitioned and put in the phone. Then, Link2SD generates mount script for the second partition of SD card and phone needs to be re-started. Some phones, e.g. Sony Xperia-L runs into infinite boot-sequence a.k.a. boot-loop. In this state, phone boot sequence starts, manufacturer logo is displayed proceeds for a few seconds and restarts. Only solution is to long press the power button or taking out the battery to switch the phone off. Interestingly, if the dual-partitioned SD card is taken out and the phone is booted without SD card inserted, it boots normally.


What did I do with my Xperia-L so that it started boot-looping?

  1. Rooted Xperia using Rootkit method. It leaved /system/etc/install_recovery.sh and /system/etc/init.d/00stop_ric scripts on the phone’s file-system. (Script code listed below). I am using the rooted phone for months without any trouble.
  2. Using an un-partitioned 32GB microSD card, formatted with FAT32, in the phone.
  3. Deciding to give a try to Link2SD, I dual-partitioned the SD using Minitool Partition Manager. First partition was formatted with FAT32 while the second one was formatted with ext4. Sizes of partitions were around ~25GB and ~4.5GB respectively.
  4. Installed Link2SD on phone.
  5. Switched the phone OFF.
  6. Put the dual-partitioned SD back in the phone slot.
  7. Switched the phone ON.
  8. Opened Link2SD app.
  9. Link2SD immediately recognized the second partiton, asking me for its file-system type.
  10. Selected ext4 from the list.
  11. Link2SD generated the mount script and prompted for restart.
  12. Restarted the phone.
  13. Boot-Loop!!!
  14. Switched the phone OFF by taking out battery.
  15. Took the dual-partitioned memory card out.
  16. Switched the phone ON.
  17. Phone starts normally!!!

How did I solve the problem?

  1. I installed Init.d Toggler app as described here.
  2. As described here, I experienced the problem of first partition not being mounted. The error was related to SD Card being empty or the file-system damaged.
  3. I re-formatted the first partition of SD with NTFS.
  4. Installed Paragon exFAT, NTFS & HFS+ app.
  5. Now, the first partition got mounted.

What does Init.d Toggler do?

  1. Appends the following command at the end of /system/etc/install_recovery.sh: /system/bin/sysinit
  2. Creates /system/bin/sysinit script.
  3. Creates /system/etc/init.d directory to put the start-up scripts in.

Does REALLY lack of init.d support cause boot-loop problem?

As the Init.d Toggler solution says,

One of the requirements to use the Link2SD is the support to init.d scripts. Most of the custom roms support this, but not the stock one, giving a boot loop.

I doubt that to be the “real” problem underlying the hood. Why?

  1. How come lack of init.d support cause the mount script /system/etc/init.d/11link2sd malfunction? At most, what could have happened is, it would NOT mount the second partition, that’s it. Right? But, isn’t it surprising to crash or the like during boot?
  2. As stated, even prior to installing Link2SD, there always existed /system/etc/init.d/00stop_ric, which contains almost similar set of commands as that of mount script /system/etc/init.d/11link2sd created by Link2SD. It used to work like a charm. I guess, because of init.d support not being there in stock ROM, the script had never been executed before I used Init.d Toggler.
  3. Had the lack of init.d support been the reason of boot-loop, how did the phone manage itself to boot normally with the dual partitioned SD card taken out? Please note that, the mount script was still residing in init.d directory.
  4. To be noted that, Xperia L (Stock ROM) boots fine with a dual-partitioned SD card put in, though it never mounts the second partition.

Please find the relevant scripts below.

Those who have played Jewel Mania (by TeamLava Games) on Android know how addictive it is! To cheat Jewel Mania for unlimited coind and gold, you need to have the following:

Now follow the steps below:

  1. Start Game-Killer, minimize it to the top left corner of the screen.
  2. Start Jewel-Mania.
  3. Bring Game-Killer in front. Type in the current count of coins from the game to the search item field of Game-Killer. (In this guide, the value is 60,090)
  4. Hit ‘Search’.
  5. Select ‘DWORD’ in the next step as the type of memory location to search for.
  6. Game-Killer will list out the memory locations where the value occurs.
  7. Modify the values of all the listed locations to some high number, say 99999999 until the correct one is found. When the correct location is found, the count of coins in the game changes, too, instantaneously. So, keep an eye on that.
  8. Now, you are the proud owner of virtually unlimited coins. But, it is not of much use unless you earn gold, too, right? So, what I did is, I repeated the same procedure as described above for gold, listed down a number of memory locations, then played the game a little bit, spent a few gold and searched for the reduced count of gold from the memory locations already listed in Game-Killer. Every time I tried doing the same, I found a generic pattern! The memory location holding the count of gold is 0x50 (HEX) offset smaller than that holding the count of coins.
  9. So, here goes my recipe. You need not do anything but simply calculate the memory address of gold by subtracting 0x50 from the memory address you have already found for coins. (In this guide, the address is 0x61FEDFDC). Switch over to RealCalc’s HEX mode to perform this calculation.
  10. Go back to Jewel-Mania and Game-Killer once again. This time, as you know the exact memory location, you need no search it over again. Instead, click on “Add Item” and select “Add Address (HEX)”. Feed the address you have calculated in RealCalc. (In this guide, the address is 0x61FEDF8C)
  11. Again, modify the values of all the listed locations to some high number, say 99999999, to obtain unlimited gold.
  12. A word of caution, every time you connect to Internet, Jewel-Mania will refresh game data and the values will be lost. You progress will remain saved though. You may need to repeat all the steps above sometimes once you disconnect from Internet. However, despite having new memory locations for gold and coin as the game is re-strarted or game-data is reloaded, those will always differ by an offset of 0x50.

Good luck and happy hacking!