00001 #include <Instruction.h> 00002 #include <SectHeader.h> 00003 #include <SymbolTable.h> 00004 #include <DemangleWrapper.h> 00005 #include <LoaderSection.h> 00006 #include <RawSection.h> 00007 #include <BinaryFile.h> 00008 00009 LSHeader* LSHeader::newHeader(LSHeader* old,bool is64Bit, 00010 uint32_t l_nsyms, 00011 uint32_t l_nreloc, 00012 uint32_t l_istlen, 00013 uint32_t l_nimpid, 00014 uint32_t l_impoff, 00015 uint32_t l_stlen, 00016 uint32_t l_stoff, 00017 uint32_t l_symoff, 00018 uint32_t l_rldoff) 00019 { 00020 LSHeader* ret = NULL; 00021 if(is64Bit){ 00022 ret = new LSHeader64(); 00023 LDHDR_64 entry; 00024 entry.l_version = old->GET(l_version); 00025 entry.l_nsyms = l_nsyms; 00026 entry.l_nreloc = l_nreloc; 00027 entry.l_istlen = l_istlen; 00028 entry.l_nimpid = l_nimpid; 00029 entry.l_impoff = l_impoff; 00030 entry.l_stlen = l_stlen; 00031 entry.l_stoff = l_stoff; 00032 entry.l_symoff = l_symoff; 00033 entry.l_rldoff = l_rldoff; 00034 memcpy(ret->charStream(),&entry,Size__64_bit_Loader_Section_Header); 00035 } else { 00036 ret = new LSHeader32(); 00037 LDHDR entry; 00038 entry.l_version = old->GET(l_version); 00039 entry.l_nsyms = l_nsyms; 00040 entry.l_nreloc = l_nreloc; 00041 entry.l_istlen = l_istlen; 00042 entry.l_nimpid = l_nimpid; 00043 entry.l_impoff = l_impoff; 00044 entry.l_stlen = l_stlen; 00045 entry.l_stoff = l_stoff; 00046 memcpy(ret->charStream(),&entry,Size__32_bit_Loader_Section_Header); 00047 } 00048 return ret; 00049 } 00050 00051 void LSHeader::print(){ 00052 PRINT_INFOR("\t\t(vrs %2d)(nsy %6d)(nrl %6d)(nim %6d)", 00053 GET(l_version),GET(l_nsyms),GET(l_nreloc),GET(l_nimpid)); 00054 } 00055 00056 #define NO_NAME_OFFSET (uint32_t)(-1) 00057 00058 uint32_t LSSymbol32::getNameOffset(){ 00059 uint32_t offset = NO_NAME_OFFSET; 00060 uint32_t zeroes = GET(l_zeroes); 00061 if(!zeroes){ 00062 offset = GET(l_offset); 00063 } 00064 return offset; 00065 } 00066 00067 uint32_t LSSymbol64::getNameOffset(){ 00068 uint32_t offset = GET(l_offset); 00069 return offset; 00070 } 00071 00072 char* LSSymbol32::getName(LSStringTable* stringTable){ 00073 00074 if(!stringTable) 00075 return NULL; 00076 00077 uint32_t offset = getNameOffset(); 00078 if(offset == NO_NAME_OFFSET){ 00079 char tmpBuffer[9]; 00080 strncpy(tmpBuffer,GET(l_name),8); 00081 tmpBuffer[8] = '\0'; 00082 return strdup(tmpBuffer); 00083 } 00084 return stringTable->getStringCopy(offset); 00085 } 00086 00087 char* LSSymbol64::getName(LSStringTable* stringTable){ 00088 if(!stringTable) 00089 return NULL; 00090 00091 uint32_t offset = getNameOffset(); 00092 return stringTable->getStringCopy(offset); 00093 } 00094 00095 void LSSymbol::print(uint32_t index,LSFileNameTable* fileNameTable,LSStringTable* stringTable){ 00096 char* name = getName(stringTable); 00097 char* importName = fileNameTable->getName(GET(l_ifile)); 00098 PRINT_INFOR("\t\t[%d]\t(adr %#18llx)(scn %3d)(typ %#x)(cls %3d)(imp %9d)(prm %9d) %s [%s]", 00099 index,GET(l_value),GET(l_scnum),GET(l_smtype),GET(l_smclas),GET(l_ifile),GET(l_parm), 00100 name,importName); 00101 free(name); 00102 } 00103 00104 LSSymbol* LSSymbol::newSymbol(bool is64Bit,uint32_t nameOffset,uint32_t fileNameId){ 00105 LSSymbol* ret = NULL; 00106 uint32_t currSize = 0; 00107 char* ptr = NULL; 00108 if(is64Bit){ 00109 ret = new LSSymbol64(); 00110 LDSYM_64 entry; 00111 ptr = (char*)&entry; 00112 currSize = Size__64_bit_Loader_Section_Symbol; 00113 bzero(ptr,currSize); 00114 entry.l_offset = nameOffset; 00115 entry.l_smtype = 0x40; 00116 entry.l_smclas = 10; 00117 entry.l_ifile = fileNameId; 00118 } else { 00119 ret = new LSSymbol32(); 00120 LDSYM entry; 00121 ptr = (char*)&entry; 00122 currSize = Size__32_bit_Loader_Section_Symbol; 00123 bzero(ptr,currSize); 00124 entry.l_offset = nameOffset; 00125 entry.l_smtype = 0x40; 00126 entry.l_smclas = 10; 00127 entry.l_ifile = fileNameId; 00128 } 00129 memcpy(ret->charStream(),ptr,currSize); 00130 return ret; 00131 } 00132 00133 LSRelocation* LSRelocation::newRelocation(bool is64Bit,uint64_t addr,uint32_t idx,uint32_t sectId){ 00134 LSRelocation* ret = NULL; 00135 uint32_t currSize = 0; 00136 char* ptr = NULL; 00137 if(is64Bit){ 00138 ret = new LSRelocation64(); 00139 LDREL_64 entry; 00140 ptr = (char*)&entry; 00141 currSize = Size__64_bit_Loader_Section_Relocation; 00142 bzero(ptr,currSize); 00143 entry.l_vaddr = addr; 00144 entry.l_symndx = idx; 00145 entry.l_rtype = 0x3f00; 00146 entry.l_rsecnm = sectId; 00147 } else { 00148 ret = new LSRelocation32(); 00149 LDREL entry; 00150 ptr = (char*)&entry; 00151 currSize = Size__32_bit_Loader_Section_Relocation; 00152 bzero(ptr,currSize); 00153 entry.l_vaddr = addr; 00154 entry.l_symndx = idx; 00155 entry.l_rtype = 0x1f00; 00156 entry.l_rsecnm = sectId; 00157 } 00158 memcpy(ret->charStream(),ptr,currSize); 00159 return ret; 00160 } 00161 00162 void LSRelocation::print(uint32_t index,LSSymbol** symbols,LSStringTable* stringTable) { 00163 char* name = NULL; 00164 if(symbols[GET(l_symndx)]) 00165 name = symbols[GET(l_symndx)]->getName(stringTable); 00166 else 00167 name = strdup(""); 00168 00169 PRINT_INFOR("\t\t[%d]\t(adr %#18llx)(sym %9d)(typ %#x)(scn %3d) %s", 00170 index,GET(l_vaddr),GET(l_symndx),GET(l_rtype),GET(l_rsecnm),name); 00171 free(name); 00172 } 00173 00174 00175 LSFileNameTable::LSFileNameTable(LSHeader* lsHeader,char* base){ 00176 00177 fileNameTableSize = lsHeader->GET(l_istlen); 00178 fileNameEntryCount = lsHeader->GET(l_nimpid); 00179 if(fileNameTableSize){ 00180 fileNameTablePtr = base + lsHeader->GET(l_impoff); 00181 fileInfos = new LSFileNameTable::FileNameEntry[fileNameEntryCount]; 00182 char* ptr = fileNameTablePtr; 00183 for(uint32_t i=0;i<fileNameEntryCount;i++){ 00184 fileInfos[i].impidpath = ptr; 00185 ptr += (strlen(ptr) + 1); 00186 fileInfos[i].impidbase = ptr; 00187 ptr += (strlen(ptr) + 1); 00188 fileInfos[i].impidmem = ptr; 00189 ptr += (strlen(ptr) + 1); 00190 } 00191 } 00192 } 00193 00194 void LSFileNameTable::print(){ 00195 for(uint32_t i=0;i<fileNameEntryCount;i++){ 00196 PRINT_INFOR("\t\t[%d]\t%s %s %s", 00197 i,fileInfos[i].impidpath,fileInfos[i].impidbase,fileInfos[i].impidmem); 00198 } 00199 } 00200 00201 LSStringTable::LSStringTable(LSHeader* lsHeader,char* base){ 00202 stringTableSize = lsHeader->GET(l_stlen); 00203 if(stringTableSize){ 00204 stringTablePtr = base + lsHeader->GET(l_stoff); 00205 } 00206 } 00207 00208 void LSStringTable::print(){ 00209 for(uint32_t currSize = 0;currSize<stringTableSize;){ 00210 char* ptr = stringTablePtr + currSize; 00211 uint16_t length = 0; 00212 memcpy(&length,ptr,sizeof(uint16_t)); 00213 ptr += sizeof(uint16_t); 00214 00215 char* tmpStr = new char[length+1]; 00216 strncpy(tmpStr,ptr,length); 00217 tmpStr[length] = '\0'; 00218 00219 DemangleWrapper wrapper; 00220 char* demangled = wrapper.demangle_combined(tmpStr); 00221 00222 PRINT_INFOR("\t\t[%d]\t%s --- %s",currSize,tmpStr,demangled); 00223 00224 delete[] tmpStr; 00225 00226 currSize += sizeof(uint16_t); 00227 currSize += length; 00228 } 00229 } 00230 char* LSStringTable::getStringCopy(uint32_t offset) { 00231 ASSERT(offset < stringTableSize); 00232 if(!offset) 00233 return strdup(""); 00234 00235 char* ptr = stringTablePtr+offset; 00236 char* szptr = ptr - sizeof(uint16_t); 00237 uint16_t length = 0; 00238 memcpy(&length,szptr,sizeof(uint16_t)); 00239 if(!length) 00240 return strdup(""); 00241 char* ret = (char*)malloc(length+1); 00242 strncpy(ret,ptr,length); 00243 ret[length] = '\0'; 00244 return ret; 00245 } 00246 00247 char* LSStringTable::getString(uint32_t offset) { 00248 ASSERT(offset < stringTableSize); 00249 if(!offset) 00250 return ""; 00251 return stringTablePtr+offset; 00252 }