Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

ld-linux hooker

  • Loading branch information...
commit 9accf90a6340ee516126e93ff2492e4c7a32b1d1 0 parents
stephane duverger authored October 28, 2011
13  Makefile
... ...
@@ -0,0 +1,13 @@
  1
+all: ld-shatner interpatch
  2
+
  3
+obj.elf: obj.c
  4
+	gcc -fpie -c obj.c -o obj.o
  5
+	ld -pie obj.o -o $@ -e func
  6
+
  7
+ld-shatner: hooked.s ld-shatner.c obj.elf
  8
+	gcc hooked.s ld-shatner.c -o $@
  9
+
  10
+interpatch: interpatch.o
  11
+
  12
+clean:
  13
+	rm -f ld-shatner interpatch ld-hook.so obj.elf *.o
9  README
... ...
@@ -0,0 +1,9 @@
  1
+$ make clean all
  2
+$ cp /lib/ld-linux.so.2 .
  3
+$ cp /bin/ls .
  4
+$ ./ld-shatner ld-linux.so.2 obj.elf
  5
+$ sudo cp ld-hook.so /lib/
  6
+$ ./interpatch ls 
  7
+$ ./ls 
  8
+ld-hook <---------------------- output of obj.elf
  9
+[...]
111  hooked.s
... ...
@@ -0,0 +1,111 @@
  1
+.text
  2
+.globl shatner, payload
  3
+.type  shatner,"function"
  4
+.type  payload,"function"
  5
+
  6
+shatner:
  7
+	jmp 1f
  8
+__old_ld:
  9
+	.long 0  /* ld original entry point (from 0) */
  10
+__old_user:
  11
+	.long 0  /* location to store original user entry point (from 0) */
  12
+__inject_entry:  /* entry point of injected code (from 0) */
  13
+	.long 0
  14
+1:
  15
+	pushl $0
  16
+	push %eax
  17
+	lea 8(%esp), %eax
  18
+	push %edx
  19
+	push %ecx
  20
+	call __get_pc
  21
+__get_pc:
  22
+	pop %edx
  23
+	mov %edx, %ecx
  24
+	add $(payload_caller - __get_pc), %edx
  25
+	sub $(__get_pc - __old_user), %ecx
  26
+	push %ebx
  27
+	push %edi
  28
+	xor  %edi, %edi
  29
+fix_auxv: /* walk stack to find 2 NULL words (one ending argv, one ending envp) */
  30
+	mov (%eax), %ebx
  31
+	test %ebx, %ebx
  32
+	jnz next_word
  33
+	inc %edi
  34
+	cmp $2, %edi
  35
+	je  auxv_found
  36
+next_word:
  37
+	add $4, %eax
  38
+	jmp fix_auxv
  39
+
  40
+auxv_found: /* found second NULL word, start lokking for AUX_TYPE==ENTRY (9) */
  41
+	add $4, %eax
  42
+next_tag:
  43
+	cmp $9, (%eax)
  44
+	je  auxv_entry_tag_found
  45
+	add $8, %eax
  46
+	jmp next_tag
  47
+
  48
+auxv_entry_tag_found:
  49
+	add $4, %eax
  50
+	mov (%eax), %edi
  51
+	mov (%ecx), %ecx
  52
+	push %esi
  53
+	call __get_pc2
  54
+__get_pc2:
  55
+	pop %esi
  56
+	sub $((__get_pc2 - shatner)+52), %esi /* base address of ld in memory */
  57
+	add %esi, %ecx
  58
+	mov %edi, (%ecx) /* save user entry */
  59
+	mov %edx, (%eax) /* install new one */
  60
+
  61
+resume_ld:
  62
+	sub $(payload_caller - __old_ld), %edx
  63
+	mov (%edx), %edx
  64
+	add %esi, %edx  /* base + ld original entry */
  65
+	pop %esi
  66
+	pop %edi
  67
+	pop %ebx
  68
+	pop %ecx
  69
+	mov %edx, 8(%esp)
  70
+	pop %edx
  71
+	pop %eax
  72
+	ret
  73
+
  74
+payload_caller:
  75
+	call real_payload_caller
  76
+	push $0
  77
+	push %eax
  78
+	call __get_pc3
  79
+__get_pc3:
  80
+	pop %eax
  81
+	push %edx
  82
+	mov %eax, %edx
  83
+	sub $((__get_pc3 - shatner)+52), %eax /* base address of ld in memory */
  84
+	sub $(__get_pc3 - __old_user), %edx /* user offset */
  85
+	mov (%edx), %edx
  86
+	add %eax, %edx
  87
+	mov (%edx), %eax  /* original user entry */
  88
+	movl $0, (%edx)   /* clear place */
  89
+	mov %eax, 8(%esp)
  90
+	pop %edx
  91
+	pop %eax
  92
+	ret
  93
+real_payload_caller:
  94
+	push %eax
  95
+	call __get_pc4
  96
+__get_pc4:
  97
+	pop %eax
  98
+	push %edx
  99
+	mov %eax, %edx
  100
+	add $(payload - __get_pc4), %eax
  101
+	sub $(__get_pc4 - __inject_entry), %edx /* injected entry offset */
  102
+	mov (%edx), %edx
  103
+	add %edx, %eax
  104
+	call *%eax
  105
+	pop %edx
  106
+	pop %eax
  107
+	ret
  108
+
  109
+	.align 4
  110
+payload:
  111
+	nop
58  interpatch.c
... ...
@@ -0,0 +1,58 @@
  1
+#include <stdio.h>
  2
+#include <elf.h>
  3
+#include <sys/types.h>
  4
+#include <sys/stat.h>
  5
+#include <sys/mman.h>
  6
+#include <string.h>
  7
+#include <fcntl.h>
  8
+
  9
+#define LDNAME "/lib/ld-hook.so"
  10
+
  11
+int main(int argc, char **argv)
  12
+{
  13
+   Elf32_Ehdr	*e_hdr;
  14
+   Elf32_Phdr	*p_hdr;
  15
+   int		fd, i;
  16
+   off_t	fd_sz;
  17
+   uint32_t     len, old;
  18
+
  19
+   if (argc != 2)
  20
+   {
  21
+      printf("usage: %s <elf>\n", argv[0]);
  22
+      return -1;
  23
+   }
  24
+
  25
+   if ((fd = open(argv[1], O_RDWR)) == -1)
  26
+   {
  27
+      printf("can't open file %s\n", argv[1]);
  28
+      return -1;
  29
+   }
  30
+
  31
+   fd_sz = lseek(fd, 0, SEEK_END);
  32
+   lseek(fd, 0, SEEK_SET);
  33
+   e_hdr = (Elf32_Ehdr*)mmap(NULL, fd_sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  34
+   p_hdr = (Elf32_Phdr*)((uint32_t)e_hdr + e_hdr->e_phoff);
  35
+
  36
+   len = strlen(LDNAME)+1;
  37
+
  38
+   for (i=0 ; i<e_hdr->e_phnum ; i++, p_hdr++)
  39
+      if (p_hdr->p_type == PT_INTERP)
  40
+      {
  41
+	 if (p_hdr->p_filesz < len)
  42
+	 {
  43
+	    printf("not enough space to fix interp name (%d)\n", p_hdr->p_filesz);
  44
+	    return -1;
  45
+	 }
  46
+
  47
+	 old = p_hdr->p_filesz;
  48
+	 p_hdr->p_filesz = p_hdr->p_memsz = len;
  49
+	 memcpy((void*)((uint32_t)e_hdr+p_hdr->p_offset), LDNAME, len-1);
  50
+	 memset((void*)((uint32_t)e_hdr+p_hdr->p_offset+len-1), 0, old-len);
  51
+
  52
+	 /* XXX: should also fix section header ... */
  53
+      }
  54
+
  55
+   munmap((void*)e_hdr, fd_sz);
  56
+   close(fd);
  57
+   return 0;
  58
+}
363  ld-shatner.c
... ...
@@ -0,0 +1,363 @@
  1
+#include <stdio.h>
  2
+#include <elf.h>
  3
+#include <sys/types.h>
  4
+#include <sys/stat.h>
  5
+#include <sys/mman.h>
  6
+#include <string.h>
  7
+#include <fcntl.h>
  8
+
  9
+#define LDOUTFILE  "ld-hook.so"
  10
+
  11
+extern void shatner(void);
  12
+extern void payload(void);
  13
+
  14
+/*
  15
+** File-to-load constraints:
  16
+**  - pie
  17
+**  - no global variables (.data/.bss)
  18
+**  - no external symbols (.reloc*, .got.plt entries)
  19
+**
  20
+** $ gcc -fpie -c file.c -o file.o
  21
+** $ ld -pie -e your_function file.o -o file
  22
+*/
  23
+int load_code_from_file(char *fname, Elf32_Ehdr **fe, uint32_t *csz)
  24
+{
  25
+   Elf32_Ehdr	*e_hdr;
  26
+   Elf32_Phdr   *p_hdr;
  27
+   int		fd, i;
  28
+   off_t	fd_sz;
  29
+
  30
+   if ((fd = open(fname, O_RDONLY)) == -1)
  31
+   {
  32
+      printf("can't open file %s\n", fname);
  33
+      return -1;
  34
+   }
  35
+
  36
+   fd_sz = lseek(fd, 0, SEEK_END);
  37
+   lseek(fd, 0, SEEK_SET);
  38
+   e_hdr = (Elf32_Ehdr*)mmap(NULL, fd_sz, PROT_READ, MAP_PRIVATE, fd, 0);
  39
+   p_hdr = (Elf32_Phdr*)((uint32_t)e_hdr + e_hdr->e_phoff);
  40
+
  41
+   *fe = e_hdr;
  42
+   *csz = 0;
  43
+   for (i=0 ; i<e_hdr->e_phnum ; i++, p_hdr++)
  44
+      if (p_hdr->p_type == PT_LOAD)
  45
+	 *csz += p_hdr->p_memsz;
  46
+
  47
+   return 0;
  48
+}
  49
+
  50
+void inject_code_from_file(uint32_t base, uint32_t load, Elf32_Ehdr *e_hdr)
  51
+{
  52
+   Elf32_Phdr   *p_hdr;
  53
+   uint32_t     *fix, offset, diff;
  54
+   int		i;
  55
+
  56
+   p_hdr = (Elf32_Phdr*)((uint32_t)e_hdr + e_hdr->e_phoff);
  57
+
  58
+   printf("---> injecting code\n");
  59
+
  60
+   offset = load;
  61
+   for (i=0 ; i<e_hdr->e_phnum ; i++, p_hdr++)
  62
+   {
  63
+      if (p_hdr->p_type == PT_LOAD)
  64
+      {
  65
+   	 uint32_t loc = (uint32_t)e_hdr + p_hdr->p_offset;
  66
+   	 memcpy((void*)offset, (void*)loc, p_hdr->p_filesz);
  67
+	 offset += p_hdr->p_filesz;
  68
+
  69
+	 diff = p_hdr->p_memsz - p_hdr->p_filesz;
  70
+	 if (diff)
  71
+	 {
  72
+	    memset((void*)offset, 0, diff);
  73
+	    offset += diff;
  74
+	 }
  75
+      }
  76
+   }
  77
+
  78
+   /* give entry point */
  79
+   fix  = (uint32_t*)((uint32_t)base + 10);
  80
+   *fix = e_hdr->e_entry;
  81
+}
  82
+
  83
+/*
  84
+** check if section holding that reloc entry
  85
+** has file offset different from load addr
  86
+** in which case we may access out of file' size
  87
+*/
  88
+uint32_t reloc_lookup_section(Elf32_Ehdr *e_hdr, uint32_t offset)
  89
+{
  90
+   int        i;
  91
+   Elf32_Shdr *s_hdr = (Elf32_Shdr*)((uint32_t)e_hdr + e_hdr->e_shoff);
  92
+
  93
+   for (i=0 ; i<e_hdr->e_shnum ; i++, s_hdr++)
  94
+      if ((s_hdr->sh_type == SHT_PROGBITS) && (s_hdr->sh_flags & SHF_ALLOC))
  95
+	 if (offset >= s_hdr->sh_addr && offset < (s_hdr->sh_addr+s_hdr->sh_size))
  96
+	    return (s_hdr->sh_addr - s_hdr->sh_offset);
  97
+
  98
+   return 0;
  99
+}
  100
+
  101
+int main(int argc, char **argv)
  102
+{
  103
+   Elf32_Ehdr	*e_hdr_in, *e_hdr_out, *e_hdr_inj;
  104
+   Elf32_Phdr	*p_hdr_in, *p_hdr_out, *code_hdr, *data_hdr, *dyn_hdr;
  105
+   Elf32_Shdr   *s_hdr_out, *s_hdr_str_out;
  106
+   int		fd_in;
  107
+   int		fd_out;
  108
+   off_t	fd_in_sz, fd_out_sz;
  109
+   uint32_t     pltgot, *fix, msk, user_offset, base_block, hook_sz, inj_sz, over_sz;
  110
+   char         *s_str_out;
  111
+   int          i;
  112
+
  113
+   if (argc != 3)
  114
+   {
  115
+      printf("usage: %s <ld-linux.so> <pie.elf>\n", argv[0]);
  116
+      return -1;
  117
+   }
  118
+
  119
+   /* check input file */
  120
+   if ((fd_in = open(argv[1], O_RDONLY)) == -1)
  121
+   {
  122
+      printf("can't open file %s\n", argv[1]);
  123
+      return -1;
  124
+   }
  125
+
  126
+   fd_in_sz = lseek(fd_in, 0, SEEK_END);
  127
+   lseek(fd_in, 0, SEEK_SET);
  128
+   e_hdr_in = (Elf32_Ehdr*)mmap(NULL, fd_in_sz, PROT_READ, MAP_PRIVATE, fd_in, 0);
  129
+   p_hdr_in = (Elf32_Phdr*)((uint32_t)e_hdr_in + e_hdr_in->e_phoff);
  130
+
  131
+   /* load file to inject */
  132
+   if (load_code_from_file(argv[2], &e_hdr_inj, &inj_sz) == -1)
  133
+      return -1;
  134
+
  135
+   hook_sz = (uint32_t)payload - (uint32_t)shatner;
  136
+   over_sz = hook_sz + inj_sz;
  137
+
  138
+   /* build out file */
  139
+   if ((fd_out = open(LDOUTFILE, O_RDWR|O_CREAT|O_TRUNC, 0755)) == -1)
  140
+   {
  141
+      printf("can't open file "LDOUTFILE"\n");
  142
+      return -1;
  143
+   }
  144
+
  145
+   fd_out_sz = fd_in_sz + over_sz;
  146
+
  147
+   lseek(fd_out, fd_out_sz - 1, SEEK_SET);
  148
+   write(fd_out, "\x00", 1);
  149
+   lseek(fd_out, 0, SEEK_SET);
  150
+   e_hdr_out = (Elf32_Ehdr*)mmap(NULL, fd_out_sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd_out, 0);
  151
+
  152
+   /* copy elf hdr */
  153
+   uint32_t offset = (uint32_t)e_hdr_out;
  154
+   memcpy((void*)offset, (void*)e_hdr_in, e_hdr_in->e_ehsize);
  155
+
  156
+   /* install hook */
  157
+   offset += e_hdr_in->e_ehsize;
  158
+   memcpy((void*)offset, (void*)shatner, hook_sz);
  159
+
  160
+   base_block = offset;
  161
+
  162
+   /* save fixed ld entry point */
  163
+   fix = (uint32_t*)((uint32_t)base_block + 2);
  164
+   *fix = e_hdr_out->e_entry + over_sz;
  165
+
  166
+   /* inject external code */
  167
+   inject_code_from_file(base_block, offset+hook_sz, e_hdr_inj);
  168
+
  169
+   /* copy remaining */
  170
+   offset += over_sz;
  171
+   memcpy((void*)offset, (void*)e_hdr_in+e_hdr_in->e_ehsize, fd_in_sz - e_hdr_in->e_ehsize);
  172
+
  173
+   /*
  174
+   ** Fix Elf header
  175
+   */
  176
+   e_hdr_out->e_entry  = e_hdr_out->e_ehsize;
  177
+   e_hdr_out->e_phoff += over_sz;
  178
+   e_hdr_out->e_shoff += over_sz;
  179
+
  180
+   /*
  181
+   ** Fix Program headers
  182
+   */
  183
+   printf("p_hdr #%d\n", e_hdr_out->e_phnum);
  184
+   p_hdr_out = (Elf32_Phdr*)((uint32_t)e_hdr_out + e_hdr_out->e_phoff);
  185
+   code_hdr = (Elf32_Phdr*)0;
  186
+   data_hdr = (Elf32_Phdr*)0;
  187
+
  188
+   for (i=0 ; i<e_hdr_out->e_phnum ; i++, p_hdr_out++)
  189
+   {
  190
+      if (!p_hdr_out->p_memsz)
  191
+	 continue;
  192
+
  193
+      if (p_hdr_out->p_type == PT_LOAD && (p_hdr_out->p_flags & (PF_R|PF_X)) && i == 0)
  194
+      {
  195
+	 code_hdr = p_hdr_out;
  196
+	 code_hdr->p_filesz += over_sz;
  197
+	 code_hdr->p_memsz  += over_sz;
  198
+	 continue;
  199
+      }
  200
+
  201
+      if (p_hdr_out->p_type == PT_LOAD && (p_hdr_out->p_flags & (PF_R|PF_W)) && i == 1)
  202
+      {
  203
+	 data_hdr = p_hdr_out;
  204
+	 msk = data_hdr->p_align - 1;
  205
+      }
  206
+
  207
+      if (p_hdr_out->p_type == PT_DYNAMIC)
  208
+	 dyn_hdr = p_hdr_out;
  209
+
  210
+      printf("fixing phdr %d\n", i);
  211
+      p_hdr_out->p_offset += over_sz;
  212
+      p_hdr_out->p_vaddr  += over_sz;
  213
+      p_hdr_out->p_paddr  += over_sz;
  214
+   }
  215
+
  216
+   if (!code_hdr || !data_hdr || !dyn_hdr)
  217
+   {
  218
+      printf("bad program headers\n");
  219
+      return -1;
  220
+   }
  221
+
  222
+   /*
  223
+   ** Fix Section headers
  224
+   */
  225
+   s_hdr_out = (Elf32_Shdr*)((uint32_t)e_hdr_out + e_hdr_out->e_shoff);
  226
+   s_hdr_str_out = &s_hdr_out[e_hdr_out->e_shstrndx];
  227
+   s_str_out = (uint8_t*)e_hdr_out + s_hdr_str_out->sh_offset + over_sz;
  228
+   printf("s_hdr #%d | s_hdr_str 0x%x\n", e_hdr_out->e_shnum, s_str_out);
  229
+
  230
+   for (i=0 ; i<e_hdr_out->e_shnum ; i++, s_hdr_out++)
  231
+   {
  232
+      if (s_hdr_out->sh_size == 0)
  233
+	 continue;
  234
+
  235
+      s_hdr_out->sh_offset += over_sz;
  236
+
  237
+      if (s_hdr_out->sh_flags & SHF_ALLOC)
  238
+	 s_hdr_out->sh_addr += over_sz;
  239
+
  240
+      printf("\\_fix shdr %s addr 0x%x off 0x%x\n",
  241
+	     &s_str_out[s_hdr_out->sh_name], s_hdr_out->sh_addr, s_hdr_out->sh_offset);
  242
+
  243
+      /* fix .dynamic */
  244
+      if (s_hdr_out->sh_type == SHT_DYNAMIC)
  245
+      {
  246
+	 Elf32_Dyn *dyn_s = (Elf32_Dyn*)((uint32_t)e_hdr_out + s_hdr_out->sh_offset);
  247
+	 Elf32_Dyn *dyn   = dyn_s;
  248
+
  249
+	 while (dyn->d_tag != DT_NULL)
  250
+	 {
  251
+	    switch (dyn->d_tag)
  252
+	    {
  253
+	    case DT_PLTGOT:
  254
+	    case DT_JMPREL:
  255
+	    case DT_GNU_HASH:
  256
+	    case DT_HASH:
  257
+	    case DT_STRTAB:
  258
+	    case DT_SYMTAB:
  259
+	    case DT_REL:
  260
+	    case DT_RELA:
  261
+	    case DT_VERDEF:
  262
+	    case DT_VERSYM:
  263
+	       dyn->d_un.d_ptr += over_sz;
  264
+	       printf(" \\_fix 0x%x\n", dyn->d_un.d_ptr);
  265
+	       break;
  266
+	    case DT_SONAME:
  267
+	       printf(" \\_soname 0x%x\n", dyn->d_un.d_val);
  268
+	       break;
  269
+	    case DT_INIT_ARRAY:
  270
+	    case DT_FINI_ARRAY:
  271
+	       printf("!!!! WARNING need to patch ARRAY !!!!\n");
  272
+	       break;
  273
+	    }
  274
+
  275
+	    if (dyn->d_tag == DT_PLTGOT)
  276
+	    {
  277
+	       pltgot = dyn->d_un.d_ptr;
  278
+	       printf(" \\_found .got.plt @ 0x%x\n", pltgot);
  279
+	    }
  280
+
  281
+	    dyn++;
  282
+	 }
  283
+
  284
+	 /* compute user offset to save old user entry into .dynamic[NULL].d_un.d_ptr */
  285
+	 user_offset = ((code_hdr->p_memsz + msk) & (~msk)) + (dyn_hdr->p_vaddr & msk) + ((uint32_t)dyn - (uint32_t)dyn_s) + 4;
  286
+	 printf("computed user_offset 0x%x\n", user_offset);
  287
+
  288
+	 fix  = (uint32_t*)((uint32_t)base_block + 6);
  289
+	 *fix = user_offset;
  290
+      }
  291
+
  292
+      /* fix .dynsym */
  293
+      if (s_hdr_out->sh_type == SHT_DYNSYM)
  294
+      {
  295
+      	 Elf32_Sym *sym = (Elf32_Sym*)((uint32_t)e_hdr_out + s_hdr_out->sh_offset);
  296
+      	 uint32_t nr = s_hdr_out->sh_size/s_hdr_out->sh_entsize;
  297
+      	 int z;
  298
+      	 for (z=0 ; z<nr ; z++)
  299
+      	 {
  300
+	    if (sym->st_size)
  301
+	    {
  302
+	       sym->st_value += over_sz;
  303
+	       printf(" \\_fix 0x%x\n", sym->st_value);
  304
+	    }
  305
+      	    sym++;
  306
+      	 }
  307
+      }
  308
+
  309
+      /* fix .got.plt */
  310
+      if (s_hdr_out->sh_addr == pltgot)
  311
+      {
  312
+      	 uint32_t *got = (uint32_t*)((uint32_t)e_hdr_out + s_hdr_out->sh_offset);
  313
+      	 uint32_t nr = s_hdr_out->sh_size/s_hdr_out->sh_entsize;
  314
+      	 int z;
  315
+      	 for (z=0 ; z<nr ; z++)
  316
+      	 {
  317
+	    *got += over_sz;
  318
+	    printf(" \\_fix 0x%x\n", *got);
  319
+      	    got++;
  320
+      	 }
  321
+      }
  322
+   }
  323
+
  324
+   /*
  325
+   ** now that s_hdr are fixed, process reloc entries
  326
+   */
  327
+   s_hdr_out = (Elf32_Shdr*)((uint32_t)e_hdr_out + e_hdr_out->e_shoff);
  328
+   for (i=0 ; i<e_hdr_out->e_shnum ; i++, s_hdr_out++)
  329
+   {
  330
+      if (s_hdr_out->sh_type != SHT_REL)
  331
+	 continue;
  332
+
  333
+      printf("\\_reloc %s fix\n", &s_str_out[s_hdr_out->sh_name]);
  334
+
  335
+      Elf32_Rel *rel = (Elf32_Rel*)((uint32_t)e_hdr_out + s_hdr_out->sh_offset);
  336
+      uint32_t	 nr  = s_hdr_out->sh_size/s_hdr_out->sh_entsize;
  337
+      int	 z;
  338
+      for (z=0 ; z<nr ; z++)
  339
+      {
  340
+	 rel->r_offset += over_sz;
  341
+	 printf(" \\_fix 0x%x\n", rel->r_offset);
  342
+
  343
+	 if (ELF32_R_TYPE(rel->r_info) == R_386_RELATIVE)
  344
+	 {
  345
+	    uint32_t rfix = (uint32_t)e_hdr_out + rel->r_offset;
  346
+	    uint32_t diff = reloc_lookup_section(e_hdr_out, rel->r_offset);
  347
+
  348
+	    if (diff)
  349
+	       rfix -= diff;
  350
+
  351
+	    *(uint32_t*)rfix += over_sz;
  352
+	 }
  353
+
  354
+	 rel++;
  355
+      }
  356
+   }
  357
+
  358
+   munmap((void*)e_hdr_in, fd_in_sz);
  359
+   close(fd_in);
  360
+   munmap((void*)e_hdr_out, fd_out_sz);
  361
+   close(fd_out);
  362
+   return 0;
  363
+}
26  obj.c
... ...
@@ -0,0 +1,26 @@
  1
+int xwrite(int fd, void *buf, int count) {
  2
+        int ret;
  3
+        asm(
  4
+	   "xchg  %%esi, %%ebx  \n"
  5
+	   "xchg  %%edi, %%ecx  \n"
  6
+	   "int   $0x80         \n"
  7
+	   "xchg  %%esi, %%ebx  \n"
  8
+	   "xchg  %%edi, %%ecx  \n"
  9
+	   :"=a"(ret)
  10
+	   :"a"(4),"S"(fd),"D"(buf),"d"(count)
  11
+	   :"cc", "memory");
  12
+        return ret;
  13
+}
  14
+
  15
+int f1(int var)
  16
+{
  17
+	return var*2;
  18
+}
  19
+
  20
+int func()
  21
+{
  22
+	f1(2);
  23
+	xwrite(1,"ld-hook\n", 8);
  24
+	return 1;
  25
+}
  26
+

0 notes on commit 9accf90

Please sign in to comment.
Something went wrong with that request. Please try again.