如何解释 ELF 文件中的“p_size”?
How to interpret `p_size` in ELF files?
最近一直在玩ELF格式的文件。我试图解决一个问题:
Given the eip
, print the name of the function in the ELF executable file
我可以用符号 table 和字符串 table 来做到这一点。由于我只需要处理那些类型为STT_FUNC
的符号,我写了如下程序:
for (i = 0; i < nr_symtab_entry; ++i) {
if ((symtab[i].st_info == STT_FUNC) &&
eip < symtab[i].st_value + symtab[i].st_size &&
eip >= symtab[i].st_value) {
strcpy(funcName, strtab + symtab[i].st_name);
}
}
其中 symtab
是符号 table,strtab
是字符串 table。
但是经过几次测试,我发现上面的程序是错误的。试了几次,改成这样:
for (i = 0; i < nr_symtab_entry; ++i) {
if ((symtab[i].st_info & STT_FUNC) &&
eip < symtab[i].st_value + symtab[i].st_size &&
eip >= symtab[i].st_value) {
strcpy(funcName, strtab + symtab[i].st_name);
}
}
然后成功了!但是当我man elf
的时候,手册告诉我:
st_info This member specifies the symbol’s type and binding attributes
它没有提到它是否是位标志。然后我遇到了一个问题,需要我检查一个段是否是PT_LOAD
。并且手册再次没有指定它是否是位标志。所以才来这里求助---PT_LOAD
也是位flag吗? ELF文件中的每个符号常量之类的东西都是位标志吗?
好像st_info
可以通过特定的宏来解释。但是 p_type
呢?
使用:
if (ELF32_ST_TYPE(symtab[i].st_info) == STT_FUNC && ...
就像内核在 linux kernel/module.c 中所做的那样。
ELF32_ST_TYPE用于从st_info中提取一个符号的类型。我在任何地方都找不到哪些符号是符号类型的列表,但是检查 #define ELF32_ST_TYPE(info) ((info) & 0xf)
和 elf.h 中的定义我可以很确定 ELF32_ST_TYPE(st_info)
等于以下宏之一:
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_COMMON 5
#define STT_TLS 6
在man elf
里面是:
There are macros for packing and unpacking the binding and
type fields:
ELF32_ST_BIND(info), ELF64_ST_BIND(info)
Extract a binding from an st_info value.
ELF32_ST_TYPE(info), ELF64_ST_TYPE(info)
Extract a type from an st_info value.
ELF32_ST_INFO(bind, type), ELF64_ST_INFO(bind, type)
Convert a binding and a type into an st_info value.
最近一直在玩ELF格式的文件。我试图解决一个问题:
Given the
eip
, print the name of the function in the ELF executable file
我可以用符号 table 和字符串 table 来做到这一点。由于我只需要处理那些类型为STT_FUNC
的符号,我写了如下程序:
for (i = 0; i < nr_symtab_entry; ++i) {
if ((symtab[i].st_info == STT_FUNC) &&
eip < symtab[i].st_value + symtab[i].st_size &&
eip >= symtab[i].st_value) {
strcpy(funcName, strtab + symtab[i].st_name);
}
}
其中 symtab
是符号 table,strtab
是字符串 table。
但是经过几次测试,我发现上面的程序是错误的。试了几次,改成这样:
for (i = 0; i < nr_symtab_entry; ++i) {
if ((symtab[i].st_info & STT_FUNC) &&
eip < symtab[i].st_value + symtab[i].st_size &&
eip >= symtab[i].st_value) {
strcpy(funcName, strtab + symtab[i].st_name);
}
}
然后成功了!但是当我man elf
的时候,手册告诉我:
st_info This member specifies the symbol’s type and binding attributes
它没有提到它是否是位标志。然后我遇到了一个问题,需要我检查一个段是否是PT_LOAD
。并且手册再次没有指定它是否是位标志。所以才来这里求助---PT_LOAD
也是位flag吗? ELF文件中的每个符号常量之类的东西都是位标志吗?
好像st_info
可以通过特定的宏来解释。但是 p_type
呢?
使用:
if (ELF32_ST_TYPE(symtab[i].st_info) == STT_FUNC && ...
就像内核在 linux kernel/module.c 中所做的那样。
ELF32_ST_TYPE用于从st_info中提取一个符号的类型。我在任何地方都找不到哪些符号是符号类型的列表,但是检查 #define ELF32_ST_TYPE(info) ((info) & 0xf)
和 elf.h 中的定义我可以很确定 ELF32_ST_TYPE(st_info)
等于以下宏之一:
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_COMMON 5
#define STT_TLS 6
在man elf
里面是:
There are macros for packing and unpacking the binding and type fields:
ELF32_ST_BIND(info), ELF64_ST_BIND(info)
Extract a binding from an st_info value.ELF32_ST_TYPE(info), ELF64_ST_TYPE(info)
Extract a type from an st_info value.ELF32_ST_INFO(bind, type), ELF64_ST_INFO(bind, type)
Convert a binding and a type into an st_info value.