Exemple #1
0
// TODO: taskswitch handling
static void save_state_to_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
{
    X86CPU *x86_cpu = X86_CPU(cpu);
    CPUX86State *env = &x86_cpu->env;

    /* CR3 and ldt selector are not saved intentionally */
    tss->eip = EIP(env);
    tss->eflags = EFLAGS(env);
    tss->eax = EAX(env);
    tss->ecx = ECX(env);
    tss->edx = EDX(env);
    tss->ebx = EBX(env);
    tss->esp = ESP(env);
    tss->ebp = EBP(env);
    tss->esi = ESI(env);
    tss->edi = EDI(env);

    tss->es = vmx_read_segment_selector(cpu, R_ES).sel;
    tss->cs = vmx_read_segment_selector(cpu, R_CS).sel;
    tss->ss = vmx_read_segment_selector(cpu, R_SS).sel;
    tss->ds = vmx_read_segment_selector(cpu, R_DS).sel;
    tss->fs = vmx_read_segment_selector(cpu, R_FS).sel;
    tss->gs = vmx_read_segment_selector(cpu, R_GS).sel;
}
Exemple #2
0
static int
_mmap_data(int pid, size_t len, void *base_address, int protections, int flags, void **out)
{
  int ret = 0;
  unsigned char *shellcode = NULL;
  
  FILE *f = fopen(MMAP_ASM, "rb");
  CHECK(f, "Error opening " MMAP_ASM);
  CHECK(fseek(f, 0, SEEK_END) == 0, "fseek error");
  long shellcode_len = ftell(f);
  CHECK(shellcode_len > 0, "ftell error");
  // align shellcode size to 32/64-bit boundary
  long shellcode_len_aligned = shellcode_len + (sizeof(void*) - (shellcode_len % sizeof(void*)));
  CHECK(fseek(f, 0, SEEK_SET) == 0, "fseek error");
  shellcode = malloc(shellcode_len_aligned);
  memset(shellcode, 0x90, shellcode_len_aligned); // fill with NOPs
  CHECK(shellcode, "malloc error");
  size_t r = fread(shellcode, 1, shellcode_len, f);
  CHECK(r == (size_t)shellcode_len, "fread error: %ld %ld", r, shellcode_len);
  fclose(f);
  
  // get current registers
  struct user_regs_struct orig_regs, regs = {0};
  CHECK(ptrace_getregs(pid, &regs),
	"Failed to get registers of target process");
  orig_regs = regs;
  
  // put our arguments in the proper registers (see mmap{64,32}.asm)
#ifdef __i386__
  regs.ebx = (long)base_address;
  regs.ecx = (long)len;
  regs.edx = (long)((protections) ? protections : MMAP_PROTS);
  regs.esi = (long)((flags) ? flags : MMAP_FLAGS);
#elif defined(__x86_64__)
  regs.rdi = (unsigned long long)base_address;
  regs.rsi = (unsigned long long)len;
  regs.rdx = (unsigned long long)((protections) ? protections : MMAP_PROTS);
  regs.r10 = (unsigned long long)((flags) ? flags : MMAP_FLAGS);
#endif
  CHECK(ptrace_setregs(pid, &regs),
	"Failed to set registers of target process");
  dprintf("Wrote our shellcode parameters into process registers");
  
  // write mmap code to target process EIP
  CHECK(ptrace_writemem(pid, (void*)EIP(&regs), shellcode, shellcode_len_aligned),
	"Failed to write mmap code to target process");
  dprintf("Wrote mmap code to EIP %p", (void*)EIP(&regs));
  
  // run mmap code and check return value
  CHECK(ptrace_continue(pid, 0), "Failed to execute mmap code");
  CHECK(_wait_trap(pid), "Error waiting for interrupt");
  dprintf("Mmap() finished execution");
  
  // get return value from mmap()
  CHECK(ptrace_getregs(pid, &regs),
	"Failed to get registers of target process");
  *out = (void*)EAX(&regs);
  dprintf("Mmap() returned %p", *out);
  CHECK(*out != MAP_FAILED, "Mmap() returned error");
  
  // restore registers
  CHECK(ptrace_setregs(pid, &orig_regs),
	"Failed to restore registers of target process");
  dprintf("Restored registers of target process");
  
  ret = 1;
error:
  if (shellcode)
    free(shellcode);
  return ret;
}
Exemple #3
0
static int
_launch_payload(int pid, void *code_cave, size_t code_cave_size, void *stack_address, size_t stack_size, void *payload_address, size_t payload_len, void *payload_param, int flags)
{
  int ret = 0;
  unsigned char *shellcode = NULL;
  FILE *f = fopen(CLONE_ASM, "rb");
  CHECK(f, "Error opening " CLONE_ASM);
  CHECK(fseek(f, 0, SEEK_END) == 0, "fseek error");
  long shellcode_len = ftell(f);
  CHECK(shellcode_len > 0, "ftell error");
  CHECK(shellcode_len <= code_cave_size, "Shellcode is too big (%ld) for allocated code cave", shellcode_len);
  CHECK(fseek(f, 0, SEEK_SET) == 0, "fseek error");
  shellcode = malloc(code_cave_size);
  CHECK(shellcode, "malloc error");
  memset(shellcode, 0x90, code_cave_size); // fill with NOPs
  size_t r = fread(shellcode, 1, shellcode_len, f);
  CHECK(r == (size_t)shellcode_len, "fread error: %ld %ld", r, shellcode_len);
  fclose(f);
  
  // get current registers
  struct user_regs_struct regs = {0};
  CHECK(ptrace_getregs(pid, &regs),
	"Failed to get registers of target process");
  
  // put our arguments in the proper registers (see clone{64,32}.asm)
#ifdef __i386__
  regs.eax = (long)code_cave_size;
  regs.ebx = (long)((flags) ? flags : CLONE_FLAGS);
  regs.ecx = (long)stack_address;
  regs.edx = (long)stack_size;
  regs.esi = (long)payload_address;
  regs.edi = (long)payload_len;
  regs.ebp = (long)payload_param;
#elif defined(__x86_64__)
  regs.rax = (unsigned long long)code_cave_size;
  regs.rdi = (unsigned long long)((flags) ? flags : CLONE_FLAGS);
  regs.rsi = (unsigned long long)stack_address;
  regs.rdx = (unsigned long long)stack_size;
  regs.rcx = (unsigned long long)payload_address;
  regs.r8  = (unsigned long long)payload_len;
  regs.r9  = (unsigned long long)payload_param;
#endif
  // move EIP to our code cave
  EIP(&regs) = ADDR2INT(code_cave);
  CHECK(ptrace_setregs(pid, &regs),
	"Failed to set registers of target process");
  dprintf("Wrote our shellcode parameters into process registers. EIP: %p", code_cave);
  
  // write shellcode to target process code cave
  CHECK(ptrace_writemem(pid, code_cave, shellcode, code_cave_size),
	"Failed to write clone trampoline code to target process");
  dprintf("Wrote clone trampoline code to address %p", code_cave);
  
  // run shellcode and check return value
  CHECK(ptrace_continue(pid, code_cave), "Failed to execute clone trampoline code");
  CHECK(_wait_trap(pid), "Error waiting for interrupt");
  dprintf("Clone() finished execution");
  CHECK(ptrace_getregs(pid, &regs),
	"Failed to get registers of target process");
  dprintf("New thread ID: %lld", EAX(&regs));
  CHECK((int)EAX(&regs) != -1, "Clone() returned error");
  
  // no need to restore registers, as we're about to call _restore_state()
  
  dprintf("Successfully launched payload");
  
  ret = 1;
error:
  if (ret == 0)
    dprintf("Failed to launch payload");
  if (shellcode)
    free(shellcode);
  return ret;
}