开始学习与Linux kernel相关的东西,第一步就是环境搭建,记录一些错误和解决方法。
参考
参考以下两篇博客:
https://www.anquanke.com/post/id/85837
http://p4nda.top/2018/04/04/kernel-pwn-start/
环境
1 | 系统镜像:ubuntu-14.04-desktop-i386 |
内核编译
1 | sudo apt-get install libncurses5-dev |
错误1
1 | /home/ubuntu/kernel/linux-2.6.32.1/arch/x86/include/asm/ptrace.h:146:13: note: previous declaration of ‘syscall_trace_leave’ was here |
这里的错误是说ptrace.c中syscall_trace_leave函数的定义与ptrace.h中的声明不同:1
2
3
4
5
6
7linux-2.6.32.1/arch/x86/include/asm/ptrace.h
extern long syscall_trace_enter(struct pt_regs *);
extern void syscall_trace_leave(struct pt_regs *);
linux-2.6.32.1/arch/x86/kernel/ptrace.c
asmregparm long syscall_trace_enter(struct pt_regs *regs);
asmregparm void syscall_trace_leave(struct pt_regs *regs);
将ptrace.h中的声明修改为和ptrace.c定义相同即可,另外添加一个头文件:1
2
3
4linux-2.6.32.1/arch/x86/include/asm/ptrace.h
extern asmregparm long syscall_trace_enter(struct pt_regs *);
extern asmregparm void syscall_trace_leave(struct pt_regs *);
解决方案参考:https://bestwing.me/Complie-linux-kernel-and-running-it-using-qemu.html
错误2
1 | gcc: error: elf_i386: No such file or directory |
解决方案:1
2
3
4
5
6
7
8
9linux-2.6.32.1/arch/x86/vdso/Makefile
VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \ //line 28
-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1 //line 73
//修改为
VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1
解决方案参考:https://www.anquanke.com/post/id/85837
错误3
1 | drivers/net/igbvf/igbvf.h: At top level: |
修改命名冲突:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20linux-2.6.32.1/drivers/net/igbvf/igbvf.h
struct igbvf_buffer { //line 111
dma_addr_t dma;
struct sk_buff *skb;
union {
/* Tx */
struct {
unsigned long time_stamp;
u16 length;
u16 next_to_watch;
};
/* Rx */
struct {
struct page *_page; //修改
u64 page_dma;
unsigned int page_offset;
};
};
struct page *page;
};
解决方案参考:https://www.anquanke.com/post/id/85837
之后执行以下命令过程中,就没有出现错误了。1
2make all
make modules
busybox
主要是busybox的编译和配置
busybox编译
1 | make menuconfig |
为了避免一些错误,在make menuconfig阶段将一些配置选项修改:
将Linux System Utilities —>中的mkfs_ext2和mkfs_vfat的[*]include改为[ ]exclude,如下图。
将Linux System Utilities —>中的Support mounting NFS file systems on Linux < 2.6.23 (NEW)的[*]include改为[ ]exclude:
将Networking Utilities —>中的inetd (18 kb) (NEW)的[*]include改为[ ]exclude:
将Settings->Build Options->Build static binary(no shared libs)的[ ]exclude改为[*]include:
busybox配置
记录一下配置busybox的命令,首先添加inittab命令。1
2
3
4cd _install
mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin}}
cd etc
gedit inittab
inittab的内容如下:1
2
3
4
5
6
7#!/bin/sh
::sysinit:/etc/init.d/rcS
::askfirst:/bin/ash
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
添加rcS文件:1
2
3
4cd _install/etc/
mkdir init.d
cd init.d
gedit rcS
rcS文件的内容如下:1
2
3
4
5
6
7#!/bin/sh
#!/bin/sh
mount -t proc none /proc
mount -t sys none /sys
/bin/mount -n -t sysfs none /sys
/bin/mount -t ramfs none /dev
/sbin/mdev -
为rcS文件添加可执行权限:1
chmod +x rcS
然后在_install目录下配置dev目录:1
2
3
4mkdir dev
sudo mknod dev/ttyAMA0 c 204 64
sudo mknod dev/null c 1 3
sudo mknod dev/console c 5 1
生成rootfs:1
find . | cpio -o --format=newc > ../rootfs.img
启动qemu:1
2
3
432位启动:
qemu-system-i386 -kernel linux-2.6.32.1/arch/i386/boot/bzImage -initrd busybox-1.28.2/rootfs.img -append "root=/dev/ram rdinit=/sbin/init"
64位启动:
qemu-system-x86_64 -kernel linux-2.6.32.1/arch/x86/boot/bzImage -initrd busybox-1.28.2/rootfs.img -append "root=/dev/ram rdinit=/sbin/init"
问题1
但是在运行后出现了一个问题,qemu终端显示”can’t open /dev/tty: No such file or directory”,一直以为是busybox配置的问题,后来配置了几遍之后仍然是这个问题,后来查到了解决方案,在配置dev目录时需要再添加一句命令:1
sudo mknod /dev/tty1 c 4 1
解决方案参考:https://www.linuxquestions.org/questions/linux-software-2/dev-tty-no-such-file-or-directory-889996/
问题2
再次启动qemu后,出现以下问题:
查找资料,找到解决方法,编辑_install/etc/目录下的inittab文件:1
2将::askfirst:/bin/ash
修改为::askfirst:-/bin/ash
再次启动qemu,成功启动:
关闭canary
后面再做题的时候需要关闭canary,因此需要将内核重新编译,修改内核的配置文件.config,将下列语句注释掉:1
2#./linux-2.6.32.1/.config
#CONFIG_CC_STACKPROTECTOR=y
重新编译:1
2
3
4make
make
make all
make modules