// SPDX-License-Identifier: MPL-2.0 #include #include #include #include #include #include #include #include #include #include #include "elfio.hpp" #include "elfio/elf_types.hpp" using namespace std; namespace fs=filesystem; const string entry_flags="-ffreestanding -nostdlib -nostartfiles -Wall -Wextra -fno-stack-protector -fno-builtin -fno-pic -m64 -mcmodel=large"; struct vyx_addresses { uint64_t text_offset; uint64_t stack_base; }; uint64_t rand_in_range(uint64_t min, uint64_t max) { static random_device rd; static mt19937_64 gen(rd()); std::uniform_int_distribution dis(min, max); return dis(gen); } uint64_t random_canonical(uint64_t start,uint64_t end) { uint64_t addr=rand_in_range(start/4096,end/4096)*4096; return addr; } vyx_addresses generate_vyx_addresses() { vyx_addresses addr; addr.text_offset=random_canonical(0xFFFF800000000000ULL,0xFFFF900000000000ULL-1); uint64_t stack_window_start=0xFFFFF00000000000ULL; uint64_t stack_window_end=0xFFFFFF8000000000ULL-0x100000ULL; addr.stack_base=random_canonical(stack_window_start,stack_window_end); return addr; } size_t pad_size(size_t value,size_t multiple) { if (multiple==0) return value; size_t remainder=value%multiple; if (remainder==0) return value; return value+multiple-remainder; } int main(int argc,char **argv) { cout<<"[Vyld] Vystem Executable Linker v0.1"< "+string(res_file)).c_str()); if (ret!=0) { cout<<"[Vyld] Error: gcc didn't returned success. Error code: "< c_files(argv+1,argv+argc-1); vector o_files; cout<<"[Vyld] Finding provided files:"< "+string(res_file)).c_str()); if (ret!=0) { cout<<"[Vyld] Error: gcc didn't returned success. File \""< "+string(res_file); ret=system(command_line_gcc.c_str()); if (ret!=0) { cout<get_size()==0) { cout<get_size(); size_t text_size_padded=pad_size(text_size,4096); cout<<"[Vyld] text_size=0x"<get_size(); data_size_padded=pad_size(data_size,4096); cout<<"[Vyld] data_size=0x"<get_size(); for (const auto &s:reader.sections) { if (s->get_name().size()>7 && s->get_name().substr(0,7)==".rodata" && s->get_name()!=".rodata") { rodata_size+=s->get_size(); } } rodata_size_padded=pad_size(rodata_size,4096); cout<<"[Vyld] rodata_size=0x"<get_size(); bss_size_padded=pad_size(bss_size,4096); cout<<"[Vyld] bss_size=0x"< TEXT\n\n"; ld<<" .data :\n"; ld<<" {\n"; ld<<" . = ORIGIN(DATA);\n"; ld<<" *(.data)\n"; ld<<" *(.data.*)\n"; ld<<" . = ALIGN(0x1000);\n"; ld<<" } > DATA\n\n"; ld<<" .rodata :\n"; ld<<" {\n"; ld<<" . = ORIGIN(RODATA);\n"; ld<<" *(.rodata)\n"; ld<<" *(.rodata.*)\n"; ld<<" . = ALIGN(0x1000);\n"; ld<<" } > RODATA\n\n"; ld<<" .bss :\n"; ld<<" {\n"; ld<<" . = ORIGIN(BSS);\n"; ld<<" *(.bss)\n"; ld<<" *(.bss.*)\n"; ld<<" . = ALIGN(0x1000);\n"; ld<<" } > BSS\n\n"; ld<<" /DISCARD/ :\n"; ld<<" {\n"; ld<<" *(.note.*)\n"; ld<<" *(.comment)\n"; ld<<" *(.eh_frame)\n"; ld<<" *(.eh_frame_hdr)\n"; ld<<" }\n}"; ld.close(); cout<<"[Vyld] Linking relocatable object."<get_size()==0) { cout<<"[Vyld] Error: .text is empty."< elf_text_bin(text_size_padded,0); vector elf_data_bin(data_size_padded,0); vector elf_rodata_bin(rodata_size_padded,0); memcpy(elf_text_bin.data(),elf_text_sec->get_data(),elf_text_sec->get_size()); if (elf_data_sec->get_size()!=0) { memcpy(elf_data_bin.data(),elf_data_sec->get_data(),elf_data_sec->get_size()); } if (elf_rodata_sec->get_size()!=0) { memcpy(elf_rodata_bin.data(),elf_rodata_sec->get_data(),elf_rodata_sec->get_size()); } uint8_t vyx_sig[3]={'V','y','X'}; uint16_t vyx_ver=0x0001; string outfile=string(argv[argc-1]); ofstream out(outfile,ios::binary); out.write(reinterpret_cast(vyx_sig),3); out.write(reinterpret_cast(&vyx_ver),2); out.write(reinterpret_cast(&va.text_offset),8); out.write(reinterpret_cast(&va.stack_base),8); out.write(reinterpret_cast(&text_size_padded),8); out.write(reinterpret_cast(&data_size_padded),8); out.write(reinterpret_cast(&rodata_size_padded),8); uint64_t bss_size_elf=elf_bss_sec->get_size(); out.write(reinterpret_cast(&bss_size_elf),8); out.write(reinterpret_cast(elf_text_bin.data()),elf_text_bin.size()); if (data_size_padded!=0) out.write(reinterpret_cast(elf_data_bin.data()),elf_data_bin.size()); if (rodata_size_padded!=0) out.write(reinterpret_cast(elf_rodata_bin.data()),elf_rodata_bin.size()); out.close(); cout<<"[Vyld] Succesfully compiled "<