int pht18(void) { if(orcPHT->p_type != PT_GNU_EH_FRAME) return 0; if(rand() % 3 == 0) orcPHT->p_offset = getElf_Off(); orcPHT->p_vaddr = getElf_Addr(); #if defined(__i386__) orcPHT->p_filesz = getElf_Word(); #elif defined(__x86_64__) orcPHT->p_filesz = getElf_Xword(); #endif #if defined(__i386__) orcPHT->p_memsz = getElf_Word(); #elif defined(__x86_64__) orcPHT->p_memsz = getElf_Xword(); #endif orcPHT->p_flags = getElf_Word(); #if defined(__i386__) orcPHT->p_align = getElf_Word(); #elif defined(__x86_64__) orcPHT->p_align = getElf_Xword(); #endif fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX",", ph, orcPHT->p_offset); fprintf(logfp, " p_vaddr = 0x"HEX",", orcPHT->p_vaddr); fprintf(logfp, " p_filesz = 0x"HEX",", orcPHT->p_filesz); fprintf(logfp, " p_memsz = 0x"HEX",", orcPHT->p_memsz); fprintf(logfp, " p_flags = 0x%x,", orcPHT->p_flags); fprintf(logfp, " p_align = 0x"HEX")", orcPHT->p_align); return 1; }
int hdr5(void) { if((rand() % 4) < 3) // 75% chance orcHDR->e_entry = getElf_Addr(); else orcHDR->e_entry = 0; fprintf(logfp, "(HDR->e_entry = 0x"HEX")", orcHDR->e_entry); return 1; }
int sht2(void) { if(rand() % 3 == 0) return 0; orcSHT->sh_addr = getElf_Addr(); fprintf(logfp, "(SHT[%d]->sh_addr = 0x"HEX")", sh, orcSHT->sh_addr); return 1; }
int sht27(void) { if(sh == 0) // Avoid the first entry of the SHT return 0; Elf_Section plt = findSectionIndexByName(".plt"); if(plt != sh) return 0; if(rand() % 4 < 3){ // 75% chance orcSHT->sh_flags &= ~SHF_EXECINSTR; fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", sh, orcSHT->sh_flags); return 1; } else { // Binary patch: the second jmp instruction in the PLT unsigned int jmp_asm; int r = rand(); // The 1st jmp in PLT is 6 bytes length in x86 and x86_64 *(orcptr + elfSHT[plt].sh_offset + 6) = 0xff; // jmp opcode *(orcptr + elfSHT[plt].sh_offset + 7) = 0x25; // jmp opcode if(r % 4 == 0) // jmp to the original entrypoint jmp_asm = (unsigned int) elfHDR->e_entry; else if(r % 4 == 1){ // jmp to _init (".init".sh_addr) Elf_Section init; if(!(init = findSectionIndexByName(".init"))) return 0; jmp_asm = (unsigned int) elfSHT[init].sh_addr; } else if(r % 4 == 2){ // jmp to _fini (".fini".sh_addr) Elf_Section fini; if(!(fini = findSectionIndexByName(".fini"))) return 0; jmp_asm = (unsigned int) elfSHT[fini].sh_addr; } else { // jmp to a semi-random address jmp_asm = (unsigned int) getElf_Addr(); if(rand() % 2) jmp_asm = SWAP32(jmp_asm); // little-endian conversion, just for phun ;D } memcpy(orcptr + elfSHT[plt].sh_offset + 8, &jmp_asm, sizeof(jmp_asm)); fprintf(logfp, "(SHT[%d]->(sh_offset + 6) = jmp 0x%x)", sh, jmp_asm); return 1; } }
int rel1(void) { if(rand() % 3 < 2) return 0; if(orcHDR->e_type == ET_REL) { if(orcSHT->sh_type == SHT_REL) orcREL->r_offset = getElf_Half(); else orcRELA->r_offset = getElf_Half(); } else if(orcHDR->e_type == ET_EXEC || orcHDR->e_type == ET_DYN) { if(orcSHT->sh_type == SHT_REL) orcREL->r_offset = getElf_Addr(); else orcRELA->r_offset = getElf_Addr(); } else return 0; fprintf(logfp, "(REL[%d]->r_offset = 0x"HEX")", entry, orcSHT->sh_type == SHT_REL ? orcREL->r_offset : orcRELA->r_offset); return 1; }
int sym3(void) { if(rand() % 5 < 4) // 80% chance to return. st_value is fuzzed in other rules as well. return 0; if(rand() % 4 < 3) orcSYM->st_value = getElf_Addr(); else orcSYM->st_value = getElf_Word(); fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value); return 1; }
int sym12(void) { if(orcSYM->st_shndx != SHN_UNDEF) return 0; if(!orcSYM->st_value) return 0; orcSYM->st_value = getElf_Addr(); fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value); return 1; }
int sym10(void) { if(orcHDR->e_type != ET_EXEC && orcHDR->e_type != ET_DYN) return 0; if(rand() % 5 < 4) return 0; orcSYM->st_value = getElf_Addr(); fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value); return 1; }
int pht12(void) { if(orcPHT->p_type != PT_DYNAMIC) return 0; if(mode & DYN) return 0; orcPHT->p_offset = getElf_Off(); orcPHT->p_vaddr = getElf_Addr(); fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX",", ph, orcPHT->p_offset); fprintf(logfp, " p_vaddr = 0x"HEX")", orcPHT->p_vaddr); return 1; }
int pht3(void) { if(orcPHT->p_type == PT_INTERP) if(rand() % 5 < 4) // 80% chance return 0; if(orcPHT->p_type == PT_DYNAMIC) if(mode & DYN) return 0; if(orcPHT->p_type == PT_NOTE) if(mode & NOTE) return 0; Elf_Addr v, p; if(rand() % 2) { if(rand() % 3 < 2) { // .5 * .6666 = 33.33% chance v = orcPHT->p_vaddr; p = getElf_Addr(); } else { // 16.66% chance v = getElf_Addr(); p = orcPHT->p_paddr; } } else { if(rand() % 2) { // .5 * .5 = 25% chance while((v = getElf_Addr())) if(v % PAGESIZE == 0) { if(rand() % 2) p = v; else p = getElf_Addr(); break; } } else { // 25% chance while((v = getElf_Addr())) if(v % PAGESIZE != 0) { if(rand() % 2) p = v; else p = getElf_Addr(); break; } } } orcPHT->p_vaddr = v; orcPHT->p_paddr = p; fprintf(logfp, "(PHT[%d]->p_vaddr = 0x"HEX",", ph, orcPHT->p_vaddr); fprintf(logfp, " p_paddr = 0x"HEX")", orcPHT->p_paddr); return 1; }
int sym8(void) { if(orcHDR->e_type != ET_REL || orcSYM->st_shndx != SHN_COMMON) return 0; Elf_Addr st_value; while((st_value = getElf_Addr())) if(st_value % 4 != 0) break; orcSYM->st_value = st_value; fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value); return 1; }
int sym1(void) { if(entry != STN_UNDEF) return 0; if(rand() % 2) return 0; #if defined(__i386__) orcSYM->st_size = getElf_Word(); #elif defined(__x86_64__) if(rand() % 3 < 2) orcSYM->st_size = getElf_Xword(); else orcSYM->st_size = getElf_Word(); #endif orcSYM->st_value = getElf_Addr(); orcSYM->st_info = rand() & 0xff; orcSYM->st_other = rand() & 0xff; if(rand() % 4 == 0) orcSYM->st_shndx = getElf_Section(); else orcSYM->st_shndx = rand() % orcHDR->e_shnum; if(rand() % 4 == 0) orcSYM->st_name = getElf_Word(); else orcSYM->st_name = rand() & 0xff; fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX",", entry, orcSYM->st_value); fprintf(logfp, " st_size = 0x"HEX",", orcSYM->st_size); fprintf(logfp, " st_info = 0x%x,", orcSYM->st_info); fprintf(logfp, " st_other = 0x%x,", orcSYM->st_other); fprintf(logfp, " st_shndx = 0x%x,", orcSYM->st_shndx); fprintf(logfp, " st_name = 0x%x)", orcSYM->st_name); return 1; }
int sht35(void) { if(sh == 0) // Avoid the first entry of the SHT return 0; if(orcSHT->sh_type != SHT_INIT_ARRAY && orcSHT->sh_type != SHT_FINI_ARRAY) return 0; if(rand() % 2) return 0; Elf_Addr addr; int r = rand(); if(r % 4 == 0) // jmp to the original entrypoint addr = elfHDR->e_entry; else if(r % 4 == 1){ // jmp to _init (".init".sh_addr) Elf_Section init; if(!(init = findSectionIndexByName(".init"))) return 0; addr = elfSHT[init].sh_addr; } else if(r % 4 == 2){ // jmp to _fini (".fini".sh_addr) Elf_Section fini; if(!(fini = findSectionIndexByName(".fini"))) return 0; addr = elfSHT[fini].sh_addr; } else addr = getElf_Addr(); memcpy(orcptr + elfSHT[sh].sh_offset, &addr, sizeof(addr)); fprintf(logfp, "(SHT[%d]->(sh_offset + 0) = 0x"HEX")", sh, addr); return 1; }
int pht22(void) { int p, found = 0; Elf_Phdr *tmpPHT = orcOrigPHT; for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++) if(tmpPHT->p_type == PT_DYNAMIC) { found++; break; } if(found) { if(mode & DYN) return 0; if(rand() % 2) // PT_DYNAMIC is important return 0; if(rand() % 3 == 0) tmpPHT->p_offset = getElf_Off(); tmpPHT->p_vaddr = getElf_Addr(); #if defined(__i386__) tmpPHT->p_filesz = getElf_Word(); #elif defined(__x86_64__) tmpPHT->p_filesz = getElf_Xword(); #endif #if defined(__i386__) tmpPHT->p_memsz = getElf_Word(); #elif defined(__x86_64__) tmpPHT->p_memsz = getElf_Xword(); #endif tmpPHT->p_flags = getElf_Word(); #if defined(__i386__) tmpPHT->p_align = getElf_Word(); #elif defined(__x86_64__) tmpPHT->p_align = getElf_Xword(); #endif fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX",", p, tmpPHT->p_offset); fprintf(logfp, " p_vaddr = 0x"HEX",", tmpPHT->p_vaddr); fprintf(logfp, " p_filesz = 0x"HEX",", tmpPHT->p_filesz); fprintf(logfp, " p_memsz = 0x"HEX",", tmpPHT->p_memsz); fprintf(logfp, " p_flags = 0x%x,", tmpPHT->p_flags); fprintf(logfp, " p_align = 0x"HEX")", tmpPHT->p_align); return 1; } else { tmpPHT = orcOrigPHT; for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++) if(tmpPHT->p_type == PT_NULL) { if(mode & DYN) return 0; tmpPHT->p_type = PT_DYNAMIC; fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", p, tmpPHT->p_type); return 1; } tmpPHT = orcOrigPHT; // Less priority than overwriting a PT_NULL for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++) if(tmpPHT->p_type == PT_GNU_STACK) { if(mode & DYN) return 0; tmpPHT->p_type = PT_DYNAMIC; fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", p, tmpPHT->p_type); return 1; } return 0; } }