IDA动态调试linux的ELF
1、准备
在 IDA 的安装目录/dbgsrc/找到 linux_server 和 linux_serverx64 拷贝到 linux 虚拟机中
2、查看文件类型
file elf
如果是32位的运行./linux_server
64位的运行./linux_serverx64
3、Windows设置
1、Debugger –>Remote Linux debugger
2、Debugger –>Process options –> hostname
4、运行
Linux下修改程序流程
1、Linux下修改程序流程
今天看见一个ctf的elf题目,很有趣,是一个dice题目,很熟悉嘛。今天有发现一种新套路,便记录下来,以后遇见就嘿嘿嘿
2、分析
打开ida,发现如下
前面生成随机数,后面验证,以往我都会改验证的地方,今天来点不一样的
3、修改
发现flag在这个函数打印
这个函数的地址是0x4006B6,同时发现main开始运行的 地址
linux下gdb调试,在下断点,run运行
i r 查看寄存器的值,此时,还没有运行到程序区
n下一步,在i r查看
发现已经到达程序区了,将rdi寄存器设置为我们想要的值 set $rdi=0x4006b6,运行c
程序员自我修养第4章——静态编译
1、什么是静态编译
静态编译,就是编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(.so或.lib)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖于动态链接库。
2、实验
这里有a.c,b.c两个文件,如下:
b.c
a.c
通过编译gcc -c a.c b.c
产生a.o,b.o两个目标文件,接着我们准备把a.o,b.o文件合并ab文件。这里有两种方法。
一种是按序叠加
(直接将一个文件加在另一个文件的尾,并依此合并)。
一种是相似段合并
(将相同性质的段合并到一起,如text段合并到text段),又称为两步链接法
。
这里我们采用第二种方法进行链接(链接器为目标文件分配地址和空间)
第一步 空间与地址分配
扫描所有的输入文件,获取他们的各个段的长度,属性和位置,并且将输入目标文件的符号表中所有的符号定义和符号引用收集起来,同意放到一个全局符号表,并建立映射关系。
第二步 符号解析与重定位
使用上面收集的所有信息,读取输入文件中断的数据,重定位信息,并且进行符号解析与重定位,调整代码中的地址等。这一步中核心是重定位过程。
我们使用ld链接器将a.o
和b.o
链接起来。ld a.o b.o -e main -o ab
-e main 表示将main函数作为程序的入口地址,ld链接器默认的程序入口地址是_start.
-o ab 表示链接输出文件名为ab,默认为a.out
上图中VMA(Vitual Meemory Address)虚拟地址,LMA(load Memory Address)加载地址,正常情况下这两个是一样的,但是在一些嵌入式系统中,特别是在哪些程序放在ROM的系统中,它们是不同的。
符号地址的确定
当完成前面一步时,链接器开始计算各个符号的虚拟地址,因为各个符号在段内的相对位置是固定的,所有这个时候main
,shared
的地址已经确认啦(只需要每一个符号加上一个偏移,就能找到正确的虚拟地址)。
符号解析和重定位
重定位
我们用objdump -d a.o
可以看到shared的地址是0,因为这里不知道的位置。swap也是一样的。我们再看看abobjdunp -d ab
发现链接后能正确的找到符号地址
重定位修正方法
对于Intel x86处理器,有两种类型的处理器,分布的修正方法
A = 保存在修正位置的值
S = 符号的实际地址
P = 被修正过的位置(相对于段开始的偏移量或是虚拟地址)
1、R_386_32 绝对寻址修正 S+A
2、R_386_PC32 相对寻址修正 S+A-P