Hi all,
Hoping somebody can provide some comments re ELF files in memory.
My ultimate question is: How can I find the .bss section of an ELF
file in memory?
But I have a more specific one. Consider the following output from a
Volatility plugin I wrote which aims to parse the segments:
Volatility Foundation Volatility Framework 2.6
# First we grab the proc_maps which are mapped to the process of
interest (in this case, Xorg)...
# This mimics the linux_proc_maps plugin
Parsing proc maps...
/usr/lib/xorg/Xorg r-x start=0x55d4ddda4000 end=0x55d4ddfe0000 length=0x23c000
/usr/lib/xorg/Xorg r-- start=0x55d4de1e0000 end=0x55d4de1e2000 length=0x2000
/usr/lib/xorg/Xorg rw- start=0x55d4de1e2000 end=0x55d4de1ef000 length=0xd000
# Not listing anonymous maps for now.
# The we parse the ELF header which is at the start of the first
proc_map shown above
Parsing elf_ehdr...
Container({'e_flags': 0, 'e_shoff': 2401000, 'e_phoff': 64, 'e_shnum':
30, 'e_entry': 270368, 'e_version': 'EV_CURRENT', 'e_machine':
'EM_X86_64', 'e_phnum': 9, 'e_shentsize': 64, 'e_ident':
Container({'EI_DATA': 'ELFDATA2LSB', 'EI_OSABI': 'ELFOSABI_SYSV',
'EI_VERSION': 'EV_CURRENT', 'EI_CLASS': 'ELFCLASS64', 'EI_ABIVERSION':
0, 'EI_MAG': [127, 69, 76, 70]}), 'e_type': 'ET_DYN', 'e_phentsize':
56, 'e_shstrndx': 29, 'e_ehsize': 64})
# This looks sane, so let's go to e_phoff (64) and read the program header
Parsing segments...
0x55d4ddda4040 Segment<p_memsz=0x1f8, p_flags=0x5, p_offset=0x40,
p_type=PT_PHDR, p_align=0x8, p_paddr=0x40, p_filesz=0x1f8,
p_vaddr=0x40>
0x55d4ddda4078 Segment<p_memsz=0x1c, p_flags=0x4, p_offset=0x238,
p_type=PT_INTERP, p_align=0x1, p_paddr=0x238, p_filesz=0x1c,
p_vaddr=0x238>
0x55d4ddda40b0 Segment<p_memsz=0x23bdd4, p_flags=0x5, p_offset=0x0,
p_type=PT_LOAD, p_align=0x200000, p_paddr=0x0, p_filesz=0x23bdd4,
p_vaddr=0x0>
0x55d4ddda40e8 Segment<p_memsz=0x1f8f0, p_flags=0x6,
p_offset=0x23c408, p_type=PT_LOAD, p_align=0x200000, p_paddr=0x43c408,
p_filesz=0xdd98, p_vaddr=0x43c408>
0x55d4ddda4120 Segment<p_memsz=0x2e0, p_flags=0x6, p_offset=0x23dc78,
p_type=PT_DYNAMIC, p_align=0x8, p_paddr=0x43dc78, p_filesz=0x2e0,
p_vaddr=0x43dc78>
0x55d4ddda4158 Segment<p_memsz=0x44, p_flags=0x4, p_offset=0x254,
p_type=PT_NOTE, p_align=0x4, p_paddr=0x254, p_filesz=0x44,
p_vaddr=0x254>
0x55d4ddda4190 Segment<p_memsz=0x9904, p_flags=0x4, p_offset=0x1f2b50,
p_type=PT_GNU_EH_FRAME, p_align=0x4, p_paddr=0x1f2b50,
p_filesz=0x9904, p_vaddr=0x1f2b50>
0x55d4ddda41c8 Segment<p_memsz=0x0, p_flags=0x6, p_offset=0x0,
p_type=PT_GNU_STACK, p_align=0x10, p_paddr=0x0, p_filesz=0x0,
p_vaddr=0x0>
0x55d4ddda4200 Segment<p_memsz=0x1bf8, p_flags=0x4, p_offset=0x23c408,
p_type=PT_GNU_RELRO, p_align=0x1, p_paddr=0x43c408, p_filesz=0x1bf8,
p_vaddr=0x43c408>
# These segments look sane, and in fact the values match what I see
from `readelf --segments` against the Xorg binary on disk.
# I ignore the first PT_LOAD segment because the p_flags and p_vaddr
tell me the .bss isn't going to be in there. (As does the output from
`readelf --segments`)
# And I try to read the data pointed to by the p_vaddr of the second PT_LOAD
Testing PT_LOAD at 0x55d4ddda40e8.
# Let's re-print the segment to remind ourselves:
0x55d4ddda40e8 Segment<p_memsz=0x1f8f0, p_flags=0x6,
p_offset=0x23c408, p_type=PT_LOAD, p_align=0x200000, p_paddr=0x43c408,
p_filesz=0xdd98, p_vaddr=0x43c408>
# So starting at the base address (0x55d4ddda4000) + p_vaddr
(0x43c408) =0x55d4de1e0408, I should be able to read p_memsz (0x1f8f0)
bytes, right?
# Wrong... I can only read 0xebf7 (60,407) bytes before volatility
reports an error
Failed to read offset 0xebf8==60408
Notably, the starting offset, 0x55d4de1e0408, is in:
/usr/lib/xorg/Xorg r-- start=0x55d4de1e0000 end=0x55d4de1e2000 length=0x2000
but of course is bigger than the size of the proc_map.
I really do appreciate any comments you might have as to where my
understanding is lacking!
Adam
Hello!
I posted this question already, but i could not find it on the
archive, so I am trying it again.
I am doing some research on RAM extraction and analysis in Android (6
Marshmallow). I succeeded in compiling my own Kernel with enabled
CONFIG_MODULE_LOAD and installing it onto my Nexus 5X. Creating the
LiME module to extract the RAM was also successful, I could get a
memory dump of the device on my computer. In a Hex-editor, I can see
content of the RAM (boot pictures, text messages,…).
I also asked this question at stackoverflow, it is better readable
there due to formatting reasons:
https://stackoverflow.com/questions/44807171/keyerror-int128-unsigned-in-dw…
But now I have problems using Volatility 2.6. My steps so far:
• get volatility
git clone https://github.com/volatilityfoundation/volatility.git
cd volatility/tools/linux
• Adjust Makefile (I also had to uncomment #define RADIX_TREE_MAX_TAGS
2 in the module.o, otherwise I got an error during make)
obj-m += module.o
KDIR := /root/compile/msm/
CCPATH := /root/compile/msm/aarch64-linux-android-4.9/bin
-include version.mk
all: dwarf
dwarf: module.c
$(MAKE) ARCH=arm64 CROSS_COMPILE=$(CCPATH)/aarch64-linux-android-
-C $(KDIR) \
CONFIG_DEBUG_INFO=y M=$(PWD) modules
dwarfdump -di module.ko > module.dwarf
make
• Combine System.map (created during kernel compilation) and
module.dwarf (created during make) and copy the .zip it into the
overlays directory
zip Nexus5X.zip module.dwarf ../../../System.map
cp Nexus5X.zip ../../volatility/plugins/overlays/linux/
• run volatility
python vol.py --profile=LinuxNexus5Xx64 -f
/root/Documents/nexus-ram.dump linux_pslist
The parameters are all correct - the profile exists, the file also and
linux_pslist is a valid command. But even with other commands such as
linux_cpuinfo, I get the following error:
root@kali:~/compile/msm/volatility-2.6# python vol.py
--profile=LinuxNexus5Xx64 -f /root/Documents/nexus-ram.dump linux_pslist
Volatility Foundation Volatility Framework 2.6
Traceback (most recent call last):
File "vol.py", line 192, in <module>
main()
File "vol.py", line 183, in main
command.execute()
File
"/root/compile/msm/volatility-2.6/volatility/plugins/linux/common.py",
line 64, in execute
commands.Command.execute(self, *args, **kwargs)
File "/root/compile/msm/volatility-2.6/volatility/commands.py",
line 116, in execute
if not self.is_valid_profile(profs[self._config.PROFILE]()):
File
"/root/compile/msm/volatility-2.6/volatility/plugins/overlays/linux/linux.py",
line 216, in __init__
obj.Profile.__init__(self, *args, **kwargs)
File "/root/compile/msm/volatility-2.6/volatility/obj.py", line
862, in __init__
self.reset()
File
"/root/compile/msm/volatility-2.6/volatility/plugins/overlays/linux/linux.py",
line 227, in reset
self.load_vtypes()
File
"/root/compile/msm/volatility-2.6/volatility/plugins/overlays/linux/linux.py",
line 264, in load_vtypes
vtypesvar = dwarf.DWARFParser(dwarfdata).finalize()
File "/root/compile/msm/volatility-2.6/volatility/dwarf.py", line
71, in __init__
self.feed_line(line)
File "/root/compile/msm/volatility-2.6/volatility/dwarf.py", line
162, in feed_line
self.process_statement(**parsed) #pylint: disable-msg=W0142
File "/root/compile/msm/volatility-2.6/volatility/dwarf.py", line
225, in process_statement
self.id_to_name[statement_id] = [self.base_type_name(data)]
File "/root/compile/msm/volatility-2.6/volatility/dwarf.py", line
125, in base_type_name
return self.tp2vol[data['DW_AT_name'].strip('"')]
KeyError: '__int128 unsigned'
Can you help me figuring out the error and how to solve it? Or any
related work which did RAM extraction from Android > 5.0 ?
The string "__int128 unsigned" is inside the module.dwarf two times. I
posted the Module.dwarf here as it would be too big for this mail (it
needs some time until the web page appears):
http://chopapp.com/#b27ludkk
Thanks in advance!
Hi all,
This is a "what don't I know?" question...
I have a very simple C program:
#include <gtk/gtk.h>
#include <stdio.h>
int main(int argc, char **argv)
{
GtkTextBuffer *buffer;
buffer = gtk_text_buffer_new(NULL);
gtk_text_buffer_set_text(buffer, "adam1adam2adam3", 15);
printf("buffer: %p\n", buffer);
getchar();
return 0;
}
Then the following to try and locate the strings in memory:
------------------------------------------------------------
$ strings --radix=d LinuxMint-17.3-Mate-x64-61951b91.vmem | fgrep
adam1adam2adam3 >/tmp/s
------------------------------------------------------------
$ cat /tmp/s
195393652 adam1adam2adam3
204175816 adam1adam2adam3
851998836 adam1adam2adam3
------------------------------------------------------------
$ ~/src/volatility/vol.py -f LinuxMint-17.3-Mate-x64-61951b91.vmem
--profile LinuxMint173x64 linux_strings -s /tmp/s
Volatility Foundation Volatility Framework 2.6
195393652 [kernel:88000ba57874] adam1adam2adam3
204175816 [kernel:88000c2b79c8] adam1adam2adam3
851998836 [kernel:880032c87874] adam1adam2adam3
------------------------------------------------------------
Why on earth would the string only be located in Kernel space??
I've been digging into Gtk for quite some time now to try and solve this
and think I understand that in Gtk, text is stored as GtkTextLineSegments.
The memory for a GtkTextLineSegment is allocated via g_slice_alloc and the
actual text copied to the allocated space via an ordinary memcpy (See:
https://github.com/GNOME/gtk/blob/406db15066f121c2b9910691f92e58
41b30e0311/gtk/gtktextsegment.c#L190-L210)
I've proved the text really is here by editing the text in the VMEM file in
a hex editor and then resuming the VM - sure enough the text is updated to
reflect the changes.
I could just about understand the text being in Kernel space AND user space
because perhaps its sent to the X server or something, but it appears to
ONLY be in Kernel space.
What don't I know??
Many thanks,
Adam