描述
- 编写一款PE加载器,用来将dll和exe文件加载到内存中并运行
- 假设程序需要动态调用dll,内存加载运行技术可以把这些dll作为资源插入自己的程序中,直接在内存中运行即可,不必释放到本地
准备知识
- 加载dll实际上模拟的是loadlibrary的过程,运行dll函数模拟的是getprocaddr的过程
- 模拟loadlibrary的步骤
- 将文件读到内存中,此时是文件对齐
- virtualalloc申请一段可读可写可执行内存,将文件内存按照映像对齐拷贝如申请内存
- 修改重定向表和导入表
- 设置映像基址字段
- 构造dll函数并调用
- 模拟getprocaddr的步骤
- 遍历dll的导出表
- 匹配导出函数的名字,若是,则将导出地址加上实际加载基址
- exe的加载运行同dll,唯一区别是exe的运行不需要构造入口函数,获取入口地址后直接跳转即可
代码
dll的加载运行
#include "stdafx.h"
#include "MemLoadDll.h"
int _tmain(int argc, _TCHAR* argv[])
{
char szFileName[MAX_PATH] = "TestDll.dll";
HANDLE hFile = ::CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
ShowError("CreateFile");
return 1;
}
system("pause");
DWORD dwFileSize = ::GetFileSize(hFile, NULL);
BYTE* lpData = new BYTE[dwFileSize];
if (NULL == lpData)
{
ShowError("new");
return 2;
}
DWORD dwRet = 0;
::ReadFile(hFile, lpData, dwFileSize, &dwRet, NULL);
LPVOID lpBaseAddress = MmLoadLibrary(lpData, dwFileSize);
if (NULL == lpBaseAddress)
{
ShowError("MmLoadLibrary");
return 3;
}
printf("DLL加载成功\n");
typedef BOOL(*typedef_ShowMessage)(char* lpszText, char* lpszCaption);
typedef_ShowMessage ShowMessage = (typedef_ShowMessage)MmGetProcAddress(lpBaseAddress, "ShowMessage");
if (NULL == ShowMessage)
{
ShowError("MmGetProcAddress");
return 4;
}
ShowMessage("You are hacked by z5onk0\n", "Hacked");
BOOL bRet = MmFreeLibrary(lpBaseAddress);
if (FALSE == bRet)
{
ShowError("MmFreeLirbary");
}
delete[] lpData;
lpData = NULL;
::CloseHandle(hFile);
system("pause");
return 0;
}
LPVOID MmLoadLibrary(LPVOID lpData, DWORD dwSize)
{
LPVOID lpBaseAddress = NULL;
DWORD dwSizeOfImage = GetSizeOfImage(lpData);
lpBaseAddress = ::VirtualAlloc(NULL, dwSizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (NULL == lpBaseAddress)
{
ShowError("VirtualAlloc");
return NULL;
}
::RtlZeroMemory(lpBaseAddress, dwSizeOfImage);
if (FALSE == MmMapFile(lpData, lpBaseAddress))
{
ShowError("MmMapFile");
return NULL;
}
if (FALSE == DoRelocationTable(lpBaseAddress))
{
ShowError("DoRelocationTable");
return NULL;
}
if (FALSE == DoImportTable(lpBaseAddress))
{
ShowError("DoImportTable");
return NULL;
}
DWORD dwOldProtect = 0;
if (FALSE == ::VirtualProtect(lpBaseAddress, dwSizeOfImage, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
ShowError("VirtualProtect");
return NULL;
}
if (FALSE == SetImageBase(lpBaseAddress))
{
ShowError("SetImageBase");
return NULL;
}
if (FALSE == CallDllMain(lpBaseAddress))
{
ShowError("CallDllMain");
return NULL;
}
return lpBaseAddress;
}
- 按照映像对齐大小将文件拷贝至申请的内存空间,并修改重定向表和导入表
DWORD GetSizeOfImage(LPVOID lpData)
{
DWORD dwSizeOfImage = 0;
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpData;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
dwSizeOfImage = pNtHeaders->OptionalHeader.SizeOfImage;
return dwSizeOfImage;
}
BOOL MmMapFile(LPVOID lpData, LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpData;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
DWORD dwSizeOfHeaders = pNtHeaders->OptionalHeader.SizeOfHeaders;
WORD wNumberOfSections = pNtHeaders->FileHeader.NumberOfSections;
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeaders + sizeof(IMAGE_NT_HEADERS));
::RtlCopyMemory(lpBaseAddress, lpData, dwSizeOfHeaders);
WORD i = 0;
LPVOID lpSrcMem = NULL;
LPVOID lpDestMem = NULL;
DWORD dwSizeOfRawData = 0;
for (i = 0; i < wNumberOfSections; i++)
{
if ((0 == pSectionHeader->VirtualAddress) ||
(0 == pSectionHeader->SizeOfRawData))
{
pSectionHeader++;
continue;
}
lpSrcMem = (LPVOID)((DWORD)lpData + pSectionHeader->PointerToRawData);
lpDestMem = (LPVOID)((DWORD)lpBaseAddress + pSectionHeader->VirtualAddress);
dwSizeOfRawData = pSectionHeader->SizeOfRawData;
::RtlCopyMemory(lpDestMem, lpSrcMem, dwSizeOfRawData);
pSectionHeader++;
}
return TRUE;
}
DWORD Align(DWORD dwSize, DWORD dwAlignment)
{
DWORD dwRet = 0;
DWORD i = 0, j = 0;
i = dwSize / dwAlignment;
j = dwSize % dwAlignment;
if (0 != j)
{
i++;
}
dwRet = i * dwAlignment;
return dwRet;
}
BOOL DoRelocationTable(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_BASE_RELOCATION pLoc = (PIMAGE_BASE_RELOCATION)((unsigned long)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
if ((PVOID)pLoc == (PVOID)pDosHeader)
{
return TRUE;
}
while ((pLoc->VirtualAddress + pLoc->SizeOfBlock) != 0)
{
WORD* pLocData = (WORD*)((PBYTE)pLoc + sizeof(IMAGE_BASE_RELOCATION));
int nNumberOfReloc = (pLoc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
for (int i = 0; i < nNumberOfReloc; i++)
{
if ((DWORD)(pLocData[i] & 0x0000F000) == 0x00003000)
{
DWORD* pAddress = (DWORD*)((PBYTE)pDosHeader + pLoc->VirtualAddress + (pLocData[i] & 0x0FFF));
DWORD dwDelta = (DWORD)pDosHeader - pNtHeaders->OptionalHeader.ImageBase;
*pAddress += dwDelta;
}
}
pLoc = (PIMAGE_BASE_RELOCATION)((PBYTE)pLoc + pLoc->SizeOfBlock);
}
return TRUE;
}
BOOL DoImportTable(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_IMPORT_DESCRIPTOR pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDosHeader +
pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
char* lpDllName = NULL;
HMODULE hDll = NULL;
PIMAGE_THUNK_DATA lpImportNameArray = NULL;
PIMAGE_IMPORT_BY_NAME lpImportByName = NULL;
PIMAGE_THUNK_DATA lpImportFuncAddrArray = NULL;
FARPROC lpFuncAddress = NULL;
DWORD i = 0;
while (TRUE)
{
if (0 == pImportTable->OriginalFirstThunk)
{
break;
}
lpDllName = (char*)((DWORD)pDosHeader + pImportTable->Name);
hDll = ::GetModuleHandle(lpDllName);
if (NULL == hDll)
{
hDll = ::LoadLibrary(lpDllName);
if (NULL == hDll)
{
pImportTable++;
continue;
}
}
i = 0;
lpImportNameArray = (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + pImportTable->OriginalFirstThunk);
lpImportFuncAddrArray = (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + pImportTable->FirstThunk);
while (TRUE)
{
if (0 == lpImportNameArray[i].u1.AddressOfData)
{
break;
}
lpImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pDosHeader + lpImportNameArray[i].u1.AddressOfData);
if (0x80000000 & lpImportNameArray[i].u1.Ordinal)
{
lpFuncAddress = ::GetProcAddress(hDll, (LPCSTR)(lpImportNameArray[i].u1.Ordinal & 0x0000FFFF));
}
else
{
lpFuncAddress = ::GetProcAddress(hDll, (LPCSTR)lpImportByName->Name);
}
lpImportFuncAddrArray[i].u1.Function = (DWORD)lpFuncAddress;
i++;
}
pImportTable++;
}
return TRUE;
}
BOOL SetImageBase(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
pNtHeaders->OptionalHeader.ImageBase = (ULONG32)lpBaseAddress;
return TRUE;
}
BOOL CallDllMain(LPVOID lpBaseAddress)
{
typedef_DllMain DllMain = NULL;
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
DllMain = (typedef_DllMain)((ULONG32)pDosHeader + pNtHeaders->OptionalHeader.AddressOfEntryPoint);
BOOL bRet = DllMain((HINSTANCE)lpBaseAddress, DLL_PROCESS_ATTACH, NULL);
if (FALSE == bRet)
{
ShowError("DllMain");
}
return bRet;
}
LPVOID MmGetProcAddress(LPVOID lpBaseAddress, PCHAR lpszFuncName)
{
LPVOID lpFunc = NULL;
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PDWORD lpAddressOfNamesArray = (PDWORD)((DWORD)pDosHeader + pExportTable->AddressOfNames);
PCHAR lpFuncName = NULL;
PWORD lpAddressOfNameOrdinalsArray = (PWORD)((DWORD)pDosHeader + pExportTable->AddressOfNameOrdinals);
WORD wHint = 0;
PDWORD lpAddressOfFunctionsArray = (PDWORD)((DWORD)pDosHeader + pExportTable->AddressOfFunctions);
DWORD dwNumberOfNames = pExportTable->NumberOfNames;
DWORD i = 0;
for (i = 0; i < dwNumberOfNames; i++)
{
lpFuncName = (PCHAR)((DWORD)pDosHeader + lpAddressOfNamesArray[i]);
if (0 == ::lstrcmpi(lpFuncName, lpszFuncName))
{
wHint = lpAddressOfNameOrdinalsArray[i];
lpFunc = (LPVOID)((DWORD)pDosHeader + lpAddressOfFunctionsArray[wHint]);
break;
}
}
return lpFunc;
}
加载运行exe
#include "stdafx.h"
#include "MmLoadExe.h"
int _tmain(int argc, _TCHAR* argv[])
{
char szFileName[] = "ExeText.exe";
HANDLE hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
ShowError("CreateFile");
return 1;
}
DWORD dwFileSize = GetFileSize(hFile, NULL);
BYTE *pData = new BYTE[dwFileSize];
if (NULL == pData)
{
ShowError("new");
return 2;
}
DWORD dwRet = 0;
ReadFile(hFile, pData, dwFileSize, &dwRet, NULL);
CloseHandle(hFile);
if (FALSE == IsExistRelocationTable(pData))
{
printf("[FALSE] IsExistRelocationTable\n");
system("pause");
return 0;
}
LPVOID lpBaseAddress = MmRunExe(pData, dwFileSize);
if (NULL == lpBaseAddress)
{
ShowError("MmRunExe");
return 3;
}
system("pause");
return 0;
}
#include "stdafx.h"
#include "MmLoadExe.h"
void ShowError(char *lpszText)
{
char szErr[MAX_PATH] = { 0 };
wsprintf(szErr, "%s Error!\nError Code Is:%d\n", lpszText, GetLastError());
#ifdef _DEBUG
MessageBox(NULL, szErr, "ERROR", MB_OK | MB_ICONERROR);
#endif
}
BOOL IsExistRelocationTable(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_BASE_RELOCATION pLoc = (PIMAGE_BASE_RELOCATION)((unsigned long)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
if ((PVOID)pLoc == (PVOID)pDosHeader)
{
return FALSE;
}
return TRUE;
}
LPVOID MmRunExe(LPVOID lpData, DWORD dwSize)
{
LPVOID lpBaseAddress = NULL;
DWORD dwSizeOfImage = GetSizeOfImage(lpData);
lpBaseAddress = ::VirtualAlloc(NULL, dwSizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (NULL == lpBaseAddress)
{
ShowError("VirtualAlloc");
return NULL;
}
::RtlZeroMemory(lpBaseAddress, dwSizeOfImage);
if (FALSE == MmMapFile(lpData, lpBaseAddress))
{
ShowError("MmMapFile");
return NULL;
}
if (FALSE == DoRelocationTable(lpBaseAddress))
{
ShowError("DoRelocationTable");
return NULL;
}
if (FALSE == DoImportTable(lpBaseAddress))
{
ShowError("DoImportTable");
return NULL;
}
DWORD dwOldProtect = 0;
if (FALSE == ::VirtualProtect(lpBaseAddress, dwSizeOfImage, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
ShowError("VirtualProtect");
return NULL;
}
if (FALSE == SetImageBase(lpBaseAddress))
{
ShowError("SetImageBase");
return NULL;
}
if (FALSE == CallExeEntry(lpBaseAddress))
{
ShowError("CallExeEntry");
return NULL;
}
return lpBaseAddress;
}
DWORD GetSizeOfImage(LPVOID lpData)
{
DWORD dwSizeOfImage = 0;
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpData;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
dwSizeOfImage = pNtHeaders->OptionalHeader.SizeOfImage;
return dwSizeOfImage;
}
BOOL MmMapFile(LPVOID lpData, LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpData;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
DWORD dwSizeOfHeaders = pNtHeaders->OptionalHeader.SizeOfHeaders;
WORD wNumberOfSections = pNtHeaders->FileHeader.NumberOfSections;
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeaders + sizeof(IMAGE_NT_HEADERS));
::RtlCopyMemory(lpBaseAddress, lpData, dwSizeOfHeaders);
WORD i = 0;
LPVOID lpSrcMem = NULL;
LPVOID lpDestMem = NULL;
DWORD dwSizeOfRawData = 0;
for (i = 0; i < wNumberOfSections; i++)
{
if ((0 == pSectionHeader->VirtualAddress) ||
(0 == pSectionHeader->SizeOfRawData))
{
pSectionHeader++;
continue;
}
lpSrcMem = (LPVOID)((DWORD)lpData + pSectionHeader->PointerToRawData);
lpDestMem = (LPVOID)((DWORD)lpBaseAddress + pSectionHeader->VirtualAddress);
dwSizeOfRawData = pSectionHeader->SizeOfRawData;
::RtlCopyMemory(lpDestMem, lpSrcMem, dwSizeOfRawData);
pSectionHeader++;
}
return TRUE;
}
DWORD Align(DWORD dwSize, DWORD dwAlignment)
{
DWORD dwRet = 0;
DWORD i = 0, j = 0;
i = dwSize / dwAlignment;
j = dwSize % dwAlignment;
if (0 != j)
{
i++;
}
dwRet = i * dwAlignment;
return dwRet;
}
BOOL DoRelocationTable(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_BASE_RELOCATION pLoc = (PIMAGE_BASE_RELOCATION)((unsigned long)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
if ((PVOID)pLoc == (PVOID)pDosHeader)
{
return TRUE;
}
while ((pLoc->VirtualAddress + pLoc->SizeOfBlock) != 0)
{
WORD *pLocData = (WORD *)((PBYTE)pLoc + sizeof(IMAGE_BASE_RELOCATION));
int nNumberOfReloc = (pLoc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
for (int i = 0; i < nNumberOfReloc; i++)
{
if ((DWORD)(pLocData[i] & 0x0000F000) == 0x00003000)
{
DWORD* pAddress = (DWORD *)((PBYTE)pDosHeader + pLoc->VirtualAddress + (pLocData[i] & 0x0FFF));
DWORD dwDelta = (DWORD)pDosHeader - pNtHeaders->OptionalHeader.ImageBase;
*pAddress += dwDelta;
}
}
pLoc = (PIMAGE_BASE_RELOCATION)((PBYTE)pLoc + pLoc->SizeOfBlock);
}
return TRUE;
}
BOOL DoImportTable(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_IMPORT_DESCRIPTOR pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDosHeader +
pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
char *lpDllName = NULL;
HMODULE hDll = NULL;
PIMAGE_THUNK_DATA lpImportNameArray = NULL;
PIMAGE_IMPORT_BY_NAME lpImportByName = NULL;
PIMAGE_THUNK_DATA lpImportFuncAddrArray = NULL;
FARPROC lpFuncAddress = NULL;
DWORD i = 0;
while (TRUE)
{
if (0 == pImportTable->OriginalFirstThunk)
{
break;
}
lpDllName = (char *)((DWORD)pDosHeader + pImportTable->Name);
hDll = ::GetModuleHandle(lpDllName);
if (NULL == hDll)
{
hDll = ::LoadLibrary(lpDllName);
if (NULL == hDll)
{
pImportTable++;
continue;
}
}
i = 0;
lpImportNameArray = (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + pImportTable->OriginalFirstThunk);
lpImportFuncAddrArray = (PIMAGE_THUNK_DATA)((DWORD)pDosHeader + pImportTable->FirstThunk);
while (TRUE)
{
if (0 == lpImportNameArray[i].u1.AddressOfData)
{
break;
}
lpImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pDosHeader + lpImportNameArray[i].u1.AddressOfData);
if (0x80000000 & lpImportNameArray[i].u1.Ordinal)
{
lpFuncAddress = GetProcAddress(hDll, (LPCSTR)(lpImportNameArray[i].u1.Ordinal & 0x0000FFFF));
}
else
{
lpFuncAddress = GetProcAddress(hDll, (LPCSTR)lpImportByName->Name);
}
lpImportFuncAddrArray[i].u1.Function = (DWORD)lpFuncAddress;
i++;
}
pImportTable++;
}
return TRUE;
}
BOOL SetImageBase(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
pNtHeaders->OptionalHeader.ImageBase = (ULONG32)lpBaseAddress;
return TRUE;
}
BOOL CallExeEntry(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG32)pDosHeader + pDosHeader->e_lfanew);
LPVOID lpExeEntry = (LPVOID)((ULONG32)pDosHeader + pNtHeaders->OptionalHeader.AddressOfEntryPoint);
__asm
{
mov eax, lpExeEntry
jmp eax
}
return TRUE;
}
结果
- 加载运行dll

- 加载运行exe

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库