一张图系列之函数重定位

.dynmic

 .rel.plt

typedef struct
{
  Elf32_Addr    r_offset;        /* Address */
  Elf32_Word    r_info;            /* Relocation type and symbol index */
} Elf32_Rel;

typedef struct
{
  Elf64_Addr    r_offset;        /* Address */
  Elf64_Xword    r_info;            /* Relocation type and symbol index */
  Elf64_Sxword    r_addend;        /* Addend */
} Elf64_Rela;

.dynsym

 * Symbol table entry.  */
typedef struct
{
  Elf32_Word    st_name;        /* Symbol name (string tbl index) */
  Elf32_Addr    st_value;        /* Symbol value */
  Elf32_Word    st_size;        /* Symbol size */
  unsigned char    st_info;        /* Symbol type and binding */
  unsigned char    st_other;        /* Symbol visibility */
  Elf32_Section    st_shndx;        /* Section index */
} Elf32_Sym;

typedef struct
{
  Elf64_Word    st_name;        /* Symbol name (string tbl index) */
  unsigned char    st_info;        /* Symbol type and binding */
  unsigned char st_other;        /* Symbol visibility */
  Elf64_Section    st_shndx;        /* Section index */
  Elf64_Addr    st_value;        /* Symbol value */
  Elf64_Xword    st_size;        /* Symbol size */
} Elf64_Sym;

#define ELF32_R_SYM(val)        ((val) >> 8)
#define ELF32_R_TYPE(val)        ((val) & 0xff)
#define ELF32_R_INFO(sym, type)        (((sym) << 8) + ((type) & 0xff))

#define ELF64_R_SYM(i)            ((i) >> 32)
#define ELF64_R_TYPE(i)            ((i) & 0xffffffff)
#define ELF64_R_INFO(sym,type)        ((((Elf64_Xword) (sym)) << 32) + (type))

 

1.控制eip为PLT[0]的地址,只需传递一个index_arg参数

index_arg = 伪造的目标地址-.rel.plt段基地址

2.控制index_arg的大小,使reloc的位置落在可控地址内
3.伪造reloc的内容,使sym落在可控地址内

r_info=[(fake_sym_addr -.dynsym基地址)/0x10]<<8 + 0x07   # 除以0x10因为Elf32_Sym结构体的大小为0x10,得到write的dynsym索引号

4.伪造sym的内容,使name落在可控地址内

align = 0x10 - ((fake_sym_addr - dynsym) & 0xf) # 这里的对齐操作是因为dynsym里的Elf32_Sym结构体都是0x10字节大小
fake_sym_addr = fake_sym_addr + align
st_name = 伪造地址 - .dynstr基地址

5.伪造name为任意库函数,如system

原文地址:https://www.cnblogs.com/0xHack/p/11656659.html