Skip to content

Commit 5443f08

Browse files
committed
Migrate to lief
1 parent ba4a5e9 commit 5443f08

File tree

7 files changed

+282
-214
lines changed

7 files changed

+282
-214
lines changed

dfint64_patch/binio.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
from collections.abc import Iterable
22
from typing import BinaryIO
33

4-
from peclasses.section_table import Section
5-
64
from dfint64_patch.type_aliases import Offset
75

86

@@ -40,11 +38,3 @@ def write_string(
4038
bs = s.encode() if encoding is None else s.encode(encoding)
4139

4240
file_object.write(bs.ljust(new_len, b"\0"))
43-
44-
45-
def read_section_data(file: BinaryIO, section: Section) -> bytes:
46-
return read_bytes(
47-
file,
48-
Offset(section.pointer_to_raw_data),
49-
Offset(section.size_of_raw_data),
50-
)

dfint64_patch/extract_strings/cli.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import operator
22
from dataclasses import dataclass
3+
from io import BufferedReader
34
from pathlib import Path
4-
from typing import BinaryIO, cast
55

6+
import lief
67
from omegaconf import DictConfig
7-
from peclasses.portable_executable import PortableExecutable
88

9-
from dfint64_patch.binio import read_section_data
109
from dfint64_patch.config import with_config
1110
from dfint64_patch.cross_references.cross_references_relative import (
1211
find_relative_cross_references,
@@ -19,25 +18,25 @@
1918
from dfint64_patch.utils import maybe_open
2019

2120

22-
def extract_strings(pe_file: BinaryIO) -> list[ExtractedStringInfo]:
23-
pe = PortableExecutable(pe_file)
21+
def extract_strings(pe_file: BufferedReader) -> list[ExtractedStringInfo]:
22+
pe = lief.PE.parse(pe_file)
23+
assert pe is not None
2424

25-
sections = pe.section_table
26-
code_section = sections[0]
27-
string_section = sections[1]
25+
code_section = pe.sections[0]
26+
string_section = pe.sections[1]
2827

29-
image_base = pe.optional_header.image_base
28+
image_base = pe.optional_header.imagebase
3029

3130
strings = list(
3231
extract_strings_from_raw_bytes(
33-
read_section_data(pe_file, string_section),
34-
base_address=Rva(cast(int, string_section.virtual_address) + image_base),
32+
string_section.content,
33+
base_address=Rva(string_section.virtual_address + image_base),
3534
),
3635
)
3736

3837
cross_references = find_relative_cross_references(
39-
read_section_data(pe_file, code_section),
40-
base_address=Rva(cast(int, code_section.virtual_address) + image_base),
38+
code_section.content,
39+
base_address=Rva(code_section.virtual_address + image_base),
4140
addresses=map(operator.itemgetter(0), strings),
4241
)
4342

dfint64_patch/extract_strings/from_raw_bytes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ExtractedStringInfo(NamedTuple):
3535

3636

3737
def extract_strings_from_raw_bytes(
38-
bytes_block: bytes,
38+
bytes_block: bytes | memoryview,
3939
base_address: Rva = RVA0,
4040
alignment: int = 4,
4141
encoding: str = "cp437",
@@ -48,6 +48,7 @@ def extract_strings_from_raw_bytes(
4848
:param encoding: string encoding
4949
:return: Iterator[ExtractedStringInfo]
5050
"""
51+
bytes_block = bytes(bytes_block)
5152
i = 0
5253
while i < len(bytes_block):
5354
if bytes_block[i] == b"\0":

dfint64_patch/patching/patch.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
from collections.abc import Iterable, Mapping
22
from pathlib import Path
3-
from typing import cast
43

4+
import lief
55
from loguru import logger
6-
from peclasses.portable_executable import PortableExecutable
76

8-
from dfint64_patch.binio import read_section_data
97
from dfint64_patch.cross_references.cross_references_relative import (
108
find_intersected_cross_references,
119
find_relative_cross_references,
@@ -17,29 +15,27 @@
1715

1816
def patch(patched_file: str | Path, translation_table: list[tuple[str, str]], encoding: str) -> None:
1917
with Path(patched_file).open("r+b") as pe_file:
20-
pe = PortableExecutable(pe_file)
18+
pe = lief.PE.parse(pe_file)
19+
assert pe is not None
2120

22-
sections = pe.section_table
23-
code_section = sections[0]
24-
data_section = sections[1]
25-
26-
cast(int, pe.optional_header.image_base)
21+
code_section = pe.sections[0]
22+
data_section = pe.sections[1]
2723

2824
logger.info("Extracting strings...")
2925
strings = {
3026
item.address: item.string
3127
for item in extract_strings_from_raw_bytes(
32-
read_section_data(pe_file, data_section),
33-
base_address=Rva(cast(int, data_section.virtual_address)),
28+
data_section.content,
29+
base_address=Rva(data_section.virtual_address),
3430
)
3531
}
3632

3733
logger.info(f"Found {len(strings)} string-like objects")
3834

3935
logger.info("Searching for cross references...")
4036
cross_references = find_relative_cross_references(
41-
read_section_data(pe_file, code_section),
42-
base_address=Rva(cast(int, code_section.virtual_address)),
37+
code_section.content,
38+
base_address=Rva(code_section.virtual_address),
4339
addresses=strings,
4440
)
4541

@@ -60,7 +56,7 @@ def patch(patched_file: str | Path, translation_table: list[tuple[str, str]], en
6056
if len(translation) <= len(string):
6157
# Shorter strings are padded with spaces
6258
encoded_translation = translation.encode(encoding).ljust(len(string) + 1) + b"\0"
63-
pe_file.seek(data_section.rva_to_offset(rva))
59+
pe_file.seek(pe.rva_to_offset(rva))
6460
pe_file.write(encoded_translation)
6561
else:
6662
# TODO: implement this case

dfint64_patch/strings_context/extract_strings_with_subs.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,35 @@
44

55
from collections import defaultdict
66
from dataclasses import dataclass
7+
from io import BufferedReader
78
from operator import itemgetter
89
from pathlib import Path
9-
from typing import BinaryIO, NamedTuple
10+
from typing import NamedTuple
1011

12+
import lief
1113
from omegaconf import DictConfig
12-
from peclasses.portable_executable import PortableExecutable
1314

14-
from dfint64_patch.binio import read_section_data
1515
from dfint64_patch.config import with_config
1616
from dfint64_patch.cross_references.cross_references_relative import find_relative_cross_references
1717
from dfint64_patch.extract_strings.from_raw_bytes import ExtractedStringInfo, extract_strings_from_raw_bytes
1818
from dfint64_patch.extract_subroutines.from_raw_bytes import SubroutineInfo, extract_subroutines, which_subroutine
1919
from dfint64_patch.type_aliases import Rva
2020

2121

22-
def extract_strings_with_xrefs(pe_file: BinaryIO, pe: PortableExecutable) -> dict[ExtractedStringInfo, list[Rva]]:
23-
sections = pe.section_table
24-
code_section = sections[0]
25-
string_section = sections[1]
22+
def extract_strings_with_xrefs(pe: lief.PE.Binary) -> dict[ExtractedStringInfo, list[Rva]]:
23+
code_section = pe.sections[0]
24+
string_section = pe.sections[1]
2625

2726
strings = list(
2827
extract_strings_from_raw_bytes(
29-
read_section_data(pe_file, string_section),
30-
base_address=string_section.virtual_address,
28+
string_section.content,
29+
base_address=Rva(string_section.virtual_address),
3130
),
3231
)
3332

3433
cross_references = find_relative_cross_references(
35-
read_section_data(pe_file, code_section),
36-
base_address=code_section.virtual_address,
34+
code_section.content,
35+
base_address=Rva(code_section.virtual_address),
3736
addresses=map(itemgetter(0), strings),
3837
)
3938

@@ -49,18 +48,18 @@ class StringCrossReference(NamedTuple):
4948
cross_reference: Rva
5049

5150

52-
def extract_strings_grouped_by_subs(pe_file: BinaryIO) -> dict[Rva, list[StringCrossReference]]:
53-
pe = PortableExecutable(pe_file)
54-
sections = pe.section_table
55-
code_section = sections[0]
51+
def extract_strings_grouped_by_subs(pe_file: BufferedReader) -> dict[Rva, list[StringCrossReference]]:
52+
pe = lief.PE.parse(pe_file)
53+
assert pe is not None
54+
code_section = pe.sections[0]
5655

57-
image_base = pe.optional_header.image_base
56+
image_base = pe.optional_header.imagebase
5857

59-
strings_with_xrefs = extract_strings_with_xrefs(pe_file, pe)
58+
strings_with_xrefs = extract_strings_with_xrefs(pe)
6059

6160
subroutines = list(
6261
extract_subroutines(
63-
read_section_data(pe_file, code_section),
62+
code_section.content,
6463
base_offset=code_section.virtual_address,
6564
)
6665
)

0 commit comments

Comments
 (0)