TimothyQiu's Blog

keep it simple stupid

Bad Apple in Windows Task Manager

分类:技术

这几天 Bad Apple 又逆袭了,比如这个这个。虽然周末时候自己也做了一个,但介于身心憔悴和一个遗留问题,暂时先不和上次一样出视频了……

首先,看到那两个演示视频就可以联想到《编程之美》里面的一道面试题,但显然完全不是一回事,因为图像的 x → yy 并不唯一。既然如此,那么就可以推定这是某种程度的「造假」,因为图像已经不是 CPU 占用率曲线了。

既然造假,我们就要造得有良心!那种类似直接在任务管理器上新建/覆盖一个视频窗口的做法略无节操了一些。作为一个死程,我们还是慢慢用程序解决吧……

视频预处理

这个就不用写程序了,看过我之前视频的童鞋一定知道我要用 ffmpeg 来把视频转成位图序列,没错,这次还是它!

而 ffmpeg 同时还提供了非常好用的滤镜支持,要把视频变成 CPU 占用率曲线的样子,我们需要边缘检测(edgedetect)和颜色通道混合器(colorchannelmixer)。

ffmpeg -i <文件名> -r <FPS> -vcodec bmp -vf edgedetect,colorchannelmixer=0:0:0:0:1:1:1:0:0:0:0:0 <输出文件名>

这样就能直接输出黑底绿线的位图序列,以备使用了。

屏蔽掉 CPU 占用率曲线的绘制

这里只考虑 Win 7 及之前的任务管理器,因为这货很好改。首先,这曲线一看就是 LineTo() 函数画出来的,那么我们用 OllyDbg 直接查看任务管理器中所有对于 LineTo() 的调用就可以找到对应代码。

我是 Win 7 的系统,用 OllyDbg 直接打开后,对 LineTo() 的调用只有:

这几处,熟悉汇编的都可以很快定位整个语句的范围。至此,我们得到了一个地址及一个长度,把这个范围内的指令全部变成 Nop 指令即可。

当然 OllyDbg 中反汇编的地址是不能直接用的,还需要减去当前模块的基地址,得到偏移量以备使用……

那么来到 C++,FindWindowGetWindowThreadProcessIdOpenProcess 即可获得任务管理器的进程句柄。

得到进程句柄后,我们首先要获得 taskmgr.exe 模块当前的基地址:EnumProcessModulesGetModuleInformation。而后,就可以用上之前得到的偏移量和长度,使用 WriteProcessMemory 把绘制 CPU 曲线的代码覆写为一串 Nop 指令。

世界清静了。

绘制动画

这里就没有什么技术含量了。无非就是自己 SetTimer 开一个定时器,按照一定的帧率往窗口上 TransparentBlt 以前处理好的图片。

需要注意的是,背景网格,这货最麻烦了。我目前没有用 Hook,所以暂时的做法是:自己维护一份干净的背景网格。这样做的缺点是,网格更新时有一定几率察觉到曲线的缺失(用 Hook 后应该会好:Hook 后替换掉 Window Proc,然后正确的 WM_DRAWITEM/WM_PAINT 之后立即把当前的图片绘制上去)。

以上。

C++FFmpeg

已有 2 条评论 »

  1. 不行我得看看 Linux 下有没有什么丧心病狂的东西可以拿来刷这个.

  2. 好高端!

添加新评论 »