summaryrefslogtreecommitdiff
path: root/other/reducebind/pcdump.c
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/reducebind/pcdump.c
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/reducebind/pcdump.c')
-rw-r--r--other/reducebind/pcdump.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/other/reducebind/pcdump.c b/other/reducebind/pcdump.c
new file mode 100644
index 0000000..7072576
--- /dev/null
+++ b/other/reducebind/pcdump.c
@@ -0,0 +1,186 @@
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 dr_dump (FILE *out, struct user *child);
17void hexdump (unsigned char *data, unsigned int amount);
18
19
20int
21main (int argc, char *argv[], char *envp[])
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 < 2) {
45 printf ("usage: %s <argv0 [argv1 [...]]>\n\n", argv[0]);
46 printf ("will run 'argv0' as program with given arguments.\n\n");
47
48 exit (EXIT_FAILURE);
49 }
50
51 fpid = fork ();
52 if (fpid < 0) {
53 perror ("fork");
54 exit (EXIT_FAILURE);
55 }
56 if (fpid == 0) { /* child */
57 if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) {
58 perror ("ptrace PTRACE_TRACEME");
59 exit (EXIT_FAILURE);
60 }
61 fprintf (stderr, " child: TRACEME set\n");
62
63 fprintf (stderr, " child: executing: %s\n", argv[2]);
64 close (1);
65 dup2 (2, 1);
66 execve (argv[1], &argv[1], envp);
67
68 /* failed ? */
69 perror ("execve");
70 exit (EXIT_FAILURE);
71 }
72
73 wait (NULL);
74
75 memset (&regs, 0, sizeof (regs));
76
77 if (ptrace (PTRACE_GETREGS, fpid, NULL, &regs) < 0) {
78 perror ("ptrace PTRACE_GETREGS");
79 exit (EXIT_FAILURE);
80 }
81 fprintf (stderr, "[0x%08lx] first stop\n", regs.regs.eip);
82 dr_dump (stderr, &regs);
83
84 regs.u_debugreg[0] = 0x41414141;
85 if (ptrace (PTRACE_SETREGS, fpid, NULL, &regs) < 0) {
86 perror ("ptrace PTRACE_GETREGS");
87 exit (EXIT_FAILURE);
88 }
89 sleep (10);
90 if (ptrace (PTRACE_GETREGS, fpid, NULL, &regs) < 0) {
91 perror ("ptrace PTRACE_GETREGS");
92 exit (EXIT_FAILURE);
93 }
94 fprintf (stderr, "[0x%08lx] first stop\n", regs.regs.eip);
95 dr_dump (stderr, &regs);
96
97 /* now single step until given eip is reached */
98 do {
99 sleep (1);
100
101 if (ptrace (PTRACE_SYSCALL, fpid, NULL, NULL) < 0) {
102 perror ("ptrace PTRACE_SINGLESTEP");
103 exit (EXIT_FAILURE);
104 }
105 wait (NULL);
106
107 memset (&regs, 0, sizeof (regs));
108 if (ptrace (PTRACE_GETREGS, fpid, NULL, &regs) < 0) {
109 perror ("ptrace PTRACE_GETREGS");
110 exit (EXIT_FAILURE);
111 }
112 fprintf (stderr, "0x%08lx\n", regs.regs.eip);
113 dr_dump (stderr, &regs);
114 } while (1);
115
116 if (ptrace (PTRACE_DETACH, fpid, NULL, NULL) < 0) {
117 perror ("ptrace PTRACE_DETACH");
118 exit (EXIT_FAILURE);
119 }
120
121 fprintf (stderr, "MEMDUMP: success. terminating.\n");
122 exit (EXIT_SUCCESS);
123}
124
125
126
127void
128hexdump (unsigned char *data, unsigned int amount)
129{
130 unsigned int dp, p; /* data pointer */
131 const char trans[] =
132 "................................ !\"#$%&'()*+,-./0123456789"
133 ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
134 "nopqrstuvwxyz{|}~...................................."
135 "....................................................."
136 "........................................";
137
138 for (dp = 1; dp <= amount; dp++) {
139 printf ("%02x ", data[dp-1]);
140 if ((dp % 8) == 0)
141 printf (" ");
142 if ((dp % 16) == 0) {
143 printf ("| ");
144 p = dp;
145 for (dp -= 16; dp < p; dp++)
146 printf ("%c", trans[data[dp]]);
147 printf ("\n");
148 }
149 }
150 if ((amount % 16) != 0) {
151 p = dp = 16 - (amount % 16);
152 for (dp = p; dp > 0; dp--) {
153 printf (" ");
154 if (((dp % 8) == 0) && (p != 8))
155 printf (" ");
156 }
157 printf (" | ");
158 for (dp = (amount - (16 - p)); dp < amount; dp++)
159 printf ("%c", trans[data[dp]]);
160 }
161 printf ("\n");
162
163 return;
164}
165
166
167void
168dr_dump (FILE *out, struct user *child)
169{
170 char * desc[] = { "dr0 (debug address register)",
171 "dr1 (debug address register)",
172 "dr2 (debug address register)",
173 "dr3 (debug address register)",
174 "dr4 (reserved)",
175 "dr5 (reserved)",
176 "dr6 (debug status register)",
177 "dr7 (debug control register)" };
178 int n;
179
180 for (n = 0 ; n < 8 ; ++n) {
181 fprintf (out, "\t0x%08lx %s\n", child->u_debugreg[n],
182 desc[n]);
183 }
184}
185
186