pip3 install qiling
git clone <https://github.com/qilingframework/qiling.git>
cd ./qiling/tests
vim gdb-test.py
...
python3 gdb-test.py

进入编译好的 op-tee

cd ./optee/out-br/target/lib/optee_armtz
dd if=8aaaf200-2450-11e4-abe2-0002a5d5c51b.ta of=8aaaf200-2450-11e4-abe2-0002a5d5c51b.elf skip=328 bs=1 count=84624
apt install gdb-multiarch
gdb-multiarch 8aaaf200-2450-11e4-abe2-0002a5d5c51b.elf -ex "target remote: 9999" -ex "display/5i \\$pc"
(gdb) x/10i $pc
=> 0x555555554334:	stp	x29, x30, [sp, #-16]!
   0x555555554338:	mov	x29, sp
   0x55555555433c:	bl	0x555555555bec
   0x555555554340:	mov	w0, w0
   0x555555554344:	bl	0x5555555554e4
   0x555555554348:	mov	w0, #0x4                   	// #4
   0x55555555434c:	ret
...

第一个问题

运行到这里 crash 了

=> 0x555555554364:	str	w0, [x1]

unicorn.unicorn.UcError: Invalid memory write (UC_ERR_WRITE_UNMAPPED)

调用栈

__ta_entry // 0x555555554334, 0x334
	_utee_entry // 0x555555555bec, 0x1bec
		entry_open_session // 0x1c24
			ta_header_add_session // 0x1c24
				init_instance // 0x1c54
					tahead_get_trace_level // 0x348
					trace_set_level // 0x350

通过 IDA 发现写入的是 GOT 表指向的变量 trace_level


.text:0000000000000350                 CMP             W0, #5
.text:0000000000000354                 MOV             W1, #4
.text:0000000000000358                 CSEL            W0, W0, W1, CC
.text:000000000000035C                 ADRP            X1, #trace_level_ptr@PAGE
.text:0000000000000360                 LDR             X1, [X1,#trace_level_ptr@PAGEOFF]
**.text:0000000000000364                 STR             W0, [X1] // trace_level = 4**
.text:0000000000000368                 RET

//   0000000000013140  **78 35 01** 00 00 00 00 00
.got:0000000000013140 trace_level_ptr DCQ **trace_level**         ; DATA XREF: trace_set_level_sub_350+C↑o
.got:0000000000013140                                         ; trace_set_level_sub_350+10↑r ...

.data:0000000000013578 trace_level     DCD **4**                   ; DATA XREF: trace_set_level_sub_350+14↑w
.data:0000000000013578                                         ; sub_36C+8↑r ...

// ta/arch/arm/user_ta_header.c
int trace_level = TRACE_LEVEL;

// lib/libutils/ext/trace.c
void trace_set_level(int level)
{
    if (((int)level >= TRACE_MIN) && (level <= TRACE_MAX))
        trace_level = level;
    else
        trace_level = TRACE_MAX;
}

1: x/5i $pc
=> 0x555555554364:	str	w0, [x1]
(gdb) i reg x1
x1             0x13578

修改 so 中的全局变量(external symbol) trace_level 时出错

内存地址是 0x13578

qiling 加载的 entry point 地址是:0x555555554334, 对应 ELF 的 0x334

所以实际上应该写入 0x555555554000 + 0x13578

(gdb) x/1xw 0x555555554000 + 0x13578
0x555555567578:	0x00000004