먼저이 완료 objcopy의 --writable 텍스트를 --set-section-flags .text = CONTENTS, ALLOC, LOAD, CODE
그런 다음 objdump -x 또는 readelf -a를 사용하여 일반적으로 프로그램 헤더 뒤의로드 섹션 테이블을 봅니다. ELF 매뉴얼 페이지를 참조하십시오.
hexedit를 사용하여 이진 파일을 열고 파일 오프셋 0x1C (종종 0x34)에서 값을 확인한 다음 찾을 때까지 0x20 바이트 구조 (파일 오프셋 0x2a에 나열된 크기)를 탐색합니다. 이전 덤프에서 .text 섹션을 포함하는 것으로 식별 한 파일. 마지막 두 번째 값은 00000005 (05 00 00 00)가되며 쓰기가 추가되어야 00000007 (07 00 00 00)이됩니다. 이제는 -Wl, - omagic의 공유 라이브러리 문제와 같은 제한없이 예상대로 작동합니다. 조금 기술적이지만, 몇 초가 걸립니다.
이 1 비트 플래그는 수많은 문제를 일으켰으며 아무런 설명없이이 작은 점이 완벽하게 작동합니다.
코드 솔루션을 쉽게 일상적으로 그 일을하면 가능성이 쉽게 변화와 더 나은 솔루션을 수행하는 GCC로 컴파일 할 수 있습니다
#include <stdlib.h>
#include <stdio.h>
#include <elf.h>
int main(int argc, char** argv)
{
if (argc <= 1) return -1;
FILE* fp = fopen(argv[1], "r+");
Elf64_Ehdr teh;
fread(&teh, sizeof(teh), 1, fp);
fseek(fp, 0, SEEK_SET);
if (teh.e_ident[EI_CLASS] == ELFCLASS64) {
Elf64_Ehdr eh;
fread(&eh, sizeof(eh), 1, fp);
Elf64_Phdr* ph = malloc(eh.e_phnum * eh.e_phentsize);
Elf64_Shdr* sh = malloc(eh.e_shnum * eh.e_shentsize);
fseek(fp, eh.e_phoff, SEEK_SET);
fread(ph, eh.e_phentsize, eh.e_phnum, fp);
fseek(fp, eh.e_shoff, SEEK_SET);
fread(sh, eh.e_shentsize, eh.e_shnum, fp);
for (int i = 0; i < eh.e_phnum; i++) {
if (ph[i].p_vaddr <= eh.e_entry && ph[i].p_vaddr + ph[i].p_memsz > eh.e_entry) {
fseek(fp, eh.e_phoff + i * eh.e_phentsize + (unsigned int)&((Elf64_Phdr*)0)->p_flags, SEEK_SET);
ph[i].p_flags |= PF_W;
fwrite(&ph[i].p_flags, sizeof(ph[i].p_flags), 1, fp);
}
}
for (int i = 0; i < eh.e_shnum; i++) {
if (sh[i].sh_addr <= eh.e_entry && sh[i].sh_addr + sh[i].sh_size > eh.e_entry) {
fseek(fp, eh.e_shoff + i * eh.e_shentsize + (unsigned int)&((Elf64_Shdr*)0)->sh_flags, SEEK_SET);
sh[i].sh_flags |= SHF_WRITE;
fwrite(&sh[i].sh_flags, sizeof(sh[i].sh_flags), 1, fp);
}
}
free(ph);
free(sh);
} else {
Elf32_Ehdr eh;
fread(&eh, sizeof(eh), 1, fp);
Elf32_Phdr* ph = malloc(eh.e_phnum * eh.e_phentsize);
Elf32_Shdr* sh = malloc(eh.e_shnum * eh.e_shentsize);
fseek(fp, eh.e_phoff, SEEK_SET);
fread(ph, eh.e_phentsize, eh.e_phnum, fp);
fseek(fp, eh.e_shoff, SEEK_SET);
fread(sh, eh.e_shentsize, eh.e_shnum, fp);
for (int i = 0; i < eh.e_phnum; i++) {
if (ph[i].p_vaddr <= eh.e_entry && ph[i].p_vaddr + ph[i].p_memsz > eh.e_entry) {
fseek(fp, eh.e_phoff + i * eh.e_phentsize + (unsigned int)&((Elf32_Phdr*)0)->p_flags, SEEK_SET);
ph[i].p_flags |= PF_W;
fwrite(&ph[i].p_flags, sizeof(ph[i].p_flags), 1, fp);
}
}
for (int i = 0; i < eh.e_shnum; i++) {
if (sh[i].sh_addr <= eh.e_entry && sh[i].sh_addr + sh[i].sh_size > eh.e_entry) {
fseek(fp, eh.e_shoff + i * eh.e_shentsize + (unsigned int)&((Elf32_Shdr*)0)->sh_flags, SEEK_SET);
sh[i].sh_flags |= SHF_WRITE;
fwrite(&sh[i].sh_flags, sizeof(sh[i].sh_flags), 1, fp);
}
}
free(ph);
free(sh);
}
fflush(fp);
fclose(fp);
return 0;
}