Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dump mapped buffer with dd

Into /proc/PID/maps I can see memory that some buffer mapped to kernel module:

44a00000-44b00000 rwxs 00000000 00:01 XXXX /dev/my_module

I know that it's logical address , and I want to dump this memory with dd?

dd need to get physical memory address , how can I calculate the physical address of this buffer to dump it?

like image 488
MicrosoctCprog Avatar asked May 23 '21 08:05

MicrosoctCprog


1 Answers

There are multiple ways to obtain the memory information associated with a running process on Linux.

First, let's determine the process IDs of the running instance that we want to obtain information from. In this test I'm running a ping at google.com.

unknown@unknown-pi4:~$  sudo ps aux | grep ping
unkno+    1402  0.0  0.1 311860  6376 ?        Ssl  15:31   0:01 /usr/libexec/gsd-housekeeping
unknon+    3716  0.0  0.0   9952  2108 pts/0    T    18:11   0:00 ping www.google.com
unknow+    4152  0.1  0.0   9952  2108 pts/0    S+   20:07   0:00 ping www.google.com
unknow+    4176  0.0  0.0   8604   824 pts/1    S+   20:12   0:00 grep --color=auto ping

Second, use /proc/$pid/maps to find out more information about a process. /proc/$pid/maps provides a list of mappings of virtual addresses together with additional information, such as the corresponding file for mapped files.

# https://man7.org/linux/man-pages/man5/proc.5.html

sudo head -1 /proc/3716/maps

aaaab61cf000-aaaab61df000 r-xp 00000000 b3:02 3748                       /usr/bin/ping

Third, use /proc/$pid/pagemap to look at the memory. /proc/$pid/pagemap provides additional information about each mapped page, including the physical address, but only if it exists..

# https://man7.org/linux/man-pages/man5/proc.5.html
# https://linux.die.net/man/1/xxd

sudo cat /proc/3716/pagemap | xxd | less

00000220: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000230: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000240: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000250: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000260: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000270: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Finally we want to use dd

  • dd - convert and copy a file
  • https://man7.org/linux/man-pages/man1/dd.1.html

Breakdown of the command:

  • sudo = requesting permission to use dd
  • if=FILE read from FILE instead of stdin
  • skip=N skip N ibs-sized blocks at start of input
  • bs=BYTES read and write up to BYTES bytes at a time (default: 512); overrides ibs and obs
  • count=N copy only N input blocks
  • od - dump files in octal and other formats
  • -t, --format=TYPE select output format or formats
  • x[SIZE] hexadecimal, SIZE bytes per integer
  • a named character, ignoring high-order bit
unknown@unknown-pi4:/tmp$ sudo dd if=/proc/3716/mem skip=$((0xaaaab61cf000))  bs=1 count=128 | od -t x1a
dd: /proc/3716/mem: cannot skip to specified offset
0000000  7f  45  4c  46  02  01  01  00  00  00  00  00  00  00  00  00
        del   E   L   F stx soh soh nul nul nul nul nul nul nul nul nul
0000020  03  00  b7  00  01  00  00  00  e0  32  00  00  00  00  00  00
        etx nul   7 nul soh nul nul nul   `   2 nul nul nul nul nul nul
0000040  40  00  00  00  00  00  00  00  18  04  01  00  00  00  00  00
          @ nul nul nul nul nul nul nul can eot soh nul nul nul nul nul
0000060  00  00  00  00  40  00  38  00  09  00  40  00  1a  00  19  00
        nul nul nul nul   @ nul   8 nul  ht nul   @ nul sub nul  em nul
0000100  06  00  00  00  04  00  00  00  40  00  00  00  00  00  00  00
        ack nul nul nul eot nul nul nul   @ nul nul nul nul nul nul nul
0000120  40  00  00  00  00  00  00  00  40  00  00  00  00  00  00  00
          @ nul nul nul nul nul nul nul   @ nul nul nul nul nul nul nul
0000140  f8  01  00  00  00  00  00  00  f8  01  00  00  00  00  00  00
          x soh nul nul nul nul nul nul   x soh nul nul nul nul nul nul
0000160  08  00  00  00  00  00  00  00  03  00  00  00  04  00  00  00
128+0 records in
128+0 records out
         bs nul nul nul nul nul nul nul etx nul nul nul eot nul nul nul
128 bytes copied, 0.0019137 s, 66.9 kB/s
0000200

Here is another dd command that will allow you to see the strings within the PID memory.

unknown@unknown-pi4:~$ sudo grep heap /proc/3716/maps
aaaad44ed000-aaaad450e000 rw-p 00000000 00:00 0                          [heap]

# note where I place the mapping addresses in this command.
unknown@unknown-pi4:~$ sudo dd if=/proc/3716/mem bs=1 skip=$((0xaaaad44ed000)) count=$((0xaaaad450e000-0xaaaad44ed000)) status=none | strings | less


GDB - GNU Project debugger

There are other ways to look at the memory of a running process. One way is to use a debugger like gdb. A debugger knows the structures used by a process and can follow pointers and other items.

You can dump your process to a file this way:

# http://www.yolinux.com/TUTORIALS/GDB-Commands.html

unknown@unknown-pi4:~$ sudo gdb --pid=3716
(gdb) gcore
(gdb) deatch 
# to exit control z

The file will be stored as core.3716, which can be read with cat.


You can also use pmap to obtain information about a process.

  • pmap - report memory map of a process
  • https://man7.org/linux/man-pages/man1/pmap.1.html
unknown@unknown-pi4:/tmp$ pmap -XX 1402 | grep ping
1402:   /usr/libexec/gsd-housekeeping
     Address Perm   Offset Device  Inode   Size KernelPageSize MMUPageSize  Rss  Pss Shared_Clean Shared_Dirty Private_Clean Private_Dirty Referenced Anonymous LazyFree AnonHugePages ShmemPmdMapped FilePmdMapped Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked THPeligible              VmFlags Mapping
aaaabe75b000 r-xp 00000000  b3:02  31059     40              4           4   20   20            0            0            20             0         20         0        0             0              0             0              0               0    0       0      0           0    rd ex mr mw me dw gsd-housekeeping
aaaabe775000 r--p 0000a000  b3:02  31059      4              4           4    4    4            0            0             0             4          4         4        0             0              0             0              0               0    0       0      0           0    rd mr mw me dw ac gsd-housekeeping
aaaabe776000 rw-p 0000b000  b3:02  31059      4              4           4    4    4            0            0             0             4          4         4        0             0              0             0              0               0    0       0      0           0 rd wr mr mw me dw ac gsd-housekeeping

On my Ubuntu system I had to temporarily disable a restriction to run a couple of commands that required ptrace.

filename:

/etc/sysctl.d/10-ptrace.conf

change this line:

kernel.yama.ptrace_scope = 1

to this:

kernel.yama.ptrace_scope = 0


You can also dump the memory with a script.

touch dump_process_memory

chmod +x dump_process_memory.sh

#!/bin/bash

grep rw-p /proc/$1/maps \
| sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' \
| while read start stop; do \
    gdb --batch --pid $1 -ex \
        "dump memory $1-$start-$stop.dump 0x$start 0x$stop"; \
done

sudo ./dump_process_memory.sh PID


There are also various open source tools that you can use for memory forensics.

  • AVML (Acquire Volatile Memory for Linux): https://github.com/microsoft/avml

  • LiME ~ Linux Memory Extractor: https://github.com/504ensicsLabs/LiME

  • Volatility: https://github.com/volatilityfoundation/volatility

----------------------------------------
My system information
----------------------------------------
Platform:     Ubuntu
OS Version:   20.10 (Groovy Gorilla)
----------------------------------------
like image 142
Life is complex Avatar answered Oct 17 '22 20:10

Life is complex