文章转载:pt007@vip.sina.com
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
文章的原文地址及代码地址在http://forum.eviloctal.com/thread-43020-1-1.html
注:文章首发I.S.T.O信息安全团队,后由作者友情提交到邪恶八进制信息安全团队技术讨论组。
出处:部分内容整理自网络

前置知识:PE WINDOWS-API

作者:Zaroty

KeyWords :捆绑 EXE PE 资源

想做文件捆绑器,于是去搜了下文件捆绑的一些原理,大致上就三种方法吧,

如果你有其他的方法,希望您能告诉我,谢谢!

1.两个EXE直接合并的方法:

一个 WIN32的可执行文件(PE)的格式,是以数据流型排列的.

PE文件的头部第3个字节处有一个4字节长的数值.这个数值用来告诉PE装载器PE header的位置.

也就是说.这个4字节的数值是一个真正可执行文件的起始偏移量.装载器就会跳到这个偏移量指的地方,

读取数据并将数据印射到内存并执行.

再说个例子:

有三个PE格式文件(A,B,C)

将A和B合并写入C里(C=A & B)

C执行的过程大致为:

PE装载器检查C的PE header偏移量--> 跳到这个位置,读取PE header里的节表结构-->将数据印射至内存--->处理(执行)

再说一个节表的概念,节表好比一个目录,用来告诉装载器.这个PE文件里面在哪个位置放了哪些数据,

并且这些数据是何种属性.

A和B合并写入C,虽然是两个可执行文件,但C的节表其实就是A的节表,

在C的节表里并没有加入B的任何东西.所以.执行C只是相当于执行了A的代码.

那么如何让执行C的同时,可以让这两个PE体都执行呢?大体思路是这样的:

1、A和B合并写入C里(咱们已经做好了)

2、修改C的PE偏移量,使这个值指向C里面所包含的B程序的PE header。(这样就使PE装载器首先跳到B代码处执行B程序体)

3、现在就要想办法使A也运行起来。这就要首先在B程序体里面(B程序要自己写的)加入一个跳转指令,

重新让PE装载器装入A程序,因为A程序的PE偏移量的数据已经被咱们修改了。

所以,必须你自己告诉装载器A的PE header的起始位置。


2.资源释放的方法:

这种方法需要你首先做好一个捆绑模板,用来装载需要捆绑的文件。

比如:A 、B、C三个文件

C为模板,我们要在C里面写入释放资源的源码,然后将A、B作为资源,利用BeginUpdateResource 、

UpdateResource、EndUpdateResource的API函数实现对资源内容的更新替换。

替换完之后,我们运行C,C就会释放他所包含的A和B,并且运行,这样做的优点是在C运行A和B的时候,

我们可以选择隐藏运行。

==

或者你也可以不用资源,直接把文件A、B加到文件C的边,然后文件C读取参数得到文件A、B的大小,

然后写出文件A、B,运行之。


3.WINRAR压缩包捆绑法

这个不是原理。。只是一种方法,,简单易用的,相关内容可以点击下面链接查看:

完美的WINRAR自解压绑马(没有右键菜单)


下面是EXE中资源的导入与导出:

复制内容到剪贴板
代码:
// UpdateResource_Console.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
//including the file & Updating the resource data
void ImportFile(void)
{
   HANDLE hFile;
   DWORD dwFileSize,      
         dwBytesRead;
   LPBYTE lpBuffer;

   hFile = CreateFile("C://WINDOWS//system32//calc.exe", GENERIC_READ,  
                      0,
                      NULL,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL,
                      NULL);

   if (INVALID_HANDLE_VALUE != hFile)
   {
       dwFileSize = GetFileSize(hFile, NULL);

       lpBuffer = new BYTE[dwFileSize];

       if (ReadFile(hFile, lpBuffer, dwFileSize, &dwBytesRead, NULL) != FALSE)
       {
           // do something with lpBuffer here //Updating the resource data
           HANDLE hResource;
           hResource = BeginUpdateResource("C://Documents and Settings//mjs//"
               "桌面//资料//RightNowDoing//UpdateResource_MFC//"
               "Debug//UpdateResource_MFC.exe", FALSE);
           if (NULL != hResource)
           {
               char* p = MAKEINTRESOURCE(104);
               if (UpdateResource(hResource,  
                   RT_RCDATA,  
                   MAKEINTRESOURCE(104),  
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),  //使用系统缺省语言
                   (LPVOID) lpBuffer,  
                   dwFileSize) != FALSE)
               {
                   EndUpdateResource(hResource, FALSE);
               }
           }
       }
       delete [] lpBuffer;          
       CloseHandle(hFile);
   }
}

//Extracting the data & Saving the data to a file
void ExtractFile(void)
{
   HMODULE hLibrary;
   HRSRC hResource;
   HGLOBAL hResourceLoaded;
   LPBYTE lpBuffer;

   hLibrary = LoadLibrary("C://Documents and Settings//mjs//"
       "桌面//资料//RightNowDoing//UpdateResource_Console//"
       "Debug//UpdateResource_Console.exe");
   if (NULL != hLibrary)
   {
       char* p = MAKEINTRESOURCE(104);
       hResource = FindResource(hLibrary, MAKEINTRESOURCE(104), RT_RCDATA);

       LPVOID   lpMsgBuf;    
       FormatMessage(      
             FORMAT_MESSAGE_ALLOCATE_BUFFER   |      
             FORMAT_MESSAGE_FROM_SYSTEM   |      
             FORMAT_MESSAGE_IGNORE_INSERTS,    
             NULL,    
             GetLastError(),   //获得错误代码
             MAKELANGID(LANG_NEUTRAL,   SUBLANG_DEFAULT),   //   Default   language    
             (LPTSTR)   &lpMsgBuf,   //错误代码对应的文字描述
             0,    
             NULL      
       );    
       //   Process   any   inserts   in   lpMsgBuf.    
       //   ...    
       //   Display   the   string.    
       MessageBox(   NULL,   (LPCTSTR)lpMsgBuf,   "Error",   MB_OK   |   MB_ICONINFORMATION   );    
       //   Free   the   buffer.    
       LocalFree(   lpMsgBuf   );  

       if (NULL != hResource)
       {
           hResourceLoaded = LoadResource(hLibrary, hResource);
           if (NULL != hResourceLoaded)        
           {
               lpBuffer = (LPBYTE) LockResource(hResourceLoaded);            
               if (NULL != lpBuffer)            
               {                
                   // do something with lpBuffer here
                   DWORD dwFileSize,dwBytesWritten;
                   HANDLE hFile;

                   dwFileSize = SizeofResource(hLibrary, hResource);

                   hFile = CreateFile("C://WINNT//TEMP//calc2.exe",
                              GENERIC_WRITE,
                              0,
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL);

                   if (INVALID_HANDLE_VALUE != hFile)
                   {
                       WriteFile(hFile, lpBuffer, dwFileSize, &dwBytesWritten, NULL);
                       CloseHandle(hFile);
                   }
               }
           }    
       }
       FreeLibrary(hLibrary);
   }
}

int main(int argc, char* argv[])
{
   ImportFile();
   ExtractFile();
   return 0;
}