二进制都不行???
原题链接:25476.看着简单做着难2025-07-05 15:56:45
发布于:山东
// 使用汇编直接构建可执行文件,无需编译
#include <cstdint>
#include <cstddef> // 新增:提供size_t
#include <cstdio> // 新增:提供putchar
// 手动定义ELF头部结构
struct Elf64_Ehdr {
uint8_t e_ident[16];
uint16_t e_type;
uint16_t e_machine;
uint32_t e_version;
uint64_t e_entry;
uint64_t e_phoff;
uint64_t e_shoff;
uint32_t e_flags;
uint16_t e_ehsize;
uint16_t e_phentsize;
uint16_t e_phnum;
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx;
};
struct Elf64_Phdr {
uint32_t p_type;
uint32_t p_flags;
uint64_t p_offset;
uint64_t p_vaddr;
uint64_t p_paddr;
uint64_t p_filesz;
uint64_t p_memsz;
uint64_t p_align;
};
// 系统调用号
enum {
SYS_write = 1,
SYS_exit = 60
};
// ELF头部数据
constexpr uint8_t elf_header[] = {
// ELF标识
0x7F, 0x45, 0x4C, 0x46, 0x02, 0x01, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// ELF类型和架构
0x02, 0x00, 0x3E, 0x00, 0x01, 0x00, 0x00, 0x00,
// 入口点地址
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 程序头表偏移
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 节头表偏移
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 其他头部字段
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 程序头表数据
constexpr uint8_t program_header[] = {
// 类型为LOAD
0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
// 偏移和虚拟地址
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 物理地址(与虚拟相同)
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 文件大小和内存大小
0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 对齐方式
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 汇编代码:输出Hello ACGO并退出
constexpr uint8_t code[] = {
// write(1, "Hello ACGO\n", 11)
0xB8, 0x01, 0x00, 0x00, 0x00, 0xBF, 0x01, 0x00,
0x00, 0x00, 0x48, 0xBE, 0xC0, 0x00, 0x40, 0x00, // 修正:指向数据段地址 0x4000C0
0x00, 0x00, 0x00, 0x00, 0xBA, 0x0B, 0x00, 0x00,
0x00, 0x0F, 0x05,
// exit(0)
0xB8, 0x3C, 0x00, 0x00, 0x00, 0x31, 0xFF, 0x0F,
0x05
};
// 数据段:字符串"Hello ACGO\n"
constexpr uint8_t data[] = {
'H', 'e', 'l', 'l', 'o', ' ', 'A', 'C', 'G', 'O', '\n'
};
// 生成完整的ELF二进制文件
constexpr uint8_t binary[] = {
// ELF头部
0x7F, 0x45, 0x4C, 0x46, 0x02, 0x01, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x3E, 0x00, 0x01, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
// 程序头表
0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 代码段
0xB8, 0x01, 0x00, 0x00, 0x00, 0xBF, 0x01, 0x00,
0x00, 0x00, 0x48, 0xBE, 0xC0, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0xBA, 0x0B, 0x00, 0x00,
0x00, 0x0F, 0x05,
0xB8, 0x3C, 0x00, 0x00, 0x00, 0x31, 0xFF, 0x0F,
0x05,
// 数据段
'H', 'e', 'l', 'l', 'o', ' ', 'A', 'C', 'G', 'O', '\n'
};
// 主函数:输出ELF二进制
int main() {
// 直接输出完整的ELF文件内容
for (std::size_t i = 0; i < sizeof(binary); ++i) {
std::putchar(binary[i]);
}
return 0;
}
这里空空如也
有帮助,赞一个