朱文哲解析VxWorks系统与Linux差异及TP-Link命令行功能演变
admin 2025年3月23日 12:23:02 tp官方下载安卓最新版2025 72
在网络设备调试这一领域,VxWorks系统与Linux系统存在显著不同,调试起来确实有一定难度。但我们可以运用特定技巧,对基于VxWorks系统的设备进行调试。下面,我将逐一为大家详细讲解。
调试背景与目标
过去我们通过解析固件获取了完整的命令行指令,然而在VxWorks系统中,若没有调试功能,就难以进行调试。2019年,我针对MIPS架构的VxWorks路由器编写了串口调试功能。然而,时至今日,TP-Link的命令行功能已有所改变,而且之前的项目是基于python2开发的,并不兼容ARM架构,因此这次需要进行调试。我们的目标是依托VxWorks 5操作系统,实现对其内核内存的直接访问和读写操作,并且能够读取task寄存器的数值。
系统差异与挑战
VxWorks系统与常规的Linux系统存在显著差异。在没有调试功能的情况下,进行调试工作变得相当困难。特别是VxWorks 5系列,它仅限于内核态,尽管其task与其他系统的线程相似且共享内存,但在调试操作上与传统系统有着显著的不同。这些差异使得调试设备面临了不少挑战。
命令获取与内存读写
以前,查看各任务PC寄存器等信息的task命令一目了然,如今却需借助task - c命令来单独获取某任务的关键信息。通过命令行的内存读写功能,可以将调试用的shellcode写入设备内存,为调试工作打下基础。这整个过程,就像是提前为设备准备好了调试所需的“工具”。
插入调试shellcode
下面是一些调试功能的示意图:
我们采用与Inline Hook类似的技术,在调试所需的代码段中实施插桩。随后,我们注入调试用的shellcode,使其转向执行Hook代码。该调试shellcode将陷入无限循环,并持续等待后续的调试指令。在此状态下,我们便可通过命令行发出指令,查看调试任务的相关寄存器和内存信息。
shellcode关键部分
调试用的shellcode包含三个主要部分。首先,它初始化调试栈,用于申请和设置调试shellcode所需的栈内存。其次,是Debug loop部分,这部分会无限循环,并根据debug flag的设置来执行恢复断点或刷新CPU缓存的操作。最后,Recover部分负责在恢复寄存器状态后,跳转回断点位置继续执行。
dbg_statck:
dbg_stack_address = SP - 0x200
dbg_stack_address + 0xa4 ~ 0x200 = reserve
dbg_stack_address + 0x20 ~ 0xa0 = regs store address
dbg_stack_address + 0x1C ~ 0x1C = reserve
dbg_stack_address + 0x18 = Debug loop count
dbg_stack_address + 0x14 = Cache updated count, use to sync update status.
dbg_stack_address + 0x10 = Cache update size(Default is bp_overwrite_size)
dbg_stack_address + 0x0c = Address Need Update Cache(Default is Break Point
Address)
dbg_stack_address + 0x08 = Break Point Address + bp_overwrite_size
dbg_stack_address + 0x04 = Original $RA Value
dbg_stack_address + 0x00 = Debug Flags(0: Keep loop, 1: Recover, 2: Need
update cache)
设备调试与效果
def create_bp_asm(self, bp_address):
"""Create breakpoint asm code
:param bp_address: break point address
:return: Breakpoint shellcode
"""
# increase stack size
asm_code = '''
mov r12, sp
sub sp, sp, #0x{:x}
// save original lr value
str lr, [sp, #0x04]
// jump to dbg loop
bl 0x{:08x}
'''.format(self.dbg_stack_size, self.debugger_base_address)
self.logger.debug("asm_code: %s" % asm_code)
asm_data = self.assemble(str(asm_code), bp_address)
if not asm_data:
return None
return asm_data
核心任务完成后,只需编写一些基础的辅助程序,即可对WDR-7660设备进行调试。调试到特定断点时,可以观察到各个寄存器的数值和其他基本信息。能够如此全面和高效地进行设备调试,说明我们已经找到了一种既可行又高效的方法。
##########################
# Init DBG Stack #
##########################
init_dbg_stack_asm_code = '''
init_dbg_stack:
// first save r0 to sp + 0x20, we need use r0 in debug loop
str r0, [sp, #0x{:x}]
// set flag to zero
mov r0, 0
str r0, [sp]
// clean up debug loop count
str r0, [sp, #0x18]
// save current return address to stack
str lr, [sp, #0x08]
// set lr to break point address and do not touch lr later.
sub lr, lr, #0x{:x}
// save regs to reg_store_offset + 0x04, skip r0
add r0, sp, {}
stmea r0!, {{R1-R11, r12, lr, pc}}
// init cache update stack value to default bp address
// Save cache update address
str lr, [sp, #0x0c]
mov r0, 0x{:x}
// Save cache update size
str r0, [sp, #0x10]
// Init Cache updated count
mov r0, 0
str r0, [sp, # 0x14]
'''.format(reg_store_offset, self.bp_overwrite_size, reg_store_offset + 0x04,
self.bp_overwrite_size)
遇到VxWorks系统调试难题的朋友们,你们觉得哪个调试环节对你们帮助最大?欢迎在评论区分享你的看法,同时别忘了点赞并转发这篇文章。
tpwallet官网下载(TokenPocket)官网是一款安全可靠的多功能数字资产钱包,提供TP钱包的下载与客服支持。TPWallet, TPWallet官方, TPWallet下载,TPWallet最新版支持BTC,ETH,BSC,TRON等所有主流公链,已为全球近千万用户提供安全的数字货币资产管理服务。##########################
# DBG Loop #
##########################
dbg_loop_asm_code = '''
start_dbg_loop:
// Update debug loop count
ldr r0, [sp, #0x18]
add r0, 1
str r0, [sp, #0x18]
// Add delay 60
mov r0, 60
// call task_delay
bl 0x{:x}
// call cacheTextUpdate if flag == 0x02
ldr r0, [sp]
cmp r0, 2
bne part_4
debug_loop:
// update cacheTextUpdate execute count
ldr r0, [sp, #0x14]
add r0, 1
str r0, [sp, #0x14]
update_cache:
// update cache
ldr r0, [sp, #0x0c]
// Force v7_flush_kern_cache_all
mov r1, -1
bl 0x{:x}
// set flag to 0x00
mov r0, 0
str r0, [sp]
// if flag != 0x01 keep loop
part_4:
// update dbg stack cache in each loop
// mov r0, sp
// mov r1, 0x{:x}
// bl 0x{:x}
ldr r0, [sp]
cmp r0, 1
bne start_dbg_loop
'''.format(task_delay_addr, self.cache_update_address, self.dbg_stack_size,
self.cache_update_address)