Go Beyond

Only read if you don't mind being offended.

/dev/mem strings recovery

Today, I'm writing about /dev/mem data recovery as I didn't see a lot after a quick google search for this after wanting to send someone a quick article.

So, let's assume that you run something involving the Linux kernel (probably potentially applicable to other Unixy operating systems).

Possible scenarios:

X crashes. You launched Vim in a terminal that died long ago and can't figure out how to gdb reattach to stdin/stdout of the process. KMS ate your video and the potentially related magic sysrq function is not giving you a TTY back. You didn't save your file. OOM killer went on a frenzy and killed your editor just before you were going to save it.

In any case, you probably want that file back. First and foremost, save regularly and make backups. This is not a replacement for good habits.

That being said, we all make mistakes and this can be an exciting potential method for recovery. Here's what you do:

Make sure you're running a kernel with /dev/mem filtering disabled. If not, rebuild it or complain adequately to your upstream package builders.

We can do this in a few ways depending on the nature of the data you have. The first thing is to dump your memory as soon as possible. You have to do this as root unless you have some pretty dumb permissions on /dev/mem (or maybe the kernel will block access as non UID 0 users regardless?).

Everything: cat /dev/mem > mem # Be smart and write this into a folder where other people can't read it.

Less than everything, probably faster: strings /dev/mem > strings

If you need to recovery binary data, this could be more tricky. You don't want to be filtering it for common ASCII characters via strings if that's the case. unstrung may be safest regardless if it's compressed or encrypted in memory for some insane reason. Either way, it'll probably be in plain text at one form. It'll still be segmented and choppy. You'll probably see repeated data from text screen-facing buffers, terminal buffers, file descriptor buffers, and other things that I'm not aware of.

Anyways, now we grep if it's string data. If it's not so ASCII, I guess you could work up a binary grep of sorts. Maybe try a hexdump -C | grep DEADBEEFCAFE, but that might actually be truncated on the end and you'll get a break in the match so it won't print. Might want to tr -d "\n", but you'd get some really funky output.

If it is string data, just grep it. Maybe case insensitive if you must, but it may be a tad bit slower. If it's binary, string it then grep it if you're only looking for ASCII.

Here's an example:

# strings /dev/mem > strings
^C # I got lazy and cut it short since it was taking ages.
# du -hs strings
520M    strings
# grep go-beyond.org strings | head
ssh root@go-beyond.org
<teran.mckinney@rackspace.com>, <sega01@go-beyond.org>
Teran McKinney <sega01@go-beyond.org>
Teran McKinney <sega01@go-beyond.org>
Teran McKinney <sega01@go-beyond.org>
# grep -10 vimrc strings | head -n 100
" All system-wide defaults are set in $VIMRUNTIME/archlinux.vim (usually just
" /usr/share/vim/vimfiles/archlinux.vim) and sourced by the call to :runtime
" you can find below.  If you wish to change any of those settings, you should
" do it in this file (/etc/vimrc), since archlinux.vim will be overwritten
" everytime an upgrade of the vim packages is performed.  It is recommended to
" make changes after sourcing archlinux.vim since it alters the value of the
" 'compatible' option.
" This line should not be removed as it ensures that various options are
" properly set to work with the Vim-related packages.
runtime! archlinux.vim
" If you prefer the old-style vim functionality, add 'runtime! vimrc_example.vim'
" Or better yet, read /usr/share/vim/vim72/vimrc_example.vim or the vim manual
" and configure vim to your own liking!
filetype plugin on
syntax on
" set t_Co=256

You can find some pretty cool stuff in /dev/mem. Passwords, keys, cached files, and most whatever that passes through your box. I've mostly used this to recover long winded emails and Facebook messages which should have probably never been sent in the first place.

You can also check your swap partition (if you have one) using the same technique. You may wish to swapoff it to help prevent contents from expiring earlier than desired.


You don't want to get all cocky and string /dev/mem and pipe it into grep for what you want. The memory is continually being overwritten and if you don't make a perfect search, it may be overwritten into oblivion. The other problem is that you get matches for your own matches which are added into memory, as well as your keyword. It just gets a lot trickier to work with.

Thanks for reading. Hope this helps someone save some data and prevent lost time.