工具使用&常用指令 0x00 qemu+IDA+ARM+Windows 指令:
1 2 3 4 5 6 # 1. 运行 raspberry qemu-system-arm.exe -M versatilepb -cpu arm1176 -m 256 -drive "file=./arm/2020-02-13-raspbian-buster.img,if=none,index=0,media=disk,format=raw,id=disk0" -device "virtio-blk-pci,drive=disk0,disable-modern=on,disable-legacy=off" -net "user,hostfwd=tcp::5022-:22,hostfwd=tcp::23946-:23946" -dtb ./arm/versatile-pb-buster.dtb -kernel ./arm/kernel-qemu-5.4.51-buster -append "root=/dev/vda2 panic=1" -no-reboot -net nic # 可以 ssh 连接树莓派, ssh pi@127.0.0.1 # 2. 运行 ida72 的 armlinux_server ./armlinux_server # 3. 使用 ida72 来连接
引用:
[1] https://cloud.tencent.com/developer/article/1867083
0x01 IDA的使用 参考链接1:https://xz.aliyun.com/t/4205
参考链接2:https://leeyuxun.github.io/IDA%E5%9F%BA%E7%A1%80%E5%8A%9F%E8%83%BD%E6%80%BB%E7%BB%93.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 R //数字转字符快捷键 "Edit"–"Patch program"–"Assemble" 修改汇编指令 X //查看引用 P //创建函数 E //选中某些数据重新编码 tab 键 //伪代码与汇编来回切换 空格键 //汇编与控制流图切换 ALT+B //搜索字符 byte not defined:from idc_bc695 import * A //将数据转换为字符串 f5 //一键反汇编 esc //回退键,能够倒回上一部操作的视图(只有在反汇编窗口才是这个作用,如果是在其他窗口按下esc,会关闭该窗口) shift+f12 //可以打开string窗口,一键找出所有的字符串,右击setup,还能对窗口的属性进行设置 ctrl+w //保存ida数据库 ctrl+s //选择某个数据段,直接进行跳转 ctrl+鼠标滚轮 //能够调节流程视图的大小 X //对着某个函数、变量按该快捷键,可以查看它的交叉引用 G //直接跳转到某个地址 N //更改变量的名称 Y //更改变量的类型 / //在反编译后伪代码的界面中写下注释 \ //在反编译后伪代码的界面中隐藏/显示变量和函数的类型描述,有时候变量特别多的时候隐藏掉类型描述看起来会轻松很多 ; //在反汇编后的界面中写下注释 ctrl+shift+w //拍摄IDA快照 U //undefine,取消定义函数、代码、数据的定义 H //在数字上按下H键或者右键进行选择,可以将数字转化为十进制 B //转换为二进制也是同理。 c //将数据段转化成代码 K //将数据解释为栈变量 M //解释为枚举成员 O //解释地址为数据段偏移量,用于字符串标号 T //解释数据为结构体成员 Y //修改参数类型 D //将字节变为数据 O //指定操作数是地址还是数据 Shift+F5 //添加sig文件 Alt+F9 //执行直到返回到用户代码段 Alt+F7 //加载python script插件 选中+options+setdatatypes //将byte数据变为4字节数据等 shift+E //将二进制数据导出为不同的格式数据,快捷键 enter //跟进函数实现 Alt+Q //将数据变为某结构体 Alt+P //修正栈帧
查看堆栈是否平衡:”Options”–”General”–”Disassembly”-“Stack pointer”。
数据转换:Q: 十六进制、H:十进制、R: 字符、A:普通字符串。
__int64 v8; *(_BYTE *)(v8 + i)
变为v8[i]
:将__int64 v8;
变为char *v8;
即可。
IDA->edit->Patch program->Assemble修改,然后 IDA->edit->Patch program->Apply patches to input file即可得到修改后的文件。patch之后调试可能与patch后的程序不同,所以记得要File->Load File->Reload the input file。
插入结构体:View -> Open subviews -> Local Types -> Insert new。
插入 emum,类似于:
1 2 3 4 5 6 7 8 const ( EncModeAuto = 0 EncModeNone encMode = 1 EncModeNumeric = 2 EncModeAlphanumeric = 4 EncModeByte = 8 EncModeJP = 16 )
View -> Open subviews -> Enums -> Insert new。之后使用 Add enum member 添加值。
idapython使用:https://lingze.xyz/book/reverse/ida_python/
创建新的segment:Edit->Segments->CreateSegment
添加结构体的几种姿势:链接
dump内存:
1 2 3 4 5 6 7 8 import sysimport idaapistart_address, data_length = xx, xx dump_file = xx data = idaapi.dbg_read_memory(start_address, data_length) fp = open (dump_file, 'wb' ) fp.write(data) fp.close()
ida中,正偏移为参数,负偏移为局部变量。如下所示:
创建数组*
,如下所示,在var_10上按*
:
窗口还原:windows->Reset Desktop
。
将数值变为常量:ida提供了命名常量目录,如果目录中不存在,可以手动添加库,进而添加常量(view->open subviews->type libraries
)。
插件 keypatch: 修改x86、x64、arm等架构的代码。
findcrypt3: 查找使用的加密算法。
Go_parser: alt+F7执行此脚本。
ida+qiling 以Qiling-study
的challenge1
脚本为例,加入ql.debugger = 'gdb:0.0.0.0:12346'
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from qiling import *def challenge1 (ql ): ql.mem.map (0x1000 , 0x1000 , info = '[challenge1]' ) ql.mem.write(0x1337 , ql.pack16(1337 )) if __name__ == '__main__' : path = ["./qiling/examples/rootfs/x8664_linux/qilinglab-x86_64" ] rootfs = "./qiling/examples/rootfs/x8664_linux" ql = Qiling(path, rootfs) challenge1(ql) ql.debugger = 'gdb:0.0.0.0:12346' ql.run()
运行此脚本,并设置ida
:
注意,192.167.75.138
为虚拟机地址,要调试的文件路径必须在..../rootfs/x8664_linux/filename
中(如果调试的是x64
文件的话)。
ida+gdb 虚拟机中运行:
1 sudo gdbserver *:7777 program_name
本地ida配置为gdb debugger即可。
0x02 x64dbg 1 2 3 4 5 6 7 8 9 F7 //步进 alt + e //进入符号栏 F8 //步过 F9 //运行 Ctrl+F9 //运行到返回 F2 //打断点 Ctrl+G //跳到某个位置 space //修改本行指令 ctrl+P+修补文件 //保存patch后的文件
scylla插件步骤:
ida与x64gdb地址对齐:
使用alt+e进入符号栏,看x64gdb的程序基址,然后调整ida为 edit->segments->rebase program。
0x03 Ollydbg的使用 1 2 3 4 5 6 7 8 9 Ctrl + F2 // 重启调试器 F12 // 让程序暂停 SHIFT + F4 // 设置条件记录断点 F2 // 断点 F3 // 加载可执行程序 F4 // 运行到光标处 F5 // 缩小还原当前窗口 Alt + F9 // 执行到用户代码处,用户跳出系统函数 Ctrl + G // 跳到16进制地址处
(1)View -> Executable Modules
,点击要定位的dll。
(2)Ctrl+N,之后输入函数名。
0x04 Windbg使用 [2] https://learn.microsoft.com/zh-cn/windows-hardware/drivers/debugger/getting-started-with-windbg
很全面:https://blog.csdn.net/mofabang/article/details/49678729
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 ctrl + e // 加载程序 .sympath srv* // 符号搜索路径指示 WinDbg 查找符号 (PDB) 文件的位置。 调试器需要符号文件来获取有关代码模块的信息,例如函数名称和变量名称。 .reload // 指示 WinDbg 执行初始搜索以查找和加载符号文件。 x notepad!* // 查看notepad.exe模块的符号 x notepad!wWin* // 查看包含 main的 notepad.exe 模块中的符号 bu notepad!wWinMain // 在 notepad!wWinMain 放置断点 bl // 输出断点列表 bc breakpoint // 删除断点 g // 运行进程 u // 显示反汇编代码 d // 显示内存数据 e // 修改内存数据 lm // 查看进程中当前加载的代码模块的列表 k // 查看堆栈跟踪。 ~ // 查看进程中所有线程的列表 ~0s // 查看线程 0 的堆栈跟踪 !analyze -v // 自动分析程序崩溃原因 dt nt!_FILE_OBJECT // 检查 _FILE_OBJECT 模块中的 nt 数据类型 x nt!*CreateProcess* // 检查模块中的 nt 一些符号 !process 0 0 // 查看所有进程的列表 !process 进程地址 2 // 显示此进程的所有线程 !thread 线程地址 // 显示此线程的信息 !db 与 db // 一个是读物理地址,一个是读虚拟地址 p // 单步执行 pa // 执行到指定地址 pt // 执行到返回指令 pc // 执行到call指令 gu // 执行到函数返回 dq rsp // dq rsp 命令表示显示当前线程d的栈顶地址(即堆栈指针 rsp 的值)指向的 8 字节数据。 lm // 查看模块数据 .sympath // 查看当前符号 u $ip L10 // 查看$ip处的10条汇编指令 r rcx=1 // 修改rcx=1 g $exentry // 执行到入口代码 rdmsr 3ah // 读取标号为 3a 的 MSR 寄存器 dv /t // 查看局部变量 x <ModuleName>!<VariableName> // 查看全局变量,使用 lm 查找所有模块 dps addr // 查看堆栈内容 !vtop cr3_addr vitual_addr // 将虚拟地址转为物理地址 // 设置并加载符号 .sympath SRV*c:\mySymbols*http://msdl.microsoft.com/download/symbols .reload // .ecxr 是一个调试命令,用于将当前线程的上下文环境设置为异常发生时的线程上下文。该命令通常用于在调试 Windows 应用程序时分析异常调用栈和异常发生时的线程上下文信息。 .ecxr // 将地址范围 0x1000 到 0x2000 内的所有数据保存到文件 data.bin 中 .writemem data.bin 0x1000 0x2000
注:
堆栈跟踪。堆栈跟踪(stack trace)是一种调试技术,用于追踪程序在执行过程中的调用链路。在程序执行过程中,每当一个函数或子程序被调用时,CPU会将当前函数的返回地址和一些其他信息(如函数参数、局部变量等)保存在堆栈中。这些信息构成了一个堆栈帧(stack frame)。堆栈跟踪就是通过分析堆栈中保存的堆栈帧信息,来确定程序执行过程中的调用链路。
windbg+win7双机调试 链接:https://blog.csdn.net/sagittarius_warrior/article/details/51305046
主机启动windbg时:
1 windbg.exe -b -k com:pipe,port=\\.\pipe\com_1,resets=0
0x05 qemu使用 risc_v环境搭建 qemu+risc_v+linux
环境搭建:https://bbs.kanxue.com/thread-272645.htm
命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 qemu-system-riscv64 \ -machine virt \ -cpu rv64 \ -m 1G \ -device virtio-net-device,netdev=net \ -netdev user,id=net,hostfwd=tcp::2222-:22 \ -device virtio-blk-device,drive=hd \ -drive file=./Image/artifacts/overlay.qcow2,if=none,id=hd \ -bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.elf \ -kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \ -append "root=LABEL=rootfs console=ttyS0" \ -nographic \ -fsdev local,security_model=passthrough,id=fsdev0,path=./share \ -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare
命令解释:
1 2 3 4 5 6 7 8 9 10 11 -cpu rv64 \\ RISC-V 64位cpu -m 1G \\ 为客户机分配1GB运行内存 -netdev user,id=net,hostfwd=tcp::2222-:22 \\ 转发22端口到localhost:2222。这样可以在外面远程SSH连接 -bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.elf \\ 指纹识别,人脸识别等,没啥用 -append "root=LABEL=rootfs console=ttyS0" \\ 内核启动参数,默认就好 -kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \\ 设置嵌入式系统引导程序 -nographic \\ 禁用图形输出 \\ 宿主机和客户机之间创建一个普通的文件夹 -fsdev local,security_model=passthrough,id=fsdev0,path=./share \ -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare
还需要在客户机(risc_v)上执行如下脚本
1 2 3 4 SHARED_FOLDER="/mnt/share" # Create shared folder mkdir ${SHARED_FOLDER} mount -t 9p -o trans=virtio,version=9p2000.L hostshare ${SHARED_FOLDER}
上述搭建流程有点问题:好多文件找不到,例如/usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.elf
、/usr/lib/u-boot/qemu-riscv64_smode/uboot.elf
等。
因此,又找了一篇文章https://risc-v-getting-started-guide.readthedocs.io/en/latest/linux-qemu.html
,根据它搭建环境。https://zhuanlan.zhihu.com/p/258394849
写的也不错,安装流程比较全 。
安装之后,设置共享文件夹,参考链接如下:
1 2 http://pwn4.fun/2020/05/27/Qemu%E8%99%9A%E6%8B%9F%E6%9C%BA%E4%B8%8E%E5%AE%BF%E4%B8%BB%E6%9C%BA%E4%B9%8B%E9%97%B4%E6%96%87%E4%BB%B6%E4%BC%A0%E8%BE%93/ https://blog.csdn.net/jcf147/article/details/124477915
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1. 创建img文件 dd if=/dev/zero of=$PWD/share.img bs=1M count=1000 2. 格式化文件 mkfs.ext4 $PWD/share.img 3. 在宿主机上创建要共享的文件夹并挂载到share.img mkdir /tmp/share sudo mount -o loop $PWD/share.img /tmp/share 4. 向/tmp/share中放文件 5. 启动qemu客户机,加一块硬盘 -drive file=$PWD/share.img,if=virtio 全部的命令为: qemu-system-riscv64 -M virt -m 256M -nographic -kernel linux/arch/riscv/boot/Image -drive file=rootfs.img,format=raw,id=hd0 -drive file=share.img,if=virtio -device virtio-blk-device,drive=hd0 -append "root=/dev/vda rw console=ttyS0" 6. 在客户机中将硬盘挂载到/share文件夹 mount -t ext4 /dev/vda(或者是/dev/vdb) /share 该方法的缺点:宿主机和虚拟机文件传输不能实时进行,如果要传输新文件,需要重启虚拟机。
虚拟机退出:CTRL+A、X
0x06 mumu+jeb调试 1 2 3 4 5 6 7 8 9 10 11 12 13 jeb 常用指令 n //重命名 Enter //双击跟踪 Esc //返回 Ctrl+Enter//前进 H //帮助 I //条目信息 X //交叉引用,Ctrl + X 源码交叉引用 ;or C //注释 B //改变进制数 Tab //反编译 ctrl+B //打断点
1 2 3 4 5 6 7 8 9 10 11 adb 使用 adb kill-server // 终止正在运行的 ADB 服务器进程 adb connect 127.0.0.1:7555 // 连接到 mumu adb -s 4TIN8TZ9YD5DPFKV shell // 打开设备4TIN8TZ9YD5DPFKV的一个shell,USB链接 adb -s 4TIN8TZ9YD5DPFKV push myfile /data/local/tmp // 向设备4TIN8TZ9YD5DPFKV发送文件 adb install -r game_signed.apk // 安装程序game_signed.apk adb devices // 查看当前连接的设备 adb root // 以 root 权限运行 adb adb shell / exit // 进入/退出 shell adb shell pm list packages // 列出手机装的所有app 的包名
[1] https://www.jianshu.com/p/919a966843c4
[2] https://crifan.github.io/android_re_repack_apk/website/repack_process/redo_sign.html
1 apktool d libdroid_fixed.apk -o unzip // 将libdroid_fixed.apk反编译到unzip文件夹中
更改apk反编译的文件后(android:debuggable="true"
),重新编译成apk,并进行重新签名。
重新编译apk如下:
1 apktool b unzip -o 11.apk
首先,生成keystone文件:
1 keytool -genkeypair -v -keystore thunderRepack.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias thunderRepack
之后,用jarsigner对apk签名:
1 jarsigner -verbose -digestalg SHA1 -sigalg SHA1withRSA -keystore thunderRepack.keystore -signedjar 签名后的文件 要签名的文件 前面指定的alias别名
用zipalign给重新打包后的apk去对齐:
1 zipalign 4 对齐前apk 对齐后apk
0x08 mumu+ida调试 [1] https://chan-shaw.github.io/2020/04/05/IDA-%E5%8A%A8%E6%80%81%E8%B0%83%E8%AF%95/
0x09 frida使用 Frida是以python为载体,注入Javascript作为Android中执行代码 的一款Hook框架。
客户端安装:
1 pip3 install frida-tools
服务端安装:在网站https://github.com/frida/frida/releases?page=2
上下载对应的frida-server版本(注意模拟器一定要下载x86版本 ),并使用adb推送到mumu上,并添加运行权限,并运行./frida-server-16.0.2-android-x86_64
1 2 adb push frida-server-16.0.2-android-arm /data/local/tmp ./frida-server-16.0.2-android-x86_64
客户端开启端口转发:
1 2 adb forward tcp:27042 tcp:27042 adb forward tcp:27043 tcp:27043
使用frida-ps -R
查看手机端进程,显示成功。这样frida就配置好了。
frida gadget使用(无需root):https://blog.csdn.net/helloworlddm/article/details/109680109
1 frida -U com.android.settings -l hello.js // 以attach模式运行Hello.js脚本
frida读取文件:https://bbs.kanxue.com/thread-278134.htm
0x10 win7搭建ftp [1] https://blog.csdn.net/m0_73792568/article/details/128624878
win7禁用签名:
1 2 bcdedit.exe -set loadoptions DDISABLE_INTEGRITY_CHECKS bcdedit /set testsigning on
0x11 OP-TEE环境搭建(qemu v7) (1)在ubuntu20.04上运行以下命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 sudo apt install \ android-tools-adb \ android-tools-fastboot \ autoconf \ automake \ bc \ bison \ build-essential \ ccache \ cscope \ curl \ device-tree-compiler \ expect \ flex \ ftp-upload \ gdisk \ iasl \ libattr1-dev \ libcap-dev \ libfdt-dev \ libftdi-dev \ libglib2.0-dev \ libgmp3-dev \ libhidapi-dev \ libmpc-dev \ libncurses5-dev \ libpixman-1-dev \ libssl-dev \ libtool \ make \ mtools \ netcat \ ninja-build \ python3-crypto \ python3-cryptography \ python3-pip \ python3-pyelftools \ python3-serial \ rsync \ unzip \ uuid-dev \ xdg-utils \ xterm \ xz-utils \ zlib1g-dev
(2)运行如下命令:
1 2 3 4 5 6 7 8 9 10 mkdir optee cd optee // 下载仓库并进行同步,这一步可能有问题,见 https://blog.csdn.net/Thanksgining/article/details/108848825 repo init -u https://github.com/OP-TEE/manifest.git repo sync cd build make toolchains make run // 会打开两个终端,normal world与secure world c // 进入normal world的控制台
(3)此时会进入normal world
与secure world
的两个终端,在normal world
终端内运行xtest
与optee_example_hello_world
来测试环境是否搭建完成。
0x12 搭建qemu-armv7环境 (1)下载buildroot 。Buildroot是一个简单、高效、易于使用的工具,用于通过交叉编译生成嵌入式Linux系统。
(2)进入buildroot目录下,运行下面3条指令(最好不要在conda
环境中运行):
1 2 3 ls configs/qemu_arm_ve* // 列出所有以 qemu_arm_ve 开头的配置文件 make qemu_arm_vexpress_defconfig // 用 QEMU ARM VExpress 的默认配置文件,生成 .config 文件 make // 构建 Buildroot 工具链和目标系统,生成交叉编译工具链和目标系统所需的文件和镜像
(3)下载qemu-6.2.0.tar.bz2
,并解压。
(4)进入此目录,运行下面3条指令:
1 2 3 cd qemu-6.2.0/ mkdir build cd build/
(5)下载依赖包:
1 sudo apt-get install ninja-build autoconf libpixman-1-dev libpixman-1-0 libsdl1.2-dev libtool libglib2.0-dev
(6)配置qemu
编译环境、进行编译并安装:
1 2 3 ../configure --target-list=arm-softmmu --audio-drv-list= make -j8 make install
(7)运行qemu:
1 2 3 4 5 6 7 8 qemu-system-arm -M vexpress-a9 -m 512M -kernel /home/xxxx/buildroot-2022.02.6/output/images/zImage -dtb /home/xxxx/buildroot-2022.02.6/output/images/vexpress-v2p-ca9.dtb -nographic -append "root=/dev/mmcblk0 console=ttyAMA0" -sd /home/zhao/buildroot-2022.02.6/output/images/rootfs.ext2
qemu-system-arm
:要启动的 QEMU 系统镜像
-M vexpress-a9
:模拟的硬件平台为 vexpress-a9,即基于 ARM Cortex-A9 处理器的开发板
-m 512M
:512MB 的内存
-kernel /home/xxxx/buildroot-2022.02.6/output/images/zImage
:要加载的 Linux 内核映像文件路径
-dtb /home/xxxx/buildroot-2022.02.6/output/images/vexpress-v2p-ca9.dtb
:要加载的设备树二进制文件路径,用于描述模拟硬件的设备信息
-nographic
:
-append "root=/dev/mmcblk0 console=ttyAMA0"
:要传递给内核的启动参数,其中 root=/dev/mmcblk0
表示根文件系统所在的设备为 MMC 卡,console=ttyAMA0
表示使用串口作为控制台输出。
-sd /home/xxx/buildroot-2022.02.6/output/images/rootfs.ext2
:要加载的根文件系统映像文件路径,用于提供虚拟机的文件系统。
(8)退出qemu环境:ctrl+A,X
0x13 搭建qemu-aarch64环境 补充 qemu-system-arm是用于模拟ARMv7、ARMv6、ARMv5等32位 ARM架构的处理器的QEMU工具。它可以模拟一系列ARM SoC(System-on-Chip)芯片,例如Versatile,RealView,Integrator等,也可以模拟一些开发板,例如Raspberry Pi,BeagleBoard等。
qemu-system-aarch64是用于模拟ARMv8-A架构的64位 处理器的QEMU工具。它可以模拟一系列ARM SoC芯片,例如Juno,Foundation,Virt等,也可以模拟一些开发板,例如HiKey970,Xilinx ZCU102等。
步骤 (1)安装qemu
。(感觉安装了好多次qemu..)安装完之后,可以qemu-system
试着补全,我们要的是qemu-system-aarch64
。
1 apt-get install qemu qemu-system qemu-user qemu-system-arm
(2)安装aarch64
交叉编译工具。具体看链接
1 2 3 sudo apt-get install gcc-10-aarch64-linux-gnu // 重命名为aarch64-linux-gnu-gcc-10 sudo mv /usr/bin/aarch64-linux-gnu-gcc-10 /usr/bin/aarch64-linux-gnu-gcc
(3)制作根文件系统。下载busybox源码,并指定工具链:
1 2 export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu-
配置(静态编译build static binary):
编译安装:
之后的步骤请看链接 。
(4)内核源码编译。看链接 。
(5)运行qemu。看链接 ,得改一改指令。
最后按照链接 进行配置的,qemu共享文件链接 。
0x14 qemu网络配置 宿主机运行以下脚本,创建网桥br0
。
1 2 3 4 5 6 7 8 9 10 11 12 #!/bin/sh #sudo ifconfig eth0 down # 首先关闭宿主机网卡接口 sudo brctl addbr br0 # 添加一座名为 br0 的网桥 sudo brctl addif br0 eth0 # 在 br0 中添加一个接口 sudo brctl stp br0 off # 如果只有一个网桥,则关闭生成树协议 sudo brctl setfd br0 1 # 设置 br0 的转发延迟 sudo brctl sethello br0 1 # 设置 br0 的 hello 时间 sudo ifconfig br0 0.0.0.0 promisc up # 启用 br0 接口 sudo ifconfig eth0 0.0.0.0 promisc up # 启用网卡接口 sudo dhclient br0 # 从 dhcp 服务器获得 br0 的 IP 地址 sudo brctl show br0 # 查看虚拟网桥列表 sudo brctl showstp br0 # 查看 br0 的各接口信息
宿主机运行以下脚本,在br0
上新开一个tap0
接口。
1 2 3 4 5 #!/bin/sh sudo tunctl -t tap0 -u root # 创建一个 tap0 接口,只允许 root 用户访问 sudo brctl addif br0 tap0 # 在虚拟网桥中增加一个 tap0 接口 sudo ifconfig tap0 0.0.0.0 promisc up # 启用 tap0 接口 sudo brctl showstp br0
qemu虚拟机启动时加上:
0x15 gdb常用指令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 r # 运行程序 c # 继续执行,到下一个断点处(或运行结束) n # 步过 s # 步进 until # 运行程序直到退出循环体 until+行号 # 运行至某行 finish # 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息 call 函数(参数) # 调用“函数”,并传递“参数”,如:call gdb_test(55) q # 退出gdb b n # 在第n行处设置断点,也可以带上代码路径和代码名称,例如 b OAGUPDATE.cpp:578 break func # 在函数func()的入口处设置断点,如:break cb_button delete 断点号n # 删除第n个断点 disable 断点号n # 停用第n个断点 enable 断点号n # 开启第n个断点 clear 行号n # 清除第n行的断点 info b # 显示当前程序的断点设置情况 l # 列出程序的源代码,默认每次显示10行。再次输入l,则继续输出10行 list 行号 # 将显示当前文件以“行号”为中心的前后10行代码,如:list 12 list 函数名 # 将显示“函数名”所在函数的源代码,如:list main print 表达式 # 其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用 print a # 将显示整数 a 的值 print ++a # 将把 a 中的值加1,并显示出来 print name # 将显示字符串 name 的值 print gdb_test(22) # 将以整数22作为参数调用 gdb_test() 函数 print gdb_test(a) # 将以变量 a 作为参数调用 gdb_test() 函数 display 表达式 # 在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a watch 表达式 # 设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a where/bt # 当前运行的堆栈列表 set args 参数 # 指定运行时的参数 set args "$(python -c 'print("\x90")')" # 参数为字节值 show args # 查看设置好的参数 info program # 来查看程序的是否在运行,进程号,被暂停的原因 layout src # 显示源代码窗口 layout asm # 显示反汇编窗口 layout regs # 显示源代码/反汇编和CPU寄存器窗口 layout split # 显示源代码和反汇编窗口 layout next:显示下一个layout layout prev:显示上一个layout Ctrl + x,再按1:单窗口模式,显示一个窗口 Ctrl + x,再按2:双窗口模式,显示两个窗口 Ctrl + x,再按a:回到传统模式,即退出layout,回到执行layout之前的调试窗口。 Ctrl + L # 刷新窗口 source xx.py # 使用自动化脚本 x/10i addr # 某地址之后的10条指令 info inferiors # 查看当前正在 GDB 中调试的进程的进程ID shell cat /proc/pid/maps # 查看进程对应的内存映射 disassemble main # 查看 main 函数的反汇编 dereference $esp # 查看当前栈顶的内容 info functions # 列出所有函数 info address main # 查看 main 函数的地址 x/10xb addr # 按字节查看数据 x/10xw addr # 按 32 位查看数据 x/10xg addr # 按 64 位查看数据
gdb 将某地址改为其它字节(调试时使用):
1 2 3 4 5 Step1:info locals 查看局部变量,并使用 p &变量名 查看此变量的地址 Step2:运行 python 脚本,将某地址之后的字节进行修改,具体用法为: source modify_mem.py modifymem addr 1234 -> 则地址 addr 变为 0x12,0x34 Step3:使用 x/100bx addr 查看修改后的结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import gdbclass ModifyMemory (gdb.Command): def __init__ (self ): super (ModifyMemory, self).__init__("modifymem" , gdb.COMMAND_USER) def invoke (self, arg, from_tty ): args = arg.split() if len (args) != 2 : print ("Usage: modifymem <address> <bytes>" ) return address = int (args[0 ], 16 ) bytes_to_write = bytes .fromhex(args[1 ]) inferior = gdb.inferiors()[0 ] memory = inferior.read_memory(address, len (bytes_to_write)) print (f"Original memory at {hex (address)} : {memory} " ) inferior.write_memory(address, bytes_to_write) new_memory = inferior.read_memory(address, len (bytes_to_write)) print (f"New memory at {hex (address)} : {new_memory} " ) ModifyMemory()
0x16 adb使用 1 2 3 4 5 6 adb devices // 查看当前所有的设备 adb install xx.apk // 安装apk,路径为宿主机路径 adb shell ps // 列出手机中所有进程的信息 adb shell pm path apk包名 // 获取apk的安装路径 adb push 源文件 手机上的路径 adb pull 手机上的路径 目的地
0x17 vim
0x18 objdump https://ivanzz1001.github.io/records/post/linux/2018/04/09/linux-objdump
0x19 驱动相关 1 2 3 // 打开调试模式 bcdedit.exe /set testsigning on bcdedit.exe /set nointegritychecks on
1 2 3 // 安装 sys sc create wd2711 binPath="C:\Users\23957\Desktop\MyDriver1.sys" type=kernel start=demand sc start wd2711
0x20 readELF https://wangchujiang.com/linux-command/c/readelf.html
0x21 Ubuntu gcc 版本切换 1 2 3 4 5 6 7 8 9 10 11 12 # 添加 gcc-7 版本 sudo apt-get install gcc-7 g++-7 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 70 # 添加 gcc-9 版本 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 90 # 使用此命令切换版本 sudo update-alternatives --config gcc sudo update-alternatives --config g++
0x22 randare2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 r2 /path/to/your/executable # 打开一个可执行文件 i # 查看二进制文件的基本信息 ii # 扫描二进制文件的入口点和符号 pd 10 # 反汇编当前地址的10条指令 pd 2 @ 0x00400550 # 从地址 0x00400550 开始反汇编2条指令 aa # 分析所有函数 afl # 列出所有已识别的函数 pdf @ sym.main # 反汇编并打印 main 函数 oo+ # 以读写方式打开文件 db 0x00400550 # 在地址 0x00400550 处设置断点 dc # 继续运行程序 dr # 查看寄存器 /c "hello" # 搜索字符串 "hello" /x 41424344 # 搜索十六进制模式 0x41424344 q # 退出 Radare2 ood # 加载并开始运行程序