01linux下cp覆盖原so文件时引起的段错误原因
动态链接器本身也是一个共享对象,但有一些特殊性。首先,动态链接器本身不可以依赖于其他任何共享对象;其次动态链接器本身所需要的全局和静态变量的重定位工作由它本身完成。对于第一个条件,可以人为的控制在编写动态链接器时保证不使用任何系统库、运行库;对于第二个条件,动态链接器必须在启动时有一段非常精巧的代码可以完成这项艰巨的工作而同时又不能用到全局和静态变量。这种具有一定限制条件的启动代码往往被称为自举(Bootstrap)。
动态链接器入口地址即是自举代码的入口,当操作系统将进程控制权交给动态链接器时,动态链接器的自举代码即开始执行。自举代码首先会找到它自己的GOT。而GOT的第一个入口保存的即是“.dynamic”段的偏移地址,由此找到了动态连接器本身的“.dynamic”段。通过“.dynamic”中的信息,自举代码便可以获得动态链接器本身的重定位表和符号表等,从而得到动态链接器本身的重定位入口,先将它们全部重定位。从这一步开始,动态链接器代码中才可以开始使用自己的全局变量和静态变量。
而cp操作导致已经重定位的数据重新初始化,导致在调用函数的时候出现找不到函数符号的情况,进而导致程序崩溃
02链接、装载与库 --- 动态链接
动态链接器本身也是一个共享对象,但有一些特殊性。首先,动态链接器本身不可以依赖于其他任何共享对象;其次动态链接器本身所需要的全局和静态变量的重定位工作由它本身完成。对于第一个条件,可以人为的控制在编写动态链接器时保证不使用任何系统库、运行库;对于第二个条件,动态链接器必须在启动时有一段非常精巧的代码可以完成这项艰巨的工作而同时又不能用到全局和静态变量。这种具有一定限制条件的启动代码往往被称为自举(Bootstrap)。
动态链接器入口地址即是自举代码的入口,当操作系统将进程控制权交给动态链接器时,动态链接器的自举代码即开始执行。自举代码首先会找到它自己的GOT。而GOT的第一个入口保存的即是“.dynamic”段的偏移地址,由此找到了动态连接器本身的“.dynamic”段。通过“.dynamic”中的信息,自举代码便可以获得动态链接器本身的重定位表和符号表等,从而得到动态链接器本身的重定位入口,先将它们全部重定位。从这一步开始,动态链接器代码中才可以开始使用自己的全局变量和静态变量。
03动态库so被覆盖导致coredump
一、为何cp覆盖进程的动态库(so)会导致coredump?
1.应用程序通过dlopen打开so的时候,kernel通过mmap把so加载到进程地址空间,对应于vma里的几个page.
2.在这个过程中loader会把so里面引用的外部符号例如malloc printf等解析成真正的虚存地址。
3.当so被cp覆盖时,确切地说是被trunc时,kernel会把so文件在虚拟内存的页清除掉。
4.当运行到so里面的代码时,因为虚拟内存的页已经清除掉了,这时会产生一次缺页中断。
5.缺页中断会导致Kernel从so文件中拷贝对应的页到内存中去:
a) 如果so里面依赖了外部符号,但是这时的外部符号并没有经过重新解析,当调用到时就产生segment fault
b) 如果需要的文件偏移大于新的so的地址范围,就会产生bus error.

04linux内核缺页中断处理
* 如果页表项页框存在标志为0,说明页框不存在,此时分为两种情况,第一种情况是页表项为 * 空,说明此页表项是第一次进行映射,并且还会分为是匿名映射还是文件映射。第二种情况是 * 页表项不为null,说明此页表项映射过页框,只不过被换到了磁盘,所以也分为匿名映射和文件 * 映射两种情况,其中匿名映射从swap区加载数据,文件映射从对应的文件加载数据缺页中断处理一般流程:
1.硬件陷入内核,在堆栈中保存程序计数器,大多数当前指令的各种状态信息保存在特殊的cpu寄存器中。
2.启动一个汇编例程保存通用寄存器和其他易丢失信息,以免被操作系统破坏。
3.当操作系统发现缺页中断时,尝试发现需要哪个虚拟页面。通常一个硬件寄存器包含了这些信息,如果没有的话操作系统必须检索程序计数器,取出当前指令,分析当前指令正在做什么。
4.一旦知道了发生缺页中断的虚拟地址,操作系统会检查地址是否有效,并检查读写是否与保护权限一致,不过不一致,则向进程发一个信号或者杀死该进程。如果是有效地址并且没有保护错误发生则系统检查是否有空闲页框。如果没有,则执行页面置换算法淘汰页面。
5.如果选择的页框脏了,则将该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程让其他进程运行直到写入磁盘结束。且回写的页框必须标记为忙,以免其他原因被其他进程占用。
6.一旦页框干净后,操作系统查找所需页面在磁盘上的地址,通过磁盘操作将其装入,当页面被装入后,产生缺页中断的进程仍然被挂起,并且如果有其他可运行的用户进程,则选择另一用户进程运行。
7.当磁盘中断发生时,表明该页已经被装入,页表已经更新可以反映他的位置,页框也标记位正常状态。
8.恢复发生缺页中断指令以前的状态,程序计数器重新指向这条指令。
9.调度引发缺页中断的进程,操作系统返回调用他的汇编例程
10.该例程恢复寄存器和其他状态信息,返回到用户空间继续执行,就好像缺页中断没有发生过。
05vim块操作:列删除、列插入
1、vim中块删除:
第一步:按下组合键“CTRL+v” 进入“可视 块”模式,选取这一列操作多少行
第二步:按下d 即可删除被选中的整块
2、vim中块插入
第一步:按下组合键“CTRL+v” 进入“可视 块”模式,选取这一列操作多少行
第二步:按下shift+i(或者大写的字母"i")
第三步:输入要插入的内容
第四步:按ESC,之后就会看到插入的效果。
06Linux替换动态库导致正在运行的程序崩溃
在替换so文件时,如果在不停程序的情况下,直接用 cp new.so old.so 的方式替换程序使用的动态库文件会导致正在运行中的程序崩溃。解决的办法是采用“rm+cp” 或“mv+cp” 来替代直接“cp” 的操作方法。
07linux进程动态so注入
1、如何能够接触到正在执行进程的内存空间.
2、__libc_dlopen_mode 的内存地址是多少(如何查找)
3、如何找到 link_map 地址
4、如何根据 符号名字符串 和 link_map 找符号的内存地址
5、如何调用 __libc_dlopen_mode?
08Linux逆向之hook&注入
利用ptrace进行hook的原理和步骤
1、首先需要使得hook程序利用ptrace attach target程序,保护现场,保存原寄存器内容和内存数据
2、通过得到指向link_map链表的指针,通过一系列的遍历操作,根据函数名查找到各种函数的真实地址
3、通过修改target程序的寄存器和内存使其调用dlopen函数,从而将hook.so加入target内存空间
4、修改需要被hook的func函数地址的GOT表为hook.so中hook_func函数地址
5、完成hook,恢复现场,恢复原寄存器内容和内存数据,退出ptrace
09dlopen函数详解
Linux提供了一套API来动态装载库。下面列出了这些API:
dlopen:该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。这种机制使得在系统中添加或者删除一个模块时,都不需要重新进行编译。
dlsym:在打开的动态库中查找符号的值。
dlclose:关闭动态库。dlerror:返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。

10Linux交换空间(swap space)
space是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者是他们的组合。简单点说,当系统物理内存吃紧时,Linux会将内存中不常访问的数据保存到swap上,这样系统就有更多的物理内存为各个进程服务,而当系统需要访问swap上存储的内容时,再将swap上的数据加载到内存中,这就是我们常说的swap11那些永不消逝的进程(nohup的原理)
一个忽略了 SIGHUP 信号的进程(nohup xxx),在它所属的会话的控制进程被终结之后依旧可以继续运行;但此时由于原有控制终端已经不再存在了,它便不再有终端输入或输出的能力;此外,原有的会话依旧存在,只不过会话先导(session leader,由于此时的会话中已没有任何终端,因此不能称之为控制进程了)变为该进程。12通过共享内存进行进程间通信
从表面上看,UNIX® 应用程序单独控制底层主机。它随时可以访问处理器,它的内存是神圣不可侵犯的,连接它的设备只为它服务。但是表面现象会骗人,这样有如君主一般的绝对地位只是幻想而已。UNIX 系统同时运行大量应用程序,有限的物理资源要在它们之间共享。处理器能力被划分为时间片,应用程序映像经常被换入和换出真实内存,设备访问由需求驱动,还受到访问权限的限制。尽管您的 shell 提示符不断闪烁,但是 UNIX 系统并非只是等着您发出命令,在幕后有许多活动正在进行。
点击排行

站长推荐

猜你喜欢
站点信息
- 建站时间:2016-04-01
- 文章统计:728条
- 文章评论:82条
- QQ群二维码:扫描二维码,互相交流
