00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "analy.h"
00022 #include "analy_alpha.h"
00023 #include "analy_names.h"
00024 #include "analy_ia64.h"
00025 #include "analy_ppc.h"
00026 #include "analy_register.h"
00027 #include "analy_x86.h"
00028 #include "global.h"
00029 #include "elf_analy.h"
00030
00031 #include "htctrl.h"
00032 #include "htdebug.h"
00033 #include "htiobox.h"
00034 #include "htelf.h"
00035 #include "htstring.h"
00036 #include "pestruct.h"
00037 #include "snprintf.h"
00038 #include "x86asm.h"
00039
00040 extern "C" {
00041 #include "demangle.h"
00042 }
00043
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047
00048
00049
00050
00051
00052 void ElfAnalyser::init(ht_elf_shared_data *Elf_shared, ht_streamfile *File)
00053 {
00054 elf_shared = Elf_shared;
00055 file = File;
00056
00057 validarea = new Area();
00058 validarea->init();
00059
00060 Analyser::init();
00061 }
00062
00063 void ElfAnalyser::beginAnalysis()
00064 {
00065 Address *entry = NULL;
00066 bool c32 = false;
00067 switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00068 case ELFCLASS32: {
00069 entry = createAddress32(elf_shared->header32.e_entry);
00070 c32 = true;
00071 break;
00072 }
00073 case ELFCLASS64: {
00074 entry = createAddress64(elf_shared->header64.e_entry);
00075 c32 = false;
00076 break;
00077 }
00078 }
00079
00080 if (!validAddress(entry, scvalid)) {
00081 delete entry;
00082 entry = NULL;
00083 }
00084
00085 setLocationTreeOptimizeThreshold(100);
00086 setSymbolTreeOptimizeThreshold(100);
00087
00088
00089
00090
00091 ELF_SECTION_HEADER32 *s32=elf_shared->sheaders.sheaders32;
00092 ELF_SECTION_HEADER64 *s64=elf_shared->sheaders.sheaders64;
00093 char blub[100];
00094 for (uint i=0; i < elf_shared->sheaders.count; i++) {
00095 Address *secaddr;
00096 if (c32) {
00097
00098 secaddr = createAddress32(s32->sh_addr);
00099 } else {
00100 secaddr = createAddress64(s64->sh_addr);
00101 }
00102 if (validAddress(secaddr, scvalid)) {
00103
00104 ht_snprintf(blub, sizeof blub, "; section %d <%s>", i, getSegmentNameByAddress(secaddr));
00105 addComment(secaddr, 0, "");
00106 addComment(secaddr, 0, ";******************************************************************");
00107 addComment(secaddr, 0, blub);
00108 ht_snprintf(blub, sizeof blub, "; virtual address %08x virtual size %08x", s32->sh_addr, s32->sh_size);
00109 addComment(secaddr, 0, blub);
00110 if (validAddress(secaddr, scinitialized)) {
00111 ht_snprintf(blub, sizeof blub, "; file offset %08x file size %08x", s32->sh_offset, s32->sh_size);
00112 } else {
00113 ht_snprintf(blub, sizeof blub, "; section is not in file");
00114 }
00115 addComment(secaddr, 0, blub);
00116 addComment(secaddr, 0, ";******************************************************************");
00117
00118
00119 ht_snprintf(blub, sizeof blub, "; end of section <%s>", getSegmentNameByAddress(secaddr));
00120 Address *secend_addr = (Address *)secaddr->duplicate();
00121 if (c32) {
00122 secend_addr->add(s32->sh_size);
00123 } else {
00124 secend_addr->add(s64->sh_size.lo);
00125 }
00126 newLocation(secend_addr)->flags |= AF_FUNCTION_END;
00127 addComment(secend_addr, 0, "");
00128 addComment(secend_addr, 0, ";******************************************************************");
00129 addComment(secend_addr, 0, blub);
00130 addComment(secend_addr, 0, ";******************************************************************");
00131
00132 validarea->add(secaddr, secend_addr);
00133
00134 delete secend_addr;
00135 }
00136 delete secaddr;
00137 s32++;
00138 s64++;
00139 }
00140
00141
00142 if (c32) {
00143 for (uint i=1; i<elf_shared->sheaders.count; i++) {
00144 if ((elf_shared->sheaders.sheaders32[i].sh_type==ELF_SHT_SYMTAB) || (elf_shared->sheaders.sheaders32[i].sh_type==ELF_SHT_DYNSYM)) {
00145 initInsertSymbols(i);
00146 }
00147 }
00148 initInsertFakeSymbols();
00149 } else {
00150 for (uint i=1; i<elf_shared->sheaders.count; i++) {
00151 if ((elf_shared->sheaders.sheaders64[i].sh_type==ELF_SHT_SYMTAB) || (elf_shared->sheaders.sheaders64[i].sh_type==ELF_SHT_DYNSYM)) {
00152 initInsertSymbols(i);
00153 }
00154 }
00155 }
00156
00157
00158
00159
00160 if (entry) {
00161 pushAddress(entry, entry);
00162 assignSymbol(entry, "entrypoint", label_func);
00163 addComment(entry, 0, "");
00164 addComment(entry, 0, ";****************************");
00165 switch (c32 ? elf_shared->header32.e_type : elf_shared->header64.e_type) {
00166 case ELF_ET_DYN:
00167 addComment(entry, 0, "; dynamic executable entry point");
00168 break;
00169 case ELF_ET_EXEC:
00170 addComment(entry, 0, "; executable entry point");
00171 break;
00172 default:
00173 addComment(entry, 0, "; entry point");
00174 }
00175 addComment(entry, 0, ";****************************");
00176 delete entry;
00177 }
00178
00179 setLocationTreeOptimizeThreshold(1000);
00180 setSymbolTreeOptimizeThreshold(1000);
00181
00182 Analyser::beginAnalysis();
00183 }
00184
00185
00186
00187
00188 void ElfAnalyser::initInsertFakeSymbols()
00189 {
00190 if (!elf_shared->undefined2fakeaddr) return;
00191 sectionAndIdx *key = NULL;
00192 ht_data_uint32 *value;
00193 while ((key = (sectionAndIdx*)elf_shared->undefined2fakeaddr->enum_next(
00194 (Object**)&value, key))) {
00195 Address *address = createAddress32(value->value);
00196 FILEOFS h = elf_shared->sheaders.sheaders32[key->secidx].sh_offset;
00197 ELF_SYMBOL32 sym;
00198 file->seek(h+key->symidx*sizeof (ELF_SYMBOL32));
00199 file->read(&sym, sizeof sym);
00200 create_host_struct(&sym, ELF_SYMBOL32_struct, elf_shared->byte_order);
00201
00202 FILEOFS sto = elf_shared->sheaders.sheaders32[
00203 elf_shared->sheaders.sheaders32[key->secidx].sh_link].sh_offset;
00204 file->seek(sto+sym.st_name);
00205 char *name = fgetstrz(file);
00206 char buf[1024];
00207 ht_snprintf(buf, sizeof buf, "undef_%s", name);
00208 free(name);
00209 make_valid_name(buf, buf);
00210 assignSymbol(address, buf, label_func);
00211 }
00212 }
00213
00214 void ElfAnalyser::initInsertSymbols(int shidx)
00215 {
00216 char elf_buffer[1024];
00217 if (elf_shared->ident.e_ident[ELF_EI_CLASS] == ELFCLASS32) {
00218 FILEOFS h = elf_shared->sheaders.sheaders32[shidx].sh_offset;
00219 FILEOFS sto = elf_shared->sheaders.sheaders32[elf_shared->sheaders.sheaders32[shidx].sh_link].sh_offset;
00220 uint symnum = elf_shared->sheaders.sheaders32[shidx].sh_size / sizeof (ELF_SYMBOL32);
00221
00222 int *entropy = random_permutation(symnum);
00223 for (uint i=0; i<symnum; i++) {
00224 ELF_SYMBOL32 sym;
00225 if (entropy[i] == 0) continue;
00226 file->seek(h+entropy[i]*sizeof (ELF_SYMBOL32));
00227 file->read(&sym, sizeof sym);
00228 create_host_struct(&sym, ELF_SYMBOL32_struct, elf_shared->byte_order);
00229
00230 file->seek(sto+sym.st_name);
00231 char *name = fgetstrz(file);
00232 if (!name) continue;
00233
00234 switch (sym.st_shndx) {
00235 case ELF_SHN_UNDEF:
00236 break;
00237 case ELF_SHN_ABS:
00238 break;
00239 case ELF_SHN_COMMON:
00240 break;
00241 default: {
00242
00243 break;
00244 }
00245 }
00246
00247 char *bind;
00248 switch (ELF32_ST_BIND(sym.st_info)) {
00249 case ELF_STB_LOCAL:
00250 bind="local";
00251 break;
00252 case ELF_STB_GLOBAL:
00253 bind="global";
00254 break;
00255 case ELF_STB_WEAK:
00256 bind="weak";
00257 break;
00258 default:
00259 bind="?";
00260 break;
00261 }
00262
00263 switch (ELF32_ST_TYPE(sym.st_info)) {
00264 case ELF_STT_NOTYPE:
00265 case ELF_STT_FUNC: {
00266 char *label = name;
00267 if (!getSymbolByName(label)) {
00268 elf32_addr sym_addr = sym.st_value;
00269 if (elf_shared->shrelocs && (sym.st_shndx>0) && (sym.st_shndx<elf_shared->sheaders.count)
00270 && elf_shared->shrelocs[sym.st_shndx].relocAddr) {
00271 sym_addr += elf_shared->shrelocs[sym.st_shndx].relocAddr;
00272 }
00273 Address *address = createAddress32(sym_addr);
00274 if (validAddress(address, scvalid)) {
00275 char *demangled = cplus_demangle(label, DMGL_PARAMS | DMGL_ANSI);
00276
00277 make_valid_name(label, label);
00278
00279 ht_snprintf(elf_buffer, sizeof elf_buffer, "; function %s (%s)", (demangled) ? demangled : label, bind);
00280
00281 if (demangled) free(demangled);
00282
00283 addComment(address, 0, "");
00284 addComment(address, 0, ";********************************************************");
00285 addComment(address, 0, elf_buffer);
00286 addComment(address, 0, ";********************************************************");
00287 pushAddress(address, address);
00288 assignSymbol(address, label, label_func);
00289 }
00290 delete address;
00291 }
00292 break;
00293 }
00294 case ELF_STT_OBJECT: {
00295 char *label = name;
00296 if (!getSymbolByName(label)) {
00297 Address *address = createAddress32(sym.st_value);
00298 if (validAddress(address, scvalid)) {
00299
00300 char *demangled = cplus_demangle(label, DMGL_PARAMS | DMGL_ANSI);
00301
00302 make_valid_name(label, label);
00303
00304 ht_snprintf(elf_buffer, sizeof elf_buffer, "; data object %s, size %d (%s)", (demangled) ? demangled : label, sym.st_size, bind);
00305
00306 if (demangled) free(demangled);
00307
00308 addComment(address, 0, "");
00309 addComment(address, 0, ";********************************************************");
00310 addComment(address, 0, elf_buffer);
00311 addComment(address, 0, ";********************************************************");
00312 assignSymbol(address, label, label_data);
00313 }
00314 delete address;
00315 }
00316 break;
00317 }
00318 case ELF_STT_SECTION:
00319 case ELF_STT_FILE:
00320 break;
00321 }
00322 free(name);
00323 }
00324 if (entropy) free(entropy);
00325 } else {
00326
00327 FILEOFS h=elf_shared->sheaders.sheaders64[shidx].sh_offset.lo;
00328 FILEOFS sto=elf_shared->sheaders.sheaders64[elf_shared->sheaders.sheaders64[shidx].sh_link].sh_offset.lo;
00329 uint symnum=elf_shared->sheaders.sheaders64[shidx].sh_size.lo / sizeof (ELF_SYMBOL64);
00330
00331 int *entropy = random_permutation(symnum);
00332 for (uint i=0; i<symnum; i++) {
00333 ELF_SYMBOL64 sym;
00334 if (entropy[i] == 0) continue;
00335 file->seek(h+entropy[i]*sizeof (ELF_SYMBOL64));
00336 file->read(&sym, sizeof sym);
00337 create_host_struct(&sym, ELF_SYMBOL64_struct, elf_shared->byte_order);
00338
00339 file->seek(sto+sym.st_name);
00340 char *name = fgetstrz(file);
00341 if (!name) continue;
00342
00343 switch (sym.st_shndx) {
00344 case ELF_SHN_UNDEF:
00345 break;
00346 case ELF_SHN_ABS:
00347 break;
00348 case ELF_SHN_COMMON:
00349 break;
00350 default: {
00351
00352 break;
00353 }
00354 }
00355
00356 char *bind;
00357 switch (ELF64_ST_BIND(sym.st_info)) {
00358 case ELF_STB_LOCAL:
00359 bind="local";
00360 break;
00361 case ELF_STB_GLOBAL:
00362 bind="global";
00363 break;
00364 case ELF_STB_WEAK:
00365 bind="weak";
00366 break;
00367 default:
00368 bind="?";
00369 break;
00370 }
00371
00372 switch (ELF64_ST_TYPE(sym.st_info)) {
00373 case ELF_STT_NOTYPE:
00374 case ELF_STT_FUNC: {
00375 char *label = name;
00376 if (!getSymbolByName(label)) {
00377 Address *address = createAddress64(sym.st_value);
00378
00379 char *demangled = cplus_demangle(label, DMGL_PARAMS | DMGL_ANSI);
00380
00381 make_valid_name(label, label);
00382
00383 ht_snprintf(elf_buffer, sizeof elf_buffer, "; function %s (%s)", (demangled) ? demangled : label, bind);
00384
00385 if (demangled) free(demangled);
00386
00387 addComment(address, 0, "");
00388 addComment(address, 0, ";********************************************************");
00389 addComment(address, 0, elf_buffer);
00390 addComment(address, 0, ";********************************************************");
00391 pushAddress(address, address);
00392 assignSymbol(address, label, label_func);
00393
00394 delete address;
00395 }
00396 break;
00397 }
00398 case ELF_STT_OBJECT: {
00399 char *label = name;
00400 if (!getSymbolByName(label)) {
00401 Address *address = createAddress64(sym.st_value);
00402
00403 char *demangled = cplus_demangle(label, DMGL_PARAMS | DMGL_ANSI);
00404
00405 make_valid_name(label, label);
00406
00407 ht_snprintf(elf_buffer, sizeof elf_buffer, "; data object %s, size %d (%s)", (demangled) ? demangled : label, sym.st_size.lo, bind);
00408
00409 if (demangled) free(demangled);
00410
00411 addComment(address, 0, "");
00412 addComment(address, 0, ";********************************************************");
00413 addComment(address, 0, elf_buffer);
00414 addComment(address, 0, ";********************************************************");
00415 assignSymbol(address, label, label_data);
00416
00417 delete address;
00418 }
00419 break;
00420 }
00421 case ELF_STT_SECTION:
00422 case ELF_STT_FILE:
00423 break;
00424 }
00425 free(name);
00426 }
00427 if (entropy) free(entropy);
00428 }
00429 }
00430
00431
00432
00433
00434 int ElfAnalyser::load(ht_object_stream *f)
00435 {
00436 GET_OBJECT(f, validarea);
00437 return Analyser::load(f);
00438 }
00439
00440
00441
00442
00443 void ElfAnalyser::done()
00444 {
00445 validarea->done();
00446 delete validarea;
00447 Analyser::done();
00448 }
00449
00450 OBJECT_ID ElfAnalyser::object_id() const
00451 {
00452 return ATOM_ELF_ANALYSER;
00453 }
00454
00455
00456
00457
00458 uint ElfAnalyser::bufPtr(Address *Addr, byte *buf, int size)
00459 {
00460 FILEOFS ofs = addressToFileofs(Addr);
00461
00462
00463
00464 assert(ofs != INVALID_FILE_OFS);
00465 file->seek(ofs);
00466 return file->read(buf, size);
00467 }
00468
00469 bool ElfAnalyser::convertAddressToELFAddress(Address *addr, ELFAddress *r)
00470 {
00471 if (addr->object_id()==ATOM_ADDRESS_FLAT_32) {
00472 r->a32 = ((AddressFlat32*)addr)->addr;
00473 return true;
00474 } else if (addr->object_id()==ATOM_ADDRESS_X86_FLAT_32) {
00475 r->a32 = ((AddressX86Flat32*)addr)->addr;
00476 return true;
00477 } else if (addr->object_id()==ATOM_ADDRESS_FLAT_64) {
00478 r->a64.lo = ((AddressFlat64*)addr)->addr.lo;
00479 r->a64.hi = ((AddressFlat64*)addr)->addr.hi;
00480 return true;
00481 } else {
00482 return false;
00483 }
00484 }
00485
00486 Address *ElfAnalyser::createAddress()
00487 {
00488 switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00489 case ELFCLASS32: {
00490 switch (elf_shared->header32.e_machine) {
00491 case ELF_EM_386:
00492 return new AddressX86Flat32();
00493 }
00494 return new AddressFlat32();
00495 }
00496 case ELFCLASS64: {
00497
00498
00499
00500
00501 return new AddressFlat64();
00502 }
00503 }
00504 return new AddressFlat32();
00505 }
00506
00507 Address *ElfAnalyser::createAddress32(dword addr)
00508 {
00509 switch (elf_shared->header32.e_machine) {
00510 case ELF_EM_386:
00511 return new AddressX86Flat32(addr);
00512 }
00513 return new AddressFlat32(addr);
00514 }
00515
00516 Address *ElfAnalyser::createAddress64(qword addr)
00517 {
00518 return new AddressFlat64(addr);
00519 }
00520
00521
00522
00523
00524 Assembler *ElfAnalyser::createAssembler()
00525 {
00526 switch (elf_shared->header32.e_machine) {
00527 case ELF_EM_386:
00528 Assembler *a = new x86asm(X86_OPSIZE32, X86_ADDRSIZE32);
00529 a->init();
00530 return a;
00531 }
00532 return NULL;
00533 }
00534
00535
00536
00537
00538 FILEOFS ElfAnalyser::addressToFileofs(Address *Addr)
00539 {
00540 if (validAddress(Addr, scinitialized)) {
00541 dword ofs;
00542 ELFAddress ea;
00543 if (!convertAddressToELFAddress(Addr, &ea)) return INVALID_FILE_OFS;
00544 if (!elf_addr_to_ofs(&elf_shared->sheaders, elf_shared->ident.e_ident[ELF_EI_CLASS], ea, &ofs)) return INVALID_FILE_OFS;
00545 return ofs;
00546 } else {
00547 return INVALID_FILE_OFS;
00548 }
00549 }
00550
00551
00552
00553
00554
00555 char *ElfAnalyser::getSegmentNameByAddress(Address *Addr)
00556 {
00557 static char elf_sectionname[33];
00558 elf_section_headers *sections=&elf_shared->sheaders;
00559 int i;
00560 ELFAddress ea;
00561 if (!convertAddressToELFAddress(Addr, &ea)) return NULL;
00562 if (!elf_addr_to_section(sections, elf_shared->ident.e_ident[ELF_EI_CLASS], ea, &i)) return NULL;
00563 if (i == elf_shared->fake_undefined_shidx) {
00564 strcpy(elf_sectionname, "$$HT_FAKE$$");
00565 } else {
00566 strncpy(elf_sectionname, elf_shared->shnames[i], 32);
00567 elf_sectionname[32] = 0;
00568 }
00569 return elf_sectionname;
00570 }
00571
00572
00573
00574
00575 const char *ElfAnalyser::getName()
00576 {
00577 return file->get_desc();
00578 }
00579
00580
00581
00582
00583 const char *ElfAnalyser::getType()
00584 {
00585 return "ELF/Analyser";
00586 }
00587
00588
00589
00590
00591 void ElfAnalyser::initCodeAnalyser()
00592 {
00593 Analyser::initCodeAnalyser();
00594 }
00595
00596
00597
00598
00599 void ElfAnalyser::initUnasm()
00600 {
00601 DPRINTF("elf_analy: ");
00602 int machine = 0;
00603 bool elf64 = false;
00604 switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00605 case ELFCLASS32: machine = elf_shared->header32.e_machine; break;
00606 case ELFCLASS64: machine = elf_shared->header64.e_machine; elf64 = true; break;
00607 }
00608 switch (machine) {
00609 case ELF_EM_386:
00610 DPRINTF("initing analy_x86_disassembler\n");
00611 analy_disasm = new AnalyX86Disassembler();
00612 ((AnalyX86Disassembler*)analy_disasm)->init(this, elf64 ? ANALYX86DISASSEMBLER_FLAGS_FLAT64 : 0);
00613 break;
00614 case ELF_EM_IA_64:
00615 if (elf_shared->ident.e_ident[ELF_EI_CLASS] != ELFCLASS64) {
00616 errorbox("Intel IA64 cant be used in a 32-Bit ELF.");
00617 } else {
00618 analy_disasm = new AnalyIA64Disassembler();
00619 ((AnalyIA64Disassembler*)analy_disasm)->init(this);
00620 }
00621 break;
00622 case ELF_EM_PPC:
00623 if (elf_shared->ident.e_ident[ELF_EI_CLASS] != ELFCLASS32) {
00624 errorbox("Intel PowerPC cant be used in a 64-Bit ELF.");
00625 } else {
00626 DPRINTF("initing analy_ppc_disassembler\n");
00627 analy_disasm = new AnalyPPCDisassembler();
00628 ((AnalyPPCDisassembler*)analy_disasm)->init(this);
00629 }
00630 break;
00631 case ELF_EM_PPC64:
00632 if (elf_shared->ident.e_ident[ELF_EI_CLASS] != ELFCLASS64) {
00633 errorbox("Intel PowerPC64 cant be used in a 32-Bit ELF.");
00634 } else {
00635 DPRINTF("initing analy_ppc_disassembler\n");
00636 analy_disasm = new AnalyPPCDisassembler();
00637 ((AnalyPPCDisassembler*)analy_disasm)->init(this);
00638 }
00639 break;
00640 default:
00641 DPRINTF("no apropriate disassembler for machine %04x\n", machine);
00642 warnbox("No disassembler for unknown machine type %04x!", machine);
00643 }
00644 }
00645
00646
00647
00648
00649 void ElfAnalyser::log(const char *msg)
00650 {
00651
00652
00653
00654
00655
00656
00657 }
00658
00659
00660
00661
00662 Address *ElfAnalyser::nextValid(Address *Addr)
00663 {
00664 return (Address *)validarea->findNext(Addr);
00665 }
00666
00667
00668
00669
00670 void ElfAnalyser::store(ht_object_stream *f)
00671 {
00672 PUT_OBJECT(f, validarea);
00673 Analyser::store(f);
00674 }
00675
00676
00677
00678
00679 int ElfAnalyser::queryConfig(int mode)
00680 {
00681 switch (mode) {
00682 case Q_DO_ANALYSIS:
00683 case Q_ENGAGE_CODE_ANALYSER:
00684 case Q_ENGAGE_DATA_ANALYSER:
00685 return true;
00686 default:
00687 return 0;
00688 }
00689 }
00690
00691
00692
00693
00694 Address *ElfAnalyser::fileofsToAddress(FILEOFS fileofs)
00695 {
00696 ELFAddress ea;
00697 if (elf_ofs_to_addr(&elf_shared->sheaders, elf_shared->ident.e_ident[ELF_EI_CLASS], fileofs, &ea)) {
00698 switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00699 case ELFCLASS32: return createAddress32(ea.a32);
00700 case ELFCLASS64: return createAddress64(ea.a64);
00701 }
00702 return new InvalidAddress();
00703 } else {
00704 return new InvalidAddress();
00705 }
00706 }
00707
00708
00709
00710
00711 bool ElfAnalyser::validAddress(Address *Addr, tsectype action)
00712 {
00713 elf_section_headers *sections=&elf_shared->sheaders;
00714 int sec;
00715 byte cls = elf_shared->ident.e_ident[ELF_EI_CLASS];
00716 ELFAddress ea;
00717 if (!convertAddressToELFAddress(Addr, &ea)) return false;
00718 if (!elf_addr_to_section(sections, cls, ea, &sec)) return false;
00719 switch (cls) {
00720 case ELFCLASS32: {
00721 ELF_SECTION_HEADER32 *s=sections->sheaders32+sec;
00722 switch (action) {
00723 case scvalid:
00724 return true;
00725 case scread:
00726 return true;
00727 case scwrite:
00728 case screadwrite:
00729 return s->sh_flags & ELF_SHF_WRITE;
00730 case sccode:
00731 return (s->sh_flags & ELF_SHF_EXECINSTR) && (s->sh_type==ELF_SHT_PROGBITS);
00732 case scinitialized:
00733 return s->sh_type==ELF_SHT_PROGBITS;
00734 }
00735 return false;
00736 }
00737 case ELFCLASS64: {
00738 ELF_SECTION_HEADER64 *s=sections->sheaders64+sec;
00739 switch (action) {
00740 case scvalid:
00741 return true;
00742 case scread:
00743 return true;
00744 case scwrite:
00745 case screadwrite:
00746 return s->sh_flags.lo & ELF_SHF_WRITE;
00747 case sccode:
00748 return (s->sh_flags.lo & ELF_SHF_EXECINSTR) && (s->sh_type==ELF_SHT_PROGBITS);
00749 case scinitialized:
00750 return s->sh_type==ELF_SHT_PROGBITS;
00751 }
00752 return false;
00753 }
00754 }
00755 return false;
00756 }