如何在LLVM上获取堆栈上的返回地址

时间:2011-07-26 11:04:41

标签: stack-overflow llvm

我想实现Xor随机canary,所以我必须在函数的序言和结尾中获取返回地址。

在函数的序言中,在我插入堆栈中的金丝雀之前,我可以通过以下方式获取返回地址:

ConstantInt* ci = llvm::ConstantInt::get(Type::getInt32Ty(RI->getContext()), 0);
Value* Args1[] = {ci};
CallInst* callInst = CallInst::Create(Intrinsic::getDeclaration(M, Intrinsic::returnaddress),
               &Args1[0], array_endof(Args1), "Call Return Address", InsPt);

callInst将获得返回地址并且有效。

虽然,在该功能的结尾,由于金丝雀已被插入。我写了类似的代码:

ConstantInt* ci2 = llvm::ConstantInt::get(Type::getInt32Ty(RI->getContext()), 1);
Value* Args3[] = {ci2};
CallInst* callInst1 = CallInst::Create(Intrinsic::getDeclaration(M,    Intrinsic::returnaddress),
             &Args3[0], array_endof(Args3), "Caaall Return Address", BB);

但这次不起作用。我无法收到回信地址。

有什么问题?我如何获得寄信人地址?

1 个答案:

答案 0 :(得分:0)

我不知道你为什么这样做,但在结语中,你正在打电话

llvm.returnaddress i32 1

尝试获取调用堆栈上 previous 函数的返回地址。即使您插入了一个金丝雀,您仍然需要结尾中当前函数的返回地址。所以你应该像在序言中一样,打电话给

 llvm.returnaddress i32 0

正如旁注,使用0以外的参数调用llvm.returnaddress可能不起作用。来自docs

  

此内在函数返回的值可能不正确,或者对于零以外的参数为0,因此它只应用于调试目的。