PE输入表DLL注入

一.实现效果
启动notepad.exe时能够加载自己编写的dll.
最终效果如图所示


下面逐步讲解并附带源码
二.编写DLL
自行编写DLL,导出一个函数,弹出对话框

  1. // MsgDLL66.cpp : Defines the entry point for the DLL application.
  2. //
  3. #include “stdafx.h”
  4. #include <windows.h>
  5. #include <stdio.h>
  6. extern “C”
  7. {
  8.         __declspec(dllexport) int Msg() ;
  9. }
  10. DWORD WINAPI ThreadShow(LPVOID LpParameter)
  11. {
  12.         char szPath[MAX_PATH]={0};
  13.         char szBuf[1024]={0};
  14.         GetModuleFileName(NULL,szPath,MAX_PATH);
  15.         sprintf(szBuf,”DLL 已注入到进程 %s [pid=%d]\n”,szPath,GetCurrentProcessId());
  16.         //以3种方式显示自己的存在
  17.         //1.Msgbox
  18.         MessageBox(NULL,szBuf,”DLL Inject”,MB_OK);
  19.         //2.控制台
  20.         printf(“%s”,szBuf);
  21.         //3.调试器
  22.         OutputDebugString(szBuf);
  23.         return 0;
  24. }
  25. __declspec(dllexport) int Msg()
  26. {
  27.         char szPath[MAX_PATH]={0};
  28.         char szBuf[1024]={0};
  29.         GetModuleFileName(NULL,szPath,MAX_PATH);
  30.         sprintf(szBuf,”DLL 已注入到进程 %s [pid=%d]\n”,szPath,GetCurrentProcessId());
  31.         MessageBoxA(NULL, szBuf, “小星星”, MB_OK);
  32.         return 0;
  33. }
  34. BOOL APIENTRY DllMain( HANDLE hModule,
  35.                                           DWORD  ul_reason_for_call,
  36.                                           LPVOID lpReserved
  37.                                           )
  38. {
  39.     switch (ul_reason_for_call)
  40.         {
  41.         case DLL_PROCESS_ATTACH:
  42.                 CreateThread(NULL,0,ThreadShow,NULL,0,NULL);
  43.                 Msg();
  44.                 break;
  45.         case DLL_THREAD_ATTACH:
  46.         case DLL_THREAD_DETACH:
  47.         case DLL_PROCESS_DETACH:
  48.                 break;
  49.     }
  50.     return TRUE;
  51. }

复制代码

上面的源码编译后得到dll文件

三.修改PE输入表实现DLL注入
新建一个工程,把上面得到的dll文件放在工程目录下

代码如下,关键地方都做了注释,如果PE基本结构体都不懂,那还是建议先系统学习下

  1. // PEImportDllInject.cpp : Defines the entry point for the console application.
  2. //
  3. #include “stdafx.h”
  4. #include <windows.h>
  5. #define FilePath “c:\\NOTEPAD.EXE”
  6. #define NewFilePath “c:\\NOTEPAD_new1.EXE”
  7. // 把文件读到Buffer里面
  8. LPVOID FileToBuffer()
  9. {
  10.         HANDLE hFile;
  11.         DWORD lpFileSizeHigh;
  12.         DWORD dwFileSize;
  13.         LPVOID  FileBuffer;
  14.         DWORD lpNumberOfBytesRead;
  15.         BOOL bRead;
  16.         hFile = CreateFile(FilePath, GENERIC_ALL,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  17.         if ( hFile == NULL)
  18.         {
  19.                 printf(“CreateFile error %d\n”, GetLastError());
  20.         }
  21.     dwFileSize = GetFileSize(hFile,&lpFileSizeHigh);
  22.         if ( dwFileSize == NULL)
  23.         {
  24.                 printf(“GetFileSize error %d\n”, GetLastError());
  25.         }
  26.         FileBuffer = VirtualAlloc(0,dwFileSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  27.         if ( FileBuffer == NULL)
  28.         {
  29.                 printf(“VirtualAlloc error %d\n”, GetLastError());
  30.         }
  31.         bRead = ReadFile(hFile,FileBuffer,dwFileSize,&lpNumberOfBytesRead,NULL);
  32.         if ( bRead == FALSE)
  33.         {
  34.                 printf(“ReadFile error %d\n”, GetLastError());
  35.         }
  36.         CloseHandle(hFile);
  37.         return  FileBuffer;
  38. }
  39. // 从文件拷贝到内存
  40. LPVOID FileToMemory(LPVOID FileBuffer)
  41. {
  42.         PIMAGE_DOS_HEADER pImageDosHeader;
  43.         PIMAGE_NT_HEADERS  pImageNtHeaders;
  44.         PIMAGE_FILE_HEADER  pImageFileHeader;
  45.         PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
  46.         PIMAGE_SECTION_HEADER  pImageSectionHeader;
  47.         pImageDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
  48.         pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pImageDosHeader+pImageDosHeader->e_lfanew);
  49.         pImageFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pImageNtHeaders+0x4);
  50.         pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pImageFileHeader+sizeof(IMAGE_FILE_HEADER));
  51.         pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImageFileHeader->SizeOfOptionalHeader);
  52.         DWORD dwSizeofImage = pImageOptionalHeader->SizeOfImage;
  53.         DWORD dwSizeofHeader = pImageOptionalHeader->SizeOfHeaders;
  54.         LPVOID MemoryBuffer;
  55.         int i;
  56.         MemoryBuffer = VirtualAlloc(0,dwSizeofImage*0x10,MEM_COMMIT,PAGE_READWRITE);
  57.         if ( MemoryBuffer == NULL)
  58.         {
  59.                 printf(“VirtualAlloc error %d\n”, GetLastError());
  60.         }
  61.         memcpy(MemoryBuffer,FileBuffer,dwSizeofHeader);
  62.         for ( i = 0; i < pImageFileHeader->NumberOfSections; i++)
  63.         {
  64.                 memcpy(  (BYTE*)((DWORD)MemoryBuffer+ pImageSectionHeader.VirtualAddress),
  65.                         (BYTE*)((DWORD)FileBuffer+ pImageSectionHeader.PointerToRawData),
  66.                         pImageSectionHeader.SizeOfRawData);
  67.         }
  68.         return MemoryBuffer;
  69. }
  70. // 从内存拷贝到新的文件
  71. LPVOID MemoryToNewFile(LPVOID MemoryBuffer)
  72. {
  73.         PIMAGE_DOS_HEADER pImageDosHeader;
  74.         PIMAGE_NT_HEADERS  pImageNtHeaders;
  75.         PIMAGE_FILE_HEADER  pImageFileHeader;
  76.         PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
  77.         PIMAGE_SECTION_HEADER  pImageSectionHeader;
  78.         pImageDosHeader = (PIMAGE_DOS_HEADER)MemoryBuffer;
  79.         pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pImageDosHeader+pImageDosHeader->e_lfanew);
  80.         pImageFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pImageNtHeaders+0x4);
  81.         pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pImageFileHeader+sizeof(IMAGE_FILE_HEADER));
  82.         pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImageFileHeader->SizeOfOptionalHeader);
  83.         DWORD dwSizeofImage = pImageOptionalHeader->SizeOfImage;
  84.         DWORD dwSizeofHeader = pImageOptionalHeader->SizeOfHeaders;
  85.         LPVOID NewFileBuffer;
  86.         int i;
  87.         NewFileBuffer = VirtualAlloc(0,dwSizeofImage,MEM_COMMIT,PAGE_READWRITE);
  88.         if ( NewFileBuffer == NULL)
  89.         {
  90.                 printf(“VirtualAlloc error %d\n”, GetLastError());
  91.         }
  92.         memcpy(NewFileBuffer,MemoryBuffer,dwSizeofHeader);
  93.         for ( i = 0; i < pImageFileHeader->NumberOfSections; i++)
  94.         {
  95.                 memcpy(  (BYTE*)((DWORD)NewFileBuffer+ pImageSectionHeader.PointerToRawData),
  96.                         (BYTE*)((DWORD)MemoryBuffer+ pImageSectionHeader.VirtualAddress),
  97.                         pImageSectionHeader.Misc.VirtualSize);
  98.         }
  99.         return NewFileBuffer;
  100. }
  101. // 存盘写文件
  102. void WriteToFile(LPVOID NewFileBuffer)
  103. {
  104.         PIMAGE_DOS_HEADER pImageDosHeader;
  105.         PIMAGE_NT_HEADERS  pImageNtHeaders;
  106.         PIMAGE_FILE_HEADER  pImageFileHeader;
  107.         PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
  108.         PIMAGE_SECTION_HEADER  pImageSectionHeader;
  109.         pImageDosHeader = (PIMAGE_DOS_HEADER)NewFileBuffer;
  110.         pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pImageDosHeader+pImageDosHeader->e_lfanew);
  111.         pImageFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pImageNtHeaders+0x4);
  112.         pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pImageFileHeader+sizeof(IMAGE_FILE_HEADER));
  113.         pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImageFileHeader->SizeOfOptionalHeader);
  114.         HANDLE hNewFile;
  115.         DWORD dwFileSize;
  116.         DWORD lpNumberOfBytesWritten;
  117.         BOOL bWrite;
  118.         hNewFile = CreateFile(NewFilePath, GENERIC_ALL,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  119.         if ( hNewFile == NULL)
  120.         {
  121.                 printf(“CreateFile error %d\n”, GetLastError());
  122.         }
  123.         int k = pImageFileHeader->NumberOfSections-1;
  124.         dwFileSize = pImageSectionHeader[k].PointerToRawData + pImageSectionHeader[k].SizeOfRawData;
  125.         bWrite = WriteFile(hNewFile,NewFileBuffer, dwFileSize,&lpNumberOfBytesWritten,NULL);
  126.         if ( bWrite == FALSE)
  127.         {
  128.                 printf(“WriteFile error %d\n”, GetLastError());
  129.         }
  130.     CloseHandle(hNewFile);
  131. }
  132. //增加节表
  133. DWORD  AddSection(LPVOID MemoryBuffer, char* SectionName, DWORD SectionSize)
  134. {
  135.         PIMAGE_DOS_HEADER pImageDosHeader;
  136.         PIMAGE_NT_HEADERS  pImageNtHeaders;
  137.         PIMAGE_FILE_HEADER  pImageFileHeader;
  138.         PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
  139.         PIMAGE_SECTION_HEADER  pImageSectionHeader;
  140.         pImageDosHeader = (PIMAGE_DOS_HEADER)MemoryBuffer;
  141.         pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pImageDosHeader+pImageDosHeader->e_lfanew);
  142.         pImageFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pImageNtHeaders+0x4);
  143.         pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pImageFileHeader+sizeof(IMAGE_FILE_HEADER));
  144.         pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImageFileHeader->SizeOfOptionalHeader);
  145.         pImageOptionalHeader->DataDirectory[0xb].Size = 0;
  146.         pImageOptionalHeader->DataDirectory[0xb].VirtualAddress = 0;
  147.         DWORD AddFileAddress;
  148.         DWORD AddMemAddress;
  149.     int i = pImageFileHeader->NumberOfSections;
  150.         pImageFileHeader->NumberOfSections += 0x1;
  151.         AddFileAddress = pImageSectionHeader[i-1].PointerToRawData + pImageSectionHeader[i-1].SizeOfRawData;
  152.         AddMemAddress = pImageSectionHeader[i-1].VirtualAddress+ pImageSectionHeader[i-1].Misc.VirtualSize;
  153.         if ( AddFileAddress % 0x1000 )
  154.         {
  155.         AddFileAddress = (AddFileAddress+0x1000)&0xFFFFF000;
  156.         }
  157.         if ( AddMemAddress % 0x1000 )
  158.         {
  159.         AddMemAddress = (AddMemAddress+0x1000)&0xFFFFF000;
  160.         }
  161.         strcpy( (char*)pImageSectionHeader.Name, SectionName);
  162.         pImageSectionHeader.PointerToRawData = AddFileAddress;
  163.         pImageSectionHeader.VirtualAddress = AddMemAddress;
  164.         pImageSectionHeader.SizeOfRawData = SectionSize;
  165.         pImageSectionHeader.Misc.VirtualSize = SectionSize;
  166.         pImageSectionHeader.Characteristics = 0xFFFFFFFF;
  167.         pImageOptionalHeader->SizeOfImage = pImageSectionHeader.VirtualAddress+pImageSectionHeader.Misc.VirtualSize;
  168.         DWORD AddSectionBuffer;
  169.         AddSectionBuffer = (DWORD)MemoryBuffer+AddMemAddress;
  170.         return AddSectionBuffer;
  171. }
  172. //输入表dll注入
  173. int DLLInject(LPVOID MemoryBuffer,DWORD AddSectionBuffer)
  174. {
  175.         PIMAGE_DOS_HEADER pImageDosHeader;
  176.         PIMAGE_NT_HEADERS  pImageNtHeaders;
  177.         PIMAGE_FILE_HEADER  pImageFileHeader;
  178.         PIMAGE_OPTIONAL_HEADER pImageOptionalHeader;
  179.         PIMAGE_SECTION_HEADER  pImageSectionHeader;
  180.         PIMAGE_IMPORT_DESCRIPTOR pImport;
  181.         pImageDosHeader = (PIMAGE_DOS_HEADER)MemoryBuffer;
  182.         pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pImageDosHeader+pImageDosHeader->e_lfanew);
  183.         pImageFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pImageNtHeaders+0x4);
  184.         pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pImageFileHeader+sizeof(IMAGE_FILE_HEADER));
  185.         pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader+pImageFileHeader->SizeOfOptionalHeader);
  186.         pImport=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)MemoryBuffer+pImageOptionalHeader->DataDirectory[1].VirtualAddress);
  187.         DWORD TotalSize;
  188.         DWORD* NewAddr=(DWORD*)AddSectionBuffer;
  189.         //1.备份原IID结构
  190.         memcpy(NewAddr,pImport,pImageOptionalHeader->DataDirectory[1].Size);
  191.         //结束标记 以0结束
  192.         memset((void*)((DWORD)NewAddr+pImageOptionalHeader->DataDirectory[1].Size),0,sizeof(_IMAGE_IMPORT_DESCRIPTOR));
  193.         //2.在原IID 区域构造新的IID的OFT Name FT结构
  194.         DWORD DLLNameRVA=(DWORD)pImport+0x16;
  195.         char*DLLName=”MsgDLL66.dll”;
  196.         DWORD DLLNameSize=(strlen(DLLName)+1+1)&0xe;
  197.         memcpy((void*)DLLNameRVA,DLLName,DLLNameSize);
  198.         DWORD ByNameRVA=DLLNameRVA+DLLNameSize;
  199.         memset((void*)ByNameRVA,0,2);//hint填充为0
  200.         char*FunName=”Msg”;
  201.         DWORD FunNameSize=(strlen(FunName)+1+1)&0xe;
  202.         memcpy((void*)(ByNameRVA+2),FunName,FunNameSize);
  203.         *(DWORD*)pImport=ByNameRVA-(DWORD)MemoryBuffer;
  204.         *(DWORD*)((DWORD)pImport+0x4)=0x0;
  205.         *(DWORD*)((DWORD)pImport+0x8)=ByNameRVA-(DWORD)MemoryBuffer;
  206.         *(DWORD*)((DWORD)pImport+0xc)=0x0;
  207.         //3.填充新输入表项的IID结构
  208.         PIMAGE_IMPORT_DESCRIPTOR NewIID=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)NewAddr+pImageOptionalHeader->DataDirectory[1].Size-sizeof(_IMAGE_IMPORT_DESCRIPTOR));
  209.         NewIID->OriginalFirstThunk=(DWORD)pImport-(DWORD)MemoryBuffer;
  210.         NewIID->Name=DLLNameRVA-(DWORD)MemoryBuffer;
  211.         NewIID->FirstThunk=(DWORD)pImport+0x8-(DWORD)MemoryBuffer;
  212.         //4.修正PE文件头的信息
  213.         //修改.txt属性
  214.         pImageSectionHeader[0].Characteristics=0xE0000020;
  215.         //修改新节表的属性为0xFFFFFFFF 以及数据目录第B项改为00 (新增节时已经改了)
  216.         //更正输入表的地址以及大小
  217.         pImageOptionalHeader->DataDirectory[1].VirtualAddress=(DWORD)NewAddr-(DWORD)MemoryBuffer;
  218.         pImageOptionalHeader->DataDirectory[1].Size+=sizeof(_IMAGE_IMPORT_DESCRIPTOR);
  219.         return 0;
  220. }
  221. int main(int argc, char* argv[])
  222. {
  223.         LPVOID  FileBuffer;
  224.         LPVOID  MemoryBuffer;
  225.         LPVOID  NewFileBuffer;
  226.         DWORD AddSectionBuffer;
  227.         // 把文件读到Buffer里面
  228.         FileBuffer = FileToBuffer();
  229.         // 从文件拷贝到内存
  230.         MemoryBuffer = FileToMemory(FileBuffer);
  231.         //增加节表
  232.         AddSectionBuffer = AddSection(MemoryBuffer, “.111”, 0x1000);
  233.         //DLL注入
  234.         DLLInject(MemoryBuffer,AddSectionBuffer);
  235.         // 从内存拷贝到新的文件
  236.         NewFileBuffer = MemoryToNewFile(MemoryBuffer);
  237.         // 存盘写文件
  238.          WriteToFile(NewFileBuffer);
  239.         printf(“Hello World!\n”);
  240.         return 0;
  241. }

复制代码

四.测试效果
运行后在C盘生成了如下新文件

双击后在打开记事本之前首先弹出了我们注入的dll弹框

注入成功;;;;
我们再用od加载:

可以看到,我们的dll也在其中
用LordPE工具加载在输入表里也看到了我们自己写的dll

由此可见,dll注入确实成功啦

下载说明:
1.本站资源都是白菜价出售,同样的东西,我们不卖几百,也不卖几十,甚至才卖几块钱,一个永久会员能下载全站100%源码了,所以单独购买也好,会员也好均不提供相关技术服务。
2.如果源码下载地址失效请联系站长QQ进行补发。
3.本站所有资源仅用于学习及研究使用,请必须在24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担。资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您权益请联系本站删除!
4.本站站内提供的所有可下载资源(软件等等)本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发);但本网站不能保证资源的准确性、安全性和完整性,由于源码具有复制性,一经售出,概不退换。用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug;同时本站用户必须明白,【安安资源网】对提供下载的软件等不拥有任何权利(本站原创和特约原创作者除外),其版权归该资源的合法拥有者所有。
5.请您认真阅读上述内容,购买即以为着您同意上述内容,由于源码具有复制性,一经售出,概不退换。
安安资源网 » PE输入表DLL注入