//-------------------------------------------------------------------------- static void read_dyninfo(ulong offset, ulong size) { qlseek(li, offset); const int entsize = elf64 ? sizeof(Elf64_Dyn) : sizeof(Elf32_Dyn); for(int i = 1; i < size; i += entsize ) { Elf64_Dyn dyn; if ( elf64 ) { if(lread8bytes(li, &dyn.d_tag, mf) || lread8bytes(li, &dyn.d_un, mf)) errstruct(); } else { ulong tag, val; if(lread4bytes(li, &tag, mf) || lread4bytes(li, &val, mf)) errstruct(); dyn.d_tag = tag; dyn.d_un = val; } switch ( WC4(dyn.d_tag) ) { case DT_STRTAB: dynstr_off = map_ea(dyn.d_un); break; case DT_SYMTAB: dynsym_off = map_ea(dyn.d_un); break; case DT_REL: dynrel_off = map_ea(dyn.d_un); break; case DT_RELA: dynrela_off = map_ea(dyn.d_un); break; case DT_STRSZ: dynstr_size = ulong(dyn.d_un); break; case DT_RELSZ: dynrel_size = ulong(dyn.d_un); break; case DT_RELASZ: dynrela_size = ulong(dyn.d_un); break; } } ulong off = dynstr_off; if ( dynrel_off ) off = qmin(dynrel_off, off); if ( dynrela_off ) off = qmin(dynrela_off, off); dynsym_size = off - dynsym_off; }
//-------------------------------------------------------------------------- // // check input file format. if recognized, then return 1 // and fill 'fileformatname'. // otherwise return 0 // static int accept_file(linput_t *li, char fileformatname[MAX_FILE_FORMAT_NAME], int n) { uint32 magic; uint16 min_ver, maj_ver; uchar jdk; if( n || lread4bytes(li, &magic, 1) || magic != MAGICNUMBER || lread2bytes(li, &min_ver, 1) || lread2bytes(li, &maj_ver, 1)) goto badfmt; if(maj_ver <= JDK_MIN_MAJOR) { if(maj_ver < JDK_MIN_MAJOR) goto badfmt; jdk = (uchar)(maj_ver >= JDK_1_1_MINOR); } else if(maj_ver > JDK_MAX_MAJOR) { badfmt: return(0); } else jdk = (uchar)(maj_ver - (JDK_MIN_MAJOR-1)); qsnprintf(fileformatname, MAX_FILE_FORMAT_NAME, "JavaVM Class File (JDK 1.%u%s)", jdk, jdk == 3 ? "/CLDC" : ""); return(f_LOADER); }
//-------------------------------------------------------------------------- static void load_sht64(void) { register int i; register Elf64_Shdr *sh; qlseek(li, ulong(e_shoff)); for(i = 0, sh = shdr64; i < e_shnum; i++, sh++) { if(lread4bytes(li, &sh->sh_name, mf) || lread4bytes(li, &sh->sh_type, mf) || lread8bytes(li, &sh->sh_flags, mf) || lread8bytes(li, &sh->sh_addr, mf) || lread8bytes(li, &sh->sh_offset, mf) || lread8bytes(li, &sh->sh_size, mf) || lread4bytes(li, &sh->sh_link, mf) || lread4bytes(li, &sh->sh_info, mf) || lread8bytes(li, &sh->sh_addralign, mf) || lread8bytes(li, &sh->sh_entsize, mf)) errstruct(); } }
static void load_sht32(void) { register int i; register Elf32_Shdr *sh; qlseek(li, uint32(ehdr.e_shoff)); for(i = 0, sh = shdr32; i < ehdr.e_shnum; i++, sh++) { if(lread4bytes(li, &sh->sh_name, mf) || lread4bytes(li, &sh->sh_type, mf) || lread4bytes(li, &sh->sh_flags, mf) || lread4bytes(li, (uint32*)&sh->sh_addr, mf) || lread4bytes(li, &sh->sh_offset, mf) || lread4bytes(li, &sh->sh_size, mf) || lread4bytes(li, &sh->sh_link, mf) || lread4bytes(li, &sh->sh_info, mf) || lread4bytes(li, &sh->sh_addralign, mf) || lread4bytes(li, &sh->sh_entsize, mf)) errstruct(); } }
//-------------------------------------------------------------------------- // read 64 or 32 bit number depending on the ELF type static bool read_uword(uint64 *p, bool sign=false) { if ( elf64 ) { #if defined(__EA64__) || !defined(BUILD_LOADER) return lread8bytes(li, p, mf) == 0; #else loader_failure("Please use IDA Pro 64-bit to load 64-bit files"); #ifdef __BORLANDC__ return false; #endif #endif } else { uint32 x; if ( lread4bytes(li, &x, mf) != 0 ) return false; *p = sign ? int32(x) : x; return true; } }