距离高空运行已经过去N多天了,只能运行简单的helloworld程序,其他的程序启动不了
,后续的隐藏模块,还是没有写出来,出错了
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include"函数列表.h"
DWORD pid = 0;//待注入进程的pid
HANDLE hSnapshot=NULL;//带注入的进程的快照句柄
HANDLE hProcess = NULL;//待注入进程的句柄
DWORD exitcode = -1;//LoadLibrary线程的返回值,模块的句柄HMODULE
void* readAFile(LPCTSTR lpFileName, LPVOID lpBaseAddress)
{
//打开文件
FILE* fp = NULL;
fp = fopen("E:/c++/pe/进程/加载进程-隐藏模块/Debug/B.exe", "r+b");
if (fp == NULL)
{
printf("打开文件失败\n");
return NULL;
}
fseek(fp, 0, SEEK_END);
int size = ftell(fp);
fseek(fp, 0, SEEK_SET);
void* filebuffer = malloc(size);
if (filebuffer == NULL)
{
printf("申请内存失败\n");
return NULL;;
}
memset(filebuffer, 0, size);//内存数据清0
fread(filebuffer, size,1,fp);//读取文件到内存
fclose(fp); //关闭文件流
return filebuffer;
}
//将文件映射到内存中
void* FileToAImageBase(void* filebuffer){
//读取文件的信息
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)filebuffer; //dos头
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); //nt头
PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)&pNtHeader->FileHeader; //文件头
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)&pNtHeader->OptionalHeader; //可选头
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);//节头
DWORD NumberOfSections = pFileHeader->NumberOfSections; //节的数量 //节的数量
//读取每个节的在内存中的起始位置
DWORD* SectioinVirtualAddress =(DWORD*) malloc(NumberOfSections * sizeof(DWORD));
if (SectioinVirtualAddress == NULL)
{
printf("申请内存失败\n");
return NULL;;
}
memset(SectioinVirtualAddress, 0, NumberOfSections * sizeof(DWORD));
//读取每个节在内存中的大小
DWORD* SectioinSize = (DWORD*)malloc(NumberOfSections * sizeof(DWORD));
if (SectioinSize == NULL)
{
printf("申请内存失败\n");
return NULL;;
}
memset(SectioinSize, 0, NumberOfSections * sizeof(DWORD));//内存数据清0
//读取每个节在文件中对齐后的大小
DWORD* SectioinSizeOfRawData = (DWORD*)malloc(NumberOfSections * sizeof(DWORD));
if (SectioinSizeOfRawData == NULL)
{
printf("申请内存失败\n");
return NULL;
}
memset(SectioinSizeOfRawData, 0, NumberOfSections * sizeof(DWORD));//内存数据清0
//读取每个节在文件中的起始位置
DWORD* SectioinPointerToRawData = (DWORD*)malloc(NumberOfSections * sizeof(DWORD));
if (SectioinPointerToRawData == NULL)
{
printf("申请内存失败\n");
return NULL;;
}
memset(SectioinPointerToRawData, 0, NumberOfSections * sizeof(DWORD)); //内存数据清0
//输出一下信息
for (int i = 0; i < NumberOfSections; i++)
{
SectioinVirtualAddress[i] = pSectionHeader[i].VirtualAddress;//内存中的起始位置
SectioinSize[i] = pSectionHeader[i].Misc.VirtualSize;//内存中没有对齐的大小
SectioinSizeOfRawData[i] = pSectionHeader[i].SizeOfRawData;//文件中对齐后的大小
SectioinPointerToRawData[i] = pSectionHeader[i].PointerToRawData;//文件中的起始位置
printf("第 %d 个节区内存起始位置 %x\n " , i, SectioinVirtualAddress[i]);
printf("第 %d 个节区内存未对齐大小 %x\n ", i, SectioinSize[i]);
printf("第 %d 个节区文件起始位置 %x\n " , i, SectioinPointerToRawData[i]);
printf("第 %d 个节区文件对齐后大小 %x\n ", i, SectioinSizeOfRawData[i]);
printf("------------------------------\n");
}
//拉伸文件到另一个内存区域 487错误 Attempt to access invalid address.
SYSTEM_INFO sys = { 0 };
GetSystemInfo(&sys);
printf("页面保护和承诺的页面大小和粒度%d\n", sys.dwPageSize);
void* lpBaseAddress = VirtualAlloc(NULL, pOptionalHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
printf("%d,内存申请在 %x\n", GetLastError(), (DWORD)lpBaseAddress);
if (lpBaseAddress == NULL)
{
printf("VirtualAlloc 0x00400000 申请内存失败\n");
return NULL;
}
//先复制头部信息
memcpy(lpBaseAddress, filebuffer, pOptionalHeader->SizeOfHeaders);//PE文件头部在文件中的按照文件对齐后的总大小
//将文件中的数据拷贝到内存中
for (int i = 0; i < NumberOfSections; i++)
{
memcpy((void*)((DWORD)lpBaseAddress + SectioinVirtualAddress[i]), (void*)((DWORD)filebuffer + SectioinPointerToRawData[i]), SectioinSizeOfRawData[i]);//(内存中的起始位置,文件中的起始位置,文件中的大小)
}
//释放第一次申请内存
free(filebuffer);//释放内存
free(SectioinVirtualAddress);//释放内存
free(SectioinSize);//释放内存
free(SectioinSizeOfRawData);// 释放内存
free(SectioinPointerToRawData); //释放内存
pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress; //dos头
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); //nt头
pFileHeader = (PIMAGE_FILE_HEADER)&pNtHeader->FileHeader; //文件头
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)&pNtHeader->OptionalHeader; //可选头
pSectionHeader = NULL; //节头
//定位导入表
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)lpBaseAddress + pOptionalHeader->DataDirectory[1].VirtualAddress);
//遍历导入表 PIMAGE_IMPORT_DESCRIPTOR,以结构中全0为结束标志,20字节
while (pImportDescriptor->Name != 0)
{
//获取导入表中DLL的名称
char* pDllName = (char*)((DWORD)lpBaseAddress + pImportDescriptor->Name);
printf("DLL的名称 %s\n", pDllName);
//获取导入表的函数
PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)lpBaseAddress + pImportDescriptor->FirstThunk);
while (pThunkData->u1.AddressOfData != 0)
{
if (0 == (pThunkData->u1.AddressOfData & 0x800000000))//判断是否为序号导入,如果是序号导入,则最高位为1,否则为0,为0时,低31位为函数名称的RVA,为1时,低31位为序号
//获取导入表的函数名称
{
PIMAGE_IMPORT_BY_NAME pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)lpBaseAddress + pThunkData->u1.AddressOfData);
//printf("导入表的函数名称 %s\n", pImportByName->Name);
//根据名称获取导入表的函数地址
HMODULE temp = LoadLibraryA(pDllName);
void* pFunAddress = GetProcAddress(temp, pImportByName->Name);
if (pFunAddress == NULL)
{
printf("GetProcAddress失败\n");
return NULL;
}
//将函数地址写入导入表
pThunkData->u1.Function = (DWORD)pFunAddress;
pThunkData++;
}
else
{
//根据序号获取导入表的函数地址
void* pFunAddress = GetProcAddress(LoadLibraryA(pDllName), (LPCSTR)(pThunkData->u1.AddressOfData & 0x7fffffff));
//将函数地址写入导入表
pThunkData->u1.Function = (DWORD)pFunAddress;//修改FirstThunk指向的 IMAGE_THUNK_DATA32的值,将函数地址写入
pThunkData++;
}
}
pImportDescriptor++;
}
//定位重定位表
PIMAGE_BASE_RELOCATION pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)lpBaseAddress + pOptionalHeader->DataDirectory[5].VirtualAddress);//重定位表
//遍历重定位表,以结构中全0为结束标志,8字节
while (pBaseRelocation->SizeOfBlock != 0)
{
//获取重定位表的大小,看图
DWORD RelocationSize = (pBaseRelocation->SizeOfBlock - 8) / 2;
//遍历TypeOffset[1] 就是 (偏移量+类型)
WORD* TypeOffsetData =(WORD*) ((DWORD)pBaseRelocation+0x8);//第一个TypeOffset[1]的指针
for (int i = 0; i < RelocationSize; i++)
{
//判断TypeOffset[1] 就是 (偏移量+类型)高4位 ==3 需要全部修正
if (((TypeOffsetData[i] >> 12) & 0x0000000f) == IMAGE_REL_BASED_HIGHLOW)
{
DWORD RelocationRVA = pBaseRelocation->VirtualAddress + (TypeOffsetData[i] & 0x0fff);//重定位表的RVA+偏移量
DWORD* pRelocationAddress = (DWORD*)((DWORD)lpBaseAddress + RelocationRVA);
//printf("当前值 =%x\n", *pRelocationAddress);
DWORD TEMP = (DWORD)lpBaseAddress + (*pRelocationAddress - pOptionalHeader->ImageBase);
*pRelocationAddress = TEMP;
// printf("修改后值 =%x\n", *pRelocationAddress);
}
}
//获取下一个重定位表
pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pBaseRelocation + pBaseRelocation->SizeOfBlock);
}
//修改imagebase
pOptionalHeader->ImageBase = (DWORD)lpBaseAddress;
//挂起的方式创建线程
HANDLE thred= CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)newthred, 0, CREATE_SUSPENDED, NULL);
//修改线程的上下文
GetLastError();
CONTEXT context = { 0 };
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(thred, &context);
context.Eip = (DWORD)lpBaseAddress + pOptionalHeader->AddressOfEntryPoint;
GetLastError();
SetThreadContext(thred, &context);
GetLastError();
ResumeThread(thred);
GetLastError();
return lpBaseAddress;//释放内存
//VirtualFree(lpBaseAddress, 0, MEM_RELEASE);
}
void newthred(LPVOID lpBaseAddress)
{
return;
}
//------------------------------------------------------- //
// 远程线程写数据后启动 //
// //
// ----------------------------------------------------//
//得到自身的句柄,得到自身的imagebase,得到自身的大小
void* GetSelfImageBase()
{
//得到自身的句柄
HMODULE hModule = GetModuleHandle(NULL);
//得到自身的imagebase
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)&pNtHeader->OptionalHeader;
//在内存中申请空间,复制自身的数据
void* lpBaseAddress = VirtualAlloc(NULL, pOptionalHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (lpBaseAddress == NULL)
{
printf("VirtualAlloc申请内存失败\n");
return NULL;
}
//复制到新的内存中
memcpy(lpBaseAddress, hModule, pOptionalHeader->SizeOfImage);//复制整个数据到新的内存中
//获取某个进程的hwnd
HWND hwnd = FindWindow(NULL, TEXT("HELLO WORD"));
//获取待注入进程的pid
GetWindowThreadProcessId(hwnd, &pid);
//提升权限
EnableDebugPrivilege();
//打开待注入的进程
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess == NULL)
{
printf("OpenProcess失败\n");
return NULL;
}
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);//拍摄待注入的进程 系统快照
if (hSnapshot == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot失败\n");
return FALSE;
}
//在hello进程中申请空间,获得申请空间的地址
void* lpBaseAddress2 = VirtualAllocEx(hProcess, NULL, pOptionalHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (lpBaseAddress2 == NULL)
{
printf("VirtualAllocEx申请内存失败\n");
return NULL;
}
//-----------------------先修复重定位表-------------------------------//
// //
//-----------------------------------------------------------------//
PIMAGE_BASE_RELOCATION pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)lpBaseAddress + pOptionalHeader->DataDirectory[5].VirtualAddress);//重定位表
//遍历重定位表,以结构中全0为结束标志,8字节
while (pBaseRelocation->SizeOfBlock != 0)
{
//数据 基地址的RVA
//获取重定位表的大小,看图
DWORD RelocationSize = (pBaseRelocation->SizeOfBlock - 8) / 2;
//遍历TypeOffset[1] 就是 (偏移量+类型)
WORD* TypeOffsetData = (WORD*)((DWORD)pBaseRelocation + 0x8);//第一个TypeOffset[1]的指针
for (int i = 0; i < RelocationSize; i++)
{
//判断TypeOffset[1] 就是 (偏移量+类型)高4位 ==3 需要全部修正
if (((TypeOffsetData[i] >> 12) & 0x0000000f) == IMAGE_REL_BASED_HIGHLOW)
{
DWORD RelocationRVA = pBaseRelocation->VirtualAddress + (TypeOffsetData[i] & 0x0fff);//重定位表的RVA+偏移量
DWORD* pRelocationAddress = (DWORD*)((DWORD)lpBaseAddress + RelocationRVA);
//printf("当前值=%x\n", *pRelocationAddress);
DWORD TEMP = (DWORD)lpBaseAddress2 + (*pRelocationAddress - pOptionalHeader->ImageBase);
*pRelocationAddress = TEMP;
// printf("修改后值=%x\n", *pRelocationAddress);
}
}
//获取下一个重定位表
pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pBaseRelocation + pBaseRelocation->SizeOfBlock);
}
-----------------------再修复导入表中的值-------------------------------//
// //
//--------------------------------------------------------------------//
//定位导入表
InjectThread(lpBaseAddress);
}
//---------------------------------------------------------------------------------------------------------//
// 给当前进程提升权限 //
// //
//=======================================================================================================//
BOOL EnableDebugPrivilege()
{
//给当前进程提升权限
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tp = { 0 };
//打开进程令牌
//第一个参数为进程句柄,第二个参数为权限,第三个参数为令牌句柄
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
printf("OpenProcessToken失败\n");
return FALSE;
}
//获取提升权限的特权LUID
//第一个参数为令牌句柄,第二个参数为权限名称,第三个参数为权限结构体
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
{
printf("LookupPrivilegeValue失败\n");
return FALSE;
}
//设置提升权限的特权
tp.PrivilegeCount = 1;//设置特权的数量
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;//设置特权的属性
//第一个参数为令牌句柄,第二个参数为是否关闭所有特权,第三个参数为权限结构体,第四个参数为权限结构体的大小
//设置权限
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL))
{
printf("AdjustTokenPrivileges失败\n");
return FALSE;
}
CloseHandle(hToken);
return TRUE;
}
//拍摄系统快照
BOOL IsAlreadyExist(LPCTSTR lpModuleName, MODULEENTRY32* me32)
{
//遍历快照
//第一个参数为快照句柄,第二个参数为快照结构体
if (!Module32First(hSnapshot, me32))
{
printf("Module32First失败\n");
return FALSE;
}
do
{
//判断是否为指定的模块
int size = _tcslen(me32->szModule);
if (_tcsncicmp(me32->szModule, lpModuleName,size) == 0)
{
//判断进程中是否有指定的模块
printf("已经存在 %ls\n", me32->szModule);
return TRUE;
}
} while (Module32Next(hSnapshot, me32));
return FALSE;
}
void InjectThread(LPVOID lpBaseAddress)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)&pNtHeader->OptionalHeader;
//定位导入表
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)lpBaseAddress + pOptionalHeader->DataDirectory[1].VirtualAddress);
PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)lpBaseAddress + pImportDescriptor->FirstThunk);//定位到导入表的FirstThunk指向的PIMAGE_THUNK_DATA32里的值
MODULEENTRY32 me32 = { 0 };
me32.dwSize = sizeof(me32);
wchar_t* W_DLLName = NULL;
char* pDllName = NULL;
//遍历导入表 PIMAGE_IMPORT_DESCRIPTOR,以结构中全0为结束标志,20字节
while (pImportDescriptor->Name != 0)
{
//获取导入表中DLL的名称
pDllName = (char*)((DWORD)lpBaseAddress + pImportDescriptor->Name);
printf("DLL的名称 %s\n", pDllName);
#ifdef UNICODE//如果是程序使用宽字符,则转换成宽字符.因为pe文件中使用的是ascii字符
W_DLLName=(wchar_t*)malloc(256*sizeof(wchar_t));
if (W_DLLName == NULL)
{
printf("DLLName申请内存失败第 %d 行\n", __LINE__);
return;
}
memset(W_DLLName, 0, 256 * sizeof(wchar_t));
int size=strlen(pDllName);
for (int i = 0; i < size; i++)
{
W_DLLName[i] = pDllName[i];
}
if (IsAlreadyExist(W_DLLName,&me32) == FALSE)//如果没有指定的模块,则注入
{
RemoteInject(W_DLLName);//获得注入后的模块的HMODULE
if(exitcode ==-1)
{
printf("RemoteInject失败,远程启动DLL失败,找到RemoteInject函数 查找问题!!!!\n");
return;
}
//修改导入表的FirstThunk指向的PIMAGE_THUNK_DATA32里保存的值
pThunkData->u1.AddressOfData= exitcode+ (pThunkData->u1.AddressOfData- pOptionalHeader->ImageBase);
}
else//如果有指定的模块,则不注入,获得模块的基址,修改导入表的FirstThunk指向的PIMAGE_THUNK_DATA32里保存的值
{
}
free(W_DLLName);
W_DLLName = NULL;
#endif
while (pThunkData->u1.AddressOfData != 0)
{
//和待注入的进程中的模块函数地址对比进行比较
pThunkData++;
}
pImportDescriptor++;
}
}
//远程线程注入,将dll注入到指定的进程中,返回的是模块的句柄
DWORD RemoteInject( LPCTSTR dllname)
{
#ifdef UNICODE
FARPROC pLoadLibrary = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryW");//获取LoadLibraryW函数的地址
if (pLoadLibrary == NULL)
{
return-1;
}
//创建远程线程,返回新线程的句柄
HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibrary, (LPVOID)dllname, 0, NULL);
GetLastError();
if (hRemoteThread == NULL)
{
return -1;
}
//等待loadlibrary 返回值,错误码
if (GetExitCodeThread(hRemoteThread, &exitcode) == NULL)
{
printf("GetExitCodeThread失败\n");
return -1;
}
//等待远程线程结束
WaitForSingleObject(hRemoteThread, INFINITE);
//释放资源
CloseHandle(hRemoteThread);
return exitcode;
#elif //ASCII
FARPROC pLoadLibrary = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");//获取LoadLibraryA函数的地址
#endif // UNICODE
}
思路1:
省略获取自身的加载地址,开辟内存,把自生的文件放到内存中,在待注入的进程中开辟内存
在自己的pe文件中修改掉 导入表中的函数地址
1.找到导入表 PIMAGE_IMPORT_DESCRIPTOR
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)lpBaseAddress + pOptionalHeader->DataDirectory[1].VirtualAddress);
2.找到导入表的PIMAGE_THUNK_DATA32
pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)lpBaseAddress + pImportDescriptor->FirstThunk);
3.这里忽略判断过程,
4.创建系统快照, pThunkData=(找到待注入的进程中模块基址 + (pThunkData - 本程序的imagebase)
5.加入待注入的进程没有这个模块怎么办?
5.1 通过远程线程注入的方式,把模块动态加载进来
到这一步,还是没有把自己的文件复制到 待注入的进程 开辟的内存中,
本来我想着直接在本程序中把导入表 里所有的函数地址都修改完,
待注入的进程中没有的DLL,先远程线程加载进去
显然这里犯了一个严重的错误,导致运行程序后, 待注入的进程会 异常退出!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
在第5步出现了问题,远程线程注入的时候,loadlibrary() 的参数必须是待注入的进程 内存中有的东西!!!!
感觉白写了,
还是先复制到待注入的进程中,定义一个要在远程线程中执行的函数,这个函数将修改导入表,并且动态加载没有的模块
// 获取当前进程中,入口函数的地址(希望在注入后运行的那个函数),然后和基址相减得到偏移
DWORD dwProcOffset = (DWORD)InjectEntry - (DWORD)hModule + (DWORD)pGameImageBase;
// 创建远程线程,执行入口代码
CreateRemoteThread(hProcess,NULL,NULL,(LPTHREAD_START_ROUTINE)dwProcOffset,NULL,NULL,NULL);
---------------------
作者:hambaga
来源:CSDN
原文:https://blog.csdn.net/kwansy/article/details/107958662
函数.h文件
#pragma once
#include<windows.h>
#include<tchar.h>
#include <tlhelp32.h>
#include<stdio.h>
void newthred(LPVOID lpBaseAddress);
//分配内存,读取A文件,放到A的imagebase位置,
void* readAFile(LPCTSTR lpFileName, LPVOID lpBaseAddress);
void* FileToAImageBase(void* filebuffer);
//得到自身的句柄,得到自身的imagebase,得到自身的大小
void* GetSelfImageBase();
//给当前进程提升权限
BOOL EnableDebugPrivilege();
//判断待注入的进程中是否已经存在指定的模块
BOOL IsAlreadyExist(LPCTSTR lpModuleName, MODULEENTRY32* me32);
//注入线程函数
void InjectThread(LPVOID lpBaseAddress);
DWORD RemoteInject(LPCTSTR dllname);//如果待注入的进程中不存在指定的模块,则注入,否则不注入,返回的是模块的句柄
main函数
// 加载进程-隐藏模块.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include "函数列表.h"
int main()
{
//------------------加载到自己的内存中------------------------//
/* void* filebuffer = NULL;
filebuffer= readAFile(0,0);
void* lpBaseAddress = NULL;
lpBaseAddress= FileToAImageBase(filebuffer);*/
//---------------------------------------------------//
//------------------加载到其他进程中------------------------//
//得到自身的句柄,得到自身的imagebase,得到自身的大小,修复导入表
GetSelfImageBase();
//--------------------------------------------------------//
getchar();
return 0;
}