滴水逆向笔记系列-win总结11-65.进程通信-66.内存写入作业

第六十五课 进程通信

1.共享内存

发送端代码

#include <Windows.h>
#include <stdio.h>

int main()
{
	HANDLE hMapObject;
	HANDLE hMapView;

	//创建FileMapping对象					
	hMapObject = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 0x1000, TEXT("shared"));
	if (!hMapObject)
	{
		MessageBox(NULL, TEXT("共享内存失败"), TEXT("Error"), MB_OK);
		return FALSE;
	}
	//将FileMapping对象映射到自己的进程					
	hMapView = MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0);
	if (!hMapView)
	{
		MessageBox(NULL, TEXT("内存映射失败"), TEXT("Error"), MB_OK);
		return FALSE;
	}
	//向共享内存写入数据					
	strcpy((char*)hMapView, "Test Shared Memery");

}

接收端代码:

#include <Windows.h>

int main()
{
	HANDLE hMapObject;
	HANDLE hMapView;

	//创建FileMapping对象					
	hMapObject = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 0x1000, TEXT("shared"));
	if (!hMapObject)
	{
		MessageBox(NULL, TEXT("共享内存失败"), TEXT("Error"), MB_OK);
		return FALSE;
	}
	//将FileMapping对象映射到自己的进程					
	hMapView = MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0);
	if (!hMapView)
	{
		MessageBox(NULL, TEXT("内存映射失败"), TEXT("Error"), MB_OK);
		return FALSE;
	}
	//从共享内存读取数据					
	TCHAR szBuffer[0x1000] = { 0 };
	memcpy(szBuffer, hMapView, 10);
}

2.匿名管道

父进程:

HANDLE hRead;							
HANDLE hWrite;							
							
SECURITY_ATTRIBUTES sa;							
							
sa.bInheritHandle = TRUE;							
sa.lpSecurityDescriptor = NULL;							
sa.nLength = sizeof(SECURITY_ATTRIBUTES);							
							
if(!CreatePipe(&hRead,&hWrite,&sa,0))							
{							
	MessageBox(0,TEXT("创建匿名管道失败!"),TEXT("Error"),MB_OK);						
}							
							
STARTUPINFO si;							
PROCESS_INFORMATION pi;							
							
ZeroMemory(&si,sizeof(STARTUPINFO));							
							
si.cb = sizeof(STARTUPINFO);							
si.dwFlags = STARTF_USESTDHANDLES;							
si.hStdInput = hRead;							
si.hStdOutput = hWrite;							
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);							
							
if(!CreateProcess("E:\\Project\\zzzzzzz\\Debug\\zzzzzzz.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))							
{							
	CloseHandle(hRead);						
	CloseHandle(hWrite);						
	hRead = NULL;						
	hWrite = NULL;						
	MessageBox(0,TEXT("创建子进程失败!"),TEXT("Error"),MB_OK);						
}							
else							
{							
	CloseHandle(pi.hProcess);						
	CloseHandle(pi.hThread);						
}							
							
							
							
//写数据							
TCHAR szBuffer[] = "http:\\www.dtdebug.com";							
DWORD dwWrite;							
if(!WriteFile(hWrite,szBuffer,strlen(szBuffer)+1,&dwWrite,NULL))							
{							
	MessageBox(0,TEXT("写数据失败!"),TEXT("Error"),MB_OK);						
}							
							
//读数据							
TCHAR szBuffer[100];							
DWORD dwRead;							
if(!ReadFile(hRead,szBuffer,100,&dwRead,NULL))							
{							
	MessageBox(NULL,TEXT("读取数据失败!"),TEXT("Error"),MB_OK);						
}							
else							
{							
	MessageBox(NULL,szBuffer,TEXT("[读取数据]"),MB_OK);						
}							

子进程:

//初始化							
HANDLE hRead = GetStdHandle(STD_INPUT_HANDLE);							
HANDLE hWrite = GetStdHandle(STD_OUTPUT_HANDLE);  							
							
//读数据							
TCHAR szBuffer[100];							
DWORD dwRead;							
if(!ReadFile(hRead,szBuffer,100,&dwRead,NULL))							
{							
	MessageBox(NULL,TEXT("读取数据失败!"),TEXT("Error"),MB_OK);						
}							
else							
{							
	MessageBox(NULL,szBuffer,TEXT("[读取数据]"),MB_OK);						
}							
							
//写数据							
TCHAR szBuffer[100] = "匿名管道";							
DWORD dwWrite;							
if(!WriteFile(hWrite,szBuffer,strlen(szBuffer)+1,&dwWrite,NULL))							
{							
	MessageBox(NULL,TEXT("写入数据失败!"),TEXT("Error"),MB_OK);						
}				

第六十六课 内存写入作业

代码暂时还有问题

#include <windows.h>
#include <stdio.h>
#include "resource.h"
#include "tools.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);

	OutPutDebugStringF("%x", ImportExtable->FirstThunk);
	while (ImportExtable->OriginalFirstThunk != 0 && ImportExtable->FirstThunk != 0) {

		char* DllName = (char*)lpParam + ImportExtable->Name;

		OutPutDebugStringF("加载的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)
			{
				OutPutDebugStringF("按序号导入序号%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);
				OutPutDebugStringF("按名称导入HIT/NAME-%x-%s\n", FirstThunkNames->Hint, FirstThunkNames->Name);
				(*pThunkData_IAT) = (DWORD)GetProcAddress(LoadLibrary(DllName), (char*)FirstThunkNames->Name);
				OutPutDebugStringF("--%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;
}

INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParma)
{
	switch (uMsg)
	{
	case WM_CLOSE:
		EndDialog(hWnd, 0);
		return TRUE;
	}

	return FALSE; //返回1 就是系统处理,0就是自己处理
}

DWORD inject(DWORD PID)
{
	//1、获取自身句柄
	HANDLE hSelf = GetModuleHandle(NULL);

	//2、获取ImageSize的大小,得到模块的Imagebuffer
	LPVOID SelfImagebase = hSelf;
	PIMAGE_DOS_HEADER pDos_header0 = NULL;
	PIMAGE_NT_HEADERS pNT_header0 = NULL;
	PIMAGE_FILE_HEADER pPE_header0 = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOption_header0 = NULL;

	//算出ImageBuffer中的dos头nt头pe头节表地址
	pDos_header0 = (PIMAGE_DOS_HEADER)SelfImagebase;
	pNT_header0 = (PIMAGE_NT_HEADERS)((DWORD)pDos_header0 + pDos_header0->e_lfanew);
	pPE_header0 = (PIMAGE_FILE_HEADER)((DWORD)pNT_header0 + 4);
	pOption_header0 = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPE_header0 + IMAGE_SIZEOF_FILE_HEADER);
	int SelfImageSize = pOption_header0->SizeOfImage;

	//3、申请空间存放自身代码
	LPVOID SelfBuffer = malloc(SelfImageSize);
	memset(SelfBuffer,0, SelfImageSize);

	//4、复制自身到SelfBuffer
	memcpy(SelfBuffer, SelfImagebase, SelfImageSize);

	PIMAGE_DOS_HEADER pDos_header = NULL;
	PIMAGE_NT_HEADERS pNT_header = NULL;
	PIMAGE_FILE_HEADER pPE_header = NULL;
	PIMAGE_OPTIONAL_HEADER32 pOption_header = NULL;

	pDos_header = (PIMAGE_DOS_HEADER)SelfBuffer;
	pNT_header = (PIMAGE_NT_HEADERS)((DWORD)pDos_header + pDos_header->e_lfanew);
	pPE_header = (PIMAGE_FILE_HEADER)((DWORD)pNT_header + 4);
	pOption_header = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPE_header + IMAGE_SIZEOF_FILE_HEADER);

	//5、打开要注入的进程
	HANDLE hInjectProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, PID);

	//6、远程申请空间
	LPVOID pRemoteBuffer = VirtualAllocEx(hInjectProcess, NULL, SelfImageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

	//7、修复重定位表
	PIMAGE_BASE_RELOCATION pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)SelfImagebase + pOption_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
	//判断有没有重定位表
	if (!pOption_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)
	{
		printf("不存在重定位表");
	}
	DWORD increment = labs((DWORD)pRemoteBuffer - (DWORD)SelfBuffer);
	while (pRelocationTable->SizeOfBlock != NULL && pRelocationTable->VirtualAddress != NULL)
	{
		PWORD pIem = ((PWORD)pRelocationTable + 4);
		DWORD NumberofIem = ((pRelocationTable->SizeOfBlock - 8) / 2);
		for (int i = 0 ; i<NumberofIem ; i++,pIem++)
		{
			
			if (*pIem >> 12 == 3)
			{
				PDWORD RVA = (PDWORD)((DWORD)SelfBuffer + pRelocationTable->VirtualAddress + (*pIem & 0xfff));
				OutPutDebugStringF("修复的地址为:%x\n",*RVA);
				if ((DWORD)pRemoteBuffer > (DWORD)SelfBuffer)
				{
					*RVA += increment;
				}
				else
				{
					*RVA -= increment;
				}
				*RVA += increment;
				OutPutDebugStringF("修复完的地址为:%x\n", *RVA);
			}

		}
		pRelocationTable = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocationTable + (DWORD)pRelocationTable->SizeOfBlock);

	}

	//8、写入远程进程的内存空间
	BOOL WP = WriteProcessMemory(hInjectProcess, pRemoteBuffer, SelfBuffer, SelfImageSize,NULL);

	//9、调用远程线程执行注入程序
	DWORD dwProcOffset = (DWORD)InjectEntry - (DWORD)hSelf + (DWORD)pRemoteBuffer;
	HANDLE hCRT = CreateRemoteThread(hInjectProcess,NULL,0, (LPTHREAD_START_ROUTINE)dwProcOffset, pRemoteBuffer,0,NULL);

	WaitForSingleObject(hCRT, -1);

	return 0;
}


int CALLBACK WinMain(HINSTANCE hIstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdSHow)
{
	DWORD PID = 6208;
	inject(PID);
	DialogBox(hIstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);;

	return 0;
}
posted @ 2024-03-17 17:34  小新07  阅读(89)  评论(1编辑  收藏  举报