Browse Source

First sheel implementation using GNU readline

Yann Weber 1 year ago
parent
commit
c97d54e149
4 changed files with 102 additions and 174 deletions
  1. 2
    2
      Makefile.am
  2. 96
    172
      asmsh.c
  3. 3
    0
      config.h.in
  4. 1
    0
      configure.ac

+ 2
- 2
Makefile.am View File

@@ -2,7 +2,7 @@ bin_PROGRAMS = asmsh child
2 2
 
3 3
 libcheck_asmsh_a_SOURCES = mmap_parse.c asm_env.c compile.c logger.c
4 4
 
5
-asmsh_SOURCES = asmsh.c $(libasmsh_a_SOURCES)
5
+asmsh_SOURCES = asmsh.c $(libcheck_asmsh_a_SOURCES)
6 6
 child_SOURCES = child.s
7 7
 
8 8
 asmsh_LDFLAGS=-g -O2
@@ -41,7 +41,7 @@ $(LCOV_HTML): $(LCOV_INFO)
41 41
 endif
42 42
 
43 43
 clean-local:
44
-	-rm -rf $(TO_CLEAN_LOCAL)
44
+	-rm -rf $(TO_LOCAL_CLEAN)
45 45
 
46 46
 endif
47 47
 

+ 96
- 172
asmsh.c View File

@@ -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(&regs, sizeof(regs));
115
-	if(ptrace(PTRACE_GETREGS, cpid, NULL, &regs) < 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
 }

+ 3
- 0
config.h.in View File

@@ -15,6 +15,9 @@
15 15
 /* Define to 1 if you have the <inttypes.h> header file. */
16 16
 #undef HAVE_INTTYPES_H
17 17
 
18
+/* Define to 1 if you have the `readline' library (-lreadline). */
19
+#undef HAVE_LIBREADLINE
20
+
18 21
 /* Define to 1 if you have the <limits.h> header file. */
19 22
 #undef HAVE_LIMITS_H
20 23
 

+ 1
- 0
configure.ac View File

@@ -68,6 +68,7 @@ AM_CONDITIONAL([HAVE_GCOV], [test -n "$GCOV"])
68 68
 AM_CONDITIONAL([HAVE_LCOV], [test -n "$LCOV"])
69 69
 
70 70
 # Checks for libraries.
71
+AC_CHECK_LIB(readline, readline)
71 72
 
72 73
 # Checks for header files.
73 74
 AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h unistd.h])

Loading…
Cancel
Save