滴水6.4号 在高空运行 ImageBase(后续)

距离高空运行已经过去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() 的参数必须是待注入的进程 内存中有的东西!!!!

感觉白写了,

还是先复制到待注入的进程中,定义一个要在远程线程中执行的函数,这个函数将修改导入表,并且动态加载没有的模块

  1. // 获取当前进程中,入口函数的地址(希望在注入后运行的那个函数),然后和基址相减得到偏移

  2. DWORD dwProcOffset = (DWORD)InjectEntry - (DWORD)hModule + (DWORD)pGameImageBase;

  3. // 创建远程线程,执行入口代码

  4. 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;
}

  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值