附加向量

附加向量

1.1 附加向量

Auxiliary vector是一种机制,内核的ELF binary loader使用附加向量在程序执行时传递某些信息到用户空间。

 #include <sys/auxv.h>

unsigned long getauxval(unsigned long type);

 

sys/auxv.h

#define AT_NULL         0               /* End of vector */

#define AT_IGNORE       1               /* Entry should be ignored */

#define AT_EXECFD       2               /* File descriptor of program */

#define AT_PHDR         3               /* Program headers for program */

#define AT_PHENT        4               /* Size of program header entry */

#define AT_PHNUM        5               /* Number of program headers */

#define AT_PAGESZ       6               /* System page size */

#define AT_BASE         7               /* Base address of interpreter */

#define AT_FLAGS        8               /* Flags */

#define AT_ENTRY        9               /* Entry point of program */

#define AT_NOTELF       10              /* Program is not ELF */

#define AT_UID          11              /* Real uid */

#define AT_EUID         12              /* Effective uid */

#define AT_GID          13              /* Real gid */

#define AT_EGID         14              /* Effective gid */

#define AT_CLKTCK       17              /* Frequency of times() */

 

/* Some more special a_type values describing the hardware.  */

#define AT_PLATFORM     15              /* String identifying platform.  */

#define AT_HWCAP        16              /* Machine-dependent hints about

                                           processor capabilities.  */

 

/* This entry gives some information about the FPU initialization

   performed by the kernel.  */

#define AT_FPUCW        18              /* Used FPU control word.  */

 

/* Cache block sizes.  */

#define AT_DCACHEBSIZE  19              /* Data cache block size.  */

#define AT_ICACHEBSIZE  20              /* Instruction cache block size.  */

#define AT_UCACHEBSIZE  21              /* Unified cache block size.  */

 

/* A special ignored value for PPC, used by the kernel to control the

   interpretation of the AUXV. Must be > 16.  */

#define AT_IGNOREPPC    22              /* Entry should be ignored.  */

 

#define AT_SECURE       23              /* Boolean, was exec setuid-like?  */

 

#define AT_BASE_PLATFORM 24             /* String identifying real platforms.*/

 

#define AT_RANDOM       25              /* Address of 16 random bytes.  */

 

#define AT_HWCAP2       26              /* More machine-dependent hints about

                                           processor capabilities.  */

#define AT_EXECFN       31              /* Filename of executable.  */

 

/* Pointer to the global system page used for system calls and other

   nice things.  */

#define AT_SYSINFO      32

#define AT_SYSINFO_EHDR 33

 

1.2 auxv的位置

Local variable

 

Return Address

 

argc

 

argv[0]

argv[1]

没有参数的情况下

argv[1]=NULL

envp[X]

最后一个指针为NULL

auxv[40]

键值对,测试中共20条记录,最后一条记录为0,0

X字节

结构不清楚,这个是调试分析的,未必准确;

32位(38字节)

7个0x0

AT_RANDOM(16字节)

AT_PLATFORM

(“i686” 0x0)

10个0x0

64位(24字节/32个字节)

0x0/9个0x0

AT_RANDOM(16字节)

AP_PLATFORM

(“x86_64” 0x0)

env string

 

1.2.1 X86

millionsky@ubuntu-16:~/tmp/return-to-vdso$ gdb ./hello

(gdb) b *0x8048061

(gdb) r

(gdb) disass

Dump of assembler code for function _start:

=> 0x08048061:  mov    $0x4,%eax

   0x08048066:  mov    $0x1,%ebx

   0x0804806b:  mov    $0x8048054,%ecx

   0x08048070:  mov    $0xd,%edx

   0x08048075:  int    $0x80

   0x08048077:  mov    $0x1,%eax

   0x0804807c:  mov    $0x0,%ebx

   0x08048081:  int    $0x80

End of assembler dump.

(gdb) x/100wx $esp

0xffffd570:     0x00000001      0xffffd6b0      0x00000000      0xffffd6da envp

0xffffd580:     0xffffd6ed      0xffffd6fd      0xffffd708      0xffffd736

0xffffd590:     0xffffd757      0xffffd76b      0xffffd77b      0xffffd7a5

0xffffd5a0:     0xffffdd2d      0xffffdd39      0xffffddf3      0xffffde0d

0xffffd5b0:     0xffffde1c      0xffffde3d      0xffffde65      0xffffde8c

0xffffd5c0:     0xffffde9d      0xffffdea6      0xffffdebc      0xffffdec4

0xffffd5d0:     0xffffded6      0xffffdee9      0xffffdf1b      0xffffdf6d

0xffffd5e0:     0xffffdf8d      0xffffdfac      0x00000000      0x00000020 auxv

0xffffd5f0:     0xf7ffcc80      0x00000021      0xf7ffc000      0x00000010

0xffffd600:     0x0fabfbff      0x00000006      0x00001000      0x00000011

0xffffd610:     0x00000064      0x00000003      0x08048034      0x00000004

0xffffd620:     0x00000020      0x00000005      0x00000001      0x00000007

0xffffd630:     0x00000000      0x00000008      0x00000000      0x00000009

0xffffd640:     0x08048061      0x0000000b      0x000003e8      0x0000000c

0xffffd650:     0x000003e8      0x0000000d      0x000003e8      0x0000000e

0xffffd660:     0x000003e8      0x00000017      0x00000000      0x00000019

0xffffd670:     0xffffd69b      0x0000001a      0x00000000      0x0000001f

0xffffd680:     0xffffdfce      0x0000000f      0xffffd6ab      0x00000000

0xffffd690:     0x00000000      0x00000000      0xa6000000      0xb5678ea1

0xffffd6a0:     0x77696372      0x2183ba58      0x697e970f      0x00363836

0xffffd6b0:     0x6d6f682f      0x696d2f65      0x6f696c6c      0x796b736e

0xffffd6c0:     0x706d742f      0x7465722f      0x2d6e7275      0x762d6f74

0xffffd6d0:     0x2f6f7364      0x6c6c6568      0x4458006f      0x45535f47

0xffffd6e0:     0x4f495353      0x44495f4e      0x3435313d      0x45485300

0xffffd6f0:     0x2f3d4c4c      0x2f6e6962      0x68736162      0x52455400

1.2.2 X64

millionsky@ubuntu-16:~/tmp/return-to-vdso$ gdb ./hello

(gdb) b *0x400085

(gdb) r

(gdb) disass

Dump of assembler code for function _start:

=> 0x0000000000400085:  mov    $0x4,%eax

   0x000000000040008a:  mov    $0x1,%ebx

   0x000000000040008f:  mov    $0x400078,%ecx

   0x0000000000400094:  mov    $0xd,%edx

   0x0000000000400099:  int    $0x80

   0x000000000040009b:  mov    $0x1,%eax

   0x00000000004000a0:  mov    $0x0,%ebx

   0x00000000004000a5:  int    $0x80

End of assembler dump.

(gdb) x/72gx $rsp  

0x7fffffffe460: 0x0000000000000001      0x00007fffffffe6b0

0x7fffffffe470: 0x0000000000000000      0x00007fffffffe6da envp

0x7fffffffe480: 0x00007fffffffe6ed      0x00007fffffffe6fd

0x7fffffffe490: 0x00007fffffffe708      0x00007fffffffe736

0x7fffffffe4a0: 0x00007fffffffe757      0x00007fffffffe76b

0x7fffffffe4b0: 0x00007fffffffe77b      0x00007fffffffe7a5

0x7fffffffe4c0: 0x00007fffffffed2d      0x00007fffffffed39

0x7fffffffe4d0: 0x00007fffffffedf3      0x00007fffffffee0d

0x7fffffffe4e0: 0x00007fffffffee1c      0x00007fffffffee3d

0x7fffffffe4f0: 0x00007fffffffee65      0x00007fffffffee8c

0x7fffffffe500: 0x00007fffffffee9d      0x00007fffffffeea6

0x7fffffffe510: 0x00007fffffffeebc      0x00007fffffffeec4

0x7fffffffe520: 0x00007fffffffeed6      0x00007fffffffeee9

0x7fffffffe530: 0x00007fffffffef1b      0x00007fffffffef6d

0x7fffffffe540: 0x00007fffffffef8d      0x00007fffffffefac

0x7fffffffe550: 0x0000000000000000      0x0000000000000021  auxv

0x7fffffffe560: 0x00007ffff7ffd000      0x0000000000000010

0x7fffffffe570: 0x000000000fabfbff      0x0000000000000006

0x7fffffffe580: 0x0000000000001000      0x0000000000000011

0x7fffffffe590: 0x0000000000000064      0x0000000000000003

0x7fffffffe5a0: 0x0000000000400040      0x0000000000000004

0x7fffffffe5b0: 0x0000000000000038      0x0000000000000005

0x7fffffffe5c0: 0x0000000000000001      0x0000000000000007

0x7fffffffe5d0: 0x0000000000000000      0x0000000000000008

0x7fffffffe5e0: 0x0000000000000000      0x0000000000000009

0x7fffffffe5f0: 0x0000000000400085      0x000000000000000b

0x7fffffffe600: 0x00000000000003e8      0x000000000000000c

0x7fffffffe610: 0x00000000000003e8      0x000000000000000d

0x7fffffffe620: 0x00000000000003e8      0x000000000000000e

0x7fffffffe630: 0x00000000000003e8      0x0000000000000017

0x7fffffffe640: 0x0000000000000000      0x0000000000000019

0x7fffffffe650: 0x00007fffffffe699      0x000000000000001a

0x7fffffffe660: 0x0000000000000000      0x000000000000001f

0x7fffffffe670: 0x00007fffffffefce      0x000000000000000f

0x7fffffffe680: 0x00007fffffffe6a9      0x0000000000000000

0x7fffffffe690: 0x0000000000000000      0x164976e45ea81400

1.3 AT_SYSINFO_EHDR&AT_SYSINFO

kernel告诉C库VDSO/__kernel_vsyscall的位置,则是通过elf的interpreter的auxiliary vector。

AT_SYSINFO __kernel_vsyscall的地址

AT_SYSINFO_EHDR VDSO的地址

64位系统只有AT_SYSINFO_EHDR,没有AT_SYSINFO;

 

GDB调试(x86)

(gdb) info auxv

32   AT_SYSINFO           Special system info/entry points 0xb7fdd414

33   AT_SYSINFO_EHDR      System-supplied DSO's ELF header 0xb7fdd000

(gdb) info program

        Using the running image of child process 7749.

Program stopped at 0x80483e8.

It stopped at breakpoint 1.

(gdb) shell cat /proc/7749/maps | grep vdso

b7fdd000-b7fde000 r-xp 00000000 00:00 0          [vdso]

 

LD_SHOW_AUXV环境变量

millionsky@ubuntu-12:~/tmp$ LD_SHOW_AUXV=1 /bin/ls

AT_SYSINFO:      0xb77c0414

AT_SYSINFO_EHDR: 0xb77c0000

1.4 AT_RANDOM

16字节随机数的地址;

这个地址在附加向量的后面,环境字符串的前面;

对于确定的系统,可以通过这个地址计算栈中数据的地址

泄露栈数据

计算AT_RANDOM的值,记为address

计算AT_RANDOM距离栈开始数据,如argc的偏移,记为offset;

Address-offset即栈开始数据如argc的地址

1.5 AT_PLATFORM

平台字符串i386\0或x86_64\0

位于AT_RANDOM字符串后面

可以通过这个地址计算栈中数据的地址

2 结论

1. 附加向量位于环境指针数组的后面,环境字符串的前面;

2. 附加向量中的AT_SYSINFO_EHDR指示VDSO的地址;

3. 附加向量中的AT_SYSINFO指示__kernel_vsyscall的地址(32位系统);

4. 附加向量中的AT_RANDOM指示栈中16字节随机数的地址。在栈中位于附加向量的后面,环境字符串的前面。可以通过这个地址计算栈中数据的地址。

5. AT_PLATFORM指示平台字符串,可以通过这个地址计算栈中数据的地址。

参考文章

1. Return to VDSO using ELF Auxiliary Vectors。https://v0ids3curity.blogspot.jp/2014/12/return-to-vdso-using-elf-auxiliary.html。

猜你喜欢

转载自blog.csdn.net/luozhaotian/article/details/79610143