問題
最近想使用llvm的pass來對每個函數進行插樁,來模擬stack guard的功能。其中碰到了一個很棘手的問題就是如何通過llvm C API實現對fs段內容的存取。要想實現該問題,我通過查看llvm如何實現stack guard,找到了具體的解決方案。下面首先看一下llvm中stackProtector pass如何實現對fs段的存取,然後再介紹一下我自己簡化版本的Stack guard。
stackProtector對fs段的存取
在stackProtector中,調用getIRStackGuard(IRBuilder<> &IRB) const函數對fs段進行存取的,其在x86下實現的具體代碼如下:
其中fs段的addressSpace爲257
實現存取
所以對fs段的存取代碼如下:
//Address爲257表示在用戶模式下的fs段寄存器
static Constant* SegmentOffsetStack(IRBuilder<> &IRB, unsigned Offset, unsigned AddressSpace) {
return ConstantExpr::getIntToPtr(
ConstantInt::get(Type::getInt32Ty(IRB.getContext()), Offset),
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace)
);
}
static Value* getTheStackGuardValue(IRBuilder<> &IRB, unsigned offset) {
return SegmentOffsetStack(IRB, offset, 257);
}
其中offset爲從fs段偏移offset處取數據。
下附我對stack guard的一個簡單的實現:
stackguard