加载exe至内存运行
来源:互联网 发布:审计中数据透视表应用 编辑:程序博客网 时间:2024/06/06 07:25
有时候需要将exe加载至内存运行,例如保护exe程序版权。
先上代码:
#ifdef WIN32
#include <windows.h>
#else
#error Process Forking Requires a Windows Operating System
#endif
#include <stdio.h>
/////////////////////////////////////////////////////////////
// NtUnmapViewOfSection (ZwUnmapViewOfSection)
// Used to unmap a section from a process.
bool ForkProcess(LPVOID lpImage)
{
char s[21] = " ";
s[0] = 'N';
s[1] = 't';
// Variables for Process Forking
long int lWritten;
long int lHeaderSize;
long int lImageSize;
long int lSectionCount;
long int lSectionSize;
long int lFirstSection;
long int lPreviousProtection;
long int lJumpSize;
bool bReturnValue;
LPVOID lpImageMemory;
LPVOID lpImageMemoryDummy;
IMAGE_DOS_HEADER dsDosHeader;
IMAGE_NT_HEADERS ntNtHeader;
IMAGE_SECTION_HEADER shSections[512 * 2];
PROCESS_INFORMATION piProcessInformation;
STARTUPINFO suStartUpInformation;
CONTEXT cContext;
// Variables for Local Process
FILE* fFile;
char* pProcessName;
long int lFileSize;
long int lLocalImageBase;
long int lLocalImageSize;
LPVOID lpLocalFile;
IMAGE_DOS_HEADER dsLocalDosHeader;
IMAGE_NT_HEADERS ntLocalNtHeader;
// End Variable Definition
bReturnValue = false;
pProcessName = new char[MAX_PATH];
ZeroMemory(pProcessName, MAX_PATH);
// Get the file name for the dummy process
if(GetModuleFileName(NULL, pProcessName, MAX_PATH) == 0)
{
delete [] pProcessName;
return bReturnValue;
}
s[2] = 'U';
s[3] = 'n';
// Open the dummy process in binary mode
fFile = fopen(pProcessName, "rb");
if(!fFile)
{
delete [] pProcessName;
return bReturnValue;
}
fseek(fFile, 0, SEEK_END);
s[4] = 'm';
s[5] = 'a';
s[6] = 'p';
// Get file size
lFileSize = ftell(fFile);
rewind(fFile);
// Allocate memory for dummy file
lpLocalFile = new LPVOID[lFileSize];
ZeroMemory(lpLocalFile, lFileSize);
s[7] = 'V';
s[8] = 'i';
s[9] = 'e';
s[10] = 'w';
// Read memory of file
fread(lpLocalFile, lFileSize, 1, fFile);
// Close file
fclose(fFile);
// Grab the DOS Headers
memcpy(&dsLocalDosHeader, lpLocalFile, sizeof(dsLocalDosHeader));
if(dsLocalDosHeader.e_magic != IMAGE_DOS_SIGNATURE)
{
delete [] pProcessName;
delete [] lpLocalFile;
return bReturnValue;
}
s[11] = 'O';
s[12] = 'f';
// Grab NT Headers
memcpy(&ntLocalNtHeader, (LPVOID)((long int)lpLocalFile +
dsLocalDosHeader.e_lfanew), sizeof(dsLocalDosHeader));
if(ntLocalNtHeader.Signature != IMAGE_NT_SIGNATURE)
{
delete [] pProcessName;
delete [] lpLocalFile;
return bReturnValue;
}
s[13] = 'S';
s[14] = 'e';
s[15] = 'c';
// Get Size and Image Base
lLocalImageBase = ntLocalNtHeader.OptionalHeader.ImageBase;
lLocalImageSize = ntLocalNtHeader.OptionalHeader.SizeOfImage;
// Deallocate
delete [] lpLocalFile;
// Grab DOS Header for Forking Process
memcpy(&dsDosHeader, lpImage, sizeof(dsDosHeader));
if(dsDosHeader.e_magic != IMAGE_DOS_SIGNATURE)
{
delete [] pProcessName;
return bReturnValue;
}
s[16] = 't';
s[17] = 'i';
s[18] = 'o';
s[19] = 'n';
// Grab NT Header for Forking Process
memcpy(&ntNtHeader, (LPVOID)((long int)lpImage +
dsDosHeader.e_lfanew), sizeof(ntNtHeader));
if(ntNtHeader.Signature != IMAGE_NT_SIGNATURE)
{
delete [] pProcessName;
return bReturnValue;
}
// Get proper sizes
lImageSize = ntNtHeader.OptionalHeader.SizeOfImage;
lHeaderSize = ntNtHeader.OptionalHeader.SizeOfHeaders;
// Allocate memory for image
lpImageMemory = new LPVOID[lImageSize];
ZeroMemory(lpImageMemory, lImageSize);
lpImageMemoryDummy = lpImageMemory;
lFirstSection = (long int)(((long int)lpImage +
dsDosHeader.e_lfanew) + sizeof(IMAGE_NT_HEADERS));
memcpy(shSections, (LPVOID)(lFirstSection),
sizeof(IMAGE_SECTION_HEADER) *
ntNtHeader.FileHeader.NumberOfSections);
memcpy(lpImageMemoryDummy, lpImage, lHeaderSize);
// Get Section Alignment
if((ntNtHeader.OptionalHeader.SizeOfHeaders %
ntNtHeader.OptionalHeader.SectionAlignment) == 0)
{
lJumpSize = ntNtHeader.OptionalHeader.SizeOfHeaders;
}
else
{
lJumpSize = (ntNtHeader.OptionalHeader.SizeOfHeaders /
ntNtHeader.OptionalHeader.SectionAlignment);
lJumpSize += 1;
lJumpSize *= (ntNtHeader.OptionalHeader.SectionAlignment);
}
lpImageMemoryDummy = (LPVOID)((long int)lpImageMemoryDummy + lJumpSize);
// Copy Sections To Buffer
for(lSectionCount = 0; lSectionCount <
ntNtHeader.FileHeader.NumberOfSections; lSectionCount++ )
{
lJumpSize = 0;
lSectionSize = shSections[lSectionCount].SizeOfRawData;
memcpy(lpImageMemoryDummy, (LPVOID)((long int)lpImage +
shSections[lSectionCount].PointerToRawData), lSectionSize);
if((shSections[lSectionCount].Misc.VirtualSize %
ntNtHeader.OptionalHeader.SectionAlignment)==0)
{
lJumpSize = shSections[lSectionCount].Misc.VirtualSize;
}
else
{
lJumpSize = (shSections[lSectionCount].Misc.VirtualSize /
ntNtHeader.OptionalHeader.SectionAlignment);
lJumpSize += 1;
lJumpSize *= (ntNtHeader.OptionalHeader.SectionAlignment);
}
lpImageMemoryDummy =
(LPVOID)((long int)lpImageMemoryDummy + lJumpSize);
}
ZeroMemory(&suStartUpInformation, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInformation, sizeof(PROCESS_INFORMATION));
ZeroMemory(&cContext, sizeof(CONTEXT));
suStartUpInformation.cb = sizeof(suStartUpInformation);
// Create Process
if(CreateProcess(NULL, pProcessName, NULL, NULL, false ,
CREATE_SUSPENDED, NULL, NULL, &suStartUpInformation,
&piProcessInformation))
{
cContext.ContextFlags = CONTEXT_FULL;
GetThreadContext(piProcessInformation.hThread, &cContext);
// Check image base and image size
if(lLocalImageBase ==
(long int)ntNtHeader.OptionalHeader.ImageBase &&
lImageSize <= lLocalImageSize)
{
VirtualProtectEx(piProcessInformation.hProcess,
(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),
lImageSize, PAGE_EXECUTE_READWRITE,
(unsigned long*)&lPreviousProtection);
}
else
{
typedef long int (__stdcall* NtUnmapViewOfSectionF)(HANDLE, PVOID);
NtUnmapViewOfSectionF NtUnmapViewOfSection =
(NtUnmapViewOfSectionF)GetProcAddress(
LoadLibrary("ntdll.dll"), s);
if(!NtUnmapViewOfSection(piProcessInformation.hProcess,
(LPVOID)((DWORD)lLocalImageBase)))
VirtualAllocEx(piProcessInformation.hProcess,
(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),
lImageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}
// Write Image to Process
if(WriteProcessMemory(piProcessInformation.hProcess,
(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),
lpImageMemory, lImageSize, (unsigned long*)&lWritten))
{
bReturnValue = true;
}
// Set Image Base
if(WriteProcessMemory(piProcessInformation.hProcess,
(LPVOID)((long int)cContext.Ebx + 8),
&ntNtHeader.OptionalHeader.ImageBase, 4,
(unsigned long*)&lWritten))
{
if(bReturnValue == true)
bReturnValue = true;
}
if(bReturnValue == false)
{
delete [] pProcessName;
delete [] lpImageMemory;
return bReturnValue;
}
// Set the new entry point
cContext.Eax = ntNtHeader.OptionalHeader.ImageBase +
ntNtHeader.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(piProcessInformation.hThread, &cContext);
if(lLocalImageBase ==
(long int)ntNtHeader.OptionalHeader.ImageBase &&
lImageSize <= lLocalImageSize)
VirtualProtectEx(piProcessInformation.hProcess,
(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),
lImageSize, lPreviousProtection, 0);
// Resume the process
ResumeThread(piProcessInformation.hThread);
}
delete [] pProcessName;
delete [] lpImageMemory;
return bReturnValue;
}
特别说明有几点:
1)调用用到的dll:ntdll.dll;
2)用到的函数为:UnmapViewOfSection,但是在程序中打散,一个一个字符赋值,这样做的目的是避免反编译程序的字串查找;
3)对于需要外部其他dll支持的exe,这时需要添加path环境变量,否则可能运行不正常。
enjoy!
- 加载exe至内存运行
- 从内存中加载并运行exe
- 从内存中加载并运行exe
- 另一个从内存中加载并运行EXE
- 从内存中加载并运行exe (c)
- Delphi中加载并运行内存中的EXE
- 从内存运行exe
- 从内存中加载并运行exe(两种方法)
- 从内存中加载并运行exe(两种方法)
- 动态加载EXE文件到内存执行
- 动态加载EXE文件到内存执行
- 动态加载EXE文件到内存执行
- NB的内存加载exe文件
- 从内存中加载并运行(一)
- 从内存中加载并运行(二)
- JVM类加载运行内存过程
- 从内存中加载并启动一个exe
- 从内存中加载并启动一个exe
- Java中hashCode的作用
- MediaCodec解码aac
- C#入门10.3——接口的实现和继承(2)
- OpenGL环境搭建(Windows下VS2010)
- iOS -- SQLite 实现 收藏功能
- 加载exe至内存运行
- 认清性能问题
- Spring+Spring MVC+MyBatis整合
- CentOS 6.5 安装无线网卡驱动实现无线上网
- 稀疏矩阵的行逻辑链接表示
- 文件系统编程
- 解决Thread性能问题:ThreadPool
- synchronized与static synchronized 的区别、synchronized在JVM底层的实现原理及Java多线程锁理解 (r)
- linux 配置redis集群