Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 47 additions & 14 deletions librz/bin/format/mz/mz.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ RzPVector /*<RzBinSection *>*/ *rz_bin_mz_get_segments(const struct rz_bin_mz_ob
void **iter;
RzBinSection *section;
MZ_image_relocation_entry *relocs;
int i, num_relocs, section_number;
int i, num_relocs;
ut16 ss;

if (!bin || !bin->dos_header) {
Expand Down Expand Up @@ -137,32 +137,65 @@ RzPVector /*<RzBinSection *>*/ *rz_bin_mz_get_segments(const struct rz_bin_mz_ob
}

/* Fixup sizes and addresses, set name, permissions and set add flag */
section_number = 0;
rz_pvector_foreach (seg_vec, iter) {
ut64 index = 0;
rz_pvector_enumerate (seg_vec, iter, index) {
section = *iter;
section->name = rz_str_newf("seg_%03d", section_number);
if (section_number) {
section->name = rz_str_newf("seg_%03" PFMT64u, index);
if (index) {
// calculate current index in loop by subtracting base ptr
ut32 ptr_gap = iter - (void **)seg_vec->v.a;
ut32 cur_index = ptr_gap / sizeof(void **);
RzBinSection *p_section = NULL;
if (cur_index == 0) {
p_section = rz_pvector_tail(seg_vec);
} else {
p_section = rz_pvector_at(seg_vec, cur_index - 1);
}
p_section = rz_pvector_at(seg_vec, index - 1);
p_section->size = section->vaddr - p_section->vaddr;
p_section->vsize = p_section->size;
}
section->vsize = section->size;
section->paddr = rz_bin_mz_la_to_pa(bin, section->vaddr);
section->perm = rz_str_rwx("rwx");
section_number++;
section->perm = RZ_PERM_RWX;
}
section = rz_pvector_tail(seg_vec);
section->size = bin->load_module_size - section->vaddr;
section->vsize = section->size;

/* Map extra data (used for bss and out-of-image stack) */
ut64 stack_laddr = rz_bin_mz_va_to_la(bin->dos_header->ss, bin->dos_header->sp) + sizeof(ut16);
ut64 stack_size_outside_image = stack_laddr > bin->load_module_size ? stack_laddr - bin->load_module_size : 0;
ut64 extra_data = RZ_MAX(bin->dos_header->min_extra_paragraphs * 16, stack_size_outside_image);

if (extra_data) {
if (!(section = rz_bin_mz_init_section(bin, section->vaddr + section->vsize))) {
goto err_out;
}
if (bin->load_module_size % 16) {
/* add extra bytes so the section get to de-facto start on a paragraph-aligned address */
extra_data += 16 - bin->load_module_size % 16;
}
if (extra_data % 16) {
/* align section size to paragraph size */
extra_data += 16 - extra_data % 16;
}
section->name = rz_str_dup("extra");
section->size = 0;
section->vsize = extra_data;
section->is_data = true;
section->perm = RZ_PERM_RW;
rz_pvector_push(seg_vec, section);
}

/* Map overlay as a separate section */
ut64 overlay_size = bin->size > bin->dos_file_size ? bin->size - bin->dos_file_size : 0;
if (overlay_size) {
ut64 start_laddr = RZ_MAX(section->vaddr + section->vsize, 0x100000); /* map at/after 1mb */
if (!(section = rz_bin_mz_init_section(bin, start_laddr))) {
goto err_out;
}
section->paddr = bin->size - overlay_size;
section->name = rz_str_dup("overlay");
section->size = overlay_size;
section->vsize = section->size;
section->perm = RZ_PERM_RWX;
rz_pvector_push(seg_vec, section);
}

return seg_vec;

err_out:
Expand Down
1 change: 1 addition & 0 deletions test/db/formats/mz/cblp0
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ EXPECT=<<EOF
paddr size vaddr vsize align perm name type flags
----------------------------------------------------------------
0x00000200 0x200 0x00000000 0x200 0x0 -rwx seg_000
0x00000000 0x0 0x00000200 0x90 0x0 -rw- extra
EOF
RUN
18 changes: 18 additions & 0 deletions test/db/formats/mz/unzip
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,21 @@ EXPECT=<<EOF
mov bp, ax
EOF
RUN

NAME=MZ: unzip-modified-ss-sp.exe - correct section sizes
FILE=bins/mz/unzip-modified-ss-sp.exe
CMDS=<<EOF
iSt
x 8 @ 0x100000
EOF
EXPECT=<<EOF
paddr size vaddr vsize align perm name type flags
--------------------------------------------------------------------
0x00000200 0x15000 0x00000000 0x15000 0x0 -rwx seg_000
0x00015200 0xfce 0x00015000 0xfce 0x0 -rwx seg_001
0x00000000 0x0 0x00015fce 0xa1f0 0x0 -rw- extra
0x000161ce 0x5 0x00100000 0x5 0x0 -rwx overlay
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0000:0000 6865 6c6c 6fff ffff hello...
EOF
RUN
Loading