load_elf_binary

load_elf_binary 流程:

填充并且检查目标程序ELF头部

load_elf_phdrs加载目标程序的程序头表

如果需要动态链接, 则寻找和处理解释器段

检查并读取解释器的程序表头

装入目标程序的段segment

填写程序的入口地址

create_elf_tables填写目标文件的参数环境变量等必要信息

start_kernel宏准备进入新的程序入口

 ————————————————

版权声明:本文为CSDN博主「JeanCheng」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/gatieme/article/details/51628257

  1.  

 

#if defined(CONFIG_MMU)

{

.procname        = "randomize_va_space",

.data                = &randomize_va_space,

.maxlen                = sizeof(int),

.mode                = 0644,

.proc_handler        = proc_dointvec,

},

#endif

 * This structure is used to hold the arguments that are used when loading binaries.

struct linux_binprm {

内核解析elf文件,随机化。

static int load_elf_binary(struct linux_binprm *bprm)

load_elf_phdrs                 load ELF program headers

 

typedef struct elf64_phdr {------------------------Program Header Table

  Elf64_Word p_type;

  Elf64_Word p_flags;

 

  Elf64_Off p_offset;                /* Segment file offset */

 

  Elf64_Addr p_vaddr;                /* Segment virtual address */

  Elf64_Addr p_paddr;                /* Segment physical address */

 

  Elf64_Xword p_filesz;                /* Segment size in file */

  Elf64_Xword p_memsz;                /* Segment size in memory */

 

  Elf64_Xword p_align;                /* Segment alignment, file & memory */

} Elf64_Phdr;

p_offset : 段偏移,这个段的第一个自己字节到文件开始的距离,也就是该段在文件中的偏移;

p_vaddr : 加载到内存中的虚拟地址;

p_paddr : 加载到内存中的物理地址;

p_filesz : 文件映像中段的大小/字节数,可能是零,比如说GNU_STACK段;

p_memsz : 内存映像中段的大小/字节数,可能是零,比如说GNU_STACK段;

p_flags : flags relevant to the segment. 和这个段有关的标志;

 

来自 <https://mudongliang.github.io/2015/10/31/linuxelf.html>

 

 

if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)---- DGL proc variable

current->flags |= PF_RANDOMIZE;

 

  1.  else if (loc->elf_ex.e_type == ET_DYN) {

if (interpreter) {

load_bias = ELF_ET_DYN_BASE;

if (current->flags & PF_RANDOMIZE)

load_bias += arch_mmap_rnd();

rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);

return rnd << PAGE_SHIFT;--------------------------dgl_4k aligned

elf_flags |= elf_fixed;

} else

load_bias = 0;

 

 

  1. if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) {

current->mm->brk = current->mm->start_brk =

arch_randomize_brk(current->mm);

 

void setup_new_exec(struct linux_binprm * bprm)

void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)

{

unsigned long random_factor = 0UL;

 

if (current->flags & PF_RANDOMIZE)

random_factor = arch_mmap_rnd();

 

mm->mmap_base = mmap_base(random_factor, rlim_stack);

create_elf_tables

elf_map

vm_mmap

start_thread

regs->pc = pc;

regs->sp = sp;

 

It sounds like your GCC is configured to build -pie binaries by default. These binaries really areshared libraries

 (of type ET_DYN), except they run just like a normal executable would.

 

来自 <https://stackoverflow.com/questions/34519521/why-does-gcc-create-a-shared-object-instead-of-an-executable-binary-according-to/34522357#34522357>

Or you could link your binary with gcc -no-pie ... and that should produce a non-PIE executable of type

 ET_EXEC, for which file will say ELF 64-bit LSB executable.

 

来自 <https://stackoverflow.com/questions/34519521/why-does-gcc-create-a-shared-object-instead-of-an-executable-binary-according-to/34522357#34522357>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值