|
@@ -1,204 +1,128 @@
|
1
|
|
-#include<fcntl.h>
|
2
|
|
-#include<stdio.h>
|
3
|
|
-#include<unistd.h>
|
4
|
|
-#include<signal.h>
|
5
|
|
-#include<stdlib.h>
|
6
|
|
-#include<string.h>
|
7
|
|
-#include<sys/ptrace.h>
|
8
|
|
-#include<sys/types.h>
|
9
|
|
-#include<sys/stat.h>
|
10
|
|
-#include<sys/user.h>
|
11
|
|
-#include<sys/wait.h>
|
|
1
|
+#include "config.h"
|
|
2
|
+#include <stdio.h>
|
|
3
|
+#include <readline/readline.h>
|
|
4
|
+#include <readline/history.h>
|
12
|
5
|
|
13
|
6
|
#define CHILD_EXEC_PATH "./child"
|
14
|
7
|
|
15
|
|
-void child_process();
|
|
8
|
+#include "asm_env.h"
|
|
9
|
+#include "compile.h"
|
16
|
10
|
|
17
|
|
-int main(int argc, char *argv[], char *envp[])
|
|
11
|
+static void print_regs(asmsh_env_t *env)
|
18
|
12
|
{
|
19
|
|
- int cpid, wstatus;
|
20
|
|
- unsigned long pret;
|
21
|
|
- pid_t wpid;
|
22
|
|
- int sigpipe[2];
|
23
|
|
- char sigbuf;
|
24
|
|
- struct user_regs_struct regs;
|
25
|
|
-
|
26
|
|
- if(pipe(sigpipe) < 0)
|
27
|
|
- {
|
28
|
|
- perror("Unable to open pipe");
|
29
|
|
- return 1;
|
30
|
|
- }
|
|
13
|
+ asmsh_env_update_regs(env);
|
|
14
|
+ struct user_regs_struct *r = &env->regs;
|
|
15
|
+
|
|
16
|
+#define FLG(b, l) ( (r->eflags & (1<<b))?l:'-' )
|
|
17
|
+
|
|
18
|
+ printf("rax: %016lx rbx: %016lx rcx: %016lx rdx: %016lx\n\
|
|
19
|
+rbp: %016lx rsi: %016lx rdi: %016lx rsp: %016lx\n\
|
|
20
|
+ r8: %016lx r9: %016lx r10: %016lx r11: %016lx\n\
|
|
21
|
+r12: %016lx r13: %016lx r14: %016lx r15: %016lx\n\
|
|
22
|
+rip: %016lx flg: %016lx\n\
|
|
23
|
+cs: %04x ds: %04x es: %04x fs:%04x gs: %04x ss:%04x\n\
|
|
24
|
+flags: %c%c%c%c|%c%c%c\n\
|
|
25
|
+ ODSZ|APC\n\
|
|
26
|
+", r->rax, r->rbx, r->rcx, r->rdx,\
|
|
27
|
+ r->rbp, r->rsi, r->rdi, r->rsp,\
|
|
28
|
+ r->r8, r->r9, r->r10, r->r11,\
|
|
29
|
+ r->r12, r->r13, r->r14, r->r15,\
|
|
30
|
+ r->rip, r->eflags,\
|
|
31
|
+ r->cs, r->ds, r->es, r->fs, r->gs, r->ss,
|
|
32
|
+ FLG(11,'O'), FLG(10, 'D'), FLG(7, 'S'), FLG(6, 'Z'),
|
|
33
|
+ FLG(4, 'A'), FLG(2, 'P'), FLG(0, 'C'));
|
|
34
|
+
|
|
35
|
+#undef FLG
|
|
36
|
+}
|
31
|
37
|
|
32
|
|
- cpid = fork();
|
33
|
|
- if(cpid < 0)
|
34
|
|
- {
|
35
|
|
- perror("Unable to fork :");
|
36
|
|
- return 1;
|
37
|
|
- }
|
38
|
|
- else if(cpid == 0)
|
39
|
|
- {
|
40
|
|
- child_process(argv, envp, sigpipe);
|
41
|
|
- }
|
42
|
38
|
|
43
|
|
- printf("Child started %d\n", cpid);
|
|
39
|
+static char *asm_match_generator(const char *text, int state)
|
|
40
|
+{
|
|
41
|
+ //dprintf(2,"2 '%s' %d\n", text, state);
|
|
42
|
+ return NULL;
|
|
43
|
+}
|
44
|
44
|
|
45
|
|
- if(ptrace(PTRACE_ATTACH, cpid, 0, 0) == -1)
|
46
|
|
- {
|
47
|
|
- perror("Unable to attach to child process");
|
48
|
|
-
|
49
|
|
- goto err_cleanup;
|
50
|
|
- }
|
51
|
45
|
|
52
|
|
- if(waitpid(cpid, &wstatus, 0) < 0)
|
53
|
|
- {
|
54
|
|
- perror("Unable to wait for child process to stop");
|
55
|
|
- goto err_cleanup;
|
56
|
|
- }
|
57
|
|
- if(!WIFSTOPPED(wstatus))
|
58
|
|
- {
|
59
|
|
- dprintf(2, "Wstatus = %d\n", wstatus);
|
60
|
|
- goto err_cleanup;
|
61
|
|
- }
|
|
46
|
+static char **asmsh_completion(const char *text, int start, int end)
|
|
47
|
+{
|
|
48
|
+ rl_attempted_completion_over = 1;
|
|
49
|
+ //dprintf(2,"\n'%s' '%s' %d %d\n", rl_line_buffer, text, start, end);
|
|
50
|
+ return rl_completion_matches(text, asm_match_generator);
|
|
51
|
+}
|
62
|
52
|
|
63
|
53
|
|
64
|
|
- //read(sigpipe[0], &sigbuf, 1); // sync message
|
65
|
|
- printf("Attached to %d\n", cpid);
|
66
|
|
- if(ptrace(PTRACE_SETOPTIONS, cpid, NULL, PTRACE_O_TRACEEXEC) < 0)
|
67
|
|
- {
|
68
|
|
- perror("Setoptions error");
|
69
|
|
- goto err_cleanup;
|
70
|
|
- }
|
|
54
|
+int main(int argc, char *argv[], char *envp[])
|
|
55
|
+{
|
|
56
|
+ asmsh_asmc_ctx_t *cctx;
|
|
57
|
+ asmsh_env_t *env;
|
|
58
|
+ asmsh_bytecode_t bcode;
|
71
|
59
|
|
72
|
|
- if(ptrace(PTRACE_CONT, cpid, NULL, 0) < 0)
|
73
|
|
- {
|
74
|
|
- perror("CONT error");
|
75
|
|
- goto err_cleanup;
|
76
|
|
- }
|
|
60
|
+ int ret, status;
|
|
61
|
+ char *cmd;
|
77
|
62
|
|
78
|
|
- if(waitpid(cpid, &wstatus, 0) < 0)
|
|
63
|
+ if(!(env = asmsh_env(CHILD_EXEC_PATH)))
|
79
|
64
|
{
|
80
|
|
- perror("Unable to wait for child process to stop");
|
81
|
|
- goto err_cleanup;
|
|
65
|
+ perror("Unable to init asm_env");
|
|
66
|
+ return 1;
|
82
|
67
|
}
|
83
|
|
- if(wstatus >> 8 != (SIGTRAP | (PTRACE_EVENT_EXEC<<8)))
|
|
68
|
+ if(!(cctx = asmsh_asmc_ctx_default()))
|
84
|
69
|
{
|
85
|
|
- dprintf(2, "Wstatus = %d\n", wstatus);
|
86
|
|
- goto err_cleanup;
|
|
70
|
+ perror("Unable to init compilation ctx");
|
87
|
71
|
}
|
88
|
72
|
|
89
|
|
- // first syscall is execve ret
|
90
|
|
- // then mmap in & out
|
91
|
|
- for(int i=0; i<3; i++)
|
92
|
|
- {
|
93
|
|
- if(ptrace(PTRACE_SYSCALL, cpid, NULL, 0) < 0)
|
94
|
|
- {
|
95
|
|
- perror("CONT error");
|
96
|
|
- goto err_cleanup;
|
97
|
|
- }
|
98
|
|
- printf("syscall sent, waiting child to stop\n");
|
|
73
|
+ rl_attempted_completion_function = asmsh_completion;
|
99
|
74
|
|
100
|
|
- if(waitpid(cpid, &wstatus, 0) < 0)
|
|
75
|
+ while(1)
|
|
76
|
+ {
|
|
77
|
+ print_regs(env);
|
|
78
|
+ cmd = readline("asmsh> ");
|
|
79
|
+ if(!cmd)
|
101
|
80
|
{
|
102
|
|
- perror("Unable to wait for child process to stop");
|
103
|
|
- goto err_cleanup;
|
|
81
|
+ break;
|
104
|
82
|
}
|
105
|
|
- if(wstatus != 1407)
|
|
83
|
+ if(strcmp(cmd, "quit") == 0)
|
106
|
84
|
{
|
107
|
|
- dprintf(2, "Wstatus = %d\n", wstatus);
|
108
|
|
- goto err_cleanup;
|
|
85
|
+ break;
|
109
|
86
|
}
|
110
|
|
- }
|
111
|
|
- printf("mmap done ?\n");
|
112
|
|
-
|
113
|
|
-
|
114
|
|
- bzero(®s, sizeof(regs));
|
115
|
|
- if(ptrace(PTRACE_GETREGS, cpid, NULL, ®s) < 0)
|
116
|
|
- {
|
117
|
|
- perror("GETREGS error");
|
118
|
|
- goto err_cleanup;
|
119
|
|
- }
|
120
|
|
-
|
121
|
|
- printf("rax = %016llX rsp=%016llX r15=%016llX rip=%016llX\n",
|
122
|
|
- regs.rax, regs.rsp, regs.r15, regs.rip);
|
123
|
|
-
|
124
|
|
- /*
|
125
|
|
- if((pret = ptrace(PTRACE_PEEKTEXT, cpid, regs.rsp, 0)) < 0)
|
126
|
|
- {
|
127
|
|
- perror("PEEKTEXT fails");
|
128
|
|
- goto err_cleanup;
|
129
|
|
- }
|
130
|
|
-
|
131
|
|
- printf("mmap_addr : %08lx", pret);
|
132
|
|
-
|
133
|
|
- if((pret = ptrace(PTRACE_PEEKTEXT, cpid, regs.rsp+sizeof(long), 0)) < 0)
|
134
|
|
- {
|
135
|
|
- perror("PEEKTEXT fails");
|
136
|
|
- goto err_cleanup;
|
137
|
|
- }
|
138
|
|
- printf(" %08lx\n", pret);
|
139
|
|
- */
|
140
|
|
- char mapfile[256];
|
141
|
|
- snprintf(mapfile, 256, "/proc/%d/maps", cpid);
|
142
|
|
- int mapfd = open(mapfile, O_RDONLY);
|
143
|
|
- char buff[256];
|
144
|
|
- int read_ret;
|
145
|
|
-
|
146
|
|
- do
|
147
|
|
- {
|
148
|
|
- read_ret = read(mapfd, buff, 255);
|
149
|
|
- buff[read_ret] = '\0';
|
150
|
|
- if(read_ret)
|
|
87
|
+ ret = asmsh_asmc_compile(cctx, cmd, &bcode);
|
|
88
|
+ if(ret < 0)
|
151
|
89
|
{
|
152
|
|
- printf("%s", buff);
|
|
90
|
+ perror("Invalid instruction");
|
|
91
|
+ continue;
|
153
|
92
|
}
|
154
|
|
- }while(read_ret > 0);
|
155
|
|
-
|
156
|
|
- printf("Exiting...\n");
|
157
|
|
- kill(cpid, SIGKILL);
|
158
|
|
- exit(0);
|
159
|
|
-
|
160
|
|
-err_cleanup:
|
161
|
|
- /*
|
162
|
|
- if(waitpid(cpid, &wstatus, 0) < 0)
|
|
93
|
+ if(asmsh_env_write_code(env, &bcode))
|
163
|
94
|
{
|
164
|
|
- perror("Unable to wait for child process to stop");
|
165
|
|
- goto err_cleanup;
|
|
95
|
+ perror("Unable to write instruction");
|
|
96
|
+ goto err;
|
166
|
97
|
}
|
167
|
|
- if(WIFEXITED(wstatus))
|
|
98
|
+ ret = asmsh_env_step(env, &status);
|
|
99
|
+ if(ret)
|
168
|
100
|
{
|
169
|
|
- dprintf(2, "child exited with status %d\n", WEXITSTATUS(wstatus));
|
170
|
|
-
|
171
|
|
- } else if(WCOREDUMP(wstatus)) {
|
172
|
|
- dprintf(2, "child segfault\n");
|
173
|
|
- } else if(WIFSTOPPED(wstatus)) {
|
174
|
|
- dprintf(2, "child stopped\n");
|
175
|
|
- } else {
|
176
|
|
- dprintf(2, "Wstatus = %d\n", wstatus);
|
|
101
|
+ if(WIFEXITED(status))
|
|
102
|
+ {
|
|
103
|
+ printf("exited with status %d\n", WEXITSTATUS(status));
|
|
104
|
+ }
|
|
105
|
+ else if(WCOREDUMP(status))
|
|
106
|
+ {
|
|
107
|
+ printf("SEGFAULT");
|
|
108
|
+ goto err;
|
|
109
|
+ }
|
|
110
|
+ else
|
|
111
|
+ {
|
|
112
|
+ printf("Unknown status %d\n", status);
|
|
113
|
+ goto err;
|
|
114
|
+ }
|
|
115
|
+ break;
|
177
|
116
|
}
|
178
|
|
- */
|
179
|
|
-
|
180
|
|
- dprintf(2, "Hardkill %d\n", cpid);
|
181
|
|
- kill(cpid, SIGKILL);
|
182
|
|
- exit(2);
|
|
117
|
+ add_history(cmd);
|
|
118
|
+ }
|
183
|
119
|
|
184
|
|
-}
|
|
120
|
+ asmsh_asmc_ctx_free(cctx);
|
|
121
|
+ asmsh_env_free(env);
|
|
122
|
+ return 0;
|
185
|
123
|
|
186
|
|
-void child_process(char * argv[], char *envp[], int sigpipe[2])
|
187
|
|
-{
|
188
|
|
- char sigbuf = '\0';
|
189
|
|
- //char* const argv[] = {"child"};
|
190
|
|
- //char* const envp[] = {};
|
191
|
|
- /*
|
192
|
|
- if(ptrace(PTRACE_TRACEME, 0,0,0) < 0)
|
193
|
|
- {
|
194
|
|
- perror("Unable to TRACEME");
|
195
|
|
- exit(5);
|
196
|
|
- }
|
197
|
|
- printf("TRACEME %d [OK]\n", getpid());
|
198
|
|
- */
|
199
|
|
- //write(sigpipe[1], &sigbuf, 1); // sync message
|
200
|
|
- printf("%d execve\n", getpid());
|
201
|
|
- execve(CHILD_EXEC_PATH, argv, envp);
|
202
|
|
- perror("Unable to execve");
|
203
|
|
- exit(5);
|
|
124
|
+err:
|
|
125
|
+ asmsh_asmc_ctx_free(cctx);
|
|
126
|
+ asmsh_env_free(env);
|
|
127
|
+ return 1;
|
204
|
128
|
}
|