Exemple #1
0
// Allocate a new handler
struct Handler* get_handler(pid_t pid, unsigned ip, struct Option* opt){
    HANDLER_ID hid;
    struct Handler *handler_p;
    unsigned buff, backup;

    hid = GETID(ip);
    handler_p = (struct Handler*)malloc(sizeof(struct Handler));
    handler_p -> global_flag = FALSE;
    handler_p -> option = opt;

    // If already exists a breakpoint at this instruction
    if (handlers[hid]){
        backup = handlers[hid] -> backup;
    }else{
    // Else, place a new breakpoint
        // Read the address of bp, making backup
        backup = Ptrace(PTRACE_PEEKTEXT, pid, (void*)ip, NULL);
        buff = (backup&0xffffff00) | 0xcc;
        Ptrace(PTRACE_POKETEXT, pid, (void*)ip, (void*)buff);
    }

    // IP is not breakpoint, just additional information
    handler_p -> ip = ip;
    handler_p -> backup = backup;
    handler_p -> life = opt->life;

    if (handlers[hid]) handlers[hid]->prev_handler = handler_p;
    handler_p -> next_handler = handlers[hid];
    handler_p -> prev_handler = NULL;
    handlers[hid] = handler_p;

    return handler_p;
}
Exemple #2
0
// ????????????????????STRANGE
void bp_show(pid_t pid, struct Handler* handler_p){
    unsigned backup, ip, buff;
    ip = handler_p -> ip;
    backup = Ptrace(PTRACE_PEEKDATA, pid, (void*)ip, NULL);
    buff = (backup&0xffffff00)|0xcc;
    Ptrace(PTRACE_POKETEXT, pid, (void*)ip, (void*)buff);
}
Exemple #3
0
void bp_hide(pid_t pid, struct Handler* handler_p){
    unsigned backup, ip;
    backup = handler_p -> backup;
    ip = handler_p -> ip;
    Ptrace(PTRACE_POKETEXT, pid, (void*)ip, (void*)backup);

    char inst_str[128];
    unsigned data;
    data = Ptrace(PTRACE_PEEKTEXT, pid, (void*)ip, NULL);
    get_single_instruction_word(data, inst_str, 128);
}
Exemple #4
0
enum __ptrace_request trace(pid_t pid, struct Handler* handler){
    unsigned ip, esp, ret;
    struct user_regs_struct regs;
    char inst_str[128];
    int len;
    Ptrace(PTRACE_GETREGS, pid, NULL, &regs);
    ip = regs.eip;
    // if ip is within a visible module. Output and trace on
    if (visible(ip, handler->option->trace_option.whitelist)){
        fprintf(handler->option->trace_option.file, "0x%x\n", ip);
        fflush(handler->option->trace_option.file);

        len = get_single_instruction_at(pid, ip, inst_str, 128);
        if (!strncmp(inst_str, "call", 4)){
            // If 'call', record the latest 'ret' addr
            get_global_handler(pid, ip + len, handler->option);
        }else{
            // If not 'call', hand on the latest 'ret' addr
            get_global_handler(pid, handler->ip, handler->option);
        }
        return PTRACE_SINGLESTEP;
    }else{
    // If not, run until the latest 'ret' addr
        get_handler(pid, handler->ip, handler->option);
        return PTRACE_CONT;
    }
}
Exemple #5
0
struct Handler* get_global_handler(pid_t pid, unsigned ip, struct Option* opt){
    struct Handler *handler_p;
    unsigned backup;
    unsigned hid;

    hid = GETID(ip);
    handler_p = (struct Handler*)malloc(sizeof(struct Handler));
    handler_p -> global_flag = TRUE;
    handler_p -> option = opt;

    // If already a breakpoint exists at this instruction
    // Then just copy the backup
    if (handlers[hid])
        backup = handlers[hid] -> backup;
    else
        backup = Ptrace(PTRACE_PEEKTEXT, pid, (void*)ip, NULL);

    // Not a breakpoint, just additional information
    handler_p -> ip = ip;
    handler_p -> backup = backup;
    handler_p -> life = opt -> life;

    if (global_handler) global_handler -> prev_handler = handler_p;
    handler_p -> next_handler = global_handler;
    handler_p -> prev_handler = NULL;
    global_handler = handler_p;
    return handler_p;
}
Exemple #6
0
int get_single_instruction_at(pid_t pid, unsigned ip, char* str, size_t bufsize){
    unsigned data;
    int len;
    data = Ptrace(PTRACE_PEEKTEXT, pid, (void*)ip, NULL);
    len = get_single_instruction_word(data, str, bufsize);
    return len;
}
Exemple #7
0
enum __ptrace_request disable(pid_t pid, struct Handler* handler_p){
    unsigned ip;
    struct user_regs_struct regs;
    char inst_str[128];
    int len = 0;
    Ptrace(PTRACE_GETREGS, pid, NULL, &regs);
    ip = regs.eip;
    switch(handler_p->option->disable_option.api_type){
        case API_TYPE_NORMAL:
            // SHOULT DETECT ELAPPED HERE.
            do{
                ip += len;
                len = get_single_instruction_at(pid, ip, inst_str, 128);
            }while (!strncmp(inst_str, "ret", 3));
            regs.eip = ip;
            Ptrace(PTRACE_SETREGS, pid, NULL, &regs);
            return PTRACE_CONT;
        case API_TYPE_PLT:
            ip = Ptrace(PTRACE_PEEKTEXT, pid, (void*)regs.esp, NULL);
            regs.eip = ip;
            Ptrace(PTRACE_SETREGS, pid, NULL, &regs);
            return PTRACE_CONT;
    }
}
Exemple #8
0
int
__ptrace (int request, pid_t pid, caddr_t addr, int data)
{
	int retval;
	long tmp;
	
	if ((request == PT_READ_I) || (request == PT_READ_D))
		data = (int) &tmp;
	
	retval = Ptrace (request, pid, addr, data);
	if (retval < 0) {
		__set_errno (-retval);
		retval = -1;
		if (errno == ENOSYS) {
			fputs ("This system does not support the Ptrace() syscall!", stderr);
		}
	} else if (retval == 0) {
		if ((request == PT_READ_I) || (request == PT_READ_D)) {
			__set_errno (0);
			retval = tmp;
		}
	}
  	return retval;
}
Exemple #9
0
int main(){
    struct Handler *handler_p, *next_handler;
    unsigned hid;
    unsigned oep;
    // This is NOT THE PROPER WAY!!!
    unsigned siginfo[512];
    unsigned baseaddr, memsize;
    enum __ptrace_request pr, pr2;
    //struct user_regs_struct regs;
    //char inst_str[128];
    // Test
    const char *prog = "./try";
    //char indirect = 0;
    //char manual = 0;
    //char plt = 1;
    //int pop = 0;
    //ban = 0x0804841b;
    int wait_status;
    struct user_regs_struct regs;

    init();

    pid_t pid = fork();
    if (pid == 0){
        Ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl(prog, prog, NULL);
    }else if (pid > 0){
        oep = get_entry_point(prog);
        // On loaded
        wait(&wait_status);
        if (WIFSTOPPED(wait_status)){
            // Test, wrong
            memsize = get_memsize(prog);
            baseaddr = get_baseaddr(prog);
            add_module(&whitelist, baseaddr, memsize);
            get_handler(pid, oep, get_trace_option(fopen("/tmp/trace","w"), whitelist));
            get_handler(pid, 0x8048380, get_disable_option(API_TYPE_PLT));
            Ptrace(PTRACE_CONT, pid, NULL, NULL);
        }

        wait(&wait_status);
        // Withdraw control from plugins
        while (WIFSTOPPED(wait_status)){
            Ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo);
            // Caused by breakpoint
            if (siginfo[2] == 0x80){
                // Discard the 0xcc int 3 instruction
                // So move the eip upper by 1
                Ptrace(PTRACE_GETREGS, pid, NULL, &regs);
                regs.eip --;
                Ptrace(PTRACE_SETREGS, pid ,NULL, &regs);
            }

            // PTRACE_CONT by default because it has the lowest priority
            pr = PTRACE_CONT;
            hid = GETID(regs.eip);

            for (handler_p=global_handler;handler_p;handler_p=next_handler){
                next_handler = handler_p->next_handler;
                pr2 = dispatch(pid, handler_p);
                pr = PRIORITY(pr, pr2);
                pr2 = global_expire(pid, handler_p, &next_handler);
                pr = PRIORITY(pr, pr2);
            }
            for (handler_p=handlers[hid];handler_p;handler_p=next_handler){
                next_handler = handler_p->next_handler;
                pr2 = dispatch(pid, handler_p);
                pr = PRIORITY(pr, pr2);
                pr2 = expire(pid, handler_p, hid, &next_handler);
                pr = PRIORITY(pr, pr2);
            }
            Ptrace(pr, pid, NULL, NULL);
            wait(&wait_status);
        }
    }else{
        perror("Folk failed: ");
        exit(-1);
    }
    finalize();
    return 0;
}