From 42e00a80ffdfa58b409fad7916ad581d02d5a929 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Jan 1970 00:00:00 +0000 Subject: [PATCH] Added 'virt-mem dump' command allowing you to hexdump arbitrary regions of virtual memory. --- MANIFEST | 1 + lib/.depend | 4 ++ lib/Makefile.in | 4 +- lib/virt_mem_dump.ml | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++ mem/.depend | 6 ++- mem/virt_mem_main.ml | 1 + 6 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 lib/virt_mem_dump.ml diff --git a/MANIFEST b/MANIFEST index dfaccfd..5c95026 100644 --- a/MANIFEST +++ b/MANIFEST @@ -27,6 +27,7 @@ lib/kernel_task_struct.mli lib/Makefile.in lib/test_mmap.ml lib/virt_mem_capture.ml +lib/virt_mem_dump.ml lib/virt_mem_kallsyms.ml lib/virt_mem_kallsyms.mli lib/virt_mem_kernels.ml diff --git a/lib/.depend b/lib/.depend index 3fbd7c9..6262905 100644 --- a/lib/.depend +++ b/lib/.depend @@ -23,6 +23,10 @@ test_mmap.cmo: virt_mem_mmap.cmi test_mmap.cmx: virt_mem_mmap.cmx virt_mem_capture.cmo: virt_mem_types.cmi virt_mem_gettext.cmo virt_mem.cmi virt_mem_capture.cmx: virt_mem_types.cmx virt_mem_gettext.cmx virt_mem.cmx +virt_mem_dump.cmo: virt_mem_types.cmi virt_mem_mmap.cmi virt_mem_gettext.cmo \ + virt_mem.cmi +virt_mem_dump.cmx: virt_mem_types.cmx virt_mem_mmap.cmx virt_mem_gettext.cmx \ + virt_mem.cmx virt_mem_kallsyms.cmo: virt_mem_utils.cmo virt_mem_types.cmi \ virt_mem_mmap.cmi virt_mem_ksyms.cmi virt_mem_gettext.cmo \ virt_mem_kallsyms.cmi diff --git a/lib/Makefile.in b/lib/Makefile.in index 5232ee7..b1f09d2 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -63,7 +63,9 @@ OBJS = virt_mem_gettext.cmo \ virt_mem_tasks.cmo \ virt_mem_net_devices.cmo \ virt_mem.cmo \ - virt_mem_capture.cmo + virt_mem_capture.cmo \ + virt_mem_dump.cmo + XOBJS = $(OBJS:%.cmo=%.cmx) all: $(TARGETS) diff --git a/lib/virt_mem_dump.ml b/lib/virt_mem_dump.ml new file mode 100644 index 0000000..615bc34 --- /dev/null +++ b/lib/virt_mem_dump.ml @@ -0,0 +1,132 @@ +(* Memory info command for virtual domains. + (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc. + http://libvirt.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Implements 'virt-mem dump' command. + *) + +open Printf +open ExtString + +module D = Libvirt.Domain + +open Virt_mem_types +open Virt_mem_gettext.Gettext + +let start_addr = ref None +let size = ref None + +let set_start_addr addr = start_addr := Some (Int64.of_string addr) +let set_size n = size := Some (int_of_string n) + +(* Early argument check. *) +let argcheck debug = + (* --start flag must have been specified. *) + if !start_addr = None then ( + prerr_endline (s_"virt-mem dump: '--start' option is required"); + exit 1 + ) + +(* Capture the image. *) +let rec run debug image kdata = + let start_addr = !start_addr in + let size = !size in + + let start_addr = + match start_addr with + | None -> assert false (* should have been caught by argcheck *) + | Some addr -> addr in + let size = + match size with + | None -> 1 lsl 20 (* large, but not unlimited *) + | Some size -> size in + + (* Load the memory. *) + let is_mapped = Virt_mem_mmap.is_mapped_range image.mem start_addr size in + let image = + if not is_mapped then + load_memory image start_addr size + else + image in + + (* Get the bytes. *) + let bytes = Virt_mem_mmap.get_bytes image.mem start_addr size in + + hexdump stdout start_addr bytes size + +(* Modified from the version in bitstring library. *) +and hexdump chan count data len = + let count = ref count in + let off = ref 0 in + let len = ref len in + let linelen = ref 0 in + let linechars = String.make 16 ' ' in + + fprintf chan "%08Lx " !count; + + while !len > 0 do + let bits = min !len 8 in + let byte, off', len' = + Bitstring.extract_char_unsigned data !off !len bits in + off := off'; len := len'; + + let byte = byte lsl (8-bits) in + fprintf chan "%02x " byte; + + count := Int64.succ !count; + linechars.[!linelen] <- + (let c = Char.chr byte in + if isprint c then c else '.'); + incr linelen; + if !linelen = 8 then fprintf chan " "; + if !linelen = 16 then ( + fprintf chan " |%s|\n%08Lx " linechars !count; + linelen := 0; + for i = 0 to 15 do linechars.[i] <- ' ' done + ) + done; + + if !linelen > 0 then ( + let skip = (16 - !linelen) * 3 + if !linelen < 8 then 1 else 0 in + for i = 0 to skip-1 do fprintf chan " " done; + fprintf chan " |%s|\n%!" linechars + ) else + fprintf chan "\n%!" + +and isprint c = + let c = Char.code c in + c >= 32 && c < 127 + +let summary = s_"dump parts of virtual memory" +let description = s_"Dump parts of virtual memory for debugging purposes. + +Use the --start and --size parameters to specify the start address +and size of the region to dump. Hexadecimal numbers can be specified +using '0x..' notation. +" + +let extra_args = [ + "--start", Arg.String set_start_addr, + "addr " ^s_"Set start address to dump"; + "--size", Arg.String set_size, + "size " ^s_"Set size (in bytes) to dump"; +] + +let () = + Virt_mem.register ~run + ~external_cmd:false ~extra_args ~argcheck + "dump" summary description diff --git a/mem/.depend b/mem/.depend index fd7322a..ca3abf3 100644 --- a/mem/.depend +++ b/mem/.depend @@ -1,2 +1,4 @@ -virt_mem_main.cmo: ../lib/virt_mem_capture.cmo ../lib/virt_mem.cmi -virt_mem_main.cmx: ../lib/virt_mem_capture.cmx ../lib/virt_mem.cmx +virt_mem_main.cmo: ../lib/virt_mem_dump.cmo ../lib/virt_mem_capture.cmo \ + ../lib/virt_mem.cmi +virt_mem_main.cmx: ../lib/virt_mem_dump.cmx ../lib/virt_mem_capture.cmx \ + ../lib/virt_mem.cmx diff --git a/mem/virt_mem_main.ml b/mem/virt_mem_main.ml index 78c7ab7..c2255b4 100644 --- a/mem/virt_mem_main.ml +++ b/mem/virt_mem_main.ml @@ -27,6 +27,7 @@ * files. *) let _ = Virt_mem_capture.summary +let _ = Virt_mem_dump.summary (* Call main program. *) let () = Virt_mem.main () -- 1.8.3.1