如何在无库依赖的x86-64 Linux下通过汇编/链接脚本访问特定内存区域
解决方案:无库依赖下访问Linux外部内存
核心思路:直接调用Linux系统调用
因为不能链接任何库,无法使用标准C库的mmap(),必须直接通过x86-64系统调用指令触发mmap系统调用。x86-64 Linux下用syscall指令触发系统调用,mmap的系统调用号为9。
手动实现mmap的代码示例
纯汇编实现(syscall.S)
.global _start _start: ; 准备mmap参数:rax存系统调用号,参数依次入rdi、rsi、rdx、r10、r8、r9 mov rax, 9 ; mmap系统调用号 xor rdi, rdi ; addr=NULL,让内核自动分配地址 mov rsi, 0x1000 ; 映射长度4KB(页面大小) mov rdx, 3 ; prot=PROT_READ|PROT_WRITE mov r10, 0x22 ; flags=MAP_PRIVATE|MAP_ANONYMOUS(匿名映射) mov r8, -1 ; fd=-1(匿名映射无需文件) xor r9, r9 ; offset=0 syscall ; 触发系统调用 ; 检查返回值:rax >= -4095则为错误 cmp rax, -4095 jl mmap_success ; 错误处理:调用exit退出 mov rax, 60 ; exit系统调用号 mov rdi, 1 ; 错误码1 syscall mmap_success: ; 读写映射的内存 mov qword [rax], 0x123456789abcdef0 ; 写入测试值 mov rbx, qword [rax] ; 读取测试值 ; 正常退出 mov rax, 60 xor rdi, rdi syscall
C内嵌汇编实现
#define MMAP_SYSCALL_NUM 9 #define EXIT_SYSCALL_NUM 60 int main(void) { void *addr; int prot = 3; // PROT_READ | PROT_WRITE int flags = 0x22; // MAP_PRIVATE | MAP_ANONYMOUS int fd = -1; off_t offset = 0; __asm__ volatile ( "syscall" : "=a"(addr) : "a"(MMAP_SYSCALL_NUM), "D"(0), // addr=NULL "S"(0x1000), // 映射长度4KB "d"(prot), "r10"(flags), "r8"(fd), "r9"(offset) : "memory", "rcx", "r11" ); // 错误判断 if ((long)addr >= -4095) { __asm__ volatile ( "syscall" : : "a"(EXIT_SYSCALL_NUM), "D"(1) : "rcx", "r11" ); } // 使用映射内存 *(unsigned long*)addr = 0x123456789abcdef0; unsigned long val = *(unsigned long*)addr; // 正常退出 __asm__ volatile ( "syscall" : : "a"(EXIT_SYSCALL_NUM), "D"(0) : "rcx", "r11" ); return 0; }
链接脚本的正确配置
之前配置MEMORY和SECTIONs失败,是因为链接器只能处理编译时已知的段,无法分配运行时动态内存。链接脚本只需确保基础段正确布局即可,示例极简脚本(linker.ld):
ENTRY(_start) SECTIONS { . = 0x400000; // x86-64 Linux默认加载地址 .text : { *(.text) } .data : { *(.data) } .bss : { *(.bss) } }
编译运行命令
# 汇编代码编译 gcc -nostdlib -static -T linker.ld syscall.S -o memtool # C代码编译 gcc -nostdlib -static -T linker.ld memtool.c -o memtool
关键注意事项
- x86-64系统调用规则:
rax存系统调用号,参数依次入rdi、rsi、rdx、r10、r8、r9,返回值存在rax。 - 若需映射特定物理内存,可打开
/dev/mem后调整flags和fd参数。 - 错误判断:系统调用返回错误时
rax为负数(绝对值是错误码),通过(long)addr >= -4095识别。
内容的提问来源于stack exchange,提问作者suncowiam
相关产品推荐
相关产品推荐

