Skip to content

Commit bd6f627

Browse files
committed
Resolve #1130
1 parent b5df89f commit bd6f627

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/MachO/Binary.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,10 @@ ok_error_t Binary::shift(size_t value) {
885885
}
886886

887887
shift_command(value, loadcommands_end);
888+
const uint64_t loadcommands_end_va = loadcommands_end + load_cmd_segment->virtual_address();
889+
890+
LIEF_DEBUG("loadcommands_end: 0x{:016x}", loadcommands_end);
891+
LIEF_DEBUG("loadcommands_end_va: 0x{:016x}", loadcommands_end_va);
888892

889893
// Shift Segment and sections
890894
// ==========================
@@ -904,19 +908,23 @@ ok_error_t Binary::shift(size_t value) {
904908
}
905909
}
906910
} else {
911+
if (segment->virtual_address() >= loadcommands_end_va) {
912+
segment->virtual_address(segment->virtual_address() + value);
913+
}
914+
907915
if (segment->file_offset() >= loadcommands_end) {
908916
segment->file_offset(segment->file_offset() + value);
909-
segment->virtual_address(segment->virtual_address() + value);
910917
}
911918

912919
for (const std::unique_ptr<Section>& section : segment->sections_) {
913-
if (section->offset() >= loadcommands_end) {
914-
section->offset(section->offset() + value);
920+
if (section->virtual_address() >= loadcommands_end_va ||
921+
section->type() == Section::TYPE::ZEROFILL)
922+
{
915923
section->virtual_address(section->virtual_address() + value);
916924
}
917925

918-
if (section->type() == Section::TYPE::ZEROFILL) {
919-
section->virtual_address(section->virtual_address() + value);
926+
if (section->offset() >= loadcommands_end_va) {
927+
section->offset(section->offset() + value);
920928
}
921929
}
922930
}

tests/macho/test_issues.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,15 @@ def test_endianness():
3131
target = lief.MachO.parse(get_sample("MachO/macho-issue-1110.bin")).at(0)
3232

3333
assert len(target.segments) == 3
34+
35+
def test_1130(tmp_path: Path):
36+
target = lief.MachO.parse(get_sample("MachO/issue_1130.macho")).at(0)
37+
target.shift(0x4000)
38+
39+
output = tmp_path / "new.macho"
40+
target.write(output.as_posix())
41+
42+
new = lief.MachO.parse(output).at(0)
43+
assert lief.MachO.check_layout(new)[0]
44+
45+
assert new.get_segment("__DATA").virtual_address == 0x100008000

0 commit comments

Comments
 (0)