dl_iterate_phdr(3) - wariua/manpages-ko GitHub Wiki
dl_iterate_phdr - ๊ณต์ ์ค๋ธ์ ํธ ๋ฆฌ์คํธ ์ํํ๊ธฐ
#define _GNU_SOURCE /* feature_test_macros(7) ์ฐธ๊ณ */
#include <link.h>
int dl_iterate_phdr(
int (*callback) (struct dl_phdr_info *info,
size_t size, void *data),
void *data);
dl_iterate_phdr()
ํจ์๋ฅผ ์ด์ฉํด ์์ฉ์์ ์ด๋ค ๊ณต์ ์ค๋ธ์ ํธ๋ค์ ์ ์ฌํ๊ณ ์ด๋ค ์์๋ก ์ ์ฌ๋๋์ง ๋ฐํ์์ ์ง์ํ ์ ์๋ค.
dl_iterate_phdr()
ํจ์๋ ์์ฉ์ ๊ณต์ ์ค๋ธ์ ํธ ๋ชฉ๋ก์ ์ํํ๋ฉด์ ๊ฐ ์ค๋ธ์ ํธ๋ง๋ค ํจ์ callback
์ ํธ์ถํ๋ค. ๋ชจ๋ ๊ณต์ ์ค๋ธ์ ํธ๋ฅผ ์ฒ๋ฆฌํ์ผ๋ฉด, ๋๋ callback
์ด 0 ์๋ ๊ฐ์ ๋ฐํํ๋ฉด ๋ฉ์ถ๋ค.
callback
ํธ์ถ ๊ฐ๊ฐ์ ์ธ ๊ฐ ์ธ์๋ฅผ ๋ฐ๋๋ค. info
๋ ๊ณต์ ์ค๋ธ์ ํธ์ ๋ํ ์ ๋ณด๋ฅผ ๋ด์ ๊ตฌ์กฐ์ฒด์ ๋ํ ํฌ์ธํฐ์ด๊ณ size
๋ info
๊ฐ ๊ฐ๋ฆฌํค๋ ๊ตฌ์กฐ์ฒด์ ํฌ๊ธฐ์ด๋ค. data
๋ ํธ์ถ ํ๋ก๊ทธ๋จ์์ dl_iterate_phdr()
ํธ์ถ ๋ (์ญ์ ์ด๋ฆ์ด data
์ธ) ๋ ๋ฒ์งธ ์ธ์๋ก ์ค ๊ฐ์ ์ฌ๋ณธ์ด๋ค.
info
์ธ์๋ ๋ค์ ํ์
์ ๊ตฌ์กฐ์ฒด์ด๋ค.
struct dl_phdr_info {
ElfW(Addr) dlpi_addr; /* ์ค๋ธ์ ํธ์ ๊ธฐ์ค ์ฃผ์ */
const char *dlpi_name; /* ์ค๋ธ์ ํธ์ (๋ ์ข
๋ฃ) ์ด๋ฆ */
const ElfW(Phdr) *dlpi_phdr; /* ์ด ์ค๋ธ์ ํธ์ ELF ํ๋ก๊ทธ๋จ
ํค๋ ๋ฐฐ์ด์ ๋ํ ํฌ์ธํฐ */
ElfW(Half) dlpi_phnum; /* dlpi_phdr์ ํญ๋ชฉ ๊ฐ์ */
/* ๋ค์ ํ๋๋ค์ ์ด ๊ตฌ์กฐ์ฒด์ ์ฒซ ๋ฒ์งธ ๋ฒ์ ์ด ๊ณต๊ฐ๋ ํ์
glibc 2.4์์ ์ถ๊ฐ๋ ๊ฒ๋ค์ด๋ค. dl_iterate_phdr ์ฝ๋ฐฑ์
์ ๋ฌ๋๋ size ์ธ์๋ฅผ ์ฌ์ฉํด์ ์ดํ ๋ฉค๋ฒ ๊ฐ๊ฐ์ด ์ฌ์ฉ
๊ฐ๋ฅํ์ง ์ฌ๋ถ๋ฅผ ํ์ธํด์ผ ํ๋ค. */
unsigned long long int dlpi_adds;
/* ์ ์ค๋ธ์ ํธ๊ฐ ์ถ๊ฐ๋์ ์๋
์์ ๋ ์ฆ๊ฐ๋จ */
unsigned long long int dlpi_subs;
/* ์ค๋ธ์ ํธ๊ฐ ์ ๊ฑฐ๋์ ์๋
์์ ๋ ์ฆ๊ฐ๋จ */
size_t dlpi_tls_modid;
/* PT_TLS ์ธ๊ทธ๋จผํธ๊ฐ ์๋ ๊ฒฝ์ฐ๋ TLS ์ฌ๋ฐฐ์น์
์ฐ์ธ ๊ทธ ๋ชจ๋ ID, ์๋๋ฉด 0 */
void *dlpi_tls_data;
/* ์ด ๋ชจ๋์ PT_TLS ์ธ๊ทธ๋จผํธ ์ธ์คํด์ค๊ฐ
ํ๋ ์๊ณ ํธ์ถ ์ค๋ ๋์ ํ ๋น๋ผ ์์ผ๋ฉด
๊ทธ ์ฃผ์, ์๋๋ฉด ๋ ํฌ์ธํฐ */
};
(ElfW()
๋งคํฌ๋ก๋ ๊ทธ ์ธ์๋ฅผ ํ๋์จ์ด ์ํคํ
์ฒ์ ๋ง๋ ELF ๋ฐ์ดํฐ ํ์
์ด๋ฆ์ผ๋ก ๋ฐ๊ฟ ์ค๋ค. ์๋ฅผ ๋ค์ด 32๋นํธ ํ๋ซํผ์์ ElfW(Addr)
์ ๋ฐ์ดํฐ ํ์
์ด๋ฆ Elf32_Addr
์ ๋ด๋๋๋ค. ์ด๋ฐ ํ์
๋ค์ ๋ํ ์ถ๊ฐ ์ ๋ณด๋ฅผ ํค๋ ํ์ผ <elf.h>
๋ฐ <link.h>
์์ ๋ณผ ์ ์๋ค.)
dlpi_addr
ํ๋๋ ๊ณต์ ์ค๋ธ์ ํธ์ ๊ธฐ์ค ์ฃผ์๋ฅผ ๋ํ๋ธ๋ค. (์ฆ ๊ณต์ ์ค๋ธ์ ํธ์ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ๊ทธ ์ค๋ธ์ ํธ๋ฅผ ์ ์ฌํ ํ์ผ ๋ด์์์ ์คํ์
๊ฐ์ ์ฐจ์ด์ด๋ค.) dlpi_name
ํ๋๋ ๊ทธ ๊ณต์ ์ค๋ธ์ ํธ๋ฅผ ์ ์ฌํ ๊ฒฝ๋ก๋ช
์ ์๋ ค ์ฃผ๋ ๋ ์ข
๋ฃ ๋ฌธ์์ด์ด๋ค.
dlpi_phdr
๋ฐ dlpi_phnum
ํ๋์ ์๋ฏธ๋ฅผ ์ดํดํ๋ ค๋ฉด ELF ๊ณต์ ์ค๋ธ์ ํธ๊ฐ ์ฌ๋ฌ ์ธ๊ทธ๋จผํธ๋ก ์ด๋ค์ ธ ์๊ณ ๊ฐ๊ฐ์ ๊ทธ ์ธ๊ทธ๋จผํธ๋ฅผ ๊ธฐ์ ํ๋ ํ๋ก๊ทธ๋จ ํค๋๊ฐ ์๋ค๋ ์ ์ ์์์ผ ํ๋ค. dlpi_phdr
ํ๋๋ ์ด ๊ณต์ ์ค๋ธ์ ํธ์ ํ๋ก๊ทธ๋จ ํค๋๋ค์ ๋ฐฐ์ด์ ๋ํ ํฌ์ธํฐ์ด๋ค. dlpi_phnum
ํ๋๋ ๊ทธ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ๋ํ๋ธ๋ค.
๊ทธ ํ๋ก๊ทธ๋จ ํค๋๋ค์ ๋ค์ ํํ์ ๊ตฌ์กฐ์ฒด์ด๋ค.
typedef struct {
Elf32_Word p_type; /* ์ธ๊ทธ๋จผํธ ํ์
*/
Elf32_Off p_offset; /* ์ธ๊ทธ๋จผํธ ํ์ผ ์คํ์
*/
Elf32_Addr p_vaddr; /* ์ธ๊ทธ๋จผํธ ๊ฐ์ ์ฃผ์ */
Elf32_Addr p_paddr; /* ์ธ๊ทธ๋จผํธ ๋ฌผ๋ฆฌ ์ฃผ์ */
Elf32_Word p_filesz; /* ํ์ผ ๋ด ์ธ๊ทธ๋จผํธ ํฌ๊ธฐ */
Elf32_Word p_memsz; /* ๋ฉ๋ชจ๋ฆฌ ๋ด ์ธ๊ทธ๋จผํธ ํฌ๊ธฐ */
Elf32_Word p_flags; /* ์ธ๊ทธ๋จผํธ ํ๋๊ทธ */
Elf32_Word p_align; /* ์ธ๊ทธ๋จผํธ ์ ๋ ฌ */
} Elf32_Phdr;
์ฐธ๊ณ ๋ก ๋ค์ ์์ ์ฌ์ฉํด ํน์ ํ๋ก๊ทธ๋จ ํค๋ x
์ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ๋ด ์์น๋ฅผ ๊ณ์ฐํ ์ ์๋ค.
addr == info->dlpi_addr + info->dlpi_phdr[x].p_vaddr;
p_type
์ ๊ฐ๋ฅํ ๊ฐ๋ค๋ก ๋ค์์ด ์๋ค. (๋ ์์ธํ ๋ด์ฉ์ <elf.h>
์ฐธ๊ณ .)
#define PT_LOAD 1 /* ์ ์ฌ ๊ฐ๋ฅ ํ๋ก๊ทธ๋จ ์ธ๊ทธ๋จผํธ */
#define PT_DYNAMIC 2 /* ๋์ ๋งํฌ ์ ๋ณด */
#define PT_INTERP 3 /* ํ๋ก๊ทธ๋จ ์ธํฐํ๋ฆฌํฐ */
#define PT_NOTE 4 /* ๋ณด์กฐ ์ ๋ณด */
#define PT_SHLIB 5 /* ์๋น */
#define PT_PHDR 6 /* ํค๋ ํ
์ด๋ธ ์์ฒด๋ฅผ ์ํ ํญ๋ชฉ */
#define PT_TLS 7 /* ์ค๋ ๋ ๋ก์ปฌ ์ ์ฅ ๊ณต๊ฐ ์ธ๊ทธ๋จผํธ */
#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
#define PT_GNU_STACK 0x6474e551 /* ์คํ ์คํ ๊ฐ๋ฅ ์ฌ๋ถ ํ์ */
#define PT_GNU_RELRO 0x6474e552 /* ์ฌ๋ฐฐ์น ํ์๋ ์ฝ๊ธฐ ์ ์ฉ */
dl_iterate_phdr()
ํจ์๋ ๋ง์ง๋ง callback
ํธ์ถ์ด ๋ฐํํ ๊ฐ์ ๊ทธ๋๋ก ๋ฐํํ๋ค.
glibc ๋ฒ์ 2.2.4๋ถํฐ dl_iterate_phdr()
๋ฅผ ์ง์ํ๋ค.
์ด ์ ์์ ์ฌ์ฉํ๋ ์ฉ์ด๋ค์ ๋ํ ์ค๋ช ์ attributes(7)๋ฅผ ๋ณด๋ผ.
์ธํฐํ์ด์ค | ์์ฑ | ๊ฐ |
---|---|---|
dl_iterate_phdr() |
์ค๋ ๋ ์์ ์ฑ | MT-Safe |
dl_iterate_phdr()
ํจ์๋ ์ด๋ ํ์ค์๋ ๋ช
์ธ๋ผ ์์ง ์๋ค. ๋ค๋ฅธ ์ฌ๋ฌ ์์คํ
์์๋ ์ด ํจ์๋ฅผ ์ ๊ณตํ์ง๋ง ๋ฐํ๋๋ dl_phdr_info
๊ตฌ์กฐ์ฒด์ ์ธ๋ถ ๋ด์ฉ์ด ๋ค๋ฅด๋ค. BSD์ ์๋ผ๋ฆฌ์ค์์๋ ๊ตฌ์กฐ์ฒด์ dlpi_addr
, dlpi_name
, dlpi_phdr
, dlpi_phnum
ํ๋์ ๋ํด์ ๋ค๋ฅธ ๊ตฌํ๋ณ ํ๋๋ค์ด ํฌํจ๋ผ ์๋ค.
C ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ดํ ๋ฒ์ ์์ dl_phdr_info
๊ตฌ์กฐ์ฒด์ ํ๋๋ฅผ ๋ ์ถ๊ฐํ ์๋ ์๋ค. ๊ทธ ๊ฒฝ์ฐ ์ฝ๋ฐฑ ํจ์์์๋ size
์ธ์๋ฅผ ํตํด ์ถ๊ฐ ํ๋๊ฐ ์๋ ์์คํ
์์ ๋์ ์ค์ธ์ง ์์๋ผ ์ ์๋ค.
callback
์ด ๋ฐฉ๋ฌธํ๋ ์ฒซ ๋ฒ์งธ ์ค๋ธ์ ํธ๋ ๋ฉ์ธ ํ๋ก๊ทธ๋จ์ด๋ค. ๋ฉ์ธ ํ๋ก๊ทธ๋จ์์ dlpi_name
ํ๋๋ ๋น ๋ฌธ์์ด์ด ๋๋ค.
๋ค์ ํ๋ก๊ทธ๋จ์์๋ ์ ์ฌํ ๊ณต์ ์ค๋ธ์ ํธ๋ค์ ๊ฒฝ๋ก๋ช ๋ชฉ๋ก์ ํ์ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ ๊ณต์ ์ค๋ธ์ ํธ์ ๋ํด์ ์ค๋ธ์ ํธ์ ๊ฐ ELF ์ธ๊ทธ๋จผํธ์ ์ ๋ณด(๊ฐ์ ์ฃผ์, ํฌ๊ธฐ, ํ๋๊ทธ, ํ์ )๋ฅผ ๋์ดํ๋ค.
๋ค์ ์ ธ ์ธ์ ์ x86-64 ์์คํ ์์ ํ๋ก๊ทธ๋จ์ด ๋ด๋๋ ์ถ๋ ฅ์ ๋ณด์ฌ ์ค๋ค. ์ถ๋ ฅ ์ฒซ ๋ฒ์งธ์ (์ด๋ฆ์ด ๋น ๋ฌธ์์ด์ธ) ๊ณต์ ์ค๋ธ์ ํธ๋ ๋ฉ์ธ ํ๋ก๊ทธ๋จ์ด๋ค.
$ ./a.out
Name: "" (9 segments)
0: [ 0x400040; memsz: 1f8] flags: 0x5; PT_PHDR
1: [ 0x400238; memsz: 1c] flags: 0x4; PT_INTERP
2: [ 0x400000; memsz: ac4] flags: 0x5; PT_LOAD
3: [ 0x600e10; memsz: 240] flags: 0x6; PT_LOAD
4: [ 0x600e28; memsz: 1d0] flags: 0x6; PT_DYNAMIC
5: [ 0x400254; memsz: 44] flags: 0x4; PT_NOTE
6: [ 0x400970; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
7: [ (nil); memsz: 0] flags: 0x6; PT_GNU_STACK
8: [ 0x600e10; memsz: 1f0] flags: 0x4; PT_GNU_RELRO
Name: "linux-vdso.so.1" (4 segments)
0: [0x7ffc6edd1000; memsz: e89] flags: 0x5; PT_LOAD
1: [0x7ffc6edd1360; memsz: 110] flags: 0x4; PT_DYNAMIC
2: [0x7ffc6edd17b0; memsz: 3c] flags: 0x4; PT_NOTE
3: [0x7ffc6edd17ec; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME
Name: "/lib64/libc.so.6" (10 segments)
0: [0x7f55712ce040; memsz: 230] flags: 0x5; PT_PHDR
1: [0x7f557145b980; memsz: 1c] flags: 0x4; PT_INTERP
2: [0x7f55712ce000; memsz: 1b6a5c] flags: 0x5; PT_LOAD
3: [0x7f55716857a0; memsz: 9240] flags: 0x6; PT_LOAD
4: [0x7f5571688b80; memsz: 1f0] flags: 0x6; PT_DYNAMIC
5: [0x7f55712ce270; memsz: 44] flags: 0x4; PT_NOTE
6: [0x7f55716857a0; memsz: 78] flags: 0x4; PT_TLS
7: [0x7f557145b99c; memsz: 544c] flags: 0x4; PT_GNU_EH_FRAME
8: [0x7f55712ce000; memsz: 0] flags: 0x6; PT_GNU_STACK
9: [0x7f55716857a0; memsz: 3860] flags: 0x4; PT_GNU_RELRO
Name: "/lib64/ld-linux-x86-64.so.2" (7 segments)
0: [0x7f557168f000; memsz: 20828] flags: 0x5; PT_LOAD
1: [0x7f55718afba0; memsz: 15a8] flags: 0x6; PT_LOAD
2: [0x7f55718afe10; memsz: 190] flags: 0x6; PT_DYNAMIC
3: [0x7f557168f1c8; memsz: 24] flags: 0x4; PT_NOTE
4: [0x7f55716acec4; memsz: 604] flags: 0x4; PT_GNU_EH_FRAME
5: [0x7f557168f000; memsz: 0] flags: 0x6; PT_GNU_STACK
6: [0x7f55718afba0; memsz: 460] flags: 0x4; PT_GNU_RELRO
#define _GNU_SOURCE
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
static int
callback(struct dl_phdr_info *info, size_t size, void *data)
{
char *type;
int p_type, j;
printf("Name: \"%s\" (%d segments)\n", info->dlpi_name,
info->dlpi_phnum);
for (j = 0; j < info->dlpi_phnum; j++) {
p_type = info->dlpi_phdr[j].p_type;
type = (p_type == PT_LOAD) ? "PT_LOAD" :
(p_type == PT_DYNAMIC) ? "PT_DYNAMIC" :
(p_type == PT_INTERP) ? "PT_INTERP" :
(p_type == PT_NOTE) ? "PT_NOTE" :
(p_type == PT_INTERP) ? "PT_INTERP" :
(p_type == PT_PHDR) ? "PT_PHDR" :
(p_type == PT_TLS) ? "PT_TLS" :
(p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" :
(p_type == PT_GNU_STACK) ? "PT_GNU_STACK" :
(p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL;
printf(" %2d: [%14p; memsz:%7lx] flags: 0x%x; ", j,
(void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr),
info->dlpi_phdr[j].p_memsz,
info->dlpi_phdr[j].p_flags);
if (type != NULL)
printf("%s\n", type);
else
printf("[other (0x%x)]\n", p_type);
}
return 0;
}
int
main(int argc, char *argv[])
{
dl_iterate_phdr(callback, NULL);
exit(EXIT_SUCCESS);
}
ldd(1)
, objdump(1), readelf(1), dladdr(3), dlopen(3), elf(5), ld.so(8)
Executable and Linking Format Specification, ์จ๋ผ์ธ ์ฌ๋ฌ ๊ณณ์์ ๊ตฌํ ์ ์์.
2019-03-06