滴水逆向笔记系列-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;
}