当前位置:   article > 正文

内存写入注入_getsizeofimage

getsizeofimage

内存写入注入

如果进程A本身就给了其他进程申请和写入空间的权限,那我只要将模块复制到指定进程A的空间里面,再利用远程线程或者hook也就能让我们的模块在进程A运行,这就是内存写入注入

思路

只要我进程A允许进程B有写入操作就可以实现注入。这样实现了隐藏模块的注入

拓展:若是不允许别的进程有写入操作,但应该也会允许系统进程有写入操作,只要我将注入功能注入到系统进程里面,让系统进程对进程A进行内存写入注入就可以了。相当于内存写入注入+伪装合法软件注入

在这里插入图片描述

步骤

1、内存写入:

  • 获取当前模块句柄,得到SizeOfImage的大小和Image Base
  • 在当前空间申请空间存放自身代码
  • 打开要注入的进程A
  • 在远程进程A中申请空间,大小为SizeOfImage
  • 对本身进程B中的代码进行重定位
  • 得到本身进程B中要在进程A中运行的函数的地址,重定位后的地址
  • 将重定位修正后的数据 通过WriteProcessMemory写入远程进程的内存空间中
  • 通过CreateRemoteThread开线程,线程函数地址为Entry重定位后的地址
  • 释放当前空间申请的内存

2、模块入口函数执行

  • 根据重定位信息,修复IAT表。
    • 因为被注入的进程可能没有自己进程的一些系统函数,所以注入模块的第一步便是修复IAT表
    • 可能两个有些系统dll没有预装到指定位置,所以修复
    • 海哥说不是所有dll都能正确加载到相同的位置
  • 执行其他功能
  • 通过全局变量来结束这个函数

为什么不用修复IAT表也可以注入成功,我想:

只要我注入进的代码这里用的函数都是被注入进程dll里面有的应该就可以不用修复,因为两个常见系统dll(user32、kernel32)都会抢占到相同的内存地址 。正因为抢占到了相同位置,所以并不需要修复IAT表。但我注入进的代码用到其他 位置不相同的dll了就需要修复IAT表了

还有调用系统函数是间接call,这样可能会想就算重定位修复了IAT的地址如:FF [4123] 变成了 FF[5123],但IAT表里面的内容没有跟着移动到新的地址,所以FF[5123]里面是空的。这样想恰恰是错误的,我们复制是根据ImageBase整体复制的,内容并没有改变,IAT表的内容也会从[4123]复制到[5123],也正是这样,我们才需要修复间接Call,让它从4123变成5123

实例

说明:XP和Win10上都可以运行,没有修复IAT表。

错误点:卸载注入时有错误,能通过内存写入改变全局变量来结束远程线程,但远程释放空间会让程序崩溃

#include <stdio.h>
#include <iostream>
#include < windows.h>
#define PID 13912
#define RELOCATION 5
using namespace std;

//得到Image_base  SizeOfImage  EntryPoint
DWORD GetSizeOfImage(IN LPVOID FileBuffer, OUT DWORD& ImageBase, OUT DWORD& EntryPoint)
{
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)FileBuffer;
	PIMAGE_FILE_HEADER pFile = (PIMAGE_FILE_HEADER)((DWORD)FileBuffer + pDos->e_lfanew + 0x4);
	PIMAGE_OPTIONAL_HEADER32 pOption = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);
	PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((DWORD)pOption + pFile->SizeOfOptionalHeader);

	ImageBase = pOption->ImageBase;
	EntryPoint = pOption->AddressOfEntryPoint;

	//防止ImageSize不准,靠最后一个节来得到ImageSize
	DWORD Last_idex = pFile->NumberOfSections - 1;
	DWORD real_ImageSize = pSection[Last_idex].VirtualAddress + pSection[Last_idex].SizeOfRawData;
	return real_ImageSize;
}

//修复重定位表
void FixRelocation(IN LPVOID Buffer, IN DWORD FixImageBase)
{

	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)Buffer;
	if (pDos->e_magic != IMAGE_DOS_SIGNATURE || *(PDWORD)((DWORD)pDos + pDos->e_lfanew) != IMAGE_NT_SIGNATURE)
	{
		cout << "NOT MZ" << endl;
		return;
	}
	PIMAGE_FILE_HEADER pFile = (PIMAGE_FILE_HEADER)((DWORD)pDos + pDos->e_lfanew + 4);
	PIMAGE_OPTIONAL_HEADER32 pOptionalFile = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFile + IMAGE_SIZEOF_FILE_HEADER);
	PIMAGE_BASE_RELOCATION pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)Buffer + pOptionalFile->DataDirectory[5].VirtualAddress);
	//保存原本值 更改ImageBase
	DWORD Imagebase = pOptionalFile->ImageBase;
	pOptionalFile->ImageBase = FixImageBase;

	//修复重定位表
	PWORD pDataAddr = (PWORD)((DWORD)pRelocation + 8);
	DWORD Block = pRelocation->SizeOfBlock;
	DWORD VitualAddr = pRelocation->VirtualAddress;

	PDWORD Replace = NULL;
	DWORD Rva = 0;
	while (Block != 0 && VitualAddr != 0)
	{
		for (DWORD i = 0; i < (Block - 8) / 2; i++)
		{
			// 高四位值为3 代表的是需要修改的数据 
			if ((*(pDataAddr + i) & 0xF000) == 0x3000)
			{
				Rva = (*(pDataAddr + i) & 0x0FFF) + VitualAddr;
				Replace = (PDWORD)((DWORD)Buffer + Rva);
				*Replace = *Replace - Imagebase + FixImageBase;
			}

		}
		pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + Block);
		Block = pRelocation->SizeOfBlock;
		VitualAddr = pRelocation->VirtualAddress;
		pDataAddr = (PWORD)((DWORD)pRelocation + 8);
	}
}

//全局变量,用于控远程线程函数
DWORD ExitCode = 0;
//要执行的函数  线程函数格式
DWORD WINAPI Entry(LPVOID lpParameter)
{
	//程序代码
	while(1)
	{
		Sleep(2000);
		MessageBox(NULL, L"执行的函数", L"注入", MB_OK);
		if (ExitCode)
		{
			ExitThread(1);
			return 0;
		}
	}
	return 0;
}

int main()
{
	cout << "注入中...." << endl;
	//获取当前模块句柄  
	HANDLE hCurrentProcess = NULL;
	hCurrentProcess = ::GetModuleHandle(NULL);
	if (hCurrentProcess == NULL)
	{
		cout << "获取当前模块句柄失败" << endl;
		return 0;
	}

	//得到自己的SizeOfImage和ImageBase
	DWORD EntryPoint = 0;
	DWORD ImageBase = 0;
	DWORD SizeOfImage = GetSizeOfImage((LPVOID)(DWORD)hCurrentProcess, ImageBase, EntryPoint);

	//当前空间申请空间存放自身代码
	LPVOID pszBuffer = malloc(SizeOfImage);
	if (pszBuffer == NULL)
	{
		cout << "申请空间失败" << endl;
		return 0;
	}
	ZeroMemory(pszBuffer, SizeOfImage);

	//空间存放自身代码
	memcpy(pszBuffer, (LPVOID)ImageBase, SizeOfImage);

	//获取要注入的进程A句柄 
	HANDLE hProcess = NULL;
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
	if (hProcess == NULL)
	{
		cout << "获取进程A句柄失败" << endl;
		return 0;
	}

	//在远程进程A中申请空间
	LPVOID pszProBuffer = NULL;
	pszProBuffer = VirtualAllocEx(hProcess, NULL, SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (pszProBuffer == NULL)
	{
		cout << "远程进程A中申请空间失败" << endl;
		return 0;
	}

	//修复重定位表
	FixRelocation(pszBuffer, (DWORD)pszProBuffer);

	//写入远程进程空间
	DWORD WriteSize = 0;
	if (!WriteProcessMemory(hProcess, pszProBuffer, pszBuffer, SizeOfImage, &WriteSize))
	{
		cout << "写入远程进程失败" << endl;
		return 0;
	}

	//创建远程线程

	坑点  给的线程函数地址需要是重定位后的
	DWORD dwProcOffset = (DWORD)Entry - (DWORD)ImageBase + (DWORD)pszProBuffer;
	坑点

	HANDLE hThread = NULL;
	hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)dwProcOffset, NULL, 0, 0);

	//释放本身内存
	free(pszBuffer);

	//释放
	system("pause");
	DWORD CodeAddr = (DWORD)&ExitCode - (DWORD)ImageBase + (DWORD)pszProBuffer;
	DWORD Code = 1;
	DWORD size;
	if (!WriteProcessMemory(hProcess, (LPVOID)CodeAddr, (LPVOID)&Code, 4, &size))
	{
		cout << "写入远程进程失败" << endl;
		return 0;
	}
	//远程释放会崩
	//VirtualFreeEx(hProcess,pszProBuffer,SizeOfImage,MEM_DECOMMIT);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171

注入成功图,在win10上测试:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/204183?site
推荐阅读
相关标签
  

闽ICP备14008679号