From c9cd4c7f37ab78957688e86abe0016408618db6b Mon Sep 17 00:00:00 2001 From: zt20xx <2326945144@qq.com> Date: Mon, 28 Oct 2024 01:00:35 +0800 Subject: [PATCH 1/6] add_ko_file_search_support --- pwnlib/elf/elf.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index 02668f0a9..128518e23 100644 --- a/pwnlib/elf/elf.py +++ b/pwnlib/elf/elf.py @@ -1258,6 +1258,23 @@ def search(self, needle, writable = False, executable = False): break yield (addr + offset + load_address_fixup) offset += 1 + if not segments: + for section in super().iter_sections(): + if section.name==".text": + addr = section['sh_addr'] + memsz = section['sh_size'] + filesz = section['sh_size'] + zeroed = memsz - filesz + offset = section['sh_offset'] + data = self.mmap[offset:offset + filesz] + data += b'\x00' + offset = 0 + while True: + offset = data.find(needle, offset) + if offset == -1: + break + yield (addr + offset + load_address_fixup) + offset += 1 def offset_to_vaddr(self, offset): """offset_to_vaddr(offset) -> int From e3c3b2f1b31968325028886393ff69275f4e2c50 Mon Sep 17 00:00:00 2001 From: zt20xx <2326945144@qq.com> Date: Wed, 13 Nov 2024 01:07:34 +0800 Subject: [PATCH 2/6] add ko search writable --- pwnlib/elf/elf.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index 128518e23..8346b42bd 100644 --- a/pwnlib/elf/elf.py +++ b/pwnlib/elf/elf.py @@ -52,7 +52,7 @@ from elftools.elf.constants import P_FLAGS from elftools.elf.constants import SHN_INDICES from elftools.elf.descriptions import describe_e_type -from elftools.elf.elffile import ELFFile +from elftools.elf.elffile import ELFFile, PAGESIZE from elftools.elf.enums import ENUM_GNU_PROPERTY_X86_FEATURE_1_FLAGS from elftools.elf.gnuversions import GNUVerDefSection from elftools.elf.relocation import RelocationSection, RelrRelocationSection @@ -1259,12 +1259,26 @@ def search(self, needle, writable = False, executable = False): yield (addr + offset + load_address_fixup) offset += 1 if not segments: + if writable: + ko_check_segments = ".data" + text_filesz=0 + rodata_filesz=0 + for section in super().iter_sections(): + if section.name == ".text": + text_filesz = section['sh_size'] + elif len(section.name)>=len(".rodata") and section.name[:len(".rodata")]==".rodata": + rodata_filesz += section['sh_size'] + addr = (text_filesz//PAGESIZE + 1 + rodata_filesz//PAGESIZE + 1)*PAGESIZE + elif executable: + ko_check_segments = ".text" + addr = 0 + else: + # There may be other sections before .rodata, such as .note.gnu.build-id or .note.Linux + ko_check_segments = ".text" + addr = 0 for section in super().iter_sections(): - if section.name==".text": - addr = section['sh_addr'] - memsz = section['sh_size'] + if section.name == ko_check_segments: filesz = section['sh_size'] - zeroed = memsz - filesz offset = section['sh_offset'] data = self.mmap[offset:offset + filesz] data += b'\x00' From f94550b5c06d226994cdf254b07133f56ba88064 Mon Sep 17 00:00:00 2001 From: zt20xx <2326945144@qq.com> Date: Wed, 13 Nov 2024 21:23:22 +0800 Subject: [PATCH 3/6] update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 553b16e99..d47593e8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ The table below shows which release corresponds to each branch, and what date th - [#2482][2482] Throw error when using `sni` and setting `server_hostname` manually in `remote` - [#2478][2478] libcdb-cli: add `--offline-only`, refactor unstrip and add fetch parser for download libc-database - [#2484][2484] Allow to disable caching +- [#2496][2496] Add linux ko file search support [2471]: https://github.com/Gallopsled/pwntools/pull/2471 [2358]: https://github.com/Gallopsled/pwntools/pull/2358 @@ -96,6 +97,7 @@ The table below shows which release corresponds to each branch, and what date th [2482]: https://github.com/Gallopsled/pwntools/pull/2482 [2478]: https://github.com/Gallopsled/pwntools/pull/2478 [2484]: https://github.com/Gallopsled/pwntools/pull/2484 +[2496]: https://github.com/Gallopsled/pwntools/pull/2496 ## 4.14.0 (`beta`) From 77952b37fae55e5004cd76c9cf286ad44362fa97 Mon Sep 17 00:00:00 2001 From: zzttbak Date: Thu, 14 Nov 2024 09:20:02 +0800 Subject: [PATCH 4/6] ko search adjust --- pwnlib/elf/elf.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index 8346b42bd..6ceaa8ae3 100644 --- a/pwnlib/elf/elf.py +++ b/pwnlib/elf/elf.py @@ -1260,24 +1260,14 @@ def search(self, needle, writable = False, executable = False): offset += 1 if not segments: if writable: - ko_check_segments = ".data" - text_filesz=0 - rodata_filesz=0 - for section in super().iter_sections(): - if section.name == ".text": - text_filesz = section['sh_size'] - elif len(section.name)>=len(".rodata") and section.name[:len(".rodata")]==".rodata": - rodata_filesz += section['sh_size'] - addr = (text_filesz//PAGESIZE + 1 + rodata_filesz//PAGESIZE + 1)*PAGESIZE + ko_check_segments = [".data"] elif executable: - ko_check_segments = ".text" - addr = 0 + ko_check_segments = [".text"] else: # There may be other sections before .rodata, such as .note.gnu.build-id or .note.Linux - ko_check_segments = ".text" - addr = 0 + ko_check_segments = [".text",".data"] for section in super().iter_sections(): - if section.name == ko_check_segments: + if section.name in ko_check_segments: filesz = section['sh_size'] offset = section['sh_offset'] data = self.mmap[offset:offset + filesz] @@ -1287,6 +1277,18 @@ def search(self, needle, writable = False, executable = False): offset = data.find(needle, offset) if offset == -1: break + if section.name == ".data": + text_filesz=0 + rodata_filesz=0 + for section in super().iter_sections(): + if section.name == ".text": + text_filesz = section['sh_size'] + elif len(section.name)>=len(".rodata") and section.name[:len(".rodata")]==".rodata": + rodata_filesz += section['sh_size'] + addr = (text_filesz//PAGESIZE + 1 + rodata_filesz//PAGESIZE + 1)*PAGESIZE + elif section.name == ".text": + addr = 0 + yield (addr + offset + load_address_fixup) offset += 1 From 11a9208e52da8a29e5f2bb65659f9e9ee5f04ff4 Mon Sep 17 00:00:00 2001 From: zt20xx <2326945144@qq.com> Date: Sat, 16 Nov 2024 11:51:05 +0800 Subject: [PATCH 5/6] add ko search readonly --- pwnlib/elf/elf.py | 63 +++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index 6ceaa8ae3..f8bf2ade8 100644 --- a/pwnlib/elf/elf.py +++ b/pwnlib/elf/elf.py @@ -1264,34 +1264,43 @@ def search(self, needle, writable = False, executable = False): elif executable: ko_check_segments = [".text"] else: - # There may be other sections before .rodata, such as .note.gnu.build-id or .note.Linux - ko_check_segments = [".text",".data"] + ko_check_segments = [".text",".note",".rodata",".data"] for section in super().iter_sections(): - if section.name in ko_check_segments: - filesz = section['sh_size'] - offset = section['sh_offset'] - data = self.mmap[offset:offset + filesz] - data += b'\x00' - offset = 0 - while True: - offset = data.find(needle, offset) - if offset == -1: - break - if section.name == ".data": - text_filesz=0 - rodata_filesz=0 - for section in super().iter_sections(): - if section.name == ".text": - text_filesz = section['sh_size'] - elif len(section.name)>=len(".rodata") and section.name[:len(".rodata")]==".rodata": - rodata_filesz += section['sh_size'] - addr = (text_filesz//PAGESIZE + 1 + rodata_filesz//PAGESIZE + 1)*PAGESIZE - elif section.name == ".text": - addr = 0 - - yield (addr + offset + load_address_fixup) - offset += 1 - + if section.name not in ko_check_segments and \ + not any(section.name.startswith(ko_check_segment) for ko_check_segment in ko_check_segments): + continue + filesz = section['sh_size'] + offset = section['sh_offset'] + data = self.mmap[offset:offset + filesz] + data += b'\x00' + offset = 0 + while True: + offset = data.find(needle, offset) + if offset == -1: + break + # ko_file: header->.note->.text->.rodata->.data + # after insmod: text page(executable page), note and rodate page(read only page), data page(writable page) + if section.name == ".text": + addr = 0 + elif section.name.startswith(".note") : + text_filesz=self.get_section_by_name(".text")['sh_size'] + addr = (text_filesz//PAGESIZE + 1)*PAGESIZE + section['sh_offset'] - self.header['e_ehsize'] + elif section.name.startswith(".rodata"): + text_filesz=self.get_section_by_name(".text")['sh_size'] + text_offset=self.get_section_by_name(".text")['sh_offset'] + addr = (text_filesz//PAGESIZE + 1)*PAGESIZE + text_offset - self.header['e_ehsize'] + elif section.name == ".data" : + text_filesz=self.get_section_by_name(".text")['sh_size'] + rodata_filesz=0 + note_filez=0 + for section in super().iter_sections(): + if section.name.startswith(".rodata"): + rodata_filesz += section['sh_size'] + elif section.name.startswith(".node"): + note_filesz += section['sh_size'] + addr = (text_filesz//PAGESIZE + 1 + (note_filez+rodata_filesz)//PAGESIZE + 1)*PAGESIZE + yield (addr + offset + load_address_fixup) + offset += 1 def offset_to_vaddr(self, offset): """offset_to_vaddr(offset) -> int From 07ac17fac206187b89c703246a40f30da312f28e Mon Sep 17 00:00:00 2001 From: zt20xx <113044696+zt20xx@users.noreply.github.com> Date: Fri, 7 Mar 2025 21:19:46 +0800 Subject: [PATCH 6/6] fix spelling mistakes Co-authored-by: Arusekk --- pwnlib/elf/elf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index 9d2939882..73c10164a 100644 --- a/pwnlib/elf/elf.py +++ b/pwnlib/elf/elf.py @@ -1297,7 +1297,7 @@ def search(self, needle, writable = False, executable = False): for section in super().iter_sections(): if section.name.startswith(".rodata"): rodata_filesz += section['sh_size'] - elif section.name.startswith(".node"): + elif section.name.startswith(".note"): note_filesz += section['sh_size'] addr = (text_filesz//PAGESIZE + 1 + (note_filez+rodata_filesz)//PAGESIZE + 1)*PAGESIZE yield (addr + offset + load_address_fixup)