implement thread register read and write. needs more testing
This commit is contained in:
parent
0196d39a4b
commit
a7fc495381
3 changed files with 42 additions and 2 deletions
|
|
@ -2,6 +2,7 @@
|
|||
#define __PROCESS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
typedef enum {
|
||||
UNINTERRUPTABLE_SLEEP = 'D',
|
||||
|
|
@ -61,4 +62,10 @@ int process_attach_all(process_status_t* threads, size_t thread_count);
|
|||
// detaches from all threads
|
||||
void process_detach_all(process_status_t* threads, size_t thread_count);
|
||||
|
||||
// read registers of thread. returns 0 on success, 1 on error
|
||||
int process_read_registers(process_status_t* thread, struct user_regs_struct* regs);
|
||||
|
||||
// write registers for thread. for return value same rules apply as read registers function
|
||||
int process_write_registers(process_status_t* thread, const struct user_regs_struct* regs);
|
||||
|
||||
#endif
|
||||
14
src/main.c
14
src/main.c
|
|
@ -3,6 +3,7 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "process.h"
|
||||
|
||||
|
|
@ -89,8 +90,17 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
puts("attached to all threads. press any key");
|
||||
getc(stdin);
|
||||
puts("attached to all threads. please enter address of destination");
|
||||
void* destination;
|
||||
scanf("%p", &destination);
|
||||
|
||||
struct user_regs_struct regs;
|
||||
if (process_read_registers(active, ®s))
|
||||
fprintf(stderr, "failed to read registers: %s\n", strerror(errno));
|
||||
// hijack instruction pointer to our destination
|
||||
regs.rip = (uintptr_t)destination;
|
||||
if (process_write_registers(active, ®s))
|
||||
fprintf(stderr, "failed to write registers: %s\n", strerror(errno));
|
||||
|
||||
process_detach_all(threads, thread_count);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include <sys/capability.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/uio.h>
|
||||
#include <linux/elf.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
|
@ -278,4 +280,25 @@ int process_attach_all(process_status_t* threads, size_t thread_count)
|
|||
void process_detach_all(process_status_t* threads, size_t thread_count)
|
||||
{
|
||||
while (thread_count--) ptrace(PTRACE_DETACH, threads[thread_count].pid, NULL, NULL);
|
||||
}
|
||||
|
||||
int process_read_registers(process_status_t* thread, struct user_regs_struct* regs)
|
||||
{
|
||||
struct iovec data = {
|
||||
.iov_base = regs,
|
||||
.iov_len = sizeof(struct user_regs_struct)
|
||||
};
|
||||
memset(regs, '\0', sizeof(struct user_regs_struct));
|
||||
|
||||
return ptrace(PTRACE_GETREGSET, thread->pid, NT_PRSTATUS, &data) < 0;
|
||||
}
|
||||
|
||||
int process_write_registers(process_status_t* thread, const struct user_regs_struct* regs)
|
||||
{
|
||||
struct iovec data = {
|
||||
.iov_base = (void*)regs,
|
||||
.iov_len = sizeof(struct user_regs_struct)
|
||||
};
|
||||
|
||||
return ptrace(PTRACE_SETREGSET, thread->pid, NT_PRSTATUS, &data) < 0;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue