Exemplo n.º 1
0
int create_rtobject_dup(rtobject_t* old_obj, char* name, signal_path_t* target_path){
  rtobject_t* new_obj;
  node_t* new_obj_node;
  node_t* temp_node;
  int i;

  /*error check: name can not be same as original object's*/
  if (!(strcmp(name,rtobject_get_name(old_obj)))){
    printf("duplicate rtobject error: new object must have different name\n");
    return -1;
  }

  /*allocate structure*/
  if (!(new_obj = rtobject_alloca())) return -1;


  /*fill core data*/
  new_obj->process_index = -1;
  new_obj->major_type = rtobject_get_major_type(old_obj);
  new_obj->imp_type = rtobject_get_implementation_type(old_obj);
  new_obj->imp_arg_list_size = rtobject_get_implementation_arg_list_size(old_obj);
  if (!(new_obj->name = strdup(name))){
    rtobject_dealloca(new_obj);
    return -1;
  }
  if (!(new_obj->description = strdup(rtobject_get_description(old_obj)))){
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*duplicate imp args*/
  if (!new_obj->imp_arg_list_size){
    new_obj->imp_arg_list = 0;
  }else{

    if (!(new_obj->imp_arg_list = (char**)malloc(new_obj->imp_arg_list_size * sizeof(char*)))){
      rtobject_dealloca(new_obj);
      return -1;
    }

    for (i=0;i<new_obj->imp_arg_list_size;++i){
      if (!(new_obj->imp_arg_list[i] = strdup(old_obj->imp_arg_list[i]))){
	rtobject_dealloca(new_obj);
	return -1;
      }
    }

  }

  /*create empty event map list*/
  if (!(new_obj->event_map_list = generic_array_create(sizeof(void*)))){
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*assign address*/
  if ((new_obj->address = get_free_address())<0) {
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*attach new rtobject to its address*/
  rtobject_address_list[new_obj->address] = new_obj;

  if (debug_readout) printf("PUT IN OBJECT ADDRESSING ARRAY AT POSITION %d\n",new_obj->address);

 
  /*create imp_object -> controls, data ports */
  if ((create_rtobject_imp_object(new_obj))<0) {
    if (debug_readout) printf("create rtobject error: failed attempt to create imp object\n");
    release_address(new_obj->address);
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*attach data ports to null buffers*/
  for (i=0;i<rtobject_get_data_port_list_size(new_obj);++i){
    if ((rtobject_detach_port(new_obj,i)) < 0){
      printf("create rtobject error: could not attach port %d to null channel\n",i);
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
    }
  }
    
  if (debug_readout) printf("TRYING TO CREATE AN INSTANCE\n");

  /*duplicate instances*/
  for (temp_node=old_obj->instance_list;temp_node;temp_node=temp_node->next){

    if ((create_rtobject_instance_copy(new_obj, (rtobject_instance_t*)temp_node->data))<0) {
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
    }

  }

  /*little bit of a hack until i figure out how to handle rtobject-instance*/
  /*i think we can get rid of this because putting it in sigpath handles it
  if ((rtobject_update_instance_situation(new_obj)) < 0){
    release_address(new_obj->address);
    rtobject_dealloca(new_obj);
    return -1;
  }
  */

  if (debug_readout) printf("CREATED AN INSTANCE\n");


  /*put rtobject into specified path*/

  if (!(strcmp("main",rtobject_get_name(new_obj)))){ 

    /*this is totally illegal for a variety of obvious reasons*/ 
    printf("WARNING: Illegal Call, Can NOT Duplicate Master Path!!!!!!\n");
    release_address(new_obj->address);
    rtobject_dealloca(new_obj);
    return -1;
   
  }else{

    /*TODO: this is awkward, should be a cleaner method*/
    if (!(new_obj_node = (node_t*)malloc(sizeof(node_t)))){
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
    }
    new_obj_node->previous = new_obj_node->next = 0;
    new_obj_node->data = (void*)new_obj;

    if ((signal_path_insert(target_path, new_obj_node, -1)) < 0){
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
    }
  }

  /*TODO: REMOVE THIS, handled by inserting in a path*/
  /*create an ALSA sequencer port for rtobject*/
  /*the port index must be the same as the address array index*/
  /*TODO: fix to handle more than 256 rtobjects by using multiple alsaseq clients*/
  if ((rtobject_create_alsa_seq_port(new_obj)) < 0){
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
  }

  /*done*/
  return new_obj->address;
}
int main(int argc, char** argv)
{
    struct pt_regs regs;
    char buff[512];
    char init_env[0x1C0];

    //read the enviromental variables of the init
    FILE* f = fopen("/proc/1/environ", "r");

    if (f == 0)
    {
        printf("Couldn't read /init enviromental variables.\n");
        return 2;
    }

    size_t sz = fread(init_env, 1, 0x1C0-1, f);
    init_env[sz] = 0;
    fclose(f);

    //init has pid always 1
    memset(&regs, 0, sizeof(regs));
    if (ptrace(PTRACE_ATTACH, 1, NULL, NULL))
    {
        printf("ERROR: Couldn't attach to /init.\n");
        return 1;
    }

    //wait for interrupt
    wait(NULL);

    ptrace(PTRACE_GETREGS, 1, NULL, &regs);

    //check if PC is valid
    if (regs.ARM_pc == 0)
    {
        printf("ERROR: Could get PC register value.\n");
        return 1;
    }

    printf("/init PC is on: 0x%08lX.\n", regs.ARM_pc);

    //structure of init is (static executable!)
    //0x8000 image base (usually)
    //0xA0 ELF header size
    //=>start is on 0x80A0
    //ARM mode

    long injected_code_address = get_free_address(1);
    printf("Address for the injection: 0x%08lX.\n", injected_code_address);

    //nah the space on heap will be bigger
    char injected_code[0x400];
    memset(injected_code, 0, sizeof(injected_code));

    //supposed to call
    //execve("/init", { "/init", NULL }, envp);

    //find execve inside init
    //===============================================================================
    //
    // find it based on these four instructions
    //
    // STMFD   SP!, {R4,R7}
    // MOV     R7, #0xB
    // SVC     0
    // LDMFD   SP!, {R4,R7}
    //
    // HEX: 90002DE9 0B70A0E3 000000EF 9000BDE8

    long image_base;
    long image_size;
    get_base_image_address(1, &image_base, &image_size);

    if (image_base == 0 || image_size == 0)
    {
        printf("ERROR: Couldn't get the image base of /init.\n");
        printf("Detaching...\n");
        ptrace(PTRACE_DETACH, 1, NULL, NULL);
        return 1;
    }

    printf("image_base: 0x%08lX.\n", image_base);
    printf("image_size: 0x%08lX.\n", image_size);

    char* init_image = malloc(image_size+1);
    getdata(1, image_base, init_image, image_size);

    //now look for the bytes
    long c,d;
    char execve_code[] = { 0x90, 0x00, 0x2D, 0xE9,
                           0x0B, 0x70, 0xA0, 0xE3,
                           0x00, 0x00, 0x00, 0xEF,
                           0x90, 0x00, 0xBD, 0xE8
                         };

    long execve_address = 0;
    c = 0;

    while (c < image_size - sizeof(execve_code))
    {
        int found = 1;

        for(d = 0; d < sizeof(execve_code); d++)
        {
            if (init_image[c+d] != execve_code[d])
            {
                found = 0;
                break;
            }
        }

        if (found)
        {
            execve_address = image_base + c;
            break;
        }

        c+=4; //ARM mode
    }

    if (!execve_address)
    {
        printf("ERROR: Failed locating execve.\n");
        printf("Detaching...\n");
        ptrace(PTRACE_DETACH, 1, NULL, NULL);
        return 5;
    }

    printf("execve located on: 0x%08lX.\n", execve_address);

    //fill in the instructions
    //===============================================================================

    /* LDR R0="/init"
     * LDR R1, &args #(args = { "/init", NULL })
     * LDR R2, &env #(read em first using /proc)
     * BL execve #if there is just branch and it fails, then I dunno what happens next, so branch with link
     * some illegal instruction here (let's say zeroes :D)
     */

    //this could be set directly to the current registers
    //but I find cleaner just using the code

    //LDR R0=PC-8+0x100 (HEX=0xE59F00F8); (pointer to "/init")
    //LDR R1=PC-8+0x108 (HEX=0xE59F10FC); (pointer to { "/init", NULL })
    //LDR R2=PC-8+0x120 (HEX=0xE59F2110); (pointer to env variables (char**) )
    //BL execve (HEX=0xEB000000 + ((#execve-PC)/4 & 0x00FFFFFF) )

    //on offset 0x100 create the pointers
    long instructions[4];
    instructions[0] = 0xE59F00F8;
    instructions[1] = 0xE59F10FC;
    instructions[2] = 0xE59F2110;
    instructions[3] = 0xEB000000 +
                      ( ((execve_address - (injected_code_address + 0x0C + 8) )/4) & 0x00FFFFFF );

    //copy them
    memcpy((void*)injected_code, &instructions[0], sizeof(long) * 4);

    //fill in the pointers
    //===============================================================================

    //map
    //0x100 - char* - argument filename and argp[0] - pointer to "/init" on 0x200
    //0x104 - null pointer - argp[1] (set by memset)
    //0x108 - char** - argument argp - pointer to the pointers on 0x100
    //0x120 - char** - argument envp - pointer to the pointers on 0x130
    //0x130 - envp[0] -
    //0x134 - envp[1]
    //0x138 - envp[2]
    //etc.

    //write the arguments
    long execve_arg_filename_target = injected_code_address + 0x200;
    long execve_arg_argp_target = injected_code_address + 0x100;
    long execve_arg_envp_target = injected_code_address + 0x130;

    memcpy(&(injected_code[0x100]), &execve_arg_filename_target, sizeof(long));
    memcpy(&(injected_code[0x108]), &execve_arg_argp_target, sizeof(long));
    memcpy(&(injected_code[0x120]), &execve_arg_envp_target, sizeof(long));

    //fill in the strings and envp
    //===============================================================================

    //"/init" goes to 0x200
    strcpy(&(injected_code[0x200]), "/init");

    //enviroment variables
    long current_envp_address_incr = 0x130;
    char* iter = init_env;
    int w = 0x220;

    while (*iter)
    {
        //an env. var is found, write its address and copy it
        long current_envp_string_address = injected_code_address + w;

        memcpy(&(injected_code[current_envp_address_incr]), &current_envp_string_address, sizeof(long));
        current_envp_address_incr += sizeof(long);
        strcpy(&(injected_code[w]), iter);
        int len = strlen(iter) + 1;
        iter += len;
        w += len;

        while (w%(sizeof(long)))
            w++;
    }

    //terminating null pointer is preset by memset

    //put the data
    putdata(1, injected_code_address, injected_code, 1024);

    //set the PC
    regs.ARM_pc = injected_code_address;
    printf("Setting /init PC to: 0x%08lX.\n", injected_code_address);
    ptrace(PTRACE_SETREGS, 1, NULL, &regs);

    //fire it
    printf("Detaching...\n");
    ptrace(PTRACE_DETACH, 1, NULL, NULL);
    return 0;
}
Exemplo n.º 3
0
int create_rtobject(int major_type, int imp_type, \
		    int imp_argc, const char** imp_argv, \
		    char* name, char* description, \
		    signal_path_t* target_path){
  rtobject_t* new_obj;
  node_t* new_obj_node;
  int i;

  /*error check types*/
  if (validate_major_type(major_type,imp_type)){
    if (debug_readout) printf("create rtobject error: failed major type validation\n");
    return -1;
  }

  /*allocate structure*/
  if (!(new_obj = rtobject_alloca())) return -1;

  /*fill core data*/
  new_obj->process_index = -1;
  new_obj->major_type = major_type;
  new_obj->imp_type = imp_type;
  new_obj->imp_arg_list_size = imp_argc;
  if (!(new_obj->name = strdup(name))){
    rtobject_dealloca(new_obj);
    return -1;
  }
  if (!(new_obj->description = strdup(description))){
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*duplicate imp args*/
  if (!imp_argc){
    new_obj->imp_arg_list = 0;
  }else{

    if (!(new_obj->imp_arg_list = (char**)malloc(new_obj->imp_arg_list_size * sizeof(char*)))){
      rtobject_dealloca(new_obj);
      return -1;
    }

    for (i=0;i<new_obj->imp_arg_list_size;++i){
      if (!(new_obj->imp_arg_list[i] = strdup(imp_argv[i]))){
	rtobject_dealloca(new_obj);
	return -1;
      }
    }

  }

  /*create empty event map list*/
  if (!(new_obj->event_map_list = generic_array_create(sizeof(void*)))){
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*assign address*/
  if ((new_obj->address = get_free_address())<0) {
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*attach new rtobject to its address*/
  rtobject_address_list[new_obj->address] = new_obj;

  if (debug_readout) 
    printf("PUT IN OBJECT ADDRESSING ARRAY AT POSITION %d\n",new_obj->address);

 
  /*create imp_object -> controls, data ports */
  if ((create_rtobject_imp_object(new_obj))<0) {
    if (debug_readout) printf("create rtobject error: failed to create imp object\n");
    release_address(new_obj->address);
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*attach data ports to null buffers*/
  for (i=0;i<rtobject_get_data_port_list_size(new_obj);++i){
    if ((rtobject_detach_port(new_obj,i)) < 0){
      printf("create rtobject error: could not attach port %d to null channel\n",i);
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
    }
  }
    
  if (debug_readout) printf("TRYING TO CREATE AN INSTANCE\n");
  
  /*create one instance*/
  if ((create_rtobject_instance(new_obj))<0) {
    release_address(new_obj->address);
    rtobject_dealloca(new_obj);
    return -1;
  }

  /*little bit of a hack until i figure out how to handle rtobject-instance*/
  if ((rtobject_update_instance_situation(new_obj)) < 0){
    release_address(new_obj->address);
    rtobject_dealloca(new_obj);
    return -1;
  }


  if (debug_readout) printf("CREATED AN INSTANCE\n");


  /*put rtobject into current path*/ /* * * * * **/

  if (!(strcmp("main",rtobject_get_name(new_obj)))){ 

    /*can't put master path into itself*/
    /*but master path is its own parent (try _that_ at home)*/
    new_obj->parent = (signal_path_t*)new_obj->imp_struct;

  }else{

    if (!(new_obj_node = (node_t*)malloc(sizeof(node_t)))){
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
    }
    new_obj_node->previous = new_obj_node->next = 0;
    new_obj_node->data = (void*)new_obj;

    if ((signal_path_insert(target_path, new_obj_node, -1)) < 0){
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
    }
  }

  /*TODO: REMOVE THIS, handled by inserting in a path*/
  /*create an ALSA sequencer port for rtobject*/
  /*the port index must be the same as the address array index*/
  /*TODO: fix to handle more than 256 rtobjects by using multiple alsaseq clients*/
  if ((rtobject_create_alsa_seq_port(new_obj)) < 0){
      release_address(new_obj->address);
      rtobject_dealloca(new_obj);
      return -1;
  }

  /*done*/
  return new_obj->address;
}