工具使用&常用指令

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 sys
import idaapi
start_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中,正偏移为参数,负偏移为局部变量。如下所示:

image-20230816231059579

 创建数组*,如下所示,在var_10上按*

image-20230816231322628

 窗口还原:windows->Reset Desktop

 将数值变为常量:ida提供了命名常量目录,如果目录中不存在,可以手动添加库,进而添加常量(view->open subviews->type libraries)。

插件

keypatch:修改x86、x64、arm等架构的代码。

findcrypt3:查找使用的加密算法。

Go_parser:alt+F7执行此脚本。

ida+qiling

 以Qiling-studychallenge1脚本为例,加入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):
# 以0x1000为起始,映射0x1000大小的数据,映射的大小必须是页大小的倍数,这里的页大小4096字节
# info是对这部分内存做的一个标记,后续可以用这个标记来定位
ql.mem.map(0x1000, 0x1000, info = '[challenge1]')
# 将整数值 1337 转换为一个16位字节写入内存地址 0x1337 所指定的内存位置,小端输入
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

image-20230706205640712

image-20230706205723508

 注意,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插件步骤:

image.png

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进制地址处
  • 定位文件中某dll的某函数:

(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

image-20230424143500201

注:

  • 堆栈跟踪。堆栈跟踪(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 的包名

0x07 apktool使用

[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 worldsecure world的两个终端,在normal world终端内运行xtestoptee_example_hello_world来测试环境是否搭建完成。

image-20230713165453429

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):

1
make menuconfig 1

 编译安装:

1
2
make 
make install

 之后的步骤请看链接

(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虚拟机启动时加上:

1
-nic tap

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
# modify_mem.py
import gdb

class 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

1
:set nu // 显示行号

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 # 加载并开始运行程序

留言

2023-03-25

© 2024 wd-z711

⬆︎TOP