搞了一两个小时。。。最终因为不知道它的频率、通道等各种因素而放弃……
说下我的进展给后来者一个思路吧。
OD载入,F8一直往下走着。
然后你会发现一个waveOutOpen,接着又有一个waveOutPrepareHeader和waveOutWrite。其实它们的调用顺序是waveOutOpen -> waveOutPrepareHeader ->waveOutWrite 然后是waveOutUnprepareHeader,这个调用的时机必须是在播放完成以后.
我们看看waveOutWrite把,毕竟他是用来播放的。
函数原型是:
MMRESULT waveOutWrite( HWAVEOUT hwo, 波形音频输出装置的柄(handle) LPWAVEHDR pwh, 一个指向包含有数据块信息的WAVEHDR结构的指针。 UINT cbwh WAVEHDR结构的大小(用sizeof (WAVEHDR) 就可以了)。 );
我们可以直接定位到这个函数。F2下断。
停在这里
1000134B . 6A 20 push 20
1000134D . 56 push esi
1000134E . FF33 push dword ptr ds:[ebx]
10001350 . FF15 50300010 call dword ptr ds:[<&winmm.waveOutWrite>] ; winmm.waveOutWrite
看到了连续的三个PUSH吧?这就是传递的参数。他用的是_cdecl调用约定,第二个参数就是我们的WAVHDR指针了。(这个就是我们要找的)
此时各参数为:
0012F43C 001681A0 爜.
0012F440 10016198 榓 bassmod.10016198
0012F444 00000020 ...
我们在数据窗口Ctrl+G到10016198 。看看里面的内容。WAVHDR指针如下:
10016198 98 61 00 10 00 00 01 00 00 00 00 00 00 00 00 00 榓............
100161A8 0E 00 00 00 FF FF FF FF 00 00 00 00 E0 9F 16 00 .......酂.
我们再看看WAVHDR指针的格式:
音频数据块缓存结构WAVEHDR
其声明如下: type struct{ LPSTR lpData; //指向锁定的数据缓冲区的指针 10006198 DWORD dwBufferLength; //数据缓冲区的大小 00010000 DWORD dwByteRecorded; //录音时指明缓冲区中的数据量 00000000 DWORD dwUser; //用户数据 00000000 DWORD dwFlag; //提供缓冲区信息的标志 0E000000 DWORD dwLoops; //循环播放的次数 FFFFFFFF struct wavehdr_tag *lpNext; //保留 00000000 DWORD reserved; //保留 00000000 } WAVEHDR;
我们把相应的数值都写上去了。可以明显看到
音频数据是从:
10006198——10016198 长度为 00010000
我们也知道,WAV是没有压缩的数据。而我们,所以10006198这段缓存里面的数据也已经是解压好了的,所以,我们直接复制这些,找一个16进制编辑器,建一个文件放进去。
大家也都知道,WAV也有它的格式。我们看看
文件头 偏移地址 字节数 数据类型 内 容 00 H 4 char "RIFF"标志 04 H 4 long int 文件长度 08 H 4 char "WAV"标志 0C H 4 char "fmt"标志 10 H 4 过渡字节(不定) 14 H 2 int 格式类别(10H为PCM形式的声音数据) 16 H 2 int 单声道为1,双声道为2通道数 18 H 2 int 采样率(每秒样本数),表示每个通道的播放速度 1C H 4 long 波形音频数据传送速率,其值为通道数×每秒数据位数×每样 本的数据位数/8。播放软件利用此值可以估计缓冲区的大小 22 H 2 每样本的数据位数,表示每个声道中各个样本的数据位数。如果有多 个声道,对每个声道而言,样本大小都一样。 24 H 4 char 数据标记符"data" 28 H 4 long int 语音数据的长度。
我们要做的就是,给我们刚才的数据,加一个文件头。
可惜,本人涉范围有限,技术不高。到这就没能完全弄好它了。只是一个音符出来……/pz
附上一个文件,方便大家的研究。
===========================================================================
不过事实证明,我的结果是错的。看了楼下那位XGalaxy说的查壳,给了我另一种思路。
首先,这些音乐的数据肯定是在资源段,不可能在code等区段中。
打开了下,这一段也挺大的,也不知道怎么入手。于是,把XGalaxy上传的附件看了下,用hex打开后,发现一个字段好像很熟悉:isglass。好像在哪见过。
于是直接用hex打开源程序,Ctrl+F,找isglass。还真有这么一个字符,后面跟着的字符就和XGalaxy上传的附件中的一模一样了,那么,他肯定也有自己的格式的。
也不想去百度了,直接复制XGalaxy上传的附件中的文件头,再加上e_patcher.exe中找到的数据,保存为XM格式,
下载一个dup2补丁制作程序,试听,发现,还真是那首歌。
附件……dup和提取的数据文件noname.xm。。。
上传的附件: