基于 Xilinx ZC706 开发板的DMA攻击工具环境搭建过程。
实现与主机PCIe总线的TLP数据包收发、解析、物理内存读取等功能。
Vivado安装
在ubuntu下安装Vivado 2019.2。
解压安装包文件,运行sudo ./xsetup
进行安装。
选择Vivado HL. Design Edition版本,安装目录选择默认的,最好不要更改。
在Vivado License Manager中选load License导入证书文件: LICENSE FOR ISE VIVADO.lic
安装Petalinux
安装依赖库:
$ sudo apt-get install tofrodos gawk xvfb git libncurses5-dev tftpd zlib1g-dev zlib1g-dev:i386 libssl-dev flex bison chrpath socat autoconf libtool texinfo gcc-multilib libsdl1.2-dev libglib2.0-dev screen pax xterm diffstat build-essential
下载Petalinux。
配置安装目录及权限:
$ sudo -s
$ mkdir -p /opt/pkg/petalinux
$ chown edvison /opt/pkg/
$ chgrp edvison /opt/pkg/
$ chgrp edvison /opt/pkg/petalinux/
$ chown edvison /opt/pkg/petalinux/
$ exit
安装petalinux:
$ sudo chmod +x petalinux-v2019.2-final-installer.run
$ ./petalinux-v2019.2-final-installer.run /opt/pkg/petalinux/
设置环境变量:
$ export PATH=$PATH:/opt/pkg/petalinux/tools/xsct/bin/
Xilinx Zynq DMA攻击项目准备
获取项目:
$ git clone https://github.com/Cr4sh/zc_pcie_dma
进入vivado安装目录,配置环境变量:
$ cd /tools/Xilinx/Vivado/2019.2
$ source settings64.sh
- 进入zc_pcie_dma项目目录下,运行
make project
从zx_pcie_dma.tcl
模板创建Vivado项目。
- 运行
vivado
,Open project >
,打开~/zc_pcie_dma/zc_pcie_dma/zc_pcie_dma.xpr
,执行Run Synthesis
,等待右上角的后台运行完成后,执行Run implementation
,完成后执行generate the bitstream
。点File --> Export --> Export Hardware..
导出到zc_pcie_dma.xsa
文件中。 - 运行
make bin
- 运行:
$ git submodule init && git submodule update
$ cd devicetree/my_dtg/
$ git clone https://github.com/Xilinx/device-tree-xlnx
$ cd device-tree-xlnx
$ git checkout xilinx-v2019.2
$ git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git
$ sudo apt install flex bison
$ cd dtc
$ make
$ export PATH=$PATH:$(pwd)
- 运行
make dts_gen
生成设备树源码 - 打开
devicetree/my_dts/pl.dtsi
文件,把所有的compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a"
和compatible = "xlnx,axi-gpio-2.0", "xlnx,xps-gpio-1.00.a"
都替换成compatible = "generic-uio"
。 - 运行
make dts_build
,生成设备树二进制文件。
Buildroot构建环境
使用 Buildroot 来交叉编译 Linux 内核和 uBoot 引导加载程序。
安装Buildroot:
$ wget https://buildroot.org/downloads/buildroot-2021.02.tar.gz
$ tar -xpvf buildroot-2021.02.tar.gz
$ cd ~/buildroot-2021.02
安装依赖:
$ sudo apt-get install libncurses-dev
使用ZC706开发板的标准配置文件初始化构建环境:
$ make zynq_zc706_defconfig
$ echo “BR2_PACKAGE_ZC_DMA_MEM=y” >> .config
配置linux内核:
$ make linux-menuconfig
开启下面的选项:
Device Drivers-->
GPIO Support-->
Memory mapped GPIO drivers-->
[*]Xilinx GPIO support
[*]Xilinx Zynq GPIO support
Device Drivers-->
Userspace I/O drivers
kernel hacking-->
[*] Filter access to /dev/mem
[*] Filter I/O access to /dev/mem
Enable loadable module support-->
[*] Forced module loading
[*] Module unloading [*] Forced module unloading [*] Module versioning support
设置br2外部树zc_dma_mem
:
$ make BR2_EXTERNAL="~/zc_pcie_dma/kernel/zc_dma_mem" menuconfig
开启选项External options -> zc_dma_mem
。
设置hostname,root密码:
System configuration -->
System hostname
System banner
Root password
编译内核、bootloder、zc_dma_mem.ko
内核模块和文件系统:
$ make
如报错cannot stat 'package/busybox/S02sysctl': No such file or directory
,添加软链接:
$ ln -s S02sysctl ../procps-ng/S02sysctl
生成zc_dma_mem.ko
位于:
~/buildroot-2021.02/output/build/zc_dma_mem-1.0
~/buildroot-2021.02/output/target/lib/modules/4.9.0-xilinx/extra
更改内核版本方法
安装buildroot 2020.02版本:
$ wget https://buildroot.org/downloads/buildroot-2020.02.tar.gz
$ tar -xpvf buildroot-2020.02.tar.gz
$ cd ~/buildroot-2020.02
这里 可查找所需的内核包。
要把内核版本改为4.0,则需要linux-xilinx-v2015.4.tar.gz版本的包,内核版本号可在包里的Makefile中查看:
找到需要的内核包后,运行make menuconfig
,更改下面的选项:
Toolchain -->
Custom kernel headers series (4.0.x) --->
GCC compiler Version (gcc 5.x) --->
kernel -->
($(call github,Xilinx,linux-xlnx,xilinx-v2015.4)/linux-xilinx-v2015.4.tar.gz) URL of custom kernel tarball
再次运行make linux-menuconfig
,即可下载并配置更改的内核版本。
设置Fat32分区引导SD卡
复制需要的文件到SD目录下:
$ mkdir -p output/images/sd
$ cp output/images/boot.bin output/images/sd
$ cp output/images/uImage output/images/sd
$ cp output/images/u-boot.img output/images/sd/u-boot.img
$ cp output/images/rootfs.cpio.uboot output/images/sd/uramdisk.image.gz
$ cp ~/zc_pcie_dma/devicetree.dtb output/images/sd
$ cp ~/zc_pcie_dma/zc_pcie_dma.bit output/images/sd
创建uEnv.txt文件:
$ gedit uEnv.txt
bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=fat rootwait devtmpfs.mount=0 mem=992M uio_pdrv_genirq.of_id=generic-uio
load_fpga=fatload mmc 0 0x4000000 zc_pcie_dma.bit && fpga loadb 0 0x4000000 13321511
load_image=fatload mmc 0 ${kernel_load_address} ${kernel_image} && fatload mmc 0 ${devicetree_load_address} devicetree.dtb
uenvcmd=echo Copying Linux from SD to RAM... && mmcinfo && run load_fpga && run load_image && bootm ${kernel_load_address} - ${devicetree_load_address}
格式化SD卡,类型为FAT:
将sd目录下所有文件复制到sd卡:
$ cd ~/buildroot-2021.02/output/images/sd
$ sudo cp -a * /media/edvison/boot
弹出SD卡:
$ sudo eject /dev/sdc
sd卡插回zc706,连接USB串口调试线,SW11设置为00110(SD卡引导模式):
主机开始监听:
$ sudo pip install pyserial
$ sudo miniterm.py --eol LF --raw /dev/ttyUSB0 115200
———————————————-分界线———————————————————–
设置ext4分区引导SD卡
下面是构建ubuntu文件系统方法
安装qemu用户空间模拟:
$ sudo apt install qemu-user-static
$ sudo apt install qemu-user-binfmt
检查ARM用户空间模拟配置:
$ cat /proc/sys/fs/binfmt_misc/qemu-arm
enabled
interpreter /usr/bin/qemu-arm-static
flags: OC
offset 0
magic 7f454c4601010100000000000000000002002800
mask ffffffffffffff00fffffffffffffffffeffffff
依赖包安装:
$ sudo apt-get install gawk wget git git-core diffstat unzip texinfo gcc-multilib build-essential \
chrpath socat cpio python python3 python3-pip python3-pexpect \
xz-utils debianutils iputils-ping libsdl1.2-dev xterm \
language-pack-en coreutils texi2html file docbook-utils \
python-pysqlite2 help2man desktop-file-utils \
libgl1-mesa-dev libglu1-mesa-dev mercurial autoconf automake \
groff curl lzop asciidoc u-boot-tools libreoffice-writer \
sshpass ssh-askpass zip xz-utils kpartx vim screen bison flex \
debootstrap qemu-system-arm qemu-user-static libssl-dev
交叉编译器安装:
$ sudo apt-get install gcc-arm-linux-gnueabi
使用debootstrap获取ubuntu 20.04文件系统:
$ sudo apt install debootstrap
$ sudo debootstrap --arch armhf --verbose --foreign focal ~/debootstrap_focal_armhf
准备chroot环境:
$ sudo cp /usr/bin/qemu-arm-static debootstrap_focal_armhf/usr/bin
$ sudo chroot debootstrap_focal_armhf /bin/bash
运行第二阶段
$ /debootstrap/debootstrap --second-stage
基本配置,创建/etc/fstab
:
$ echo "/dev/mmcblk0p1 /boot vfat umask=0077 0 1" >> /etc/fstab
$ echo "/dev/mmcblk0p2 /ext4 relatime,errors=remount-ro 0 1" >> /etc/fstab
配置主机名:
$ cat /etc/hostname
zc706
$ cat /etc/hosts
127.0.0.1 localhost zc706
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
设置root密码:
$ passwd
创建非root用户添加到sudo组中
$ adduser edvison
$ adduser edvison sudo
添加apt下载源:
$ cat /etc/apt/sources.list
deb http://ports.ubuntu.com/ubuntu-ports focal main
安装vim:
$ sudo apt install vim
配置网络:
$ sudo apt install network-manager network-manager-pptp network-manager-gnome network-manager-pptp-gnome
$ sudo apt install net-tools
报错解决:
Ubuntu下locale命令路径无法找到问题解决方法:Cannot set LC_CTYPE to default locale: No such file or directory
退出chroot环境:
$ exit
擦除SD卡内容:
$ dd if=/dev/zero of=/dev/sdc bs=1024
运行fdisk创建两个分区,256MB的引导分区和存放根文件系统的分区:
$ sudo fdisk /dev/sdc
欢迎使用 fdisk (util-linux 2.32)。
更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。
设备不包含可识别的分区表。
创建了一个磁盘标识符为 0x7f900099 的新 DOS 磁盘标签。
命令(输入 m 获取帮助): p
Disk /dev/sdc:14.9 GiB,16005464064 字节,31260672 个扇区
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x7f900099
命令(输入 m 获取帮助): n
分区类型
p 主分区 (0个主分区,0个扩展分区,4空闲)
e 扩展分区 (逻辑分区容器)
选择 (默认 p): p
分区号 (1-4, 默认 1): 1
第一个扇区 (2048-31260671, 默认 2048): 2048
上个扇区,+sectors 或 +size{K,M,G,T,P} (2048-31260671, 默认 31260671): +256M
创建了一个新分区 1,类型为“Linux”,大小为 256 MiB。
命令(输入 m 获取帮助): t
已选择分区 1
Hex 代码(输入 L 列出所有代码): c
已将分区“Linux”的类型更改为“W95 FAT32 (LBA)”。
命令(输入 m 获取帮助): n
分区类型
p 主分区 (1个主分区,0个扩展分区,3空闲)
e 扩展分区 (逻辑分区容器)
选择 (默认 p): p
分区号 (2-4, 默认 2): 2
第一个扇区 (526336-31260671, 默认 526336): 526336
上个扇区,+sectors 或 +size{K,M,G,T,P} (526336-31260671, 默认 31260671): 31116287
创建了一个新分区 2,类型为“Linux”,大小为 14.6 GiB。
命令(输入 m 获取帮助): w
分区表已调整。
The kernel still uses the old partitions. The new table will be used at the next reboot.
正在同步磁盘。
给引导分区创建FAT32文件系统:
$ sudo mkfs.vfat -F 32 -n BOOT /dev/sdc1
mkfs.fat 4.1 (2017-01-24)
给根分区创建ext4文件系统:
$ sudo mkfs.ext4 /dev/sdc2
mke2fs 1.44.4 (18-Aug-2018)
创建含有 3823744 个块(每块 4k)和 956592 个inode的文件系统
文件系统UUID:a02929a4-bc1b-4591-999b-7d4812b95edc
超级块的备份存储于下列块:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
正在分配组表: 完成
正在写入inode表: 完成
创建日志(16384 个块) 完成
写入超级块和文件系统账户统计信息:已完成
挂载引导分区并复制文件:
$ sudo mkdir /mnt/tmp
$ sudo mount /dev/sdc1 /mnt/tmp
$ sudo cp ~/buildroot-2021.02/output/images/boot.bin /mnt/tmp
$ sudo cp ~/buildroot-2021.02/output/images/u-boot.img /mnt/tmp
$ sudo cp ~/buildroot-2021.02/output/images/uImage /mnt/tmp
$ sudo cp ~/zc_pcie_dma/uEnv.txt /mnt/tmp
$ sudo cp ~/zc_pcie_dma/devicetree.dtb /mnt/tmp
$ sudo cp ~/zc_pcie_dma/zc_pcie_dma.bit /mnt/tmp
$ sudo umount /mnt/tmp
挂载根分区,复制根文件系统和内核模块:
$ sudo mount /dev/sdc2 /mnt/tmp
$ sudo cp -a ~/debootstrap_focal_armhf/. /mnt/tmp
$ sudo cp -a ~/buildroot-2021.02/output/target/lib/modules /mnt/tmp/lib
$ sudo umount /mnt/tmp
弹出SD卡:
$ sudo eject /dev/sdc
sd卡插回zc706,连接USB串口调试线,SW11设置为00110(SD卡引导模式),插上网线。
主机开始监听
$ sudo miniterm.py --eol LF --raw /dev/ttyUSB0 115200
自动加载内核失败,进入u-boot命令行,手动加载内核:
zynq> run load_image
zynq> bootm ${kernel_load_address} - ${devicetree_load_address}
成功加载ubuntu 20.04:
zc706 ubuntu环境配置
配置网络:
$ sudo ifconfig eth0 up
$ sudo dhclient eth0
$ sudo service network-manager restart
安装python2.7和相关依赖库:
$ sudo apt install software-properties-common
$ sudo add-apt-repository universe
$ sudo apt install python2
$ sudo apt install python-dev python-setuptools libssl-dev
安装pip:
$ sudo apt install curl
$ curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
$ sudo python2 get-pip.py
安装gcc:
$ sudo apt install gcc-9 gcc-9-multilib
安装numpy包:
$ sudo pip install numpy
获取s6_pcie_microblaze项目:
$ git clone https://github.com/Cr4sh/s6_pcie_microblaze.git
近期评论