As the title says.
* Makefile.in: Add rules to build, but not install,
rebase-dump.exe.
* rebase-db.h: Declare new dump_rebasedb* functions.
* rebase-db.c (dump_rebasedb_header): New function.
(dump_rebasedb_entry): New function.
(dump_rebasedb): New function.
* rebase-dump.c: New file.
--
Chuck
? rebase-dump.c
Index: Makefile.in
===================================================================
RCS file: /cvs/cygwin-apps/rebase/Makefile.in,v
retrieving revision 1.7
diff -u -p -r1.7 Makefile.in
--- Makefile.in 29 Jul 2011 13:17:44 -0000 1.7
+++ Makefile.in 29 Jul 2011 13:54:45 -0000
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.7 2011/07/29 13:17:44 cwilson Exp $
+# $Id: Makefile.in,v 1.6 2011/07/21 19:10:04 corinna Exp $
# @configure_input@
# Makefile for rebase
@@ -77,6 +77,9 @@ LIBIMAGEHELPER = imagehelper/libimagehel
REBASE_OBJS = rebase.$(O) rebase-db.$(O) $(LIBOBJS)
REBASE_LIBS = $(LIBIMAGEHELPER)
+REBASE_DUMP_OBJS = rebase-dump.$(O) rebase-db.$(O) $(LIBOBJS)
+REBASE_DUMP_LIBS =
+
PEFLAGS_OBJS = peflags.$(O) $(LIBOBJS)
PEFLAGS_LIBS =
@@ -86,7 +89,7 @@ SRC_DISTFILES = aclocal.m4 configure.ac
build-aux/config.guess build-aux/config.sub \
build-aux/install-sh getopt.h_ getopt_long.c
-all: libimagehelper rebase$(EXEEXT) \
+all: libimagehelper rebase$(EXEEXT) rebase-dump$(EXEEXT) \
peflags$(EXEEXT) rebaseall peflagsall
libimagehelper:
@@ -99,6 +102,11 @@ rebase.$(O):: rebase.c rebase-db.h Makef
rebase-db.$(O):: rebase-db.c rebase-db.h Makefile
+rebase-dump$(EXEEXT): $(REBASE_DUMP_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(REBASE_DUMP_OBJS) $(REBASE_DUMP_LIBS)
+
+rebase-dump.$(O):: rebase-dump.c rebase-db.h Makefile
+
peflags$(EXEEXT): $(PEFLAGS_OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PEFLAGS_OBJS)
@@ -182,7 +190,8 @@ dist: srcdist
.PHONY: clean
clean:
- $(RM) *.$(O) rebase$(EXEEXT) peflags$(EXEEXT) *.tmp
+ $(RM) *.$(O) *.tmp
+ $(RM) rebase$(EXEEXT) peflags$(EXEEXT) rebase-dump$(EXEEXT)
$(RM) rebaseall peflagsall
.PHONY: realclean
Index: rebase-db.c
===================================================================
RCS file: /cvs/cygwin-apps/rebase/rebase-db.c,v
retrieving revision 1.1
diff -u -p -r1.1 rebase-db.c
--- rebase-db.c 29 Jul 2011 13:17:44 -0000 1.1
+++ rebase-db.c 29 Jul 2011 13:54:45 -0000
@@ -18,6 +18,13 @@
*/
#include "rebase-db.h"
+#if defined(__MSYS__)
+/* MSYS has no inttypes.h */
+# define PRIx64 "llx"
+#else
+# include <inttypes.h>
+#endif
+
const char IMG_INFO_MAGIC[4] = "rBiI";
const ULONG IMG_INFO_VERSION = 1;
@@ -40,3 +47,84 @@ img_info_name_cmp (const void *a, const
return strcmp (((img_info_t *) a)->name, ((img_info_t *) b)->name);
}
+void
+dump_rebasedb_header (FILE *f, img_info_hdr_t const *h)
+{
+ if (h == NULL)
+ {
+ fprintf (f, "Rebase DB Header is null\n");
+ return;
+ }
+
+ fprintf (f,
+ "Header\n"
+ " magic : %c%c%c%c\n"
+ " machine: %s\n"
+ " version: %d\n"
+ " base : 0x%0*" PRIx64 "\n"
+ " offset : 0x%08lx\n"
+ " downflg: %s\n"
+ " count : %ld\n",
+ h->magic[0], h->magic[1], h->magic[2], h->magic[3],
+ (h->machine == IMAGE_FILE_MACHINE_I386
+ ? "i386"
+ : (h->machine == IMAGE_FILE_MACHINE_AMD64
+ ? "x86_64"
+ : "unknown")),
+ h->version,
+ (h->machine == IMAGE_FILE_MACHINE_I386 ? 8 : 12),
+ h->base,
+ h->offset,
+ (h->down_flag ? "true" : "false"),
+ h->count);
+}
+
+void
+dump_rebasedb_entry (FILE *f,
+ img_info_hdr_t const *h,
+ img_info_t const *entry)
+{
+ if (h == NULL)
+ {
+ fprintf (f, "Rebase DB Header is null\n");
+ return;
+ }
+ if (entry == NULL)
+ {
+ fprintf (f, "Rebase DB Entry is null\n");
+ return;
+ }
+ fprintf (f,
+ "%-*s base 0x%0*" PRIx64 " size 0x%08lx slot 0x%08lx %c\n",
+ h->machine == IMAGE_FILE_MACHINE_I386 ? 45 : 41,
+ entry->name,
+ h->machine == IMAGE_FILE_MACHINE_I386 ? 8 : 12,
+ entry->base,
+ entry->size,
+ entry->slot_size,
+ entry->flag.needs_rebasing ? '*' : ' ');
+}
+
+void
+dump_rebasedb (FILE *f, img_info_hdr_t const *h,
+ img_info_t const *list, unsigned int sz)
+{
+ unsigned int i;
+ if (h == NULL)
+ {
+ fprintf (f, "Rebase DB Header is null\n");
+ return;
+ }
+ if (list == NULL)
+ {
+ fprintf (f, "Rebase DB List is null\n");
+ return;
+ }
+
+ dump_rebasedb_header (stdout, h);
+ for (i = 0; i < sz ; ++i)
+ {
+ dump_rebasedb_entry (stdout, h, &(list[i]));
+ }
+}
+
Index: rebase-db.h
===================================================================
RCS file: /cvs/cygwin-apps/rebase/rebase-db.h,v
retrieving revision 1.1
diff -u -p -r1.1 rebase-db.h
--- rebase-db.h 29 Jul 2011 13:17:44 -0000 1.1
+++ rebase-db.h 29 Jul 2011 13:54:45 -0000
@@ -20,6 +20,7 @@
#define REBASE_DB_H
#include <windows.h>
+#include <stdio.h>
#define roundup(x,y) ((((x) + ((y) - 1)) / (y)) * (y))
#define roundup2(x,y) (((x) + (y) - 1) & ~((y) - 1))
@@ -65,6 +66,12 @@ typedef struct _img_info
int img_info_cmp (const void *a, const void *b);
int img_info_name_cmp (const void *a, const void *b);
+void dump_rebasedb_header (FILE *f, img_info_hdr_t const *h);
+void dump_rebasedb_entry (FILE *f, img_info_hdr_t const *h,
+ img_info_t const *entry);
+void dump_rebasedb (FILE *f, img_info_hdr_t const *h,
+ img_info_t const *list, unsigned int sz);
+
#ifdef __cplusplus
}
#endif
/*
* Copyright (c) 2011 Charles Wilson
*
* 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, see <http://www.gnu.org/licenses/>.
*
* See the COPYING file for full license information.
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(__CYGWIN__) || defined(__MSYS__)
#include <sys/cygwin.h>
#endif
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
#include <getopt.h>
#include <string.h>
#if defined(__MSYS__)
/* MSYS has no inttypes.h */
# define PRIx64 "llx"
#else
# include <inttypes.h>
#endif
#include <errno.h>
#include <windows.h>
#include "rebase-db.h"
BOOL load_image_info ();
void parse_args (int argc, char *argv[]);
void usage ();
void help ();
void version ();
int args_index = 0;
BOOL verbose = FALSE;
BOOL quiet = FALSE;
const char *progname;
img_info_hdr_t hdr;
img_info_t *img_info_list = NULL;
unsigned int img_info_size = 0;
unsigned int img_info_rebase_start = 0;
unsigned int img_info_max_size = 0;
char *db_file = NULL;
void
gen_progname (const char *arg0)
{
char *p;
p = strrchr (arg0, '/');
if (!p)
p = strrchr (arg0, '\\');
progname = p ? p + 1 : arg0;
if ((p = strrchr (progname, '.')) && !strcmp (p, ".exe"))
*p = 0;
}
int
main (int argc, char *argv[])
{
setlocale (LC_ALL, "");
gen_progname (argv[0]);
parse_args (argc, argv);
if (args_index != argc - 1)
{
fprintf (stderr, "%s: no database file specified\n",
progname);
usage ();
return 1;
}
db_file = strdup (argv[args_index]);
if (load_image_info () < 0)
return 2;
/* Nothing to do? */
if (img_info_size == 0)
return 0;
dump_rebasedb (stdout, &hdr, img_info_list, img_info_size);
return 0;
}
int
load_image_info ()
{
int fd;
int ret = 0;
int i;
fd = open (db_file, O_RDONLY | O_BINARY);
if (fd < 0)
{
fprintf (stderr, "%s: failed to open rebase database \"%s\":\n%s\n",
progname, db_file, strerror (errno));
return -1;
}
/* First read the header. */
if (read (fd, &hdr, sizeof hdr) < 0)
{
fprintf (stderr, "%s: failed to read rebase database \"%s\":\n%s\n",
progname, db_file, strerror (errno));
close (fd);
return -1;
}
if (verbose)
printf ("== read %u (0x%08x) bytes (database header)\n",
sizeof hdr, sizeof hdr);
/* Check the header. */
if (memcmp (hdr.magic, IMG_INFO_MAGIC, 4) != 0)
{
fprintf (stderr, "%s: \"%s\" is not a valid rebase database.\n",
progname, db_file);
close (fd);
return -1;
}
if (verbose)
{
dump_rebasedb_header (stdout, &hdr);
}
if (hdr.machine != IMAGE_FILE_MACHINE_I386 &&
hdr.machine != IMAGE_FILE_MACHINE_AMD64)
{
fprintf (stderr, "%s: \"%s\" is a database file for a machine type\n"
"I don't know about.", progname, db_file);
close (fd);
return -1;
}
if (hdr.version != IMG_INFO_VERSION)
{
fprintf (stderr, "%s: \"%s\" is a version %u rebase database.\n"
"I can only handle versions up to %lu.\n",
progname, db_file, hdr.version, IMG_INFO_VERSION);
close (fd);
return -1;
}
img_info_size = hdr.count;
/* Allocate memory for the image list. */
if (ret == 0)
{
img_info_max_size = roundup (img_info_size, 100);
img_info_list = (img_info_t *) calloc (img_info_max_size,
sizeof (img_info_t));
if (!img_info_list)
{
fprintf (stderr, "%s: Out of memory.\n", progname);
ret = -1;
}
}
/* Now read the list. */
if (ret == 0
&& read (fd, img_info_list, img_info_size * sizeof (img_info_t)) < 0)
{
fprintf (stderr, "%s: failed to read rebase database \"%s\":\n%s\n",
progname, db_file, strerror (errno));
ret = -1;
}
if (ret == 0 && verbose)
{
printf ("== read %u (0x%08x) bytes (database w/o strings)\n",
img_info_size * sizeof (img_info_t),
img_info_size * sizeof (img_info_t));
}
/* Make sure all pointers are NULL (also dump db as read) */
if (ret == 0)
{
if (verbose)
printf ("---- database records without strings ----\n");
for (i = 0; i < img_info_size; ++i)
{
img_info_list[i].name = NULL;
if (verbose)
printf ("%03d: base 0x%0*" PRIx64 " size 0x%08lx slot 0x%08lx
namesize %4ld %c\n",
i,
hdr.machine == IMAGE_FILE_MACHINE_I386 ? 8 : 12,
img_info_list[i].base,
img_info_list[i].size,
img_info_list[i].slot_size,
img_info_list[i].name_size,
img_info_list[i].flag.needs_rebasing ? '*' : ' ');
}
}
/* Eventually read the strings. */
if (ret == 0)
{
if (verbose)
printf ("---- database strings ----\n");
for (i = 0; i < img_info_size; ++i)
{
img_info_list[i].name = (char *)
calloc (img_info_list[i].name_size,
sizeof(char));
if (!img_info_list[i].name)
{
fprintf (stderr, "%s: Out of memory.\n", progname);
ret = -1;
break;
}
if (read (fd, (void *)img_info_list[i].name,
(size_t) img_info_list[i].name_size) < 0)
{
fprintf (stderr, "%s: failed to read rebase database \"%s\": "
"%s\n", progname, db_file, strerror (errno));
ret = -1;
break;
}
else if (verbose)
{
printf ("%03d: namesize %4ld (0x%04lx) %s\n", i,
img_info_list[i].name_size,
img_info_list[i].name_size,
img_info_list[i].name);
}
}
}
close (fd);
/* On failure, free all allocated memory and set list pointer to NULL. */
if (ret < 0)
{
for (i = 0; i < img_info_size && img_info_list[i].name; ++i)
free (img_info_list[i].name);
free (img_info_list);
img_info_list = NULL;
img_info_size = 0;
img_info_max_size = 0;
}
return ret;
}
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"usage", no_argument, NULL, 'h'},
{"quiet", no_argument, NULL, 'q'},
{"usage", no_argument, NULL, 'h'},
{"verbose", no_argument, NULL, 'v'},
{"version", no_argument, NULL, 'V'},
{NULL, no_argument, NULL, 0 }
};
static const char *short_options = "hqvV";
void
parse_args (int argc, char *argv[])
{
int opt = 0;
while ((opt = getopt_long (argc, argv, short_options, long_options, NULL))
!= -1)
{
switch (opt)
{
case 'q':
quiet = TRUE;
break;
case 'v':
verbose = TRUE;
break;
case 'h':
help ();
exit (1);
break;
case 'V':
version ();
exit (1);
break;
default:
usage ();
exit (1);
break;
}
}
args_index = optind;
}
void
usage ()
{
fprintf (stderr,
"usage: %s [-hqvV] dbfile\n"
" %s --help or --usage for full help text\n",
progname, progname);
}
void
help ()
{
printf ("\
Usage: %s [OPTIONS] [FILE]n\
Dumps the rebase database file in readable format.\n\
-q, --quiet Be quiet about non-critical issues.\n\
-v, --verbose Print some debug output.\n\
-V, --version Print version info and exit.\n\
-h, --help, --usage This help.\n",
progname);
}
void
version ()
{
fprintf (stderr, "rebase-dump version %s (imagehelper version %s)\n",
VERSION, LIB_VERSION);
fprintf (stderr, "Copyright (c) 2011 Charles Wilson\n");
}