基于对UPX加载分析所制
模拟内核对栈区布局
动态加载可执行文件
.global _start
.type _start, @function
.extern load
_start:
mov x0, sp // x0->argc
ldr x1, [x0],#8 // x0->argv
add x0, x0, w1, sxtw #3
add x0, x0, #0x8 // x0->envp
envp:
ldr x1, [x0],#8
cbnz x1, envp
bl load
br x0
.global _svc
.type _svc, @function
_svc:
mov x8, x0
mov x0, x1
mov x1, x2
mov x2, x3
mov x3, x4
mov x4, x5
mov x5, x6
svc #0
ret
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <elf.h>
extern "C" __u64 _svc(...);
#define __align_up(x) ((x + 0x1000 - 1) & ~(0x1000 - 1))
#define _exit_group(sig) _svc(__NR_exit_group,sig)
#define _mprotect(addr,len,prot) _svc(__NR_mprotect,addr,len,prot)
#define _open(name,flag) _svc(__NR_openat,AT_FDCWD,name,flag)
#define _close(fd) _svc(__NR_close,fd)
#define _lseek(fd,offset,whence) _svc(__NR_lseek,fd,offset,whence)
#define _read(fd,buf,count) _svc(__NR_read,fd,buf,count)
#define _mmap(addr,length,prot,flags,fd,offset) _svc(__NR_mmap,addr,length,prot,flags,fd,offset)
#define _mremap(addr, old_size, new_size, flags) _svc(__NR_mremap, addr, old_size, new_size, flags)
#define _munmap(addr,length) _svc(__NR_munmap,addr,length)
static inline void _memcpy(void *dest,void *src,size_t n)
{
for(int i = 0; i < n; i++)
{
*(char *)((uint64_t)dest + i) = *(char *)((uint64_t)src + i);
}
}
static inline void _memset(void *dest,size_t n)
{
for(int i = 0; i < n; i++)
{
*(char *)((uint64_t)dest + i) = 0;
}
}#include <svc.h>
__attribute__((section(".bss"))) Elf64_Phdr *Phdr; //段表指针
__attribute__((section(".bss"))) __u64 e_phnum; //条目数量
__attribute__((section(".bss"))) __u64 e_entry; //入口点
#ifdef __cplusplus
extern "C" {
#endif
int elf_mmap(int fd)
{
int linker_fd;
int size = _lseek(fd, 0, SEEK_END);
_lseek(fd, 0, SEEK_SET);
void *data = (void *)_mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, nullptr);
void *ptr = (void *)_mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, nullptr, nullptr);
Elf64_Ehdr *Ehdr = (Elf64_Ehdr *)data;
Phdr = (Elf64_Phdr *)((__u64)data + Ehdr->e_phoff);
for(int i = 0; i < Ehdr->e_phnum; i++)
{
if(__align_up(Phdr[i].p_vaddr + Phdr[i].p_memsz) > size)
{
ptr = (void *)_mremap(ptr,size,__align_up(Phdr[i].p_vaddr + Phdr[i].p_memsz),MREMAP_MAYMOVE);
size = __align_up(Phdr[i].p_vaddr + Phdr[i].p_memsz);
}
_memcpy((void *)((__u64)ptr + Phdr[i].p_vaddr),(void *)((__u64)data + Phdr[i].p_offset),Phdr[i].p_filesz);
if(Phdr[i].p_type == PT_INTERP)
{
linker_fd = _open((__u64)ptr + Phdr[i].p_vaddr, O_RDONLY);
}
}
Phdr = (Elf64_Phdr *)((__u64)ptr + Ehdr->e_phoff);
e_phnum = Ehdr->e_phnum;
e_entry = (__u64)ptr + Ehdr->e_entry;
_munmap(data,_lseek(fd, 0, SEEK_END));
_close(fd);
return linker_fd;
}
__u64 load(Elf64_auxv_t* auxv)
{
int linker_fd = elf_mmap(_open("/system/bin/sh",O_RDONLY)); // /system/bin/sh 需要加载的文件
int size = _lseek(linker_fd, 0, SEEK_END);
Elf64_Ehdr *Ehdr = (Elf64_Ehdr *)_mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, linker_fd, nullptr);
_close(linker_fd);
for(int i = 0;auxv[i].a_type != 0;i++)
{
switch (auxv[i].a_type)
{
case AT_PHDR:
auxv[i].a_un.a_val = (__u64)Phdr; //段表
break;
case AT_PHNUM:
auxv[i].a_un.a_val = e_phnum; //段表条目数量
break;
case AT_BASE:
auxv[i].a_un.a_val = (__u64)Ehdr; //链接器基地址
break;
case AT_ENTRY:
auxv[i].a_un.a_val = e_entry; // 入口
break;
default:
break;
}
}
Phdr = (Elf64_Phdr *)((__u64)Ehdr + Ehdr->e_phoff);
for(int i = 0; i < Ehdr->e_phnum; i++) //为动态链接器初始化
{
_memset((void *)((__u64)Ehdr + Phdr[i].p_vaddr + Phdr[i].p_filesz),Phdr[i].p_memsz - Phdr[i].p_filesz);
}
return (__u64)Ehdr + Ehdr->e_entry;
}
#ifdef __cplusplus
}
#endif
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2026-1-14 19:17
被CSProtect1.0编辑
,原因: