#include #include #include int main() { const char data[] = "Hello, World from SCC PE Builder!\n\0"; /* clang-format off */ const char code[] = { // sub rsp, 0x28 ; 为函数调用分配栈空间 0x48, 0x83, 0xEC, 0x28, // lea rcx, [rip + data_offset] ; 将字符串地址加载到RCX(第一个参数) 0x48, 0x8D, 0x0D, 0x00, 0x00, 0x00, 0x00, // call qword ptr [rip + puts_iat] ; 通过IAT调用puts 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, // add rsp, 0x28 ; 恢复栈空间 0x48, 0x83, 0xC4, 0x28, // xor eax, eax ; 设置返回值为0 0x33, 0xC0, // ret ; 返回 0xC3, }; /* clang-format on */ scc_pe_builder_t builder = {0}; scc_pe_builder_init(&builder, true, 4096, 512); scc_pe_reserve_header(&builder, 3); scc_pe_section_range code_range = scc_pe_reserve_text_section_header(&builder, sizeof(code)); scc_pe_section_range data_range = scc_pe_reserve_data_section_header(&builder, sizeof(data)); scc_pe_idata_builder_t idata_builder; scc_pe_idata_lib_vec_t idata_libs; scc_vec_init(idata_libs); scc_pe_idata_lib_t ucrtbase; ucrtbase.name = "ucrtbase.dll"; scc_vec_init(ucrtbase.symbol_names); scc_vec_push(ucrtbase.symbol_names, "puts"); scc_vec_push(idata_libs, ucrtbase); scc_pe_idata_builder_init(&idata_builder, &idata_libs); u32 idata_size = scc_pe_reserve_idata(&idata_builder); scc_pe_section_range idata_range = scc_pe_reserve_idata_section_header(&builder, idata_size); scc_pe_buffer_t idata_buffer = scc_pe_construct_idata(&idata_builder, &idata_range); u32 entry_point_offset = 0; u64 base_address = 0x140000000; u32 entry_point = code_range.virual_address + entry_point_offset; scc_pe_config_t config = (scc_pe_config_t){ .machine = IMAGE_FILE_MACHINE_AMD64, .time_date_stamp = 0, .characteristics = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE, .major_linker_version = 14, .minor_linker_version = 0, .address_of_entry_point = entry_point, .image_base = base_address, .major_operating_system_version = 6, .minor_operating_system_version = 0, .major_image_version = 0, .minor_image_version = 0, .major_subsystem_version = 6, .minor_subsystem_version = 0, .subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI, .dll_characteristics = IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT, .size_of_stack_reserve = 0x100000, .size_of_stack_commit = 0x1000, .size_of_heap_reserve = 0x100000, .size_of_heap_commit = 0x1000, }; // FIXME 需要确保宿主机为小端 *(u32 *)((u8 *)code + 7) = (data_range.virual_address + 0) - (code_range.virual_address + 7 + 4); *(u32 *)((u8 *)code + 13) = (u64)scc_pe_idata_get_symbol_rva(&idata_builder, "puts") - (code_range.virual_address + 13 + 4); scc_pe_write_header(&builder, &config); scc_pe_write_section(&builder, &code_range, (u8 *)code, sizeof(code)); scc_pe_write_section(&builder, &data_range, (u8 *)data, sizeof(data)); scc_pe_write_section(&builder, &idata_range, scc_vec_unsafe_get_data(idata_buffer), scc_vec_size(idata_buffer)); scc_pe_dump_to_file(&builder, __FILE__ "/../pe_write_idata.exe"); }