summaryrefslogtreecommitdiff
path: root/other/wrez/tmp
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /other/wrez/tmp
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/wrez/tmp')
-rw-r--r--other/wrez/tmp/call.c106
-rw-r--r--other/wrez/tmp/call.c.backup137
-rw-r--r--other/wrez/tmp/elf-runtime-fixup.txt324
-rw-r--r--other/wrez/tmp/foo.c11
-rw-r--r--other/wrez/tmp/memdump.c249
-rw-r--r--other/wrez/tmp/ptrace-legit.c143
-rw-r--r--other/wrez/tmp/str.c30
7 files changed, 1000 insertions, 0 deletions
diff --git a/other/wrez/tmp/call.c b/other/wrez/tmp/call.c
new file mode 100644
index 0000000..d81f072
--- /dev/null
+++ b/other/wrez/tmp/call.c
@@ -0,0 +1,106 @@
1/* use ht on the 'call' executeable to set the first PT_LOAD rwx
2 * else it will segfault
3 */
4
5#include <stdio.h>
6
7int foofunc (void);
8
9
10#define FUNCPTR(dst,functionname) \
11{ \
12 register unsigned int fptr; \
13 \
14 __asm__ __volatile__ ( \
15 " call l0_%=\n" \
16 "l0_%=: movl $"##functionname", %%eax\n" \
17 " subl $l0_%=, %%eax\n" \
18 " popl %%edx\n" \
19 " addl %%edx, %%eax\n" \
20 : "=a" (fptr) : : "edx"); \
21 \
22 (dst) = (void *) fptr; \
23}
24
25#define PTRINSTALL(hook,chain) \
26{ \
27 __asm__ __volatile__ ( \
28 " call l0_%=\n" \
29 "lr_%=: jmp lo_%=\n" \
30 "l0_%=: pushl %%edx\n" \
31 " pushl $0x64466226\n" \
32 " jmpl *%%eax\n" \
33 "lo_%=:\n" \
34 : : "a" (hook), "d" (chain)); \
35}
36
37#define PTRCONTROL(chain) \
38{ \
39 __asm__ __volatile__ ( \
40 " jmp l0_%=\n" \
41 "lp_%=: .byte 0x0\n" \
42 " .byte 0x0\n" \
43 " .byte 0x0\n" \
44 " .byte 0x0\n" \
45 "\n" \
46 "l0_%=: call l1_%=\n" \
47 "l1_%=: popl %%edx\n" \
48 " addl $lp_%=, %%edx\n" \
49 " subl $l1_%=, %%edx\n" \
50 "\n" \
51 " movl 0x4(%%ebp), %%eax\n" \
52 " cmpl $0x64466226, %%eax\n" \
53 " jne lo_%=\n" \
54 "\n" \
55 " movl 0x8(%%ebp), %%eax\n" \
56 " movl %%eax, (%%edx)\n" \
57 "\n" \
58 " movl %%ebp, %%esp\n" \
59 " popl %%ebp\n" \
60 " addl $0x8, %%esp\n" \
61 " ret\n" \
62 "\n" \
63 "lo_%=: movl (%%edx), %%eax\n" \
64 : "=a" (chain) : : "edx"); \
65}
66
67
68int
69main (int argc, char *argv[])
70{
71 void (* addr)(void);
72
73#if 0
74 __asm__ __volatile__ ("
75 call l1_%=
76 l1_%=: movl $foofunc, %%eax
77 subl $l1_%=, %%eax
78 popl %%edx
79 addl %%edx, %%eax
80 pusha
81 call *%%eax
82 popa"
83 : "=a" (addrdiff) : : "edx");
84#endif
85 FUNCPTR (addr, "foofunc");
86
87 printf ("0x%08lx\n", (unsigned long int) addr);
88
89 PTRINSTALL (addr, 0x42424242);
90
91 foofunc ();
92}
93
94
95int
96foofunc (void)
97{
98 void * chain;
99
100 PTRCONTROL (chain);
101
102 printf ("0x%08lx\n", chain);
103}
104
105
106
diff --git a/other/wrez/tmp/call.c.backup b/other/wrez/tmp/call.c.backup
new file mode 100644
index 0000000..13d3565
--- /dev/null
+++ b/other/wrez/tmp/call.c.backup
@@ -0,0 +1,137 @@
1/* use ht on the 'call' executeable to set the first PT_LOAD rwx
2 * else it will segfault
3 */
4
5#include <stdio.h>
6
7int foofunc (void);
8
9
10#define FUNCPTR(dst,functionname) \
11{ \
12 register unsigned int fptr; \
13 \
14 __asm__ __volatile__ ( \
15 " call l0_%=\n" \
16 "l0_%=: movl $"##functionname", %%eax\n" \
17 " subl $l0_%=, %%eax\n" \
18 " popl %%edx\n" \
19 " addl %%edx, %%eax\n" \
20 : "=a" (fptr) : : "edx"); \
21 \
22 (dst) = (void *) fptr; \
23}
24
25#define PTRINSTALL(hook,chain) \
26{ \
27 __asm__ __volatile__ ( \
28 " call l0_%=\n" \
29 "lr_%=: jmp lo_%=\n" \
30 "l0_%=: pushl %%edx\n" \
31 " pushl $0x64466226\n" \
32 " jmpl *%%eax\n" \
33 "lo_%=:\n" \
34 : : "a" (hook), "d" (chain)); \
35}
36
37#define PTRCONTROL(chain) \
38{ \
39 __asm__ __volatile__ ( \
40 " jmp l0_%=\n" \
41 "lp_%=: .byte 0x0\n" \
42 " .byte 0x0\n" \
43 " .byte 0x0\n" \
44 " .byte 0x0\n" \
45 "\n" \
46 "l0_%=: call l1_%=\n" \
47 "l1_%=: popl %%edx\n" \
48 " addl $lp_%=, %%edx\n" \
49 " subl $l1_%=, %%edx\n" \
50 "\n" \
51 " movl 0x4(%%ebp), %%eax\n" \
52 " cmpl $0x64466226, %%eax\n" \
53 " jne lo_%=\n" \
54 "\n" \
55 " movl 0x8(%%ebp), %%eax\n" \
56 " movl %%eax, (%%edx)\n" \
57 "\n" \
58 " movl %%ebp, %%esp\n" \
59 " popl %%ebp\n" \
60 " addl $0x8, %%esp\n" \
61 " ret\n" \
62 "\n" \
63 "lo_%=: movl (%%edx), %%eax\n" \
64 : "=a" (chain) : : "edx"); \
65}
66
67int
68main (int argc, char *argv[])
69{
70 void (* addr)(void);
71
72#if 0
73 __asm__ __volatile__ ("
74 call l1_%=
75 l1_%=: movl $foofunc, %%eax
76 subl $l1_%=, %%eax
77 popl %%edx
78 addl %%edx, %%eax
79 pusha
80 call *%%eax
81 popa"
82 : "=a" (addrdiff) : : "edx");
83#endif
84 FUNCPTR (addr, "foofunc");
85
86 printf ("0x%08lx\n", (unsigned long int) addr);
87
88 __asm__ __volatile__ ("
89 call l0_%=
90 lr_%=: jmp lo_%=
91 l0_%=: pushl %%edx
92 pushl $0x64466226
93 jmpl *%%eax
94 lo_%=:
95 " : : "a" (addr), "d" (0x42424242));
96
97 foofunc ();
98}
99
100
101int
102foofunc (void)
103{
104 void * chain;
105
106 __asm__ __volatile__ ("
107 ls1_%=: jmp l0_%=
108 ptr_%=: .byte 0x0
109 .byte 0x0
110 .byte 0x0
111 .byte 0x0
112
113 l0_%=: call l1_%=
114 l1_%=: popl %%edx
115 addl $ptr_%=, %%edx
116 subl $l1_%=, %%edx
117
118 movl 0x4(%%ebp), %%eax
119 cmpl $0x64466226, %%eax
120 jne lo_%=
121
122 movl 0x8(%%ebp), %%eax
123 movl %%eax, (%%edx)
124
125 movl %%ebp, %%esp
126 popl %%ebp
127 addl $0x8, %%esp
128 ret
129
130 lo_%=: movl (%%edx), %%eax
131 " : "=a" (chain) : : "edx");
132
133 printf ("0x%08lx\n", chain);
134}
135
136
137
diff --git a/other/wrez/tmp/elf-runtime-fixup.txt b/other/wrez/tmp/elf-runtime-fixup.txt
new file mode 100644
index 0000000..a594cdd
--- /dev/null
+++ b/other/wrez/tmp/elf-runtime-fixup.txt
@@ -0,0 +1,324 @@
1
2**************************************************************************
3
4 Reversing the ELF
5
6 Stepping with GDB during PLT uses and .GOT fixup
7
8 mayhem (mayhem@hert.org)
9
10**************************************************************************
11
12
13This text is a GDB tutorial about runtime process fixup using the Procedure
14Linkage Table section (.plt) and the Global Offset Table section (.got) .
15If you dont know what is ELF, you should read the ELF ultimate documentation
16you can find here :
17
18 http://www.devhell.org/~mayhem/stuffs/ELF.pdf
19
20Some basic ASM knowledge may be requested .
21
22This text has not been written for ELF specialists . This tutorial is an
23alternative , interactive way to understand the PLT mechanisms .
24
25When the executable is mapped into memory, the core code segment _start
26fonction the executable file is called as soon as the _dl_start function
27of the dynamic linker has returned . I will go step by step in the
28process structures initialization mechanims using objdump, gdb and gcc ;
29
30
31
32
33bash-2.03$ cat test.c
34int called()
35{
36 puts("toto");
37}
38
39int main()
40{
41 called();
42}
43bash-2.03$ cc test.c && objdump -D ./a.out | less
44
45<...>
46
4708048318 <_start>:
48 8048318: 31 ed xor %ebp,%ebp
49 804831a: 5e pop %esi
50 804831b: 89 e1 mov %esp,%ecx
51 804831d: 83 e4 f8 and $0xfffffff8,%esp
52 8048320: 50 push %eax
53 8048321: 54 push %esp
54 8048322: 52 push %edx
55 8048323: 68 04 84 04 08 push $0x8048404
56 8048328: 68 98 82 04 08 push $0x8048298
57 804832d: 51 push %ecx
58 804832e: 56 push %esi
59 804832f: 68 c8 83 04 08 push $0x80483c8
60 8048334: e8 cf ff ff ff call 8048308 <_init+0x70> <===
61 8048339: f4 hlt
62 804833a: 90 nop
63 804833b: 90 nop
64
65
66<...>
67
68
69
70
71Even if the dynamic linker creates some basic stuffs before everything,
72he first core function called is _start .
73
74We can see that this function initialize the stack . Some things we have
75to notice :
76
77$0x8048404 : _fini() function offset in the .fini section
78$0x8048298 : _init() function offset in the .init section
79$0x80483c8 : main() function offset in the .text section
80
81
82This information is pushed because it's used in the libc in the
83__libc_start_main function . This libc function has to :
84
85 - call the constructors .
86 - call the main .
87 - call the destructors .
88
89
90The call to the offset 0x8048308 points in the Procedure Linkage Table
91(.plt section) . This section provides a way to transfert inter-object
92calls . Remember we're trying to call the __libc_start_main function .
93
94The PLT code for this entry is :
95
96
97080482c8 <.plt>:
98 80482c8: ff 35 54 94 04 08 pushl 0x8049454
99 80482ce: ff 25 58 94 04 08 jmp *0x8049458
100 80482d4: 00 00 add %al,(%eax)
101 80482d6: 00 00 add %al,(%eax)
102 80482d8: ff 25 5c 94 04 08 jmp *0x804945c
103 80482de: 68 00 00 00 00 push $0x0
104 80482e3: e9 e0 ff ff ff jmp 80482c8 <_init+0x30>
105 80482e8: ff 25 60 94 04 08 jmp *0x8049460
106 80482ee: 68 08 00 00 00 push $0x8
107 80482f3: e9 d0 ff ff ff jmp 80482c8 <_init+0x30>
108 80482f8: ff 25 64 94 04 08 jmp *0x8049464
109 80482fe: 68 10 00 00 00 push $0x10
110 8048303: e9 c0 ff ff ff jmp 80482c8 <_init+0x30>
111 8048308: ff 25 68 94 04 08 jmp *0x8049468 *YOU ARE HERE*
112 804830e: 68 18 00 00 00 push $0x18
113 8048313: e9 b0 ff ff ff jmp 80482c8 <_init+0x30>
114
115
116
117We can see that our call in the PLT is followed by a JMP :
118
119 jmp *0x8049468
120
121The 0x8049468 offset is in the Global Offset Table (.got section) . The
122stars means (for non x86 att syntax experts readers) that we are using
123the four byte pointer at 0x8049468 as an offset . This offset in actually
124retreivable from the Global Offset Table (GOT) .
125
126In the beginning, the GOT offsets points on the following push (offset
1270x804830e : look at the objdump trace above) . At the moment , the GOT
128in our process is said to be "empty", and is going to be filled as long
129as the process calls remote functions (one entry is updated each time the
130program calls this remote function *for the first time*) .
131
132
133
134 .got :
135
136 [00] 0x8049470 [01] (nil)
137 [02] (nil) [03] 0x80482de
138 [04] 0x80482ee [05] 0x80482fe
139 [06] 0x804830e [07] (nil)
140
141
142 The GOT is empty : every offsets point on a push instruction in
143 the procedure linkage table (.plt) .
144
145
146
147We can see that the third first entries in the GOT have special values :
148
149 - The [0] entry contains the offset for the .dynamic section of
150 this object, it's used by the dynamic linker to know some
151 preferences and some very useful informations . Look at the
152 ELF reference for further details . Some stuff are also explained
153 in the dynamic linking related chapter of this tfile .
154
155 - The [1] one is the link_map structure offset associated with
156 this object, it's an internal structure in ld.so describing
157 a lot of interresting stuffs, I wont go in depth with it in this
158 paper .
159
160 - The [2] entry contains the runtime process fixup function offset
161 (pointing in the dynamic linking code zone). This pointer is used by
162 the first entry of the plt which is called when you want to launch
163 a remote (undefined) function for the first time .
164
165
166The 2nd and 3rd entries are set to NULL at the beginning and are filled by
167the dynamic linker before the process code segment starting function takes
168control . These are filled in elf_machine_runtime_setup() in
169sysdeps/i386/dl-machine.h .
170
171With that mechanism, we have to execute three call instructions (if the
172corresponding GOT entry has not been updated yet), or two call instructions
173(if the GOT has been filled) . Remember that the GOT has been filled during
174the first call on the corresponding function . Only external functions need
175that mechanism, since only in-core code segment functions offsets are known
176before the process start (the executable object base address is known) .
177
178
179Get back to our code, we can see that this entry jumps to the 3rd offset of
180the GOT entry, it means that the code calls the dynamic linker's resolution
181function dl-resolve() . Some other papers have been describing useful
182information gathering with it (check Nergal's phrack 58 or grugq's subversive
183dynamic linking paper)
184
185
186We can note that these 2 offsets are pushed each time a call is done via
187the PLT :
188
189 - The first is an offset (in octets) in the .rel.plt section of the
190 program binary . It's used to identify the corresponding symbol for
191 the function we are trying to get the real absolute address .
192 - The second one is the offset contained in the 2nd GOT entry
193 (it's 0x8049454 in our code) .
194
195This information allows us to identify the symbol for which we want to do
196a relocation . Let's discover the runtime .got fixup offset with gdb and
197the procfs :
198
199
200bash-2.03$ gdb a.out
201
202(gdb) b called
203Breakpoint 1 at 0x80483b7
204
205(gdb) r
206Starting program: /home/mayhem/a.out
207Breakpoint 1, 0x80483b7 in called ()
208
209(gdb) disassemble called
210Dump of assembler code for function called:
2110x80483b4 <called>: push %ebp
2120x80483b5 <called+1>: mov %esp,%ebp
2130x80483b7 <called+3>: push $0x8048428
2140x80483bc <called+8>: call 0x80482e8 <puts> <======== LOOK HERE !
2150x80483c1 <called+13>: add $0x4,%esp
2160x80483c4 <called+16>: leave
2170x80483c5 <called+17>: ret
2180x80483c6 <called+18>: mov %esi,%esi
219End of assembler dump.
220
221
222What is this routine ?
223
224
225
226(gdb) x/3i 0x80482e8
2270x80482e8 <puts>: jmp *0x8049460
2280x80482ee <puts+6>: push $0x8
2290x80482f3 <puts+11>: jmp 0x80482c8 <_init+48>
230
231
232It's the procedure linkage table entry for this function, it uses offset
233in the GOT . As the GOT is not yet filled, the offset is the 32 bits address
234of the following push ("push $0x8") . This entry is going to be modified
235by the dynamic linker as soon as the symbol resolution is done ( see
236chapter 2) .
237
238
239
240(gdb) x/1x 0x8049460
2410x8049460 <_GLOBAL_OFFSET_TABLE_+16>: 0x080482ee
242
243
244Each first time you call a remote function, the PLT first entry code
245is executed :
246
247
248(gdb) x/3i 0x80482c8
2490x80482c8 <_init+48>: pushl 0x8049454
2500x80482ce <_init+54>: jmp *0x8049458
2510x80482d4 <_init+60>: add %al,(%eax)
252
253
254This first entry uses the third entry of the GOT , then the dynamic
255linker takes control :
256
257
258(gdb) x/1x 0x8049458
2590x8049458 <_GLOBAL_OFFSET_TABLE_+8>: 0x40009a10
260
261(gdb)
262
263
264Let's see what is the library containing this function at the offset
2650x40009a10 .
266
267
268bash-2.04$ pidof a.out
2697905
270bash-2.04$ cat /proc/7905/maps
27108048000-08049000 r-xp 00000000 03:01 135375 /home/mayhem/a.out
27208049000-0804a000 rw-p 00000000 03:01 135375 /home/mayhem/a.out
27340000000-40012000 r-xp 00000000 03:01 229408 /lib/ld-2.1.2.so <== *GOOD*
27440012000-40013000 rw-p 00011000 03:01 229408 /lib/ld-2.1.2.so
27540013000-40014000 rw-p 00000000 00:00 0
2764001a000-400fb000 r-xp 00000000 03:01 229410 /lib/libc-2.1.2.so
277400fb000-400ff000 rw-p 000e0000 03:01 229410 /lib/libc-2.1.2.so
278400ff000-40102000 rw-p 00000000 00:00 0
279bfffe000-c0000000 rwxp fffff000 00:00 0
280bash-2.04$
281
282
283The wanted function is in the dynamic linker code segment, more precisely
284in the _dl_runtime_fixup() function, in the sysdeps/i386/dl-machine.h
285file . To be honest, i had difficulties to find it , because I could not
286deduce the symbol giving its virtual address, and this for 2 reasons :
287
288 - The libc and the dynamic linker are stripped (the symbol table
289 and the debug information has been removed) . As a consequence,
290 I could get the function name from the symbol table .
291
292 - In a shared library, offsets are relative (actually it's
293 calculated from the beginning of the file, so you can't retreive
294 the absolute function addresses from the ld.so symbol table) .
295 You can do a "objdump -D /lib/libc.so.6" to see it by yourself .
296
297 Even if I had a symbol table, I could not have got the good offset .
298 I could have compare the first bytes of the function in the debugged
299 process and the library (ld.so) code segment to find some hexadecimal
300 sequences matching, but I prefered to read the sources . ;)
301
302 The solution is to calculate the relocation ourself, most of the
303 time we have : base_addr + symbol_value = runtime address . You
304 can get the base address from the procfs (if you have read access,
305 this is okay by default) and you can check the symbol's value
306 from the library's .dynsym section (list of exported symbols).
307 Note that you can retreive it from the symbol table (.symtab)
308 but this section may be removed from the shared library using
309 known basic tools like strip(3) .
310
311
312Shoutouts to silvio and grugq !
313
314
315*EOF*
316
317
318
319
320
321
322
323
324
diff --git a/other/wrez/tmp/foo.c b/other/wrez/tmp/foo.c
new file mode 100644
index 0000000..51d4bd2
--- /dev/null
+++ b/other/wrez/tmp/foo.c
@@ -0,0 +1,11 @@
1
2#include <stdio.h>
3
4int
5main (int argc, char *argv[])
6{
7 printf ("my home is my castle\n");
8 printf ("my castle is my home\n");
9}
10
11
diff --git a/other/wrez/tmp/memdump.c b/other/wrez/tmp/memdump.c
new file mode 100644
index 0000000..3215d20
--- /dev/null
+++ b/other/wrez/tmp/memdump.c
@@ -0,0 +1,249 @@
1/* memory dump utility
2 * -scut
3 */
4
5#include <sys/types.h>
6#include <sys/ptrace.h>
7#include <sys/wait.h>
8#include <sys/user.h>
9#include <errno.h>
10#include <unistd.h>
11#include <stdlib.h>
12#include <stdio.h>
13#include <libgen.h> /* basename */
14
15
16void
17hexdump (unsigned char *data, unsigned int amount);
18
19
20int
21main (int argc, char *argv[])
22{
23 pid_t fpid; /* child pid, gets ptraced */
24 char * argv0;
25 struct user regs; /* PTRACE pulled registers */
26 unsigned long int addr, /* segment start address */
27 addr_end, /* segment end address */
28 len; /* length of segment */
29 unsigned long int addr_walker, /* walker to dump memory */
30 eip; /* current childs eip */
31
32 /* array to temporarily store data into */
33 unsigned char data_saved[sizeof (unsigned long int)];
34
35 /* file to read mapping information */
36 FILE * map_f; /* /proc/<pid>/maps stream */
37 unsigned char map_line[256]; /* one line each from map */
38
39 /* data for the dump files */
40 FILE * dump_f; /* stream */
41 char dump_name[64]; /* filename buffer */
42
43
44 if (argc < 3 || sscanf (argv[1], "0x%lx", &eip) != 1) {
45 printf ("usage: %s <eip> <argv0 [argv1 [...]]>\n\n", argv[0]);
46 printf ("will run 'argv0' as program with given arguments, "
47 "until 'eip' is reached, then\n"
48 "dumping 'len' bytes from 'addr'.\n\n"
49 "example: %s 0x08049014 0x08048000 0x100 /bin/ls "
50 "-l\n\n", argv[0]);
51
52 exit (EXIT_FAILURE);
53 }
54
55 argv0 = argv[2];
56
57 fpid = fork ();
58 if (fpid < 0) {
59 perror ("fork");
60 exit (EXIT_FAILURE);
61 }
62 if (fpid == 0) { /* child */
63 if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) {
64 perror ("ptrace PTRACE_TRACEME");
65 exit (EXIT_FAILURE);
66 }
67 fprintf (stderr, " child: TRACEME set\n");
68
69 fprintf (stderr, " child: executing: %s\n", argv[2]);
70 close (1);
71 dup2 (2, 1);
72 execve (argv[2], &argv[2], NULL);
73
74 /* failed ? */
75 perror ("execve");
76 exit (EXIT_FAILURE);
77 }
78
79 wait (NULL);
80
81 memset (&regs, 0, sizeof (regs));
82
83 if (ptrace (PTRACE_GETREGS, fpid, NULL, &regs) < 0) {
84 perror ("ptrace PTRACE_GETREGS");
85 exit (EXIT_FAILURE);
86 }
87 fprintf (stderr, "[0x%08lx] first stop\n", regs.regs.eip);
88
89 /* now single step until given eip is reached */
90 do {
91 if (ptrace (PTRACE_SINGLESTEP, fpid, NULL, NULL) < 0) {
92 perror ("ptrace PTRACE_SINGLESTEP");
93 exit (EXIT_FAILURE);
94 }
95 wait (NULL);
96
97 memset (&regs, 0, sizeof (regs));
98 if (ptrace (PTRACE_GETREGS, fpid, NULL, &regs) < 0) {
99 perror ("ptrace PTRACE_GETREGS");
100 exit (EXIT_FAILURE);
101 }
102 } while (regs.regs.eip != eip);
103
104 fprintf (stderr, "MEMDUMP: eip @ 0x%08lx, dumping...\n", eip);
105
106 snprintf (dump_name, sizeof (dump_name), "%s.regs",
107 basename (argv0));
108 dump_name[sizeof (dump_name) - 1] = '\0';
109 dump_f = fopen (dump_name, "w");
110 if (dump_f == NULL) {
111 perror ("fopen dumpfile regs");
112 exit (EXIT_FAILURE);
113 }
114 fprintf (dump_f, "eax = 0x%08lx\n", regs.regs.eax);
115 fprintf (dump_f, "ebx = 0x%08lx\n", regs.regs.ebx);
116 fprintf (dump_f, "ecx = 0x%08lx\n", regs.regs.ecx);
117 fprintf (dump_f, "edx = 0x%08lx\n", regs.regs.edx);
118 fprintf (dump_f, "esi = 0x%08lx\n", regs.regs.esi);
119 fprintf (dump_f, "edi = 0x%08lx\n", regs.regs.edi);
120 fprintf (dump_f, "ebp = 0x%08lx\n", regs.regs.ebp);
121 fprintf (dump_f, "esp = 0x%08lx\n", regs.regs.esp);
122 fprintf (dump_f, "eflags = 0x%08lx\n", regs.regs.eflags);
123 fprintf (dump_f, "xcs = 0x%08lx\n", regs.regs.xcs);
124 fprintf (dump_f, "xds = 0x%08lx\n", regs.regs.xds);
125 fprintf (dump_f, "xes = 0x%08lx\n", regs.regs.xes);
126 fprintf (dump_f, "xss = 0x%08lx\n", regs.regs.xss);
127 fclose (dump_f);
128
129 snprintf (map_line, sizeof (map_line), "/proc/%d/maps", fpid);
130 map_line[sizeof (map_line) - 1] = '\0';
131 map_f = fopen (map_line, "r");
132 if (map_f == NULL) {
133 perror ("fopen map-file");
134
135 exit (EXIT_FAILURE);
136 }
137
138 while (fgets (map_line, sizeof (map_line), map_f) != NULL) {
139 char map_perm[8];
140
141 if (sscanf (map_line, "%08lx-%08lx %7[rwxp-] ",
142 &addr, &addr_end, map_perm) != 3)
143 {
144 perror ("invalid map-line");
145
146 exit (EXIT_FAILURE);
147 }
148 if (addr_end < addr) {
149 fprintf (stderr, "sanity required, not so: "
150 "addr = 0x%08lx, addr_end = 0x%08lx",
151 addr, addr_end);
152
153 exit (EXIT_FAILURE);
154 }
155 len = addr_end - addr;
156 map_perm[sizeof (map_perm) - 1] = '\0'; /* ;-) */
157
158 fprintf (stderr, "MEMDUMP: -> 0x%08lx (0x%08lx bytes, "
159 "perm %s)\n", addr, len, map_perm);
160
161 snprintf (dump_name, sizeof (dump_name),
162 "%s.0x%08lx.0x%08lx.%s",
163 basename (argv0), addr, len, map_perm);
164 dump_name[sizeof (dump_name) - 1] = '\0';
165 dump_f = fopen (dump_name, "wb");
166 if (dump_f == NULL) {
167 perror ("fopen dumpfile");
168
169 exit (EXIT_FAILURE);
170 }
171
172 /* save data, assuming addr is page aligned */
173 for (addr_walker = 0 ; addr_walker < len ;
174 addr_walker += sizeof (data_saved))
175 {
176 errno = 0;
177
178 *((unsigned long int *) &data_saved[0]) =
179 ptrace (PTRACE_PEEKDATA, fpid,
180 addr + addr_walker, NULL);
181
182 if (errno == 0 && fwrite (&data_saved[0], 1, 4,
183 dump_f) != 4)
184 {
185 perror ("fwrite dumpfile");
186
187 exit (EXIT_FAILURE);
188 } else if (errno != 0) {
189 fprintf (stderr,
190 "[0x%08lx] invalid PTRACE_PEEKDATA\n",
191 addr + addr_walker);
192
193 exit (EXIT_FAILURE);
194 }
195 }
196
197 fclose (dump_f);
198 }
199 fclose (map_f);
200
201 if (ptrace (PTRACE_DETACH, fpid, NULL, NULL) < 0) {
202 perror ("ptrace PTRACE_DETACH");
203 exit (EXIT_FAILURE);
204 }
205
206 fprintf (stderr, "MEMDUMP: success. terminating.\n");
207 exit (EXIT_SUCCESS);
208}
209
210
211
212void
213hexdump (unsigned char *data, unsigned int amount)
214{
215 unsigned int dp, p; /* data pointer */
216 const char trans[] =
217 "................................ !\"#$%&'()*+,-./0123456789"
218 ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
219 "nopqrstuvwxyz{|}~...................................."
220 "....................................................."
221 "........................................";
222
223 for (dp = 1; dp <= amount; dp++) {
224 printf ("%02x ", data[dp-1]);
225 if ((dp % 8) == 0)
226 printf (" ");
227 if ((dp % 16) == 0) {
228 printf ("| ");
229 p = dp;
230 for (dp -= 16; dp < p; dp++)
231 printf ("%c", trans[data[dp]]);
232 printf ("\n");
233 }
234 }
235 if ((amount % 16) != 0) {
236 p = dp = 16 - (amount % 16);
237 for (dp = p; dp > 0; dp--) {
238 printf (" ");
239 if (((dp % 8) == 0) && (p != 8))
240 printf (" ");
241 }
242 printf (" | ");
243 for (dp = (amount - (16 - p)); dp < amount; dp++)
244 printf ("%c", trans[data[dp]]);
245 }
246 printf ("\n");
247
248 return;
249}
diff --git a/other/wrez/tmp/ptrace-legit.c b/other/wrez/tmp/ptrace-legit.c
new file mode 100644
index 0000000..a6c53d7
--- /dev/null
+++ b/other/wrez/tmp/ptrace-legit.c
@@ -0,0 +1,143 @@
1/* -scutstyle */
2
3#include <sys/types.h>
4#include <sys/ptrace.h>
5#include <sys/wait.h>
6#include <sys/user.h>
7#include <unistd.h>
8#include <stdlib.h>
9#include <stdio.h>
10
11void
12hexdump (unsigned char *data, unsigned int amount);
13
14unsigned char shellcode[] = "\x90\x90\xcc\x73";
15
16int
17main (int argc, char *argv[])
18{
19 pid_t cpid;
20 struct user regs;
21 unsigned long int safed_eip;
22 unsigned long int addr,
23 addr_walker;
24 unsigned char data_saved[256];
25
26
27#if 1
28 if (argc != 2 || sscanf (argv[1], "%d", &cpid) != 1) {
29 printf ("usage: %s <pid>\n", argv[0]);
30 exit (EXIT_FAILURE);
31 }
32#else
33 cpid = getppid();
34#endif
35
36 printf ("pid = %d\n", cpid);
37
38 printf ("exploiting\n\n");
39
40 if (ptrace (PTRACE_ATTACH, cpid, NULL, NULL) < 0) {
41 perror ("ptrace");
42 exit (EXIT_FAILURE);
43 }
44
45 /* save data */
46 addr = 0xbffff010;
47 for (addr_walker = 0 ; addr_walker < 256 ; ++addr_walker) {
48 data_saved[addr_walker] = ptrace (PTRACE_PEEKDATA, cpid,
49 addr + addr_walker, NULL);
50 }
51 hexdump (data_saved, sizeof (data_saved));
52
53 /* write */
54 for (addr_walker = 0 ; addr_walker < sizeof (shellcode) ;
55 ++addr_walker)
56 {
57 ptrace (PTRACE_POKEDATA, cpid, addr + addr_walker,
58 shellcode[addr_walker] & 0xff);
59 }
60
61 /* redirect eip */
62 memset (&regs, 0, sizeof (regs));
63 if (ptrace (PTRACE_GETREGS, cpid, NULL, &regs) < 0) {
64 perror ("ptrace PTRACE_GETREGS");
65 exit (EXIT_FAILURE);
66 }
67 // write eip */
68 safed_eip = regs.regs.eip;
69 regs.regs.eip = 0xbffff010;
70 if (ptrace (PTRACE_SETREGS, cpid, NULL, &regs) < 0) {
71 perror ("ptrace PTRACE_GETREGS");
72 exit (EXIT_FAILURE);
73 }
74
75 if (ptrace (PTRACE_CONT, cpid, NULL, NULL) < 0) {
76 perror ("ptrace PTRACE_CONT");
77 exit (EXIT_FAILURE);
78 }
79
80 wait (NULL);
81 printf ("detrap\n");
82
83 /* restore */
84 for (addr_walker = 0 ; addr_walker < 256 ; ++addr_walker) {
85 ptrace (PTRACE_POKEDATA, cpid, addr + addr_walker,
86 data_saved[addr_walker] & 0xff);
87 }
88
89 /* restore regs */
90 regs.regs.eip = safed_eip;
91 if (ptrace (PTRACE_SETREGS, cpid, NULL, &regs) < 0) {
92 perror ("ptrace PTRACE_GETREGS");
93 exit (EXIT_FAILURE);
94 }
95
96 if (ptrace (PTRACE_DETACH, cpid, NULL, NULL) < 0) {
97 perror ("ptrace PTRACE_DETACH");
98 exit (EXIT_FAILURE);
99 }
100
101 exit (EXIT_SUCCESS);
102}
103
104
105
106void
107hexdump (unsigned char *data, unsigned int amount)
108{
109 unsigned int dp, p; /* data pointer */
110 const char trans[] =
111 "................................ !\"#$%&'()*+,-./0123456789"
112 ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
113 "nopqrstuvwxyz{|}~...................................."
114 "....................................................."
115 "........................................";
116
117 for (dp = 1; dp <= amount; dp++) {
118 printf ("%02x ", data[dp-1]);
119 if ((dp % 8) == 0)
120 printf (" ");
121 if ((dp % 16) == 0) {
122 printf ("| ");
123 p = dp;
124 for (dp -= 16; dp < p; dp++)
125 printf ("%c", trans[data[dp]]);
126 printf ("\n");
127 }
128 }
129 if ((amount % 16) != 0) {
130 p = dp = 16 - (amount % 16);
131 for (dp = p; dp > 0; dp--) {
132 printf (" ");
133 if (((dp % 8) == 0) && (p != 8))
134 printf (" ");
135 }
136 printf (" | ");
137 for (dp = (amount - (16 - p)); dp < amount; dp++)
138 printf ("%c", trans[data[dp]]);
139 }
140 printf ("\n");
141
142 return;
143}
diff --git a/other/wrez/tmp/str.c b/other/wrez/tmp/str.c
new file mode 100644
index 0000000..d822f20
--- /dev/null
+++ b/other/wrez/tmp/str.c
@@ -0,0 +1,30 @@
1
2#include <stdio.h>
3
4#define STRINGPTR(dst,string) \
5{ \
6 register unsigned char * regtmp; \
7 \
8 __asm__ __volatile__ ( \
9 " call l0_%=\n\t" \
10 " .ascii \""##string"\"\n\t" \
11 " .byte 0x00\n\t" \
12 "l0_%=: popl %%eax\n\t" \
13 : "=a" (regtmp)); \
14\
15 (dst) = regtmp; \
16}
17
18
19int
20main (int argc, char *argv[])
21{
22 char * foo;
23
24
25 STRINGPTR(foo,"foobarcow");
26
27 printf ("%s\n", foo);
28}
29
30