Android Process Memory Dumps with memfetch – Android 4.4.2 (on Ubuntu 16.04)
I used 2 different C code scripts to achieve the same goal of achieving the process memory dump. The specific code scripts are referred to as Memfetch (by Michal Zalewski – found on his blog) and Memdump (by Tal Aloni – found on StackExchange)
Update [2017-01-16]: I’m not sure whether this will work for Android on both x86 and ARM architectures. I tested it on an ARM architecture (physical device), and it worked. I’m yet to test it on an x86 architecture. Will update after testing.
Memfetch:
Find the code from the author’s webpage here – http://lcamtuf.coredump.cx/soft/memfetch.tgz
Unzip/Extract the code from the TarGZ archive
tar -xvf memfetch.tgz
Get into the directory:
cd memfetch
Use the ls
command to list the files. The files should be listed as below:
COPYING Makefile memfetch.c mffind.pl README
Now install the gcc compiler for Android on ARM (not sure if this is what it’s described as):
sudo apt-get install gcc-arm-linux-android-eabi
(some instructions say use the gcc-arm-linux-gnueabi
but this didn’t work for me )
Edit the Makefile
Normally at this point you should be able to run the make
command and compiling should work, however in Ubuntu the Canonical developers seem to have moved some key .h
source files around causing problems. The first file that might cause problems if you run the make
command will probably be this is because Ubuntu has moved them from the original location of
/usr/include/asm
to be in the kernel source files /usr/src/linux-headers-[your-specific-kernel]/include/asm-generic
Make sure you’ve installed build-essential
for this path to be existent
sudo apt-get install build-essential
You can get to the correct path with:
cd /usr/src/linux-headers-$(uname -r)/include/asm-generic
Once you locate the asm-generic
folder check that the page.h
file is present.
Now the best way to solve this problem is to create a symbolic link (symlink) in /usr/include/
called asm
that links to /usr/src/linux-headers-[your-specific-kernel]/include/asm-generic/
. This is done with the following command:
sudo ln -s /usr/src/linux-headers-$(uname -r)/include/asm-generic /usr/include/asm
Even with this, there will still be some problems because there are some .h
files in asm-generic
that will be looking for asm-generic
in /usr/include/
where the folder doesn’t actually have those header files. So an extra include (-I
) directive will need to be added in the Makefile
The beginning of your make file should look like this:
FILE = memfetch CFLAGS = -Wall -O9 -static CC = arm-linux-androideabi-gcc
NB: its a capital ‘O’ not a zero, and it’s a 9 (nine), not a ‘g’. The “O” “9” directive is some optimization thing (i don’t know if it’s necessary or not)
Run make
at this point. If it works, then great, you should get a memfetch
executable file in your memfetch
directory if not, follow on.
If you run make
and you still get errors of missing .h
files, what i did was to just copy the files from /usr/src/linux-headers-$(uname -r)/include/asm-generic
to /usr/include/
e.g:
sudo cp /usr/src/linux-headers-$(uname -r)/include/asm-generic/memory_model.h /usr/include/asm-generic/memory_model.h
The following files were missing …
getorder.h
/linux/compiler.h
/linux/log2.h
/linux/bitops.h
/linux/irqflags.h
/linux/typecheck.h
At this point i got more files in /bitops that were missing, so i decided to copy the entire directory :
cd /usr/include/asm-generic
sudo mkdir bitops
sudo cp /usr/src/linux-headers-$(uname -r)/include/asm-generic/bitops/* /usr/include/asm-generic/bitops/
At this point i finally ran the make
command in the the memfetch
directory and an executable was created. There were a couple of warnings, but no errors and the executable worked when I pushed into onto the Android device.
Pushing to the Android Device and Executing “Memfetch”:
NB: We are assuming that the device is properly rooted, and the setting for giving adb shell
root permissions has been set in your “Super User” management app.
Go to the adb
executable location, which might be /home/Android/Sdk/platform-tools
it could also be elsewhere … depending on where you installed it
cd /home/Android/Sdk/platform-tools
The best location to push the executable is /data/local/tmp
. Let’s create a directory in this location and use the adb push
command to push the executable here
./adb shell su root cd /data/local/tmp mkdir mem_dump_tools exit exit
We exited first all the way out so that we can run the ./adb push
command
./adb push ~/Desktop/memfetch/memfetch /data/local/tmp/mem_dump_tools/
Verify that the memfetch
executable has been pushed to the right location:
./adb shell su root cd /data/local/tmp/mem_dump_tools ls -al
The memfetch
executable should be in place however it cannot be executed because it does not have execute permissions. We can give it execute permissions with the following command (assuming we are still the root
user)
chmod 755 memfetch
(As a side note: chmod u+x memfetch
should also work.)
Verify that the Execute permissions have been applied
ls -al
You should see rwx
against the name of the memfetch executable. (The x
being the important thing)
Now if we run a particular app and search this process’ ID we can dump the process memory. Pick an app e.g. Google Chrome and fire it. Browse to some page
On the adb shell:
ps | grep chrome
You should get 1-3 processes with Chrome (one with sandboxed
and another with privileged
attached to the process name). Pick the process ID of the process that is plain com.android.chrome
Now we can run memfetch
./memfetch
e.g: ./memfetch 2314
if the process id is “2314”
You should now get some output to screen showing that the memory-mapped regions are being copied. The result is that for each address range (block) from the /proc//mem
folder there is a sub folder called map
that contains the mappings. These mappings result in an individual “region dump” per file (with a .bin
extension) and each region dump filename is appended into a single file with a /lst
extension containing all the filenames of all the regions dumped. So the end result is a lot of .bin
files and a single .lst
file.
NB: If at this point when you try to run memfetch
and all you get is a listing of the available options/directives, and nothing else, then you need to comment out some section of the code in memfetch.c
and recompile. I don’t know why this is the case, but someone on StackExchange [2] figured this out and it also worked for me.
The lines to comment out are:
while ((opt=getopt(argc,(void*)argv, "+samwS:h"))!=EOF) switch(opt) case 's': waitsig=1; break; case 'a': skipmap=1; break; case 'w': textout=1; break; case 'm': avoid_mmap=1; break; case 'S': if (sscanf(optarg,"%x",&onlyseg)!=1) fatal("Incorrect -S syntax (hex address expected).\n"); break; default: usage(argv[0]); }
With that, everything should work.
This blog post has become too long, so i’ll do memdump
in the next one …
Sources:
[1]. http://lcamtuf.coredump.cx/memfetch.tgz
[2]. http://stackoverflow.com/questions/18372120/memfetch-with-android-samsung-galaxy-nexus