老伙计,别太相信返回地址

有些朋友曾经问过这么个问题
“通过Microsoft编译器扩展指令ReturnAddress , 我可以轻易的知道代码执行流返回到调用者后的下一条指令的地址 。 那么 , 我怎样才能通过返回地址来确定它属于哪个DLL呢?”
要小心了
即使你知道这个返回地址属于哪个DLL(使用GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) , 那也不一定是那个实际调用的DLL 。
我可以想到的一个小技巧是:在一个”可信的”DLL里对某些特定的字节进行搜索 , 根据搜索到的结果 , 你(攻击者)就可以决定是否执行它 。
我们可以简单的使用”retd”这条指令实现这个功能点 。 然后攻击者可以创建如下图所示的一个栈帧(StackFrame) , 例如 , 一个带有两个参数的函数:
老伙计,别太相信返回地址
文章图片
构建完上述的栈帧之后 , 攻击者可以通过指令跳转到那个被攻击的函数上 。
【老伙计,别太相信返回地址】这个被攻击的函数查看了返回地址并观察到了一个指向可信DLL的地址trusted_retd , 然后它就信任了调用者并使用攻击者构造的2个参数进行了不安全的操作 。
紧接着 , 被攻击函数执行了一条”retd8″来返回并清理参数 。 这个操作将导致控制流转移到trusted_retd , 这条指令只是简单的一条retd指令 , 这将会把控制权转移到hacker_code_addr这个位置 , 然后攻击者就可以使用这个结果进行后续的攻击流程 。
这就是为什么当你听到有人说”我的代码对调用者进行了身份验证 , 确保调用者是可信的”时需要保持警惕的原因 。 因为 , 他们怎么知道调用者是谁呢?
最后
RaymondChen的《TheOldNewThing》是我非常喜欢的博客之一 , 里面有很多关于Windows的小知识 , 对于广大Windows平台开发者来说 , 确实十分有帮助 。
本文来自:《Don’ttrustthereturnaddress》
老伙计,别太相信返回地址
文章图片


    推荐阅读