如何在没有jtag,断点,模拟器,模拟器的情况下单步执行目标代码

时间:2017-11-09 16:49:15

标签: c assembly arm gdb embedded

让我们说你有一个指向功能的指针,你的源代码没有,而且不受信任"因为可能读取/写入不允许的内存区域。

在执行每个汇编指令之前,您需要验证它是否访问不允许的内存区域。

操作系统(几乎)是裸机,即自定义RTOS(因此没有Linux或QNX)。

这是针对不仅需要在开发期间而且在正常运行时期间启用的功能。

理想情况下,它会运行如下:

void (*fptr)(int);
fptr = &someFunction; // untrusted, don't have source
// enable interrupts for each assembly instruction
_EN_INT();
// call the function
fptr();
// everytime the PC increments, some other code runs which verifies that if any load/stores are executed, it doesn't access some disallowed memory range

// disable interrupts for each assembly instruction
_DIS_INT();

问题

是否可以在每个汇编指令后调用该函数并暂停执行?

2 个答案:

答案 0 :(得分:6)

  

操作系统(几乎)是裸机,即自定义RTOS(因此没有Linux或QNX)。

我的回答是假设你可以按照你需要的方式修改“操作系统”...

  

Cortex MK20DX256VLH7

这似乎是一个Cortex M4 CPU。

  

如何在没有jtag,断点的情况下单步执行目标代码

     

从文档中,它没有说明您是否需要外部调试器来恢复执行。

如果CPU真的停止了,你肯定需要一个外部信号(例如来自调试器)。

但是大多数CPU都支持软件调试。这意味着只要遇到断点就会执行中断服务程序。要继续执行,只需从中断服务程序返回。

我不知道Cortex M4,但对于Cortex M3,你必须设置一些特殊的寄存器来启用该功能。只要命中“BKPT”指令,就会执行中断#12(*)。

对于RAM中的代码,您只需将BKPT指令(0xBExx,例如0xBEBE)写入要设置断点的地址。 (在写之前,你读出了以后可以恢复的值)。

对于Flash中的代码,M3有一个“Flash补丁单元”,它允许您指定最多三个地址,即使其他数据存储在那里也应该读出为0xBExx(0xBEBE?)。这允许您在Flash中设置最多3个断点。

有趣的是:控制M3中调试功能的寄存器(名为“DEMCR”)也有一个名为“MON_STEP”的位:

如果在中断处理程序#12中设置此位,则在从中断处理程序返回后只执行一条指令,并再次触发中断#12。此功能的用例当然是单步代码!

要停止单步执行,您必须再次清除MON_STEP位...

重要1:

我不知道 MK20DX256VLH7是否真的具备所有这些功能。然而,因为它是一个Cortex M4芯片而且M4应该具有M3的几乎所有功能,所以这些功能应该存在......

重要2:

实施单步和调试并不是很快。汇编语言知识非常有用,你需要很多时间......

  

来自文档,......

您不仅需要恩智浦MK20DX256VLH7的文档,还需要ARM提供的Cortex M4文档。

(*)向量表中的偏移量4 * 12在这里(在某些ARM文档中称为“IRQ(-4)”);不是IRQ12。

答案 1 :(得分:0)

  

是的,ARM模拟器/解释器的声音与我想要的完全一样。有免费的吗?

qemu是开源的,大多数是GPLv2。 https://wiki.qemu.org/License。你可能需要对它进行很多修改,因为它被设计用作整个Unix进程(qemu-user)或整个机器(qemu-system)的独立包装器。

我用Google搜索,并且还有http://www.unicorn-engine.org/,它被设计用作更大程序的一部分(用C编写,带有用于从各种语言调用的绑定)。它也是GPLv2(不是LGPL),因此如果您的其余代码也是免费软件,您可以使用它。

它实际上基于QEMU的CPU仿真代码;他们剥离了所有的设备/ BIOS仿真工具,以便为模拟CPU提供灵活的库。

据推测,你可以为它配置一些内存保护并设置启动机器状态,让它运行你的功能(返回地址会导致一些代码控制回你的主代码?)