我需要获取以下进程段的开始和结束地址:代码、数据、堆栈、环境。我了解它如何位于内存中,但不知道如何使用 api 调用或其他方式获取它。我找到了如何使用此代码开始某些片段
#include <stdio.h>
int temp_data = 100;
static int temp_bss;
void print_addr ( void )
{
int local_var = 100;
int *code_segment_address = ( int* ) &print_addr;
int *data_segment_address = &temp_data;
int *bss_address = &temp_bss;
int *stack_segment_address = &local_var;
printf ( "\nAddress of various segments:" );
printf ( "\n\tCode Segment : %p" , code_segment_address );
printf ( "\n\tData Segment : %p" , data_segment_address );
printf ( "\n\tBSS : %p" , bss_address );
printf ( "\n\tStack Segment : %p\n" , stack_segment_address );
}
int main ( )
{
print_addr ();
return 0;
}
但我不知道如何找到每个段的结尾。我唯一的想法是一个片段的结束是另一个片段的开始。
请解释我如何使用 C 和 linux API 来做到这一点。
我不确定数据或堆段是否定义良好且唯一(特别是在多线程应用程序中,或者只是在使用动态库的应用程序中,包括libc.so
)。换句话说,不再有任何明确定义的文本、数据或堆段的开始和结束,因为今天的进程有许多这样的段。所以你的问题在一般情况下甚至没有意义。
Most malloc
实现使用mmap(2) http://man7.org/linux/man-pages/man2/mmap.2.html and munmap
比...多得多sbrk
你应该阅读更多关于proc(5) http://man7.org/linux/man-pages/man5/proc.5.html。特别是,您的应用程序可以读取/proc/self/maps
(or /proc/1234/maps
对于 pid 1234 的进程)或/proc/self/smaps
; try cat /proc/self/maps
并考虑使用fopen(3) http://man7.org/linux/man-pages/man3/fopen.3.html on "/proc/self/maps"
(然后循环fgets
or readline
,最后很快fclose
)。也许dladdr(3) http://man7.org/linux/man-pages/man3/dladdr.3.html可能相关。
您还可以阅读ELF https://en.wikipedia.org/wiki/Executable_and_Linkable_Format程序的标题,例如的/proc/self/exe
。也可以看看雷德尔夫(1) http://man7.org/linux/man-pages/man1/readelf.1.html and 对象转储(1) http://man7.org/linux/man-pages/man1/objdump.1.html & 执行(2) http://man7.org/linux/man-pages/man2/execve.2.html & elf(5) http://man7.org/linux/man-pages/man5/elf.5.html & ld.so(8) http://man7.org/linux/man-pages/man8/ld.so.8.html & libelf http://www.mr511.de/software/english.html。另请阅读莱文的链接器和加载器 http://www.iecc.com/linker书和德雷珀的论文:如何编写共享库 http://people.redhat.com/drepper/dsohowto.pdf.
也可以看看这个答案 https://stackoverflow.com/a/26436766/841108到一个相关的问题(以及那个问题 https://stackoverflow.com/q/26437921/841108)。请注意,最近的 Linux 系统有ASLR https://en.wikipedia.org/wiki/Address_space_layout_randomization,因此在同一环境中运行同一程序的两个相似进程的地址布局会有所不同。
也尝试跟踪(1) http://man7.org/linux/man-pages/man1/strace.1.html一些简单的命令或您的程序。你会更了解一些相关的内容系统调用(2) http://man7.org/linux/man-pages/man2/syscalls.2.html。另请阅读高级Linux编程 http://advancedlinuxprogramming.com/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)