Windows下利用钩子函数抓取声卡数据
(2013-04-06 00:46:27)分类: 技术文章 |
[讨论]Windows下利用钩子函数抓取声卡数据
Windows下利用钩子函数抓取声卡数据
利用本文介绍的知识可以实现优酷网等播放视频时声音的抓取,及所有以wave系列API为渲染接口的软件声音的抓取。
Windows下的声音播放函数有两类,一类是旧的winmm.dll 里面的API,另一类是比较新的DirectSound。
录音的策略可以分为三类:
第一类是利用windows的Mixer系列API(适用于DirectSound),稍微差一点的录音软件会用这种,(这种方法的好处是可以抓取wave系列及Direct系列的声音,不足之处是只能通过混音抓取,这样的缺点就是万一有麦克风开起来,效果可能比较差)
第二类是利用钩子函数,当系统调用某个函数进行播放时,我们对其数据进行抓取,获得其中的数据后,将数据返还给系统调用(只适用与winmm.dll里的函数,DirectSound的API我没有找到直接对数据操作的,DirectSound是用了两个缓冲,然后系统会自动混音,没有找到类似于wave系列的数据接口),今天准备介绍这种方法。
第三类是编写虚拟声卡(专业级都是利用这种),所有流到物理声卡的数据,都会先进入虚拟声卡,Total Recorder等比较著名的录音软件都是采取这个策略。这个还不会,驱动程序没写过。
对于旧的多媒体接口,通过dumpbin.exe -exports winmm.dll ,我们可以看到这个dll导出了很多函数,
包括混音类API(第一类录音策略用下面的API,国内有一些商业化的软件就是这么搞得),如下:
以及传统的Wave系列API等,今天我们准备用钩子函数来抓取这些API,其中参考了VC知识库的Skype答录机这篇文章,其实主要也是人家的思路,如下:
虚拟声卡需要驱动程序,我是个门外汉,很不幸最近还没精力去学习,所以将来一段时间都是门外汉。
下面我们进入正题,来看看如何用钩子函数抓取 wave系列API,使系统播放声音时,我们的程序能够偷偷的将要发送到声卡的数据备份一份,
然后在返还给系统。
因此涉及到了几方面知识,钩子函数的编写,dll的注入,如何修改函数的地址(IAT表(Import Address Table))等。
关于钩子函数与dll编写,大家可以看一下孙鑫的VC教程最后两课,看完之后,基本就算入门了。
学了孙鑫的VC之后,我们来编写声音抓取程序还是有很大难度,可以查看如下链接的信息http://www.vckbase.com/document/viewdoc/?id=1842
这篇文章基本阐述了如何抓取声卡数据,也给我们描绘了一个比较好的使用前景,比如抓取skype的数据,实际上优酷,Google音乐等都是调用wave系列API的,
所以他们的声音均可通过这种方法进行抓取。
看了上面的链接里的文章,基本就明白了如何用钩子函数来抓取声卡数据,有两个我当时不大明白的东西在这里说明一下,
因为skype答录机是商业化软件,所以它是部分开源的,实际上已经够用了,里面有个CShareMemory类,这个类做的工作我猜想主要是内存的映射(CMapView)及互斥访问等,实际上,我们并不要管这个类,可以自己用简单的文件读写,在Hook_waveOutWrite 系列函数内将数据写入文件,得到的数据不是wave类型的,是pcm,用声音转换软件可以转换为wav及mp3格式。
CAPIHook类实现了函数地址的修改,方法是通过修改函数的IAT表,关于这方面的资料可以查看网上的一篇文章API Hook完全手册,
钩子的类型为全局钩子,设置的消息为WM_GETMESSAGE,如果自己不懒,加上一个lame_enc.dll转换为mp3也不错。
整个软件做成一个dll,然后导出一个接口,在另外一个程序内导入上面编写好的dll,就可以实现声卡的录音了,
好像没写什么,因为别人已经写得非常好了,仅做个整理,给需要做声卡录音的朋友做个参考,
我当时跌跌撞撞的花了不少时间,所以知道学技术不容易,^_^不一定正确,仅供参考,
呵呵,第一次在这上面写文章,以马斌读报里的台词结尾:到这里吧,就到这里了^_^