前言

就如标题所言,这篇文章是(被迫)学docker写出来的。

事情的起因是这样的,我最近在学堆,需要编译一个libc2.23的题目,问过pwn爹之后才知道,在本机时肯定不行 的,需要在docker里用ubuntu16.04编译。

于是就开始了docker的学习。

当然下面的docker学习仅限我能用就行(不够用了再学)

安装docker

https://zhuanlan.zhihu.com/p/675938110

本着能用就行的原则,我选择了直接apt安装。

sudo apt update
sudo apt install docker.io docker-compose

之后查看是否正确安装

docker -v

生成镜像

我们的镜像是基于ubuntu16.04的,因此首先要先拉取一个ubuntu16.04。

docker pull ubuntu:16.04

现在我们本地已经有了ubuntu16.04镜像,之后就需要写dockerfile,docker通过dockerfile来生成我们需要的镜像。

我现在有了我需要编译程序的源代码,将其命名为fastbins.c,我需要用ubuntu16.04的gcc来编译这个文件,并命名为fastbin。

写dockerfile

通过询问gpt,就可以得到我们的dockerfile了。

# 使用官方的Ubuntu镜像作为基础镜像
FROM ubuntu:16.04

# 安装GCC编译器
RUN apt-get update && apt-get install -y gcc

# 设置工作目录
WORKDIR /app

# 将当前目录下的fastbins.c文件复制到容器的/app目录下
COPY fastbins.c /app/

# 使用GCC编译fa.c文件,并将可执行文件命名为fastbin
RUN gcc -o fastbin fastbins.c

# 设置环境变量,使得容器启动时可以直接运行fastbin程序
ENV PATH="/app:${PATH}"

# 定义一个默认的执行命令,这里我们什么也不做
CMD ["bash"]

要注意,dockerfile要和fastbins.c放在同一个目录下。

建立镜像

docker build -t my_first_docker .

这句指令要在dockerfile所在的文件夹下使用。

my_first_docker是生成镜像的名称

.表示要在当前文件夹下找dockerfile

因此dockerfile一定要命名成dockerfile。

成功之后,现在的我们就已经有了镜像了,之后的操作都是基于这个镜像的,多次调试的时候也不会需要我们从头再来。

如何查看我们生成的所有镜像?

docker images

这句指令可以查看所有镜像

如何删除镜像?

docker rmi images_id

生成容器

https://www.bilibili.com/video/BV1e64y1F7pJ/?spm_id_from=333.337.search-card.all.click&vd_source=a85daf8eb54f32264d9f6976d087fe98

这个视频讲了很多有用的东西。

现在我们已经有了镜像,生成容器就可以了。

docker run -it  my_first_docker

这里的my_first_docker就是我们镜像的名字。

之后就会直接进入我们创建的容器的shell。

之后的操作都需要直到容器的id。我们可以这样查看

(新开一个shell)

docker ps 
docker ps -a

第一个指令显示正在运行的容器,第二个指令会显示所有容器,包括已经停止的容器。

对于我来说,接下来需要把docker中我生成的fastbin转移到本机上来,还需要进行换库,因此需要libc-2.23.so和ld-2.23.so。

docker cp e1r7y6:/app/fastbin /ctf

其中这个e1r7y6是容器的id,/app/fastbin是docker中的文件路径,/ctf是我本机的路径。

还要转移两个库文件。

docker cp e1r7y6:/lib/x86-64-linux-gnu/libc-2.23.so /ctf
docker cp e1r7y6:/lib/x86-64-linux-gnu/ld-2.23.so /ctf

容器的工作已经完成了,现在需要销毁容器。

首先,在已经进入容器的shell里

exit

这样容器就停止运行了

之后需要移除容器

docker rm e1r7y6

现在docker的使用已经可以满足我的需求了。

不过对于我来说,之后还需要换库。

#patchelf --set-interpreter ./ld-2.23.so ./libc-2.23.so
patchelf --set-interpreter ./ld-2.23.so ./fastbin
patchelf --replace-needed libc.so.6 ./libc-2.23.so ./fastbin

以前我换库都是这三条语句都用,但是这次换库失败了,通过询问pwn爹,怀疑第一句话可能patchelf出现了bug,损坏了库文件,但是只用后两条就可以了。