首页
社区
课程
招聘
[旧帖] [原创]VC2008简单文件生成 0.00雪花
发表于: 2011-7-1 21:06 4638

[旧帖] [原创]VC2008简单文件生成 0.00雪花

2011-7-1 21:06
4638

文件生成技术之资源法学习笔记
摘要:介绍文件生成技术。通过VC2008将应用程序所需多个文件合并成一个文件。
关键字:VC2008 文件生成 资源法

一、引言
对于许多应用程序来说,运行一个程序通常需要包含多个文件。但是有些环境或应用中,需要把所有程序包含文件整合成一个文件,以简化操作流程。
将多个文件合并成一个文件,实质上就是在编译程序是将多个文件整合成一个文件,
运行后先释放原文件到相应目录,再执行应用程序。比如有一个程序需要一个DLL文件和一个EXE文件,我们可以把DLL文件包含到一个EXE文件中,运行EXE文件就会将原来的DLL文件释放到相应目录,程序就可以正常运行了。
  本文将通过在程序中添加一个DLL文件资源,然后在程序运行时再释放该DLL文件的实例,介绍资源法释放文件的技术过程。程序代码在XP系统VS2008下编译通过。
二、功能与实现
2.1 PE文件资源
  PE文件中的资源包含了如图片、声音、视频等一些信息,计算机上任何以文件形式存在的数据都可以做成资源包含在PE文件中。这些资源可以在PE文件载入内存运行是被自身访问、修改。一般资源都包含在PE文件的.rsrc的节中。
  资源法生成文件,就是指通过编译在PE文件中的资源生成文件。

2.2 整体思路
  在编译EXE文件时,将DLL文件作为它的资源一起编译。编译EXE后,DLL文件就会以资源形式包含在EXE文件中。在EXE文件中添加新的代码,通过新代码释放资源中的DLL文件。需要注意的是,新添加的代码必须在调用DLL文件之前执行,具体实现过程如图1所示。

 
图1
2.3 添加资源过程
  1.首先打开VS2008,并打开所要修改程序的解决方案。选中需要修改的项目,点击右键,弹出菜单,选择添加资源如图2所示:
 
图2
2.在弹出窗口中选择导入,如图3所示:
 
图3

  3.选择导入后,在弹出的导入对话框中的对象类型中选择所有文件,选中需要导入的文件,如图4所示:
 
图4

4、选中文件后,点击确认,继续弹出自定义资源类型对话框,在资源类型中输入DLL或者其它自己认为合适的类型名称,确认既完成资源的添加。如图5所示:
 
图5
这样就完成了资源添加工作,通过资源试图可以查看已添加成功的资源文件,默认添加后的资源ID名称为IDR_DLL1,如需要修改ID名称,可以通过右键点击属性来修改成自己想要的名称。
2.4 生成文件代码
2.4.1 所需要用的API函数
  在编写释放资源代码前,先介绍几个对资源进行操作的API函数。
1.  FindResource函数
功能:  寻找模块中的资源
原型:  HRSRC FindResource(
       HMODULE hModule,
      LPCTSTR lpName,
      LPCTSTR lpType);
参数:  hModule    指向要查找的模块句柄,本进程NULL即可。
      lpName    指向要查找的资源名称。(既本例中的ID_DLL1)
      lpType    指向要查找资源的类型。(既添加过程中输入的DLL)
返回:  函数调用成功,返回要查找的资源句柄,调用失败则返回NULL。
2.  LoadResource函数
功能:  载入指定资源到全局存储器
原型:  HGLOSAL LoadResource(
      HMODULE hModule,
      HRSRC hResInfo);
参数:  hModule    同FindResource,指向要载入的模块句柄。
      hResInfo    指向被装载资源的句柄,又FindResource返回。
返回:  成功则返回相关资源句柄,失败则返回NULL。
3.  LockResource函数
功能:  锁定内存中的资源
原型:  LPVOID LockResource(
      HGLOBAL hResDate);
参数:  指向被装载的资源句柄,该参数由LoadResource函数返回。
返回:  成功则返回资源第一个字节的指针,调用失败返回NULL。
4.  SizeofResource函数
功能:  得到指定资源的字节数大小。
原型:  DWORD SizeofResource(
      HMODULE hModule,
      HRSRC hResInfo);
参数:  hModule 和FindResource函数的第一个参数相同
      hResinfo 指向被装载资源的句柄,由FindResource函数返回。
返回:  成功则返回指定资源的字节数,失败则返回零。
2.4.2 释放文件实现流程
介绍所需要的API函数后,下面介绍释放文件流程。具体过程如图6所示:
 
图6
2.4.3具体实现代码
按照图6所示流程,编写释放文件实现代码,可以把整个过程封装成一个函数。具体代码如下:
BOOL ResourceToFile(TCHAR *szFilename, TCHAR *szName, TCHAR* szType)
{
  // 寻找自身进程中的资源
  HRSRC hRes = FindResource(NULL, szName, szType);
  if(hRes == NULL)
    return FALSE;

  // 装载资源
  HGLOBAL hgRes = LoadResource(NULL, hRes);
  if(hgRes == NULL)
    return FALSE;

  // 锁定资源
  LPVOID pRes = LockResource(hgRes);
  if(pRes == NULL)
    return FALSE;

  // 得到资源字数
  DWORD dwSize = SizeofResource(NULL, hRes);
  if(dwSize == 0)
    return FALSE;

  // 创建文件
  HANDLE hFile = CreateFile(szFilename,
    GENERIC_WRITE,
    0,
    0,
    CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    0);
  if(hFile == INVALID_HANDLE_VALUE)
    return FALSE;

  // 把资源写入到文件
  DWORD dwWritten;
  if(!WriteFile(hFile, pRes, dwSize, &dwWritten, 0))
    return FALSE;

  // 关闭文件句柄
  CloseHandle(hFile);
  return TRUE;
}
注意:有的资料上在装载资源后提到要用GlobalFree(hgRes)释放资源,使用LoadResource函数装载资源不需要释放。
该函数有三个参数,第一个szFilename为生成文件名(带路径,最好是全路径),第二个参数szName为资源ID,第三个参数szType,为资源类型。使用起来非常方便,当然也可以根据个人需要修改,具体调用过程代码如下:
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szPath[256];
    CONFIGINFO info = {0};
  
    // 得到程序自身路径
    GetCurrentDirectory(sizeof(szPath), szPath);
  
    // 得到生成文件名,带路径
    _tcscat(szPath, L"\\need.dll");

    // 把资源导出成为文件
    if(!ResourceToFile(szPath, MAKEINTRESOURCE(IDR_DLL1), TEXT("DLL")))
    {
      _tprintf(L"generate need.dll error...\r\n");
      return 0;
    }
    else
    _tprintf(L"generate need.dll success...\r\n");
  return 0;
}
编译后运行该程序,既会在该程序目录下生成need.dll文件。本文为个人学习笔记,抄袭别人资料居多,没有太多技术含量,主要是为了加深印象,不当之处,请及时与本人联系。

主要参考书目:
《精通黑客编程》HACK编程实例精讲II    作者:边立忠


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (32)
雪    币: 8764
活跃值: (5240)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
确实没什么技术含量。。。
2011-7-1 21:52
0
雪    币: 48
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
晕,资源释放啊
2011-7-1 21:54
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
菜鸟过来学习、
2011-7-1 22:04
0
雪    币: 763
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
没有什么技术的东西.一般的
2011-7-2 09:24
0
雪    币: 270
活跃值: (97)
能力值: ( LV8,RANK:140 )
在线值:
发帖
回帖
粉丝
6
资源释放是基本的东西了,不过对楼主那个图感兴趣,不知道用什么画的
2011-7-2 09:48
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
hao a
2011-7-2 10:24
0
雪    币: 41
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
word2007 ,呵呵 。。。菜鸟学习中。。
2011-7-2 11:03
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
不错,很好!!!
2011-7-2 14:12
0
雪    币: 69
活跃值: (157)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
还是支持一下,图画得挺好的
2011-7-15 11:56
0
雪    币: 57
活跃值: (55)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
很认真,顶一下……
2011-7-15 15:15
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
虽然东西蛮简单,但是LZ很认真,值得学习,写的文字好多
2011-7-15 15:37
0
雪    币: 615
活跃值: (172)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
13
还没看就猜到了是用CE工具修改内存, 楼主的最后一句很没有技术含量,不能说是QQ号不一样地址不一样,
同一个QQ不同时间启动无聊地址也不一样的, 你应该告诉我们偏移地址。
果断是自慰大侠...
2011-7-15 18:50
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
释放文件是没什么问题
但调用dll的exe程序需要 延迟加载 该dll,否则程序一启动就会报错。
2011-7-16 20:50
0
雪    币: 26
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
myt
15
哎,一点也看不懂啊
2011-7-16 22:43
0
雪    币: 213
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
这个回复那个的,看不明白!
2011-7-17 21:56
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
这个需要慢慢来学习才知道啊!
2011-7-18 12:39
0
雪    币: 129
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
学习一下哦哦
2011-7-18 22:00
0
雪    币: 1259
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stu
19
来看2L头像。
2011-7-19 11:55
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
有学习价值,赞一个
2011-7-20 14:08
0
雪    币: 147
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
很好的文章,非常感谢
2011-7-20 16:39
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
恭喜你转正
2011-7-21 05:03
0
雪    币: 26
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
能把exe檔案解開的嗎?????
2011-7-21 06:04
0
雪    币: 34
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
顶楼主,早知道我也写文章获取邀请码了,虽然顶楼主,但这个技术含量......
2011-7-22 11:31
0
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
word写好,然后截图。图片也没什么技术含量。
2011-9-24 08:48
0
游客
登录 | 注册 方可回帖
返回
//