能力值:
( LV12,RANK:450 )
|
-
-
2 楼
好文章。。
|
能力值:
(RANK:10 )
|
-
-
3 楼
|
能力值:
( LV12,RANK:660 )
|
-
-
4 楼
恩,是个好的方法,我以前写的注册机是把MIDI数据写到磁盘上再播放,这个方法省了读写磁盘文件的步骤,方便了一些.但是手写那个MIDI的二进制数据也是个非常麻烦的事情.推荐流行时代Sen写的文章,将二进制数据写入资源,然后在内存中释放,这样就可以把手写MIDI数据的步骤也省略掉了,强烈推荐:
原文如下:
近来看到prince发贴甚多,想我自论坛创建来就没写什么东西,因为本人才疏学浅。今天突然感觉心中不快,写篇小儿文章让大家见笑。文中尚有很多愚钝之辞,还望各位兄弟指出。
很久以前love和小子就写了一个文件补丁工具,他们的是asm版本,我今天的是C的版本,如果没有兴趣,可以就此打住。
我们写程序的时候经常要生成或者是创建新的文件,这个是怎么做到的呢?老的CIH病毒是这么写的:
BYTE byExe[] = {
0x4d, 0x87 ......
..... .....
}
这个如果要生成的文件很大的时候这个就会很难写,而且写出来的源文件会非常的庞大。这个时候,我们可以用载入资源的方式来解决。
用到的相关API:
FineResource:查找一个资源。我们是把相关要生成的文件载入,就是用这个函数来确定其资源的位置。
SizeofResource:获得资源的尺寸。
LoadResource:装载资源,装入到内存中。
LockResource:锁定资源,在内存中锁定。
好了,现在在VC的工程中载入这个文件吧。首先,我们把***.exe或者***.mid该成***.bin二进制文件,在资源文件上点击右键,选择Import(导入)。这里我们为自定义资源类型,即Custom Resource Type,Resource type为读者兴趣随便填写,这里用MyRes,资源名称用IDR_MyRes。
好了,现在就可以写一个函数进行文件的生成了:
BOOL Create()
{
HRSRC hResInfo;
HGLOBAL hResData;
DWORD dwSize, dwWritten;
HANDLE hFile;
//开始所需的资源
hResInfo = FineResource(NULL,MAKEINTRESOURCE(IDR_MyRes),"MyRes");
if(hResInfo == NULL)
return FALSE;
//获得资源尺寸
dwSize = SizeofResource(NULL,hResInfo);
//装载
hResData = LoadResource(NULL,hResInfo);
if(hResData == NULL)
return FALSE;
//最重要的地方,写文件
hFile = CreateFile("c:\\MyResG.exe",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
if(hFile == NULL)
return FALSE;
WriteFile(hFile,(LPCVOID)LockResource(hResData),dwSize,&dwWritten,NULL);
CloseHandle(hFile);
return TRUE;
}
用这个函数就可以把资源文件的东西拖出来了,哈哈。完工
|
能力值:
( LV4,RANK:50 )
|
-
-
5 楼
最初由 prince 发布 恩,是个好的方法,我以前写的注册机是把MIDI数据写到磁盘上再播放,这个方法省了读写磁盘文件的步骤,方便了一些.但是手
写那个MIDI的二进制数据也是个非常麻烦的事情.推荐流行时代Sen写的文章,将二进制数据写入资源,然后在内存中释放,这样就可
以把手写MIDI数据的步骤也省略掉了,强烈推荐: 原文如下: ........
原来那些数据需要手写-_-!汗~~~
写个小程序来自动帮我们写吧!
[COLOR=blue]
#include<stdio.h>
void main()
{
unsigned char c;
unsigned int n=0;
FILE *fin =fopen("data.bin","rb");
FILE *fout=fopen("data.h" ,"wb");
if(!fin||!fout) {printf("not found data.bin!\n");return;}
fprintf(fout,"unsigned char *data[]={\r\n");
while(1)
{
c=fgetc(fin);
if(feof(fin)) break;
fprintf(fout,"0x%02X,",c);
if(++n%16==0) fprintf(fout,"\r\n");
}
fseek(fout,-1,SEEK_CUR);
fprintf(fout,"\r\n};\r\n");
fclose(fout);
fclose(fin);
}
当然使用资源也是一个好办法,但比起直接使用数组缺点如下:
1.需要调用FineResource,SizeofResource,LoadResource,LockResource等函数,代码量多一些.
2.资源目录表和资源名称(如果使用字符串格式)需要一些额外的数据,且不能被加壳工具压缩.
3.使用资源就非常明显让别人轻易提取出该资源的数据.
4.便于某些无资源编译器或不方便编辑资源的编译器编译(如Dev C++).
还有另一个方法可以直接包含文件,而不是一堆十六进制数据.
但需要有nasm汇编器(把nasmw.exe放入VC编译程序目录中).
工程中添加文件mididata.asm,内容:
section .data
global _mididata
_mididata incbin "midi.mid" ;包含文件的文件名,与此文件同目录
设置mididata.asm的编译属性:
Custom Build/Commands: nasmw -f win32 -o $(OutDir)\$(InputName).obj $(InputPath)
Custom Build/Outputs: $(OutDir)\$(InputName).obj
然后只需要在需要mididata的C++文件中加入下面一行即可:
extern "C" unsigned char mididata[12345]; //大小需要手动输入
哪个方法更方便自己决定吧......
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
以上都不错,只是我不太懂,强烈支持
|
能力值:
( LV12,RANK:660 )
|
-
-
7 楼
最初由 dwing 发布
当然使用资源也是一个好办法,但比起直接使用数组缺点如下: 1.需要调用FineResource,SizeofResource,LoadResource,LockResource等函数,代码量多一些. 2.资源目录表和资源名称(如果使用字符串格式)需要一些额外的数据,且不能被加壳工具压缩. 3.使用资源就非常明显让别人轻易提取出该资源的数据. 4.便于某些无资源编译器或不方便编辑资源的编译器编译(如Dev C++).
还有另一个方法可以直接包含文件,而不是一堆十六进制数据. 但需要有nasm汇编器(把nasmw.exe放入VC编译程序目录中). 工程中添加文件mididata.asm,内容: section .data global _mididata _mididata incbin "midi.mid" ;包含文件的文件名,与此文件同目录 设置mididata.asm的编译属性: Custom Build/Commands: nasmw -f win32 -o $(OutDir)\$(InputName).obj $(InputPath) Custom Build/Outputs: $(OutDir)\$(InputName).obj 然后只需要在需要mididata的C++文件中加入下面一行即可: extern "C" unsigned char mididata[12345]; //大小需要手动输入 哪个方法更方便自己决定吧...... ........
呵呵,学习了!
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
谁来转成asm的播放函数造福大家。
|
能力值:
( LV4,RANK:50 )
|
-
-
9 楼
最初由 hyzhang 发布 谁来转成asm的播放函数造福大家。
如果MASM32中包含COM库和DirectX库的话就可以转换.
|
能力值:
( LV4,RANK:50 )
|
-
-
10 楼
哦hoho,prince把老文都搬出来了
|