龙马谷

 找回密码
 立即注册

QQ登录

只需一步,快速开始

龙马谷VIP会员办理客服QQ:82926983(如果临时会话没有收到回复,请先加QQ好友再发。)
1 [已完结] GG修改器新手入门与实战教程 31课 2 [已完结] GG修改器美化修改教程 6课 3 [已完结] GG修改器Lua脚本新手入门教程 12课
4 [已完结] 触动精灵脚本新手入门必学教程 22课 5 [已完结] 手游自动化脚本入门实战教程 9课 6 [已完结] C++射击游戏方框骨骼透视与自瞄教程 27课
7 [已完结] C++零基础UE4逆向开发FPS透视自瞄教程 29课 8 [已完结] C++零基础大漠模拟器手游自动化辅助教程 22课 9 [已完结] C++零基础开发DXF内存脚本辅助教程 32课
以下是天马阁VIP教程,本站与天马阁合作,赞助VIP可以获得天马阁对应VIP会员,名额有限! 点击进入天马阁论坛
1 [已完结] x64CE与x64dbg入门基础教程 7课 2 [已完结] x64汇编语言基础教程 16课 3 [已完结] x64辅助入门基础教程 9课
4 [已完结] C++x64内存辅助实战技术教程 149课 5 [已完结] C++x64内存检测与过检测技术教程 10课 6 [已完结] C+x64二叉树分析遍历与LUA自动登陆教程 19课
7 [已完结] C++BT功能原理与x64实战教程 29课 8 [已完结] C+FPS框透视与自瞄x64实现原理及防护思路
查看: 4342|回复: 0

分享一个简短的内存加载DLL EXE C++源码

[复制链接]

10

主题

1

回帖

15

积分

编程入门

Rank: 1

龙马币
40
实现类似功能的代码很多,但是我这份没有参考到别人的代码,纯粹是看微软文档撸出来的。这个需求是源于我的一个比较复杂的x86_64 shellcode,需要实现的功能很多,依赖也很多。因此用传统的方法弄的shellcode很不方便。于是我想着直接用dll/exe当作shellcode,写一个简短的linker控制在0x1000字节以内,将linker直接填在PE头处,调用时直接call头部的linker实现dll/exe的self link并执行。需求已经测试通过,完整项目不能发出来,但是可以跟大家分享验证阶段的测试代码。

主要原理:
SDK_GetProcAddress 解析kernel32拿到LoadLibraryA和GetProcAddress供linker使用。如果不是裸的代码,这里不需要。
SDK_LoadLibrary 解析dos头和nt头,并将section展开到内存。
RelocImage  进行image base重定向
LinkDLL  加载和连接依赖的dll

这里并没有处理TLS和32位的支持。这个有机会再说吧。

以下代码用mingw-w64编译,可加载运行vs和mingw-w64编译出来的pe。



  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4. #include "winapi.h"

  5. #ifndef MIN
  6. #define MIN(a, b) ((a) > (b) ? (b) : (a))
  7. #endif

  8. #define RVA(a) ((PVOID)((ULONG_PTR)hExecutable + (a)))
  9. #define K32RVA(a) ((PVOID)((ULONG_PTR)hKernel32 + (a)))

  10. #define API pContext->

  11. typedef struct {
  12.     union {
  13. #ifdef _WIN64
  14.         struct {
  15.             DWORD64  Unused1:63;
  16.             DWORD64  OrdinalIfSet:1;
  17.         } Flag;
  18.         DWORD64 Long;
  19. #else
  20.         struct {
  21.             DWORD  Unused1:31;
  22.             DWORD  OrdinalIfSet:1;
  23.         } Flag;
  24.         DWORD Long;
  25. #endif
  26.         WORD OrdinalNumber;
  27.         DWORD NameAddress;
  28.     } u;
  29. } IMPORT_LOOKUP_DESC, *PIMPORT_LOOKUP_DESC;

  30. typedef struct {
  31.     LoadLibraryA_t LoadLibraryA;
  32.     GetProcAddress_t GetProcAddress;
  33.     GetModuleHandleA_t GetModuleHandleA;
  34. } LINK_CONTEXT, *PLINK_CONTEXT;

  35. typedef struct {
  36.     DWORD Page;
  37.     DWORD BlockSize;
  38.     struct {
  39.         WORD Offset:12;
  40.         WORD Type:4;
  41.     } TypeOffset[0];
  42. } BASE_RELOCATION_BLOCK, *PBASE_RELOCATION_BLOCK;

  43. HMODULE hExecutable = NULL;

  44. int SDK_strcmp(const char *s1, const char *s2)
  45. {
  46.     while(*s1 && *s2) {
  47.         if (*s1 != *s2)
  48.             return -1;
  49.         s1 ++;
  50.         s2 ++;
  51.     }
  52.     return *s2 - *s1;
  53. }

  54. PVOID SDK_GetProcAddress(HMODULE hKernel32, const char *FuncName)
  55. {
  56.     PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hKernel32;
  57.     PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((char *)pDos + pDos->e_lfanew);

  58.     PIMAGE_EXPORT_DIRECTORY EDT = (PIMAGE_EXPORT_DIRECTORY)K32RVA(pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

  59.     // printf("DLL Name: %s\n", K32RVA(EDT->Name));
  60.     // printf("Number Of Functions: %d\n", EDT->NumberOfFunctions);
  61.     // printf("Number Of Names: %d\n", EDT->NumberOfNames);

  62.     PDWORD ExportAddressTable = (PDWORD)MOD_RVA(EDT->AddressOfFunctions);
  63.     PDWORD ExportNamePointerTable = (PDWORD)MOD_RVA(EDT->AddressOfNames);
  64.     PWORD ExportOrdinalTable  = (PWORD)MOD_RVA(EDT->AddressOfNameOrdinals);

  65.     for(size_t i = 0; i < EDT->NumberOfNames; i++)
  66.     {
  67.         PCHAR name = (PCHAR)MOD_RVA(ExportNamePointerTable[i]);

  68.         if (SDK_strcmp(name, FuncName) == 0) {
  69.             WORD Ordinal = ExportOrdinalTable[i];
  70.             return (PVOID)MOD_RVA(ExportAddressTable[Ordinal]);
  71.         }
  72.     }

  73.     return NULL;
  74. }

  75. void LinkDLL(PLINK_CONTEXT pContext, PIMAGE_IMPORT_DESCRIPTOR IDT)
  76. {
  77.     const char* DLLName = (const char*)RVA(IDT->Name);
  78.     HMODULE hDLL = API GetModuleHandleA(DLLName);

  79.     if (!hDLL) {
  80.         hDLL = API LoadLibraryA(DLLName);
  81.     }

  82.     if (!hDLL) {
  83.         return -1;
  84.     }

  85.     printf("** %s **\n", DLLName);

  86.     PIMPORT_LOOKUP_DESC ILD = (PIMPORT_LOOKUP_DESC)RVA(IDT->OriginalFirstThunk);
  87.     PULONG_PTR IAT = (PULONG_PTR)RVA(IDT->FirstThunk);

  88.     while (ILD->u.Long) {
  89.         if (!ILD->u.Flag.OrdinalIfSet) {
  90.             *IAT = (ULONG_PTR) API GetProcAddress(hDLL, (PCSTR)RVA(ILD->u.NameAddress+2));
  91.             printf("%s %p\n", RVA(ILD->u.NameAddress+2), *IAT);
  92.         } else {
  93.             *IAT = (ULONG_PTR) API GetProcAddress(hDLL, (PCSTR)MAKEINTRESOURCE(ILD->u.OrdinalNumber));
  94.             printf("%d %p\n", RVA(ILD->u.OrdinalNumber), *IAT);
  95.         }
  96.         IAT ++;
  97.         ILD ++;
  98.     }
  99. }

  100. void RelocImage(PBASE_RELOCATION_BLOCK BRB, ptrdiff_t Difference)
  101. {
  102.     printf("Difference: %ld\n", Difference);
  103.     for(size_t i = 0; i < (BRB->BlockSize - 8)/2; i++)
  104.     {
  105.         WORD Offset = BRB->TypeOffset[i].Offset;
  106.         printf("0x%.4x\t%d ", Offset, BRB->TypeOffset[i].Type);

  107.         switch(BRB->TypeOffset[i].Type) {
  108.             case IMAGE_REL_BASED_ABSOLUTE:break; // The base relocation is skipped
  109.             case IMAGE_REL_BASED_HIGHLOW: // TODO Not test yet
  110.                 *(DWORD*)RVA(BRB->Page + Offset) += Difference;
  111.                 break;
  112.             case IMAGE_REL_BASED_DIR64:
  113.                 printf("DIR64 %lx => ", *(ptrdiff_t*)RVA(BRB->Page + Offset));
  114.                 *(ptrdiff_t*)RVA(BRB->Page + Offset) += Difference;
  115.                 printf("%lx", *(ptrdiff_t*)RVA(BRB->Page + Offset));
  116.                 break;
  117.             default:
  118.                 fprintf(stderr, "Not support this relocation type yet.");
  119.                 abort();
  120.                 break;
  121.         }
  122.         putchar('\n');
  123.     }
  124. }

  125. #define LLRVA(a) ((PVOID)((char*)Image + (a)))

  126. HMODULE SDK_LoadLibrary(PCSTR LibraryName)
  127. {
  128.     IMAGE_DOS_HEADER DosHdr;
  129.     IMAGE_NT_HEADERS NtHdr;
  130.     HMODULE hModule = NULL;

  131.     FILE *libfp = fopen(LibraryName, "rb");

  132.     if (!libfp)
  133.         goto CLEAN;

  134.     fread(&DosHdr, sizeof(IMAGE_DOS_HEADER), 1, libfp);

  135.     fseek(libfp, DosHdr.e_lfanew, SEEK_SET);
  136.     fread(&NtHdr, sizeof(IMAGE_NT_HEADERS), 1, libfp);

  137.     PVOID Image = VirtualAlloc(NULL, NtHdr.OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  138.     if (!Image)
  139.         goto CLEAN;

  140.     fseek(libfp, 0, SEEK_SET);
  141.     fread(Image, NtHdr.OptionalHeader.SizeOfHeaders, 1, libfp);

  142.     PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((char *)Image + DosHdr.e_lfanew);

  143.     PIMAGE_SECTION_HEADER Sections = IMAGE_FIRST_SECTION(pNt);

  144.     for(size_t i = 0; i < pNt->FileHeader.NumberOfSections; i++)
  145.     {
  146.         fseek(libfp, Sections[i].PointerToRawData, SEEK_SET);
  147.         fread(LLRVA(Sections[i].VirtualAddress), Sections[i].SizeOfRawData, 1, libfp);
  148.         printf("%s\n", Sections[i].Name);
  149.     }

  150.     hModule = (HMODULE)Image;
  151. CLEAN:
  152.     if (libfp)
  153.         fclose(libfp);
  154.     return hModule;
  155. }

  156. void SDK_FreeLibrary(HMODULE hModule)
  157. {
  158.     VirtualFree(hModule, 0, MEM_RELEASE);
  159. }

  160. int main(int argc, const char *argv[])
  161. {
  162.     LINK_CONTEXT Context;

  163.     if (argc != 2) {
  164.         fprintf(stderr, "Missing dll\n");
  165.         return -1;
  166.     }

  167.     HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
  168.      
  169.     Context.LoadLibraryA = (LoadLibraryA_t)SDK_GetProcAddress(hKernel32, "LoadLibraryA");
  170.     Context.GetProcAddress = (GetProcAddress_t)SDK_GetProcAddress(hKernel32, "GetProcAddress");
  171.     Context.GetModuleHandleA = (GetModuleHandleA_t)SDK_GetProcAddress(hKernel32, "GetModuleHandleA");

  172.     printf("LoadLibraryA\t\t%p\n", Context.LoadLibraryA);
  173.     printf("GetProcAddress\t\t%p\n", Context.GetProcAddress);
  174.     printf("GetModuleHandleA\t%p\n", Context.GetModuleHandleA);

  175.     hExecutable = SDK_LoadLibrary(argv[1]);

  176.     if (hExecutable == NULL) {
  177.         fprintf(stderr, "Can not load dll\n");
  178.         exit(-1);
  179.     }

  180.     PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hExecutable;
  181.     PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((char *)pDos + pDos->e_lfanew);

  182.     if ((PVOID)hExecutable != (PVOID)pNt->OptionalHeader.ImageBase)
  183.     {

  184.         printf("Image Base: %p\n", pNt->OptionalHeader.ImageBase);
  185.         printf("Loaded Base: %p\n", hExecutable);

  186.         ptrdiff_t Difference = (ptrdiff_t)hExecutable - (ptrdiff_t)pNt->OptionalHeader.ImageBase;

  187.         PBASE_RELOCATION_BLOCK BRB = (PBASE_RELOCATION_BLOCK)RVA(pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);

  188.         while (BRB->BlockSize) {
  189.             RelocImage(BRB, Difference);
  190.             BRB = (PBASE_RELOCATION_BLOCK)((char*)BRB + BRB->BlockSize);
  191.         }
  192.     }

  193.     PIMAGE_IMPORT_DESCRIPTOR IDT = (PIMAGE_IMPORT_DESCRIPTOR)RVA(pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  194.     while (IDT->Name != 0) {
  195.         LinkDLL(&Context, IDT);
  196.         IDT ++;
  197.     }

  198.     ((void(*)(HMODULE,DWORD,PVOID))RVA(pNt->OptionalHeader.AddressOfEntryPoint))(hExecutable, DLL_PROCESS_ATTACH, NULL);

  199.     SDK_FreeLibrary(hExecutable);

  200.     return 0;
  201. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

龙马谷| C/C++辅助教程| 安卓逆向安全| 论坛导航| 免责申明|Archiver|
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表龙马谷立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2018-2021 All Right Reserved.
在线客服
快速回复 返回顶部 返回列表