Index: trunk/Makefile.in
===================================================================
--- trunk/Makefile.in	(revision 47)
+++ trunk/Makefile.in	(revision 48)
@@ -1629,5 +1629,5 @@
 samhain_stealth.o: $(srcsrc)/samhain_stealth.c Makefile config_xor.h 
 encode.o: $(srcsrc)/encode.c Makefile 
-sstrip.o: $(srcsrc)/sstrip.c Makefile 
+sstrip.o: $(srcsrc)/sstrip.c Makefile config.h 
 trustfile.o: $(srcsrc)/trustfile.c Makefile config_xor.h $(srcinc)/sh_calls.h $(srcinc)/slib.h $(srcinc)/sh_static.h 
 exepack.o: $(srcsrc)/exepack.c Makefile config.h $(srcinc)/minilzo.h $(srcinc)/exepack.data 
Index: trunk/configure.ac
===================================================================
--- trunk/configure.ac	(revision 47)
+++ trunk/configure.ac	(revision 48)
@@ -13,5 +13,5 @@
 dnl start
 dnl
-AM_INIT_AUTOMAKE(samhain, 2.2.1a)
+AM_INIT_AUTOMAKE(samhain, 2.2.1b)
 AC_CANONICAL_HOST
 
@@ -198,4 +198,5 @@
 	regex.h glob.h \
 	linux/ext2_fs.h ext2fs/ext2_fs.h \
+	elf.h linux/elf.h \
 	paths.h arpa/nameser.h arpa/nameser_compat.h,
 	[],
Index: trunk/depend.dep
===================================================================
--- trunk/depend.dep	(revision 47)
+++ trunk/depend.dep	(revision 48)
@@ -40,5 +40,5 @@
 samhain_stealth.o: $(srcsrc)/samhain_stealth.c Makefile config_xor.h 
 encode.o: $(srcsrc)/encode.c Makefile 
-sstrip.o: $(srcsrc)/sstrip.c Makefile 
+sstrip.o: $(srcsrc)/sstrip.c Makefile config.h 
 trustfile.o: $(srcsrc)/trustfile.c Makefile config_xor.h $(srcinc)/sh_calls.h $(srcinc)/slib.h $(srcinc)/sh_static.h 
 exepack.o: $(srcsrc)/exepack.c Makefile config.h $(srcinc)/minilzo.h $(srcinc)/exepack.data 
Index: trunk/depend.sum
===================================================================
--- trunk/depend.sum	(revision 47)
+++ trunk/depend.sum	(revision 48)
@@ -1,1 +1,1 @@
-2018699483
+896592903
Index: trunk/docs/Changelog
===================================================================
--- trunk/docs/Changelog	(revision 47)
+++ trunk/docs/Changelog	(revision 48)
@@ -1,6 +1,9 @@
-2.2.1a:
+2.2.1b (20-06-2006):
+	* fix compile error on SuSE 10.1 (reported by Leonhard Maylein)
+
+2.2.1a (15-06-2006):
 	* fix compile error on i686/MacOS X (reported by Andreas Neth)
 
-2.2.1:
+2.2.1 (13-06-2006):
 	* fix gcc 4 warnings and build failure on x86_64 (debian bug #370808)
 	* fix compiling with Oracle (noticed by Colapinto Giovanni)
@@ -23,5 +26,5 @@
 	* fix manual version in spec file, first noticed by Imre Gergely
 	
-2.2.0:
+2.2.0 (01-05-2006):
 	* patch by Jim Simmons for samhainadmin.pl.in
 	* fix testsuite portability problems
Index: trunk/src/sstrip.c
===================================================================
--- trunk/src/sstrip.c	(revision 47)
+++ trunk/src/sstrip.c	(revision 48)
@@ -3,5 +3,7 @@
  */
 
-/* #include "config_xor.h" */ 
+/* Modified for portability and 64bit/32bit elf executables, Rainer Wichmann */
+ 
+#include "config.h" 
 
 #include	<stdio.h>
@@ -14,13 +16,15 @@
 #if !defined(__ia64)  && !defined(__ia64__)  && !defined(__itanium__) &&  \
     !defined(__alpha) && !defined(__alpha__) && \
-    (defined(__linux__) || defined(__FreeBSD__)) && \
-    (defined(__i386__)  || defined(__i386) || defined(i386))
+    (defined(HAVE_ELF_H) || defined(HAVE_LINUX_ELF_H)) && \
+    (defined(__linux__)  || defined(__FreeBSD__)) && \
+    (defined(__i386__)   || defined(__i386) || defined(i386))
 
 /* || defined(__sun) || defined(__sun__) || defined(sun) */
 
-#if defined(__linux__)
+
+#if defined(HAVE_ELF_H)
+#include        <elf.h>
+#else
 #include        <linux/elf.h>
-#else
-#include        <elf.h>
 #endif
 
@@ -30,11 +34,12 @@
 #endif
 
-#if ELF_CLASS == ELFCLASS32
-#define Elf_Ehdr        Elf32_Ehdr
-#define Elf_Phdr        Elf32_Phdr
-#else
-#define Elf_Ehdr        Elf64_Ehdr
-#define Elf_Phdr        Elf64_Phdr
-#endif
+#ifndef ELFCLASS32
+#define ELFCLASS32      1               /* 32-bit objects */
+#endif
+#ifndef ELFCLASS64
+#define ELFCLASS64      2               /* 64-bit objects */
+#endif
+
+
 
 /* The name of the program.
@@ -65,5 +70,5 @@
  * munging.
  */
-static int readelfheader(int fd, Elf_Ehdr *ehdr)
+static int readelfheader_32(int fd, Elf32_Ehdr *ehdr)
 {
     errno = 0;
@@ -81,20 +86,25 @@
     /* Compare the file's class and endianness with the program's.
      */
+#ifdef ELF_DATA
     if (ehdr->e_ident[EI_DATA] != ELF_DATA)
 	return err("ELF file has different endianness.");
-    if (ehdr->e_ident[EI_CLASS] != ELF_CLASS)
-	return err("ELF file has different word size.");
+#endif
+
+    if (ehdr->e_ident[EI_CLASS] != ELFCLASS32)
+	return FALSE;
 
     /* Check the target architecture.
      */
+#ifdef ELF_ARCH
     if (ehdr->e_machine != ELF_ARCH)
 	return err("ELF file created for different architecture.");
+#endif
 
     /* Verify the sizes of the ELF header and the program segment
      * header table entries.
      */
-    if (ehdr->e_ehsize != sizeof(Elf_Ehdr))
+    if (ehdr->e_ehsize != sizeof(Elf32_Ehdr))
 	return err("unrecognized ELF header size.");
-    if (ehdr->e_phentsize != sizeof(Elf_Phdr))
+    if (ehdr->e_phentsize != sizeof(Elf32_Phdr))
 	return err("unrecognized program segment header size.");
 
@@ -107,7 +117,76 @@
 }
 
+static int readelfheader_64(int fd, Elf64_Ehdr *ehdr)
+{
+    errno = 0;
+
+    if (lseek(fd, 0, SEEK_SET))
+	return ferr("could not rewind file");
+
+    if (read(fd, ehdr, sizeof *ehdr) != sizeof *ehdr)
+	return ferr("missing or incomplete ELF header.");
+
+    /* Check the ELF signature.
+     */
+    if (!(ehdr->e_ident[EI_MAG0] == ELFMAG0 &&
+	  ehdr->e_ident[EI_MAG1] == ELFMAG1 &&
+	  ehdr->e_ident[EI_MAG2] == ELFMAG2 &&
+	  ehdr->e_ident[EI_MAG3] == ELFMAG3))
+	return err("missing ELF signature.");
+
+    /* Compare the file's class and endianness with the program's.
+     */
+#ifdef ELF_DATA
+    if (ehdr->e_ident[EI_DATA] != ELF_DATA)
+	return err("ELF file has different endianness.");
+#endif
+
+    if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
+	return err("ELF file has different word size.");
+
+    /* Check the target architecture.
+     */
+#ifdef ELF_ARCH
+    if (ehdr->e_machine != ELF_ARCH)
+	return err("ELF file created for different architecture.");
+#endif
+
+    /* Verify the sizes of the ELF header and the program segment
+     * header table entries.
+     */
+    if (ehdr->e_ehsize != sizeof(Elf64_Ehdr))
+	return err("unrecognized ELF header size.");
+    if (ehdr->e_phentsize != sizeof(Elf64_Phdr))
+	return err("unrecognized program segment header size.");
+
+    /* Finally, check the file type.
+     */
+    if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+	return err("not an executable or shared-object library.");
+
+    return TRUE;
+}
+
 /* readphdrtable() loads the program segment header table into memory.
  */
-static int readphdrtable(int fd, Elf_Ehdr const *ehdr, Elf_Phdr **phdrs)
+static int readphdrtable_32(int fd, Elf32_Ehdr const *ehdr, Elf32_Phdr **phdrs)
+{
+    size_t	size;
+
+    if (!ehdr->e_phoff || !ehdr->e_phnum)
+	return err("ELF file has no program header table.");
+
+    size = ehdr->e_phnum * sizeof **phdrs;
+    if (!(*phdrs = malloc(size)))
+	return err("Out of memory!");
+
+    errno = 0;
+    if (read(fd, *phdrs, size) != (ssize_t)size)
+	return ferr("missing or incomplete program segment header table.");
+
+    return TRUE;
+}
+
+static int readphdrtable_64(int fd, Elf64_Ehdr const *ehdr, Elf64_Phdr **phdrs)
 {
     size_t	size;
@@ -132,10 +211,39 @@
  * is executing, and thus can be safely discarded.)
  */
-static int getmemorysize(Elf_Ehdr const *ehdr, Elf_Phdr const *phdrs,
-			 unsigned long *newsize)
-{
-    Elf_Phdr   const   *phdr;
+static int getmemorysize_32(Elf32_Ehdr const *ehdr, Elf32_Phdr const *phdrs,
+			    unsigned long *newsize)
+{
+    Elf32_Phdr   const   *phdr;
     unsigned long	size, n;
     int			i;
+
+    /* Start by setting the size to include the ELF header and the
+     * complete program segment header table.
+     */
+    size = ehdr->e_phoff + ehdr->e_phnum * sizeof *phdrs;
+    if (size < sizeof *ehdr)
+	size = sizeof *ehdr;
+
+    /* Then keep extending the size to include whatever data the
+     * program segment header table references.
+     */
+    for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) {
+	if (phdr->p_type != PT_NULL) {
+	    n = phdr->p_offset + phdr->p_filesz;
+	    if (n > size)
+		size = n;
+	}
+    }
+
+    *newsize = size;
+    return TRUE;
+}
+
+static int getmemorysize_64(Elf64_Ehdr const *ehdr, Elf64_Phdr const *phdrs,
+			    unsigned long *newsize)
+{
+    Elf64_Phdr   const   *phdr;
+    unsigned long  	  size, n;
+    int			  i;
 
     /* Start by setting the size to include the ELF header and the
@@ -196,9 +304,9 @@
  * included truncated bytes at the end of the file.
  */
-static int modifyheaders(Elf_Ehdr *ehdr, Elf_Phdr *phdrs,
-			 unsigned long newsize)
-{
-    Elf_Phdr   *phdr;
-    int		i;
+static int modifyheaders_32(Elf32_Ehdr *ehdr, Elf32_Phdr *phdrs,
+			    unsigned long newsize)
+{
+    Elf32_Phdr   *phdr;
+    int	 	  i;
 
     /* If the section header table is gone, then remove all references
@@ -228,9 +336,41 @@
 }
 
+static int modifyheaders_64(Elf64_Ehdr *ehdr, Elf64_Phdr *phdrs,
+			    unsigned long newsize)
+{
+    Elf64_Phdr   *phdr;
+    int	 	  i;
+
+    /* If the section header table is gone, then remove all references
+     * to it in the ELF header.
+     */
+    if (ehdr->e_shoff >= newsize) {
+	ehdr->e_shoff = 0;
+	ehdr->e_shnum = 0;
+	ehdr->e_shentsize = 0;
+	ehdr->e_shstrndx = 0;
+    }
+
+    /* The program adjusts the file size of any segment that was
+     * truncated. The case of a segment being completely stripped out
+     * is handled separately.
+     */
+    for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) {
+	if (phdr->p_offset >= newsize) {
+	    phdr->p_offset = newsize;
+	    phdr->p_filesz = 0;
+	} else if (phdr->p_offset + phdr->p_filesz > newsize) {
+	    phdr->p_filesz = newsize - phdr->p_offset;
+	}
+    }
+
+    return TRUE;
+}
+
 /* commitchanges() writes the new headers back to the original file
  * and sets the file to its new size.
  */
-static int commitchanges(int fd, Elf_Ehdr const *ehdr, Elf_Phdr *phdrs,
-			 unsigned long newsize)
+static int commitchanges_32(int fd, Elf32_Ehdr const *ehdr, Elf32_Phdr *phdrs,
+			    unsigned long newsize)
 {
     size_t	n;
@@ -275,4 +415,48 @@
 }
 
+static int commitchanges_64(int fd, Elf64_Ehdr const *ehdr, Elf64_Phdr *phdrs,
+			    unsigned long newsize)
+{
+    size_t	n;
+
+    /* Save the changes to the ELF header, if any.
+     */
+    if (lseek(fd, 0, SEEK_SET))
+	return ferr("could not rewind file");
+    errno = 0;
+    if (write(fd, ehdr, sizeof *ehdr) != sizeof *ehdr)
+	return err("could not modify file");
+
+    /* Save the changes to the program segment header table, if any.
+     */
+    if (lseek(fd, ehdr->e_phoff, SEEK_SET) == (off_t)-1) {
+	err("could not seek in file.");
+	goto warning;
+    }
+    n = ehdr->e_phnum * sizeof *phdrs;
+    if (write(fd, phdrs, n) != (ssize_t)n) {
+	err("could not write to file");
+	goto warning;
+    }
+
+    /* Eleventh-hour sanity check: don't truncate before the end of
+     * the program segment header table.
+     */
+    if (newsize < ehdr->e_phoff + n)
+	newsize = ehdr->e_phoff + n;
+
+    /* Chop off the end of the file.
+     */
+    if (ftruncate(fd, newsize)) {
+	err("could not resize file");
+	goto warning;
+    }
+
+    return TRUE;
+
+  warning:
+    return err("ELF file may have been corrupted!");
+}
+
 /* main() loops over the cmdline arguments, leaving all the real work
  * to the other functions.
@@ -281,6 +465,9 @@
 {
     int			fd;
-    Elf_Ehdr		ehdr;
-    Elf_Phdr	       *phdrs = NULL;
+    int                 is_32bit_elf;
+    Elf32_Ehdr		ehdr32;
+    Elf32_Phdr	       *phdrs32 = NULL;
+    Elf64_Ehdr		ehdr64;
+    Elf64_Phdr	       *phdrs64 = NULL;
     unsigned long	newsize;
     char	      **arg;
@@ -308,11 +495,31 @@
 	}
 
-	if (!(readelfheader(fd, &ehdr)			&&
-	      readphdrtable(fd, &ehdr, &phdrs)		&&
-	      getmemorysize(&ehdr, phdrs, &newsize)	&&
-	      truncatezeros(fd, &newsize)		&&
-	      modifyheaders(&ehdr, phdrs, newsize)	&&
-	      commitchanges(fd, &ehdr, phdrs, newsize)))
+	if (readelfheader_32(fd, &ehdr32)) {
+	  is_32bit_elf = TRUE;
+	} 
+	else if (readelfheader_64(fd, &ehdr64)) {
+	  is_32bit_elf = FALSE;
+	}
+	else {
+	  close(fd);
+	  return EXIT_FAILURE;
+	}
+
+	if (is_32bit_elf) {
+	  if (!(readphdrtable_32(fd, &ehdr32, &phdrs32)	        &&
+	      getmemorysize_32(&ehdr32, phdrs32, &newsize)	&&
+	      truncatezeros(fd, &newsize)		        &&
+	      modifyheaders_32(&ehdr32, phdrs32, newsize)	&&
+	      commitchanges_32(fd, &ehdr32, phdrs32, newsize)))
 	    ++failures;
+	} 
+	else {
+	  if (!(readphdrtable_64(fd, &ehdr64, &phdrs64)	        &&
+	      getmemorysize_64(&ehdr64, phdrs64, &newsize)	&&
+	      truncatezeros(fd, &newsize)		        &&
+	      modifyheaders_64(&ehdr64, phdrs64, newsize)	&&
+	      commitchanges_64(fd, &ehdr64, phdrs64, newsize)))
+	    ++failures;
+	}
 
 	close(fd);
