Esempio n. 1
0
/**
 * @param fp le fichier elf original
 * @param seg le segment à reloger
 * @param mem l'ensemble des segments
 *
 * @brief Cette fonction effectue la relocation du segment passé en parametres
 * @brief l'ensemble des segments doit déjà avoir été chargé en memoire.
 *
 * VOUS DEVEZ COMPLETER CETTE FONCTION POUR METTRE EN OEUVRE LA RELOCATION !!
 */
void reloc_segment(FILE* fp, segment seg, mem memory,unsigned int endianness,stab symtab) 
{
    byte *ehdr    = __elf_get_ehdr( fp );
    uint32_t  scnsz  = 0;
    Elf32_Rel *rel = NULL;
    char* reloc_name = malloc(strlen(seg.name)+strlen(RELOC_PREFIX_STR)+1);
    scntab section_tab;

    // on recompose le nom de la section
    memcpy(reloc_name,RELOC_PREFIX_STR,strlen(RELOC_PREFIX_STR)+1);
    strcat(reloc_name,seg.name);

    // on récupere le tableau de relocation et la table des sections
    rel = (Elf32_Rel *)elf_extract_scn_by_name( ehdr, fp, reloc_name, &scnsz, NULL );
    elf_load_scntab(fp ,32, &section_tab);



    if (rel != NULL && seg.content!=NULL && seg.size._32!=0) {

        INFO_MSG("--------------Relocation de %s-------------------\n",seg.name) ;
        INFO_MSG("Nombre de symboles a reloger: %ld\n",scnsz/sizeof(*rel)) ;


        //------------------------------------------------------

        //TODO : faire la relocation ICI !

        //------------------------------------------------------

    }
    del_scntab(section_tab);
    free( rel );
    free( reloc_name );
    free( ehdr );

}
/**
 * @param fp le fichier elf original
 * @param seg le segment à reloger
 * @param mem l'ensemble des segments
 * @param endianness le boutisme du programme
 * @param symtab la table des symbole du programme
 *
 * @brief Cette fonction effectue la relocation du segment passé en parametres
 * @brief l'ensemble des segments doit déjà avoir été chargé en memoire.
 *
 */
void reloc_segment(FILE* fp, segment seg, char* segname, memory mem, unsigned int endianness,stab* symtab) {
  byte *ehdr    = __elf_get_ehdr(fp);
  uint32_t  scnsz  = 0;
  Elf32_Rel *rel = NULL;
  char* reloc_name = malloc(strlen(segname)+strlen(RELOC_PREFIX_STR)+1);
  scntab section_tab;

  // on recompose le nom de la section
  memcpy(reloc_name,RELOC_PREFIX_STR,strlen(RELOC_PREFIX_STR)+1);
  strcat(reloc_name,segname);

  // on récupere le tableau de relocation et la table des sections
  rel = (Elf32_Rel *)elf_extract_scn_by_name( ehdr, fp, reloc_name, &scnsz, NULL );
  elf_load_scntab(fp ,32, &section_tab);

  if (rel != NULL && seg.raddr!=NULL && seg.size !=0) {

      INFO_MSG("--------------Relocation de %s-------------------\n",segname) ;
      INFO_MSG("Nombre de symboles a reloger: %ld\n",scnsz/sizeof(*rel)) ;

      int i = 0, j = 0;
      unsigned int V = 0;
      unsigned int S = 0;
      unsigned int A = 0;
      unsigned int T = 0;
      
      for (i=0; i<scnsz/sizeof(*rel); i++) {
          T =0;
          __Elf_Rel_flip_endianness((byte *)(rel+i), 32, endianness);
          unsigned int offset = rel[i].r_offset; // decalage par rapport au debut de section
          int sym = (int) ELF32_R_SYM(rel[i].r_info);
          int type = (unsigned char) ELF32_R_TYPE(rel[i].r_info);
	  int P = seg.vaddr + offset;

          DEBUG_MSG("Entrée de relocation : offset %08x info =%08x sym = %08x type =%08x\n",rel[i].r_offset,rel[i].r_info,sym,type);
          DEBUG_MSG("Symbole en fonction duquel on reloge : symbole %s de type %d\n",symtab->sym[sym].name, type);

          if (symtab->sym[sym].type==STT_SECTION) {
            S = symtab->sym[sym].addr._32;
 
	    if (type == R_ARM_ABS8) {
              uint8_t oct = read_memory_value(P, mem);
              if (oct < 0)
                A = oct | 0xFFFFFF00;
              else
                A = oct;
              V = A + S;
              write_memory_value(P, V, mem);  
              printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V);
            }
            
            if (type == R_ARM_ABS32) {
              A = read_word(P, mem) ;
              V = (S + A) | T;
              printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V);
              write_word(P, V, mem);
            }

            if (type == R_ARM_THM_CALL) {
            }
                         
          } 
          
          else if (symtab->sym[sym].type==STT_FUNC) {
          
            T = 1;
            S = symtab->sym[sym].addr._32;   

	    if (type == R_ARM_ABS8) {
              A = read_memory_value(P, mem) ;
              V = A + S;
              printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V);
              write_memory_value(P, V, mem);  
            }
            
            if (type == R_ARM_ABS32) {
              A = read_word(P, mem) << 1;
              V = (S + A) | T;
              printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V);
              write_word(P, V, mem);
            }

            if (type == R_ARM_THM_CALL) {
            }               
          } 

          else if (symtab->sym[sym].type==STT_NOTYPE) {
          
            S = symtab->sym[sym].addr._32;   

	    if (type == R_ARM_ABS8) {
              A = read_memory_value(P, mem);
              V = A + S;
              printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V);
              write_memory_value(P, V, mem);  
            }
            
            if (type == R_ARM_ABS32) {
              A = read_word(P, mem);
              V = (S + A) | T;
              printf("A: %d, P: %d, S: %d, T: %d, V:%x\n", A, P, S, T, V);
              write_word(P, V, mem);
            }

            if (type == R_ARM_THM_CALL) {
            }               
          }  
       
          else {
              WARNING_MSG("%d non traité pour l'instant",symtab->sym[sym].type) ;
              continue;
          }
      }
  }
  del_scntab(section_tab);
  free( rel );
  free( reloc_name );
  free( ehdr );
}
Esempio n. 3
0
/**
 * @param fp le fichier elf original
 * @param seg le segment a reloger
 * @param mem l'ensemble des segments
 * @param endianness le boutisme du programme
 * @param symtab la table des symbole du programme
 * @param symtab_libc la table des symbole de la libc (NULL si inutile)
 * @param fp_libc le fichier elf de la libc (NULL si inutile)
 * @brief Cette fonction effectue la relocation du segment passe en parametres
 * @brief l'ensemble des segments doit deja avoir ete charge en memoire.
 *
 * VOUS DEVEZ COMPLETER CETTE FONCTION POUR METTRE EN OEUVRE LA RELOCATION !!
 */
void reloc_segment(FILE* fp, segment seg, mem memory,unsigned int endianness,stab* symtable,stab* symtab_libc,FILE* fp_libc) {
    byte *ehdr    = __elf_get_ehdr( fp );
    uint32_t  scnsz  = 0;
    Elf32_Rel *rel = NULL;
    char* reloc_name = malloc(strlen(seg.name)+strlen(RELOC_PREFIX_STR)+1);
    scntab section_tab;
    scntab section_tab_libc;

    // on recompose le nom de la section
    memcpy(reloc_name,RELOC_PREFIX_STR,strlen(RELOC_PREFIX_STR)+1);
    strcat(reloc_name,seg.name);

    // on recupere le tableau de relocation et la table des sections
    rel = (Elf32_Rel *)elf_extract_scn_by_name( ehdr, fp, reloc_name, &scnsz, NULL );
    elf_load_scntab(fp ,32, &section_tab);

    if (symtab_libc!=NULL && fp_libc!=NULL)
        elf_load_scntab(fp_libc ,32, &section_tab_libc);


    if (rel != NULL &&seg.content!=NULL && seg.size._32!=0) {
        if(verbose>0) {
            INFO_MSG("--------------Relocation of %s-------------------\n",seg.name) ;
            INFO_MSG("Number of symbol to relocate: %ld\n",scnsz/sizeof(*rel)) ;
        }

        //------------------------------------------------------

        int i=0;
        uint sym;
        uint type;
        uint info;
        uint offset;
        //display :
        if(verbose>0) {
            //printf("scnsz=%d\n", scnsz);
            //print_scntab(section_tab);
            printf("Offset    Info      Type            Sym.Value  Sym.Name\n");
            while(i<scnsz/sizeof(*rel)) {
                info=rel[i].r_info;
                offset=rel[i].r_offset;
                FLIP_ENDIANNESS(info) ;
                FLIP_ENDIANNESS(offset) ;
                sym=ELF32_R_SYM(info);
                type=ELF32_R_TYPE(info);
                if (type>32) {
                    WARNING_MSG("Unknown type : %d",type);
                }
                else {
                    printf("%08X  %08X  %-14s  %08X   %s\n",offset,info,MIPS32_REL[type],sym,(*symtable).sym[sym].name);
                    i++;
                }

            }
        }
        i=0;
        //------------------------------------------------------
        //Reloc :
        int A,V,P;
        //int segnum;
        uint32_t S;
        while(i<scnsz/sizeof(*rel)) {
            info=rel[i].r_info;
            offset=rel[i].r_offset;
            FLIP_ENDIANNESS(info) ;
            FLIP_ENDIANNESS(offset) ;
            sym=ELF32_R_SYM(info);
            type=ELF32_R_TYPE(info);
            //printf("Relocating symbol %d\n",i );
            //segnum=seg_from_scnidx((*symtable).sym[sym].scnidx,(*symtable),memory);
            //if(segnum==-1){
            //    WARNING_MSG("Couldn't resolve scndix correspondance");
            //    break;
            //}
            //S=memory->seg[segnum].start._32+(*symtable).sym[sym].addr._32;//a verif
            //printf("sym=%d, symbtable size=%d\n", sym,(*symtable).size);
            if(addr_from_symnb(sym, (*symtable), memory,&S)==-1) {
                WARNING_MSG("Trying to resolve scndix correspondance in libcsymtab");
            }

            P=seg.start._32+offset;
            memRead(P,1,&A);
            //printf("Relocation type %s\n",MIPS32_REL[type] );
            switch (type) {
            case 2:
                V=S+A;

                //printf("V= %X,S=%X,A=%X,P=%X\n",V,S,A,P);
                memWrite(P,1,V);
                break;
            case 4:
                V=(A&0xFC00000)|((((A<<2)|((P&0xF0000000)+S))>>2)&0x3FFFFFF);

                //printf("V= %X,S=%X,A=%X,P=%X\n",V,S,A,P);
                memWrite(P,1,V);
                break;
            case 5:
                ;
                uint nexttype=rel[i+1].r_info;
                uint nextoffset=rel[i+1].r_offset;
                FLIP_ENDIANNESS(nexttype);
                FLIP_ENDIANNESS(nextoffset);
                nexttype=ELF32_R_TYPE(nexttype);
                if(nexttype!=6) {
                    WARNING_MSG("R_MIPS_HI16 not followed by R_MIIPS_LO16 : %s",MIPS32_REL[nexttype]);
                }
                else {

                    int P2=seg.start._32+nextoffset,A2;
                    memRead(P2,1,&A2);
                    int AHL;
                    AHL=(A<<16)+(short)(A2);
                    //printf("A2=%X short A2=%X\n",A2, (short)A2 );
                    //printf("AHL : %X\n",AHL );
                    //printf("Total=%X AHL+S=%X, (AHL+S)&0xFFFF=%X, diff=%X\n",((AHL+S-(short)(AHL+S))>>16),AHL+S,(AHL+S)&0xFFFF,AHL+S-(short)AHL+S) ;
                    V=(A & 0xFFFF0000)|(  ((AHL+S-(short)(AHL+S))>>16)   &0xFFFF);

                    //printf("V= %X,S=%X,A=%X,A2=%X,P=%X,P2=%X, AHL=%X\n",V,S,A,A2,P,P2,AHL);
                    memWrite(P,1,V);
                }
                break;
            case 6:
                ;
                int previoustype=rel[i-1].r_info;
                int previousoffset=rel[i-1].r_offset;
                FLIP_ENDIANNESS(previoustype);
                FLIP_ENDIANNESS(previousoffset);
                previoustype=ELF32_R_TYPE(previoustype);
                if(previoustype!=5) {
                    WARNING_MSG("R_MIPS_LO16 not preceded by R_MIPS_HI16 : %s",MIPS32_REL[previoustype]);
                }
                else {

                    int32_t P2=seg.start._32+previousoffset,A2;
                    memRead(P2,1,&A2);
                    int32_t AHL=(A2<<16)+(short)(A);
                    V=(A&0xFFFF0000)|((short)(AHL+S)&0xFFFF);

                    //printf("V= %X,S=%X,A=%X,P=%X\n",V,S,A,P);
                    memWrite(P,1,V);
                }
                break;
            default:
                if (type>32) {
                    WARNING_MSG("Unknown type : %d, relocation impossible for element %d",type,i);
                }
                else {
                    WARNING_MSG("Unknown type : %s(code : %d), relocation impossible for element %d",MIPS32_REL[type],type,i);
                }
                break;
            }
            i++;
        }
        //------------------------------------------------------

    }
    del_scntab(section_tab);
    free( rel );
    free( reloc_name );
    free( ehdr );

}