隐藏模块(无模块注入)

隐藏模块(无模块注入)实现

隐藏模块(无模块注入)

代码

// memoryLoad.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdlib.h"
#include "PeTools.h"

DWORD WINAPI InjectEntry(LPVOID lpParam)
{
	//RepairIAT(lpParam);
	//定义PE头的信息
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	
	if(!lpParam)
	{
		printf("读取到内存的pfilebuffer无效!\n");
		return 0;
	}
	//判断是不是exe文件
	if(*((PWORD)lpParam) != IMAGE_DOS_SIGNATURE)
	{
		printf("不含MZ标志,不是exe文件!\n");
		return 0;
	}
	pDosHeader = (PIMAGE_DOS_HEADER)lpParam;
	if(*((PDWORD)((BYTE *)lpParam + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){
		printf("无有效的PE标志\n");
		return 0;
	}
	
	//读取pFileBuffer 获取DOS头,PE头,节表等信息
	pDosHeader =(PIMAGE_DOS_HEADER)lpParam;
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)lpParam + pDosHeader->e_lfanew);
	//打印NT头	
	pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);  //加4个字节到了标准PE头
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //标准PE头+标准PE头的大小 20
	
	
	//1000
	
	
	PIMAGE_IMPORT_DESCRIPTOR ImportExtable = (PIMAGE_IMPORT_DESCRIPTOR)((char*)lpParam + pOptionHeader->DataDirectory[1].VirtualAddress);	
	
	DbgPrintf("%x",ImportExtable->FirstThunk);
	while(ImportExtable->OriginalFirstThunk !=0 && ImportExtable->FirstThunk !=0){
		
		char *DllName =(char*)lpParam + ImportExtable->Name;
		
		DbgPrintf("加载的DLL名称:%s\n",DllName);
		
		//这个时候的INT表已经找不到函数了,要先遍历INT表找到序号和名称,然后利用LoadLibrary获取函数的地址然后修复
		
		DWORD* pThunkData_INT = (DWORD*)((char*)lpParam + ImportExtable->OriginalFirstThunk);
		DWORD*	pThunkData_IAT = (PDWORD)(((PBYTE)lpParam + ImportExtable->FirstThunk));
		while(*pThunkData_INT){
			
			if (*pThunkData_INT & 0x80000000)
			{
				DbgPrintf("按序号导入序号%x\n",(*pThunkData_INT & 0xFFFF));
				(*pThunkData_IAT) = (DWORD)GetProcAddress(LoadLibrary(DllName),(char*)(*pThunkData_INT & 0xFFFF));
				printf("--%x\n",*pThunkData_IAT);
			}else{
				
				PIMAGE_IMPORT_BY_NAME FirstThunkNames = (_IMAGE_IMPORT_BY_NAME*)((char*)lpParam + *pThunkData_INT);
				DbgPrintf("按名称导入HIT/NAME-%x-%s\n",FirstThunkNames->Hint,FirstThunkNames->Name);
				(*pThunkData_IAT) = (DWORD)GetProcAddress(LoadLibrary(DllName),(char*)FirstThunkNames->Name);
				DbgPrintf("--%x\n",*pThunkData_IAT);
			}	
			
			pThunkData_IAT++,pThunkData_INT++;
		}
		
		ImportExtable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)ImportExtable+sizeof(IMAGE_IMPORT_DESCRIPTOR));
		
	}
	
	
	while (TRUE)
	{
		MessageBoxA(0,TEXT("注入成功"),0,0);
		Sleep(10000);
	}
	return 0;
}

BOOL EnableDebugPrivilege()
{
	HANDLE hToken;
	BOOL fOk=FALSE;
	if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))
	{
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount=1;
		LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
		
		tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
		AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
		
		fOk=(GetLastError()==ERROR_SUCCESS);
		CloseHandle(hToken);
	}
    return fOk;
}

int main(int argc, char* argv[])
{
		//1、获取自身句柄					
		
	
		EnableDebugPrivilege(); 	


		HMODULE pImageBuffer = GetModuleHandle(NULL);
		PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
		PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
		PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);
		PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));

		//获取自身sizeofimage
		DWORD sizeOfImage = pOptionHeader->SizeOfImage;

		//3、在当前空间申请空间存放自身代码					

		LPVOID pNewImagebuffer = malloc(sizeOfImage);
		
		//4、拷贝自身到缓存					
		memset(pNewImagebuffer, 0, sizeOfImage);
		memcpy(pNewImagebuffer, pImageBuffer, sizeOfImage);
		
		//5、打开要注入的进程					
		//先获取进程句柄
		DWORD pid = 0;
		printf("PID:");
		scanf("%d", &pid);
		
		HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);  //参数一,选择所有权限,参数二,不继承给false,参数三,给我们上面获得的pid的值
		if(NULL == hProcess)
		{
			printf("打开进程失败\n");
			return 0;
			}

		//6、在远程进程申请空间					

		
		LPVOID pImageBase = VirtualAllocEx(hProcess, NULL, sizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		if (!pImageBase)
		{
			printf("申请内存失败!\n");
			return false;
		}
	

		//7、对模块中的代码进行重定位					
		RestoreRelocation(pNewImagebuffer,(DWORD)pImageBase);
		
		//8、得到模块中要运行的函数的地址					
	
			//9、将模块在进程中的地址作为参数传递给入口函数	
			
		//10、将修正后的模块 通过WriteProcessMemory写入远程进程的内存空间中							
		DWORD byteWritten = 0;
		BOOL Write = WriteProcessMemory(hProcess, pImageBase, pNewImagebuffer, sizeOfImage, &byteWritten);
		if (!Write)
		{
			printf("can not write process memory!");
			return -1;
		}
		
		DWORD dwProcOffset = (DWORD)InjectEntry - (DWORD)pImageBuffer + (DWORD)pImageBase;	
		//11、通过CreateRemoteThread启动刚写入的代码							
		
		//创建行程线程,执行相应函数.
		HANDLE pThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)dwProcOffset, pImageBase, NULL, NULL);
		WaitForSingleObject(pThread, -1);

		//12、释放内存							

		return 0;

}


重定位表修复代码:


void RestoreRelocation(IN LPVOID pImageBuffer, IN DWORD newImageBase){
	
	//定义PE头的信息
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNTHeader = NULL;
	PIMAGE_FILE_HEADER pPEHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
	PIMAGE_SECTION_HEADER pSectionHeader = NULL;
	LPVOID pTempBuffer = NULL;
	bool Ssize = false;
	if(!pImageBuffer)
	{
		printf("读取到内存的pfilebuffer无效!\n");
		return;
	}
	//判断是不是exe文件
	if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
	{
		printf("不含MZ标志,不是exe文件!\n");
		return;
	}
	pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
	if(*((PDWORD)((BYTE *)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE){
		printf("无有效的PE标志\n");
		return;
	}
	
	//读取pFileBuffer 获取DOS头,PE头,节表等信息
	pDosHeader =(PIMAGE_DOS_HEADER)pImageBuffer;
	pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew);
	//打印NT头	
	pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);  //加4个字节到了标准PE头
	pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); //标准PE头+标准PE头的大小 20
	pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);
	
	DWORD oldImagebase = pOptionHeader->ImageBase;

    pOptionHeader->ImageBase = newImageBase;


	//定位重定位表
	PIMAGE_BASE_RELOCATION ReloCation = (_IMAGE_BASE_RELOCATION*)((char*)pImageBuffer + pOptionHeader->DataDirectory[5].VirtualAddress);
		

	
	PWORD pItem;		//重定向表块中的项指针,2字节不断移动
	int NumberOfItems;	//重定向表一块中的项数
	
	//这里pRelocationTable已经是当前绝对地址了
	
	while (ReloCation->VirtualAddress && ReloCation->SizeOfBlock)
	{
		
		NumberOfItems = (ReloCation->SizeOfBlock - 8) / 2;
		pItem = (PWORD)((DWORD)ReloCation + 8);	//这里取出来的是还没加上重定向块中的VirtualAddress的Rva
	
		for (int j = 0; j < NumberOfItems; j++)
		{
			WORD* offset = (WORD*)((char*)ReloCation+8+2*j); //每个数据项的地址
			if (*offset >= 0x3000)
			{
				//低12位加上x就是要修改的地方
				
				PDWORD RVA = (PDWORD)((DWORD)pImageBuffer + (ReloCation->VirtualAddress + (*offset-0x3000)));	//变为FOA再变为绝对地址才能找到真正的值
				*RVA =  *RVA - oldImagebase + pOptionHeader->ImageBase;
			}
			
		}
		ReloCation = (PIMAGE_BASE_RELOCATION)(ReloCation->SizeOfBlock + (DWORD)ReloCation);
	}

	
}

stdafx.h

// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__A359ADEE_2268_4545_9688_6E6BB264B3B3__INCLUDED_)
#define AFX_STDAFX_H__A359ADEE_2268_4545_9688_6E6BB264B3B3__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers

#include 
#include   
#include 
#include 


void __cdecl OutputDebugStringF(const char *format, ...); 

#ifdef _DEBUG  
#define DbgPrintf   OutputDebugStringF  
#else  
#define DbgPrintf  
#endif 


void __cdecl OutputDebugStringF(const char *format, ...)  
{  
    va_list vlArgs;  
    char    *strBuffer = (char*)GlobalAlloc(GPTR, 4096);  
	
    va_start(vlArgs, format);  
    _vsnprintf(strBuffer, 4096 - 1, format, vlArgs);  
    va_end(vlArgs);  
    strcat(strBuffer, "\n");  
    OutputDebugStringA(strBuffer);  
    GlobalFree(strBuffer);  
    return;  
}  



// TODO: reference additional headers your program requires here

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__A359ADEE_2268_4545_9688_6E6BB264B3B3__INCLUDED_)

petools.h可以删除,最终实现效果;

隐藏模块(无模块注入)_第1张图片

你可能感兴趣的:(逆向,滴水三期,windows,c语言,c++)