我想确定Keil中函数的返回地址。在Keil uvision中,我在调试模式下打开了diassembly部分。所显示的是如下所示的一些汇编代码:

我的目的是通过使用微控制器的缓冲区溢出向微控制器注入一个简单的二进制代码。见:缓冲区溢出我想确定“测试”函数的返回地址。是否必须知道如何读取程序集代码,或者是否存在查找返回地址的任何技巧?
我是新来开会的。
发布于 2020-02-26 16:26:20
调用函数时,R14将被调用("BL“或"BLX")指令后面的地址覆盖。如果该函数不调用任何其他函数,则通常会让R14在其持续时间内保存返回地址。此外,如果函数尾调用另一个函数,则可以将尾调用替换为分支("B“或"BX"),其中R14保存原始调用方的返回地址。如果一个函数对另一个函数进行非尾调用,则需要在此之前的某个时间将R14“保存在某个地方”(通常是堆栈,但可能保存到另一个以前使用的调用方保存的寄存器),并在以后的某个时候从堆栈中检索该值,但是如果启用优化,保存R14的位置通常是不可预测的。
有些编译器可能有一种模式,可以一致地堆叠东西以使其可用,但代码将非常依赖于编译器。最有可能成功的方法可能是做以下事情:
extern int getStackAddress(uint8_t **addr); // Always returns zero
void myFunction(...whavever...)
{
uint8_t *returnAddress;
if (getStackAddress(&returnAddress)) return; // Put this first.
}其中getStackAddress将是一个机器代码函数,它将R14存储到R0中的地址,将R0加载为零,然后分支到R14。相对较少的代码序列可能会遵循这一点,如果代码检查存储在returnAddress中的地址上的指令并识别其中一个代码序列,它就会知道myFunction的返回地址存储在与所讨论的序列相匹配的位置上。例如,如果它看到:
test r0,r0
be ...
pop {r0,pc}它会知道调用者的地址在堆栈中排在第二位。同样,如果它看到:
cmp r0,#0
bne somewhere:
somewhere: ; Compute address based on lower byte of bne
pop {r0,r1,r2,r4,r5,pc}然后它就会知道来电者的地址是第六位。
有几个指令编译器可以用来针对零测试寄存器,一些编译器可能使用be,而其他编译器可能使用bne,但是对于上面的代码,编译器可能会使用上面的模式,因此在pop指令中设置了多少位将显示堆栈上返回地址的下落。人们直到运行时才知道这个测试是否真正有效,但是如果它声称要识别返回地址,那么它实际上应该是正确的。
发布于 2020-02-26 14:13:28
R14或以其他名称命名的LR保存返回地址。在左边,你可以在图片中看到它。是0x08000287。
发布于 2020-02-26 14:26:41
您可以在Cortex-M文档中找到所有答案。
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337h/Chdedegj.html

https://stackoverflow.com/questions/60415734
复制相似问题