diff options
author | Alex Nelson <ajnelson@cs.ucsc.edu> | 2011-08-12 23:03:37 -0700 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2011-08-13 09:42:27 +0100 |
commit | e0b21193257f9784b28e931525f2a382a74775c6 (patch) | |
tree | 970d790ff798a915d8ec8b24b421dce551c107f2 /xml | |
parent | 98d83de9444c893fded2e92a3c454ffbda4bd4ad (diff) | |
download | hivex-e0b21193257f9784b28e931525f2a382a74775c6.tar.gz hivex-e0b21193257f9784b28e931525f2a382a74775c6.tar.xz hivex-e0b21193257f9784b28e931525f2a382a74775c6.zip |
Report last-modified time of hive root and nodes
The infrastructure for modified-time reporting has been essentially
unused. These changes report the registry time by treating the
time fields as Windows filetime fields stored in little-Endian
(which means they can be treated as a single 64-bit little-Endian
integer).
This patch adds to the hivex ABI:
* int64_t hivex_last_modified (hive_h *)
* int64_t hivex_node_timestamp (hive_h *, hive_node_h)
These two functions return the hive's last-modified time and
a particular node's last-modified time, respectively. Credit
to Richard Jones for the ABI suggestion, and for the tip on
Microsoft's filetime time span.
hivexml employs these two functions to produce mtime elements
for a hive and all of its nodes, producing ISO-8601 formatted
time.
Signed-off-by: Alex Nelson <ajnelson@cs.ucsc.edu>
A lot of code cleanup by RWMJ.
Diffstat (limited to 'xml')
-rw-r--r-- | xml/hivexml.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/xml/hivexml.c b/xml/hivexml.c index 90cb22b..2967ac9 100644 --- a/xml/hivexml.c +++ b/xml/hivexml.c @@ -25,6 +25,7 @@ #include <inttypes.h> #include <unistd.h> #include <errno.h> +#include <time.h> #include <libxml/xmlwriter.h> @@ -39,6 +40,8 @@ //#define N_(str) str #endif +static char *filetime_to_8601 (int64_t windows_ticks); + /* Callback functions. */ static int node_start (hive_h *, void *, hive_node_h, const char *name); static int node_end (hive_h *, void *, hive_node_h, const char *name); @@ -124,6 +127,17 @@ main (int argc, char *argv[]) XML_CHECK (xmlTextWriterStartDocument, (writer, NULL, "utf-8", NULL)); XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "hive")); + int64_t hive_mtime = hivex_last_modified (h); + if (hive_mtime >= 0) { + char *timebuf = filetime_to_8601 (hive_mtime); + if (timebuf) { + XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "mtime")); + XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST timebuf)); + XML_CHECK (xmlTextWriterEndElement, (writer)); + free (timebuf); + } + } + if (hivex_visit (h, &visitor, sizeof visitor, writer, visit_flags) == -1) { perror (argv[optind]); exit (EXIT_FAILURE); @@ -141,12 +155,66 @@ main (int argc, char *argv[]) exit (EXIT_SUCCESS); } +/* Convert Windows filetime to ISO 8601 format. + * http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux/6161842#6161842 + * + * Source for time_t->char* conversion: Fiwalk version 0.6.14's + * fiwalk.cpp. + * + * The caller should free the returned buffer. + */ + +#define WINDOWS_TICK 10000000LL +#define SEC_TO_UNIX_EPOCH 11644473600LL +#define TIMESTAMP_BUF_LEN 32 + +static char * +filetime_to_8601 (int64_t windows_ticks) +{ + char *ret; + time_t t; + struct tm *tm; + + t = windows_ticks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH; + tm = gmtime (&t); + if (tm == NULL) + return NULL; + + ret = malloc (TIMESTAMP_BUF_LEN); + if (ret == NULL) { + perror ("malloc"); + exit (EXIT_FAILURE); + } + + if (strftime (ret, TIMESTAMP_BUF_LEN, "%FT%TZ", tm) == 0) { + perror ("strftime"); + exit (EXIT_FAILURE); + } + + return ret; +} + static int node_start (hive_h *h, void *writer_v, hive_node_h node, const char *name) { + int64_t last_modified; + char *timebuf; + xmlTextWriterPtr writer = (xmlTextWriterPtr) writer_v; XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "node")); XML_CHECK (xmlTextWriterWriteAttribute, (writer, BAD_CAST "name", BAD_CAST name)); + + last_modified = hivex_node_timestamp (h, node); + if (last_modified >= 0) { + timebuf = filetime_to_8601 (last_modified); + if (timebuf) { + XML_CHECK (xmlTextWriterStartElement, (writer, BAD_CAST "mtime")); + XML_CHECK (xmlTextWriterWriteString, (writer, BAD_CAST timebuf)); + XML_CHECK (xmlTextWriterEndElement, (writer)); + free (timebuf); + } + } + return 0; } |