shut up & fix for bigger stuff
This commit is contained in:
parent
5c29ef41ff
commit
3e49b5e418
109
src/main.rs
109
src/main.rs
@ -141,14 +141,16 @@ fn write_le_header(new_header: &LEHeader, le_stub: &mut std::fs::File) -> std::r
|
|||||||
// Fixup record table offset 6Ch
|
// Fixup record table offset 6Ch
|
||||||
le_stub.write_at(&(fixup_record_table_offset as u32 - le_header_offset as u32).to_le_bytes(), le_header_offset + 0x6C)?;
|
le_stub.write_at(&(fixup_record_table_offset as u32 - le_header_offset as u32).to_le_bytes(), le_header_offset + 0x6C)?;
|
||||||
// Data pages offset 80h
|
// Data pages offset 80h
|
||||||
let data_pages_offset = 0x1000 +
|
//let data_pages_offset = 0x1000 +
|
||||||
((new_header.fixup_records.len() + new_header.fixup_page_offsets.len() * 4 + 0x68 + le_header_offset as usize) / 0x1000) * 0x1000;
|
// ((new_header.fixup_records.len() + new_header.fixup_page_offsets.len() * 4 + 0x68 + le_header_offset as usize) / 0x1000) * 0x1000;
|
||||||
|
//le_stub.write_at(&(data_pages_offset as u32).to_le_bytes(), le_header_offset + 0x80)?;
|
||||||
|
let data_pages_offset = ((le_stub.stream_position()? >> 12) + 1) << 12;
|
||||||
le_stub.write_at(&(data_pages_offset as u32).to_le_bytes(), le_header_offset + 0x80)?;
|
le_stub.write_at(&(data_pages_offset as u32).to_le_bytes(), le_header_offset + 0x80)?;
|
||||||
|
|
||||||
Ok(data_pages_offset as u32)
|
Ok(data_pages_offset as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_le_relocations(obj_file: &object::File, le_header: &mut LEHeader) {
|
fn output_le_relocations(obj_file: &object::File, le_header: &mut LEHeader, verbose: bool) {
|
||||||
let mut current_page = 0;
|
let mut current_page = 0;
|
||||||
let mut reloc_idx = 0;
|
let mut reloc_idx = 0;
|
||||||
// start with 0
|
// start with 0
|
||||||
@ -156,7 +158,7 @@ fn output_le_relocations(obj_file: &object::File, le_header: &mut LEHeader) {
|
|||||||
let current_section = obj_file.section_by_name(".text").unwrap();
|
let current_section = obj_file.section_by_name(".text").unwrap();
|
||||||
let mut text_relocations: Vec<(u64, Relocation)> = current_section.relocations().collect();
|
let mut text_relocations: Vec<(u64, Relocation)> = current_section.relocations().collect();
|
||||||
text_relocations.sort_by(|(loca, _), (locb, _)| loca.cmp(locb));
|
text_relocations.sort_by(|(loca, _), (locb, _)| loca.cmp(locb));
|
||||||
println!("\t[LE Text Relocations]");
|
if verbose { println!("\t[LE Text Relocations]"); }
|
||||||
for (loc, rel) in text_relocations {
|
for (loc, rel) in text_relocations {
|
||||||
match rel.target() {
|
match rel.target() {
|
||||||
object::RelocationTarget::Symbol(s) => {
|
object::RelocationTarget::Symbol(s) => {
|
||||||
@ -209,9 +211,10 @@ fn output_le_relocations(obj_file: &object::File, le_header: &mut LEHeader) {
|
|||||||
// new page
|
// new page
|
||||||
le_header.fixup_page_offsets.push(reloc_idx);
|
le_header.fixup_page_offsets.push(reloc_idx);
|
||||||
current_page += 1;
|
current_page += 1;
|
||||||
println!("\nFixup page rollover at {:05x} for page {}", reloc_idx, current_page);
|
|
||||||
|
if verbose { println!("\nFixup page rollover at {:05x} for page {}", reloc_idx, current_page); }
|
||||||
}
|
}
|
||||||
print!("{}:0x{:05x}->{}:0x{:05x} ", current_page, loc, target_sec, target_offset);
|
if verbose { print!("{}:0x{:05x}->{}:0x{:05x} ", current_page, loc, target_sec, target_offset); }
|
||||||
if dwordoffset {
|
if dwordoffset {
|
||||||
// 32-bit offset
|
// 32-bit offset
|
||||||
reloc_idx += 2;
|
reloc_idx += 2;
|
||||||
@ -225,12 +228,12 @@ fn output_le_relocations(obj_file: &object::File, le_header: &mut LEHeader) {
|
|||||||
le_header.fixup_page_offsets.push(reloc_idx);
|
le_header.fixup_page_offsets.push(reloc_idx);
|
||||||
current_page += 1;
|
current_page += 1;
|
||||||
}
|
}
|
||||||
println!();
|
if verbose { println!(); }
|
||||||
current_page = 0;
|
current_page = 0;
|
||||||
let current_section = obj_file.section_by_name(".data").unwrap();
|
let current_section = obj_file.section_by_name(".data").unwrap();
|
||||||
let mut data_relocations: Vec<(u64, Relocation)> = current_section.relocations().collect();
|
let mut data_relocations: Vec<(u64, Relocation)> = current_section.relocations().collect();
|
||||||
data_relocations.sort_by(|(loca, _), (locb, _)| loca.cmp(locb));
|
data_relocations.sort_by(|(loca, _), (locb, _)| loca.cmp(locb));
|
||||||
println!("\t[LE Data Relocations]");
|
if verbose { println!("\t[LE Data Relocations]"); }
|
||||||
for (loc, rel) in data_relocations {
|
for (loc, rel) in data_relocations {
|
||||||
match rel.target() {
|
match rel.target() {
|
||||||
object::RelocationTarget::Symbol(s) => {
|
object::RelocationTarget::Symbol(s) => {
|
||||||
@ -283,9 +286,9 @@ fn output_le_relocations(obj_file: &object::File, le_header: &mut LEHeader) {
|
|||||||
// new page
|
// new page
|
||||||
le_header.fixup_page_offsets.push(reloc_idx);
|
le_header.fixup_page_offsets.push(reloc_idx);
|
||||||
current_page += 1;
|
current_page += 1;
|
||||||
println!("\nFixup page rollover at {:05x} for page {}", reloc_idx, current_page);
|
if verbose { println!("\nFixup page rollover at {:05x} for page {}", reloc_idx, current_page); }
|
||||||
}
|
}
|
||||||
print!("{}:0x{:05x}->{}:0x{:05x} ", current_page, loc, target_sec, target_offset);
|
if verbose { print!("{}:0x{:05x}->{}:0x{:05x} ", current_page, loc, target_sec, target_offset); }
|
||||||
if dwordoffset {
|
if dwordoffset {
|
||||||
// 32-bit offset
|
// 32-bit offset
|
||||||
reloc_idx += 2;
|
reloc_idx += 2;
|
||||||
@ -299,30 +302,29 @@ fn output_le_relocations(obj_file: &object::File, le_header: &mut LEHeader) {
|
|||||||
le_header.fixup_page_offsets.push(reloc_idx);
|
le_header.fixup_page_offsets.push(reloc_idx);
|
||||||
current_page += 1;
|
current_page += 1;
|
||||||
}
|
}
|
||||||
println!();
|
if verbose { println!(); }
|
||||||
// End of Fixup page table
|
// End of Fixup page table
|
||||||
le_header.fixup_page_offsets.push(reloc_idx);
|
le_header.fixup_page_offsets.push(reloc_idx);
|
||||||
|
|
||||||
println!("{} bytes of relocations", reloc_idx);
|
println!("{} bytes of relocations", reloc_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
fn convert(data: &[u8], verbose: bool) -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||||
let args: Vec<String> = env::args().collect();
|
let obj_file = object::File::parse(data)?;
|
||||||
let path = &args[1];
|
|
||||||
let data = fs::read(path)?;
|
|
||||||
let obj_file = object::File::parse(&*data)?;
|
|
||||||
|
|
||||||
for section in obj_file.sections() {
|
if verbose {
|
||||||
println!("\tSECTION [{}]\tKIND {}", section.name().unwrap(), match section.kind() {
|
for section in obj_file.sections() {
|
||||||
object::SectionKind::Text => "text",
|
println!("\tSECTION [{}]\tKIND {}", section.name().unwrap(), match section.kind() {
|
||||||
object::SectionKind::Data => "data",
|
object::SectionKind::Text => "text",
|
||||||
object::SectionKind::ReadOnlyData => "rodata",
|
object::SectionKind::Data => "data",
|
||||||
object::SectionKind::UninitializedData => "bss",
|
object::SectionKind::ReadOnlyData => "rodata",
|
||||||
_ => "Other",
|
object::SectionKind::UninitializedData => "bss",
|
||||||
});
|
_ => "Other",
|
||||||
println!("\tRELOCATIONS FOR [{}]", section.name().unwrap());
|
});
|
||||||
print_section_relocations(§ion, &obj_file);
|
println!("\tRELOCATIONS FOR [{}]", section.name().unwrap());
|
||||||
println!();
|
print_section_relocations(§ion, &obj_file);
|
||||||
|
println!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for symbol in obj_file.symbols() {
|
for symbol in obj_file.symbols() {
|
||||||
let sym_sec_idx = symbol.section_index();
|
let sym_sec_idx = symbol.section_index();
|
||||||
@ -336,13 +338,13 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|||||||
} else {
|
} else {
|
||||||
"None"
|
"None"
|
||||||
};
|
};
|
||||||
println!("SYMBOL [{}]\tKIND {}\tSECTION {}", symbol.name().unwrap(), match symbol.kind() {
|
if verbose { println!("SYMBOL [{}]\tKIND {}\tSECTION {}", symbol.name().unwrap(), match symbol.kind() {
|
||||||
object::SymbolKind::Text => "Func",
|
object::SymbolKind::Text => "Func",
|
||||||
object::SymbolKind::Data => "Data",
|
object::SymbolKind::Data => "Data",
|
||||||
object::SymbolKind::Section => "Section",
|
object::SymbolKind::Section => "Section",
|
||||||
object::SymbolKind::Label => "Label",
|
object::SymbolKind::Label => "Label",
|
||||||
_ => "Other",
|
_ => "Other",
|
||||||
}, sym_sec_name);
|
}, sym_sec_name); }
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut new_elf = object::write::Object::new(object::BinaryFormat::Elf, object::Architecture::I386, object::Endianness::Little);
|
let mut new_elf = object::write::Object::new(object::BinaryFormat::Elf, object::Architecture::I386, object::Endianness::Little);
|
||||||
@ -478,6 +480,8 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|||||||
match reloc.target() {
|
match reloc.target() {
|
||||||
RelocationTarget::Symbol(sym_idx) => {
|
RelocationTarget::Symbol(sym_idx) => {
|
||||||
let old_sym = obj_file.symbol_by_index(sym_idx).unwrap();
|
let old_sym = obj_file.symbol_by_index(sym_idx).unwrap();
|
||||||
|
// ???????
|
||||||
|
if old_sym.section_index().is_none() { continue }
|
||||||
let old_sec = obj_file.section_by_index(old_sym.section_index().unwrap()).unwrap();
|
let old_sec = obj_file.section_by_index(old_sym.section_index().unwrap()).unwrap();
|
||||||
let new_sym = if let Some(new_sym) = new_sym_map.get(old_sym.name().unwrap()) {
|
let new_sym = if let Some(new_sym) = new_sym_map.get(old_sym.name().unwrap()) {
|
||||||
Some(new_sym)
|
Some(new_sym)
|
||||||
@ -498,7 +502,7 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|||||||
symbol: *new,
|
symbol: *new,
|
||||||
addend: reloc.addend(),
|
addend: reloc.addend(),
|
||||||
})?;
|
})?;
|
||||||
println!("reloc {:04x} in {} -> {} in {} {:04x}@{:04x} Became {:04x} in {} -> {} in {} ({:04x})",
|
if verbose { println!("reloc {:04x} in {} -> {} in {} {:04x}@{:04x} Became {:04x} in {} -> {} in {} ({:04x})",
|
||||||
src,
|
src,
|
||||||
section.name().unwrap(),
|
section.name().unwrap(),
|
||||||
old_sym.name().unwrap(),
|
old_sym.name().unwrap(),
|
||||||
@ -510,14 +514,14 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|||||||
new_elf.symbol(*new).name().unwrap(),
|
new_elf.symbol(*new).name().unwrap(),
|
||||||
new_elf.section(new_elf.symbol(*new).section.id().unwrap()).name().unwrap(),
|
new_elf.section(new_elf.symbol(*new).section.id().unwrap()).name().unwrap(),
|
||||||
new_elf.symbol(*new).value
|
new_elf.symbol(*new).value
|
||||||
);
|
); }
|
||||||
} else {
|
} else {
|
||||||
println!("Couldn't find new equivalent of {:04x} -> symbol {} in {} ({:04x}@{:04x})", src,
|
if verbose { eprintln!("Warning: Couldn't find new equivalent of {:04x} -> symbol {} in {} ({:04x}@{:04x})", src,
|
||||||
old_sym.name().unwrap(),
|
old_sym.name().unwrap(),
|
||||||
old_sec.name().unwrap(),
|
old_sec.name().unwrap(),
|
||||||
old_sym.address(),
|
old_sym.address(),
|
||||||
old_sec.address()
|
old_sec.address()
|
||||||
);
|
); }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => { panic!("Unsupported Relocation Type"); },
|
_ => { panic!("Unsupported Relocation Type"); },
|
||||||
@ -530,12 +534,13 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|||||||
new_elf.write_stream(&mut out_elf)?;
|
new_elf.write_stream(&mut out_elf)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("\n\n\tWrote [new.elf]! Trying to produce LE executable.");
|
if verbose { print!("\n\n\t"); }
|
||||||
|
println!("Wrote [new.elf]! Trying to produce LE executable.");
|
||||||
|
|
||||||
let new_file = fs::read("new.elf")?;
|
let new_file = fs::read("new.elf")?;
|
||||||
let new_obj = object::File::parse(&*new_file)?;
|
let new_obj = object::File::parse(&*new_file)?;
|
||||||
|
|
||||||
println!();
|
if verbose { println!(); }
|
||||||
let text_len = new_obj.section_by_name(".text").unwrap().data().unwrap().len();
|
let text_len = new_obj.section_by_name(".text").unwrap().data().unwrap().len();
|
||||||
let data_len = new_obj.section_by_name(".data").unwrap().data().unwrap().len();
|
let data_len = new_obj.section_by_name(".data").unwrap().data().unwrap().len();
|
||||||
let text_pages = if text_len % 0x1000 == 0 {
|
let text_pages = if text_len % 0x1000 == 0 {
|
||||||
@ -551,12 +556,14 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("[.text] size: 0x{:08x} ({} pages)", text_len, text_pages);
|
println!("[.text] size: 0x{:08x} ({} pages)", text_len, text_pages);
|
||||||
println!("[.data] size: 0x{:08x} ({} pages)", data_len, data_pages);
|
println!("[.data] size: 0x{:08x} ({} pages)", data_len, data_pages);
|
||||||
|
|
||||||
let text_sec = new_obj.section_by_name(".text").unwrap();
|
if verbose {
|
||||||
println!("\n\tRELOCATIONS FOR [.text]");
|
let text_sec = new_obj.section_by_name(".text").unwrap();
|
||||||
print_section_relocations(&text_sec, &new_obj);
|
println!("\n\tRELOCATIONS FOR [.text]");
|
||||||
println!("\n\tRELOCATIONS FOR [.data]");
|
print_section_relocations(&text_sec, &new_obj);
|
||||||
let data_sec = new_obj.section_by_name(".data").unwrap();
|
println!("\n\tRELOCATIONS FOR [.data]");
|
||||||
print_section_relocations(&data_sec, &new_obj);
|
let data_sec = new_obj.section_by_name(".data").unwrap();
|
||||||
|
print_section_relocations(&data_sec, &new_obj);
|
||||||
|
}
|
||||||
|
|
||||||
let le_stub: Vec<u8> = Vec::from(*LE_STUB);
|
let le_stub: Vec<u8> = Vec::from(*LE_STUB);
|
||||||
let mut out_file = fs::File::create("a.exe")?;
|
let mut out_file = fs::File::create("a.exe")?;
|
||||||
@ -569,12 +576,30 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
|||||||
fixup_page_offsets: Vec::new(),
|
fixup_page_offsets: Vec::new(),
|
||||||
fixup_records: Vec::new(),
|
fixup_records: Vec::new(),
|
||||||
};
|
};
|
||||||
output_le_relocations(&new_obj, &mut header);
|
output_le_relocations(&new_obj, &mut header, verbose);
|
||||||
let data_pages_offset = write_le_header(&header, &mut out_file)?;
|
let data_pages_offset = write_le_header(&header, &mut out_file)?;
|
||||||
println!("Data Pages Offset: 0x{:04x}", data_pages_offset);
|
println!("Data Pages Offset: 0x{:04x}", data_pages_offset);
|
||||||
out_file.write_all_at(new_obj.section_by_name(".text").unwrap().data().unwrap(), data_pages_offset as u64)?;
|
out_file.write_all_at(new_obj.section_by_name(".text").unwrap().data().unwrap(), data_pages_offset as u64)?;
|
||||||
let data_loc = (header.num_text_pages * 0x1000) + data_pages_offset;
|
let data_loc = (header.num_text_pages * 0x1000) + data_pages_offset;
|
||||||
out_file.write_all_at(new_obj.section_by_name(".data").unwrap().data().unwrap(), data_loc as u64)?;
|
out_file.write_all_at(new_obj.section_by_name(".data").unwrap().data().unwrap(), data_loc as u64)?;
|
||||||
|
|
||||||
|
println!("Wrote a.exe, {} bytes.", data_loc as usize + new_obj.section_by_name(".data").unwrap().data().unwrap().len());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
|
if args.len() < 2 { eprintln!("Not enough args"); }
|
||||||
|
|
||||||
|
let verbose = args[1] == "-v";
|
||||||
|
|
||||||
|
if verbose && args.len() < 3 { eprintln!("Not enough args"); }
|
||||||
|
|
||||||
|
let path = if verbose { &args[2] } else { &args[1] };
|
||||||
|
let data = fs::read(path)?;
|
||||||
|
convert(&data, verbose)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user