吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4200|回复: 3
收起左侧

[原创] 关于RDTSC的学习日记(新手)

[复制链接]
徐先生xjmtxwd 发表于 2015-8-4 16:33
       接触脱壳有段时间了,之前我遇到的所有脱壳单步跟踪都可以慢慢的梳理流程,至少我学习的壳都可以这样做。直到遇到了TELOCK0.98这个壳,才发现SEH 将标志寄存器的TF == 1 可以防止单步调试,在我这个菜鸟的思想中只有这一种方式可以阻止单步调试,所以在以后调试程序的时候每次遇到SEH都会很小心的判断是否有TF = 1的操作。
      今天第一次跟踪穿山甲的壳然后很是郁闷,使用最后一次异常可以直接正确的程序,只要我单步跟踪程序就会挂,我检查了一下并没有TF = 1,这是怎么回事呢???在出错的程序附近发现了RDTSC 命令,之前单步跟踪发现了该指令不知道其什么意思就直接F7跳过。百度了一下才发现这个指令是测试指令周期和时间的,恍然大悟。如果我单步跟踪将导致该部分程序段执行时间过长,在程序中有判断如果程序执行时间大于某一域值,程序将写入非法内存地址导致错误!

下面是我找到的描述比较清楚的RDTSC http://blog.csdn.net/Solstice/article/details/5196544

多核时代不宜再用 x86 的 RDTSC 指令测试指令周期和时间


陈硕
Blog.csdn.net/Solstice


自从 Intel Pentium 加入 RDTSC 指令以来,这条指令是 micro-benchmarking 的利器,可以以极小的代价获得高精度的 CPU 时钟周期数(Time Stamp Counter),不少介绍优化的文章[1]和书籍用它来比较两段代码的快慢。甚至有的代码用 RDTSC 指令来计时,以替换 gettimeofday() 之类的系统调用。在多核时代,RDTSC 指令的准确度大大削弱了,原因有三:


  • 不能保证同一块主板上每个核的 TSC 是同步的;
  • CPU 的时钟频率可能变化,例如笔记本电脑的节能功能;
  • 乱序执行导致 RDTSC 测得的周期数不准,这个问题从 Pentium Pro 时代就存在。

这些都影响了 RDTSC 的两大用途,micro-benchmarking 和计时。


RDTSC 一般的用法是,先后执行两次,记下两个 64-bit 整数 start 和 end,那么 end-start 代表了这期间 CPU 的时钟周期数。


在多核下,这两次执行可能会在两个 CPU 上发生,而这两个 CPU 的计数器的初值不一定相同(由于完成上电复位的准确时机不同),(有办法同步,见[3]),那么就导致 micro-benchmarking 的结果包含了这个误差,这个误差可正可负,取决于先执行的那块 CPU 的时钟计数器是超前还是落后。


另外,对于计时这个用途,时间 = 周期数 / 频率,由于频率可能会变(比如我的笔记本的 CPU 通常半速运行在 800MHz,繁忙的时候全速运行在 1.6GHz),那么测得的时间也就不准确了。有的新 CPU 的 RDTSC 计数频率是恒定的,那么时钟是准了,那又会导致 micro-benchmarking 的结果不准,见 [2]。还有一个可能是掉电之后恢复(比如休眠),那么 TSC 会清零。 总之,用 RDTSC 来计时是不灵的。


乱序执行这个问题比较简单 [1],但意义深远:在现代 CPU 的复杂架构下,测量几条或几十条指令的耗时是无意义的,因为观测本身会干扰 CPU 的执行(cache, 流水线, 多发射,乱序, 猜测),这听上去有点像量子力学系统了。要么我们以更宏观的指标来标示性能,把"花 xxx 个时钟周期"替换"每秒处理 yyy 条消息"或"消息处理的延时为 zzz 毫秒";要么用专门的 profiler 来减小对观测结果的影响(无论是 callgrind 这种虚拟 CPU,还是 OProfile 这种采样器)。


虽然 RDTSC 废掉了,性能测试用的高精度计时还是有办法的 [2],在 Windows 用 QueryPerformanceCounter 和 QueryPerformanceFrequency,Linux 下用 POSIX 的 clock_gettime 函数,以 CLOCK_MONOTONIC 参数调用。或者按文献 [3] 的办法,先同步 TSC, 再使用它。(我不知道现在最新的 Linux 官方内核是不是内置了这个同步算法。也不清楚校准后的两个 CPU 的“钟”会不会再次失步。)


免费评分

参与人数 2热心值 +2 收起 理由
Hmily + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.
Pizza + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

蚯蚓翔龙 发表于 2015-8-4 16:54
看了以后我还不不懂你是怎么解决RDTSC的问题的,我记得是用驱动可以Patch掉
你想玩单步调试的话可以跟下最高强度下的VM代码
 楼主| 徐先生xjmtxwd 发表于 2015-8-5 12:48
蚯蚓翔龙 发表于 2015-8-4 16:54
看了以后我还不不懂你是怎么解决RDTSC的问题的,我记得是用驱动可以Patch掉
你想玩单步调试的话可以跟下最 ...

更改了阈值的判断,这样就可以单步跟踪了,因为我是在单步跟踪,也不需要PATCH,直接到了阈值判断,修改ZF值,VM壳我还不敢。。呜呜 循序渐进吧,最后再单步VM壳,我怕早了整不明白,打消我的积极性,(*^__^*) 嘻嘻……!
segasonyn64 发表于 2015-8-5 22:33
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 18:21

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表