Skip to content
This repository has been archived by the owner on May 16, 2019. It is now read-only.

Commit

Permalink
Finished API and implementation
Browse files Browse the repository at this point in the history
needs more documentation though


temp


wtf just happened


informative commit message


woa
  • Loading branch information
Lenni Hein committed Dec 1, 2018
1 parent b6e0faf commit 7808b2f
Show file tree
Hide file tree
Showing 16 changed files with 265 additions and 67 deletions.
40 changes: 40 additions & 0 deletions MiniBug/api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <stdint.h>

#define __MSG_SIZE__ 0x40
#define __REQ_SIZE__ 0x10

typedef struct MESSAGE
{
char str[64];
}MESSAGE;

typedef struct REQUEST
{
uint64_t control;
uint64_t value;
}REQUEST;

// careful with stack alignment
// https://stackoverflow.com/a/5435890/8114293
// #define __REQ_SIZE__ sizeof(struct REQUEST)

// REQUESTS

// control

#define __EOF__ 0x00
#define __REQ_REP__ 0x01
#define __CMD__ 0x02
#define __RECEIVED__ 0x03
#define __DATA_SIZE__ 0x04
#define __VALUE__ 0x05
#define __UNRECOGN__ 0x06

// value

#define __ANY__ 0x00
#define __EXIT__ 0x01

#define __PEEK_REG__ 0x11

#define __NEXT_SYSCALL__ 0x21 // TODO
18 changes: 18 additions & 0 deletions MiniBug/assertion.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "assertion.h"

void __assertion_failed__(char *file, int line, char *msg, int do_exit)
{
fprintf(stderr, "ASSERT%s: %s : %i\n", do_exit ? " " : "(soft)", file, line);
if(msg) fprintf(stderr, "MESSAGE%s: %s\n", do_exit ? " " : " ", msg);
if(do_exit) exit(EXIT_FAILURE);
}

void print_bytes(void *ptr, int size)
{
unsigned char *p = ptr;
int i;
for (i=0; i<size; i++) {
printf("0x%02hhX ", p[i]);
}
printf("\n");
}
12 changes: 12 additions & 0 deletions MiniBug/assertion.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <stdio.h>
#include <stdlib.h>

#define assert(expr, msg) \
if (!(expr)) \
__assertion_failed__(__FILE__, __LINE__, msg, 1)

#define assert_soft(expr, msg) if(!(expr))__assertion_failed__(__FILE__,__LINE__,msg,0)

void __assertion_failed__(char *file, int line, char *msg, int do_exit);

void print_bytes(void *ptr, int size);
21 changes: 21 additions & 0 deletions MiniBug/functions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "functions.h"

void peek_reg(pid_t pid, int fd)
{
int err;
REQUEST req;
req.control = __RECEIVED__;
req.value = __ANY__;
write(fd, &req, __REQ_SIZE__);

err = read(fd, &req, __REQ_SIZE__);
assert(err == __REQ_SIZE__, "");

int rax = ptrace(PTRACE_PEEKUSER, pid, req.value, NULL);

req.control = __VALUE__;
req.value = rax;
write(fd, &req, __REQ_SIZE__);

printf("> Peek Reg\n");
}
13 changes: 13 additions & 0 deletions MiniBug/functions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Functions
*
* every function has the same signature (apart from the name).
*
* void FUNCTION_NAME(pid_t pid, int fd);
*
*/

#include "api.h"
#include "khh.h"

void peek_reg(pid_t pid, int fd);
57 changes: 31 additions & 26 deletions MiniBug/khh.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,39 @@
// misc
#include <string.h>
#include <sys/wait.h> // waitpid
#include <signal.h>

// defines
#define __PORT__ 4711
#define __SOCKET_PATH__ "tmp_sock"
#define __MSG_SIZE__ 64

/* assert
Assertions
void assert(expr, char* msg);
void assert_soft(expr, char* msg);
assert() checks `expr`, if the expression is `false` assert() will produce output on the stderr, including `msg`.
assert() will then exit the program with `EXIT_FAILURE`, assert_soft() will only produce the warning.
Attention: side effects in assert() will take place, e.g. `assert(++i == 0, "");` will increment i regardless of check.
*/
#define assert(expr, msg) \
if (!(expr)) \
__assertion_failed__(__FILE__, __LINE__, msg, 1)

#define assert_soft(expr, msg) if(!(expr))__assertion_failed__(__FILE__,__LINE__,msg,0)

void __assertion_failed__(char* file, int line, char* msg, int do_exit)
{
fprintf(stderr, "ASSERT%s: %s : %i\n", do_exit?" ":"(soft)", file, line);
if(msg) fprintf(stderr, "MESSAGE%s: %s\n", do_exit?" ":" ",msg);
if(do_exit) exit(EXIT_FAILURE);
}
#include "assertion.h"

// registers
# define R15 8*00
# define R14 8*01
# define R13 8*02
# define R12 8*03
# define RBP 8*04
# define RBX 8*05
# define R11 8*06
# define R10 8*07
# define R9 8*08
# define R8 8*09
# define RAX 8*10
# define RCX 8*11
# define RDX 8*12
# define RSI 8*13
# define RDI 8*14
# define ORIG_RAX 8*15
# define RIP 8*16
# define CS 8*17
# define EFLAGS 8*18
# define RSP 8*19
# define SS 8*20
# define FS_BASE 8*21
# define GS_BASE 8*22
# define DS 8*23
# define ES 8*24
# define FS 8*25
# define GS 8*26
15 changes: 7 additions & 8 deletions MiniBug/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,22 @@ DEPS := $(wildcard *.h)

dir_exists: | $(DIR)

%.o: %.c
@gcc -c -o $(DIR)$@ $^ $(CFLAGS) $(LIBS)
$(DIR)%.o: %.c
@gcc -c -o $@ $^ $(CFLAGS) $(LIBS)

compile_mdb: mdb.o
@gcc -o $(DIR)mdb $(DIR)$^ $(CFLAGS) $(LIBS)
# todo: OBJECTS PATSUBST
compile_mdb: $(DIR)mdb.o $(DIR)functions.o $(DIR)assertion.o
@gcc -o $(DIR)mdb $^ $(CFLAGS) $(LIBS)

compile_mview: mview.o
@gcc -o $(DIR)mview $(DIR)$^ $(CFLAGS) $(LIBS)
compile_mview: $(DIR)mview.o $(DIR)assertion.o
@gcc -o $(DIR)mview $^ $(CFLAGS) $(LIBS)

clean: | compile_all
@rm -r -f $(DIR)

mdb: | compile_mdb
@./$(DIR)mdb

# @rm tmp_sock # existence of tmp_sock creates problems with binding a berkeley socket

mview: | compile_mview
@./$(DIR)mview

Expand Down
86 changes: 64 additions & 22 deletions MiniBug/mdb.c
Original file line number Diff line number Diff line change
@@ -1,29 +1,72 @@
#include "mdb.h"

/* could be useful
*
* void checked_read(int fd, char* buf) { assert((int) read(fd, buf, __MSG_SIZE__)) == __MSG_SIZE__, "read unsuccessful"); }
*
* or a macro?
*
* #define checked_read(fd,buf) err=(int)read(fd,buf,__MSG_SIZE__);assert(err==__MSG_SIZE__,"read\ unsuccessful");
*/

int main()
{
// initialise
fprintf(stderr, "MiniBug service started\n");
init_log();
int fd = init_net();
int err;
char buf[__MSG_SIZE__];

char buf[__MSG_SIZE__];
memset(buf, 0, __MSG_SIZE__);
err = read(fd, buf, __MSG_SIZE__);
// awaiting target from client
err = (int) read(fd, buf, __MSG_SIZE__);
assert(err == __MSG_SIZE__, "read unsuccessful");
printf("%s\n", buf);

// creating and tracing tracee
pid_t pid = init_tracee(buf);
// tracee now created and traced

// notifying client
strncpy(buf, "successful", __MSG_SIZE__);
write(fd, buf, __MSG_SIZE__);
// client notified

// debug routine
debug_loop(pid, fd);

// destroy
fprintf(stderr, "MiniBug shutting down (EXIT_SUCCESS)\n");
unlink(__SOCKET_PATH__); // free up file for further use on next startup
return EXIT_SUCCESS;
}

void debug_loop(pid_t pid, int fd)
{
int err;
REQUEST req;

loop: printf("> debug loop .... \n");
err = (int) read(fd, &req, __REQ_SIZE__);
assert(err == __REQ_SIZE__, "read unsuccessful");
assert(req.control == __CMD__, "did not receive a command");

switch(req.value)
{
case __EXIT__: goto exit;
case __PEEK_REG__: peek_reg(pid, fd); break;

default: printf("> unrecognised command .. awaiting another\n");
req.control = __UNRECOGN__;
req.value = __ANY__;
write(fd, &req, __REQ_SIZE__);
break;
}
goto loop;

exit: err = kill(pid, SIGKILL);
assert(err != -1, "killing tracee failed");
printf("> EXIT\n");
}

int init_net()
{
int fd, socket_fd;
Expand All @@ -35,7 +78,7 @@ int init_net()
assert(socket_fd != -1, "Socket Creation Failed");
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, __SOCKET_PATH__, strlen(__SOCKET_PATH__) + 1);
sockaddr_un_len = strlen(server_addr.sun_path) + sizeof(server_addr.sun_family);
sockaddr_un_len = (socklen_t) strlen(server_addr.sun_path) + sizeof(server_addr.sun_family);

// check if file already exists
int err = access(__SOCKET_PATH__, F_OK); // file exists -> err := zero
Expand All @@ -45,41 +88,39 @@ int init_net()
err = bind(socket_fd, (struct sockaddr *) &server_addr, sockaddr_un_len);
assert(err != -1, "Bind failed");

printf("listening: ..");
printf("> listening ..");

err = listen(socket_fd, 5);
assert(err != -1, "Listen failed");

fd = accept(socket_fd, (struct sockaddr *) &client_addr, &sockaddr_un_len);
fd = accept(socket_fd, (struct sockaddr *) &client_addr, &sockaddr_un_len);
assert(fd != -1, "Accept failed");

printf(".. Connection established\n");

return fd;
}

pid_t init_tracee(char* str)
pid_t init_tracee(char *str)
{
//convert string to tokens
int counter = 1;
for(int i = 0; str[i] != 0x0; i++)
{
if(str[i] == 32) counter++;
}
char** tokens = malloc(sizeof(void*) * counter);
char **tokens = malloc(sizeof(void *) * counter);
counter = 0;
tokens[0] = str+counter;
tokens[0] = str + counter;
for(int i = 0; str[i] != 0x0; i++)
{
if(str[i] == 32)
if(str[i] == 32)
{
tokens[++counter] = str+i+1;
tokens[++counter] = str + i + 1;
str[i] = 0x0;
}
}

fprintf(stderr, "%s", tokens[0]);

// create tracee
pid_t pid;
int status, err;
Expand All @@ -89,26 +130,27 @@ pid_t init_tracee(char* str)
if(!(pid)) // child
{
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
// close(STDOUT_FILENO);
// close(STDOUT_FILENO); // currently we are writing stdout to log.txt anyway
raise(SIGSTOP);
err = execvp(tokens[0], tokens);
exit(EXIT_FAILURE);
}
}

// wait for tracee
waitpid(pid, &status, 0);
assert(!WIFEXITED(status), "execvp() failed");
printf("Tracee created, traced, and interrupted\n");
printf("> Tracee created, traced, and interrupted\n");
return pid;
}

void init_log()
{
FILE* log_out = fopen("log.txt", "w");
int log_fd = fileno(log_out);
FILE *log_out = fopen("log.txt", "w");
int log_fd = fileno(log_out);
close(1); //closing stdout
dup(log_fd); //stdout is now written to "log.txt"
fclose(log_out); // closing stream
close(log_fd); // closing File Descriptor
// only stdout is open, and leads towards log.txt
printf("Log output redirected\n");
// only stdout is open, and leads towards log.txt
printf("> Log output redirected\n");
}
6 changes: 4 additions & 2 deletions MiniBug/mdb.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "khh.h"
#include "functions.h"

int init_net(); // initialises berkeley socket server

void init_log(); // closes `stdout` and redirects every output to `stdout` to `log.txt`

pid_t init_tracee(char* str); // starts and traces tracee
pid_t init_tracee(char *str); // starts and traces tracee

void debug_loop(pid_t pid, int fd);
Loading

0 comments on commit 7808b2f

Please sign in to comment.