L o a d i n g . . .
主打一个C++
文章详情

C++入口点注入dll(x64创建挂起进程注入后注入dll)

Posted on 2019-01-02 18:05:16 by 主打一个C++

C++入口点注入dll(创建挂起进程注入后注入dll),也成为主线程注入。

  1. 以CREATE_SUSPENDED标志启动进程为挂起状态,
  2. 写入用于装载dll的shellcode
  3. 写入dll路径
  4. 获取程序入口点写入跳转代码
  5. 确保是x64进程和dll,因为shellcode是x64编码,可自行改x86

C++完整代码:

//入口点注入
int EntryInjectDll(const char* _exeFullPath, const char* _dllFullPath) {
	STARTUPINFOA si = { sizeof(STARTUPINFOA) };// si.cb = sizeof(STARTUPINFOA);
	PROCESS_INFORMATION pi = { 0 };

	BOOL ret = CreateProcessA(_exeFullPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
	if (ret == FALSE)
		return 1;
	int error = 0;
	LPVOID addr = NULL;
	do
	{
		addr = VirtualAllocEx(pi.hProcess, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		if (addr == NULL) {
			error = 3;
			break;
		}
		//加载代码
		char code[] = {
			0x51,0x52,0x41,0x50,0x41,0x51,						//push rcx,rdx,r8,r9
			0xFC,												//cld
			0x48,0xBE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	//mov rsi,0000000000000000 - 数据地址
			0x48,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	//mov rdi,0000000000000000 - 要还原的地址
			0x48,0xB9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	//mov rcx,0000000000000000 - 还原字节的长度
			0xF3,0xA4,											//repe movsb 											
			0x48,0xB9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	//mov rcx,0000000000000000 - dll路径地址
			0x51,												//push rcx
			0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	//mov rax,0000000000000000 - LoadLibraryA地址
			0xFF,0xD0,											//call rax
			0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	//mov rax,0000000000000000 - 返回地址
			0x41,0x59,											//pop r9
			0x41,0x58,											//pop r8
			0x5A,												//pop rdx
			0x59,												//pop rcx
			0x50,												//push rax
			0x50,												//push rax
			0xC3												//ret 
		};
		//获取入口点
		typedef INT(__stdcall* _ZwQueryInformationThread)(
			_In_      HANDLE          ThreadHandle,
			_In_      INT ThreadInformationClass,
			_In_      PVOID           ThreadInformation,
			_In_      ULONG           ThreadInformationLength,
			_Out_opt_ PULONG          ReturnLength);
		_ZwQueryInformationThread ZwQueryInformationThread = (_ZwQueryInformationThread)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQueryInformationThread");
		if (ZwQueryInformationThread == NULL) {
			error = 1;
			break;
		}
		ULONGLONG entry_addr = 0; ULONG len = 0;
		ZwQueryInformationThread(pi.hThread, 9, &entry_addr, 8, &len);
		if (entry_addr == 0) {
			error = 2;
			break;
		}
		//填充 数据地址
		BYTE data1[16] = {};
		SIZE_T rSize = 0;
		ReadProcessMemory(pi.hProcess, (LPVOID)entry_addr, data1, sizeof(data1), &rSize);
		//写入还原数据
		ULONGLONG address = (ULONGLONG)addr + 500;
		WriteProcessMemory(pi.hProcess, (LPVOID)address, data1, sizeof(data1), &rSize);
		memcpy(&9[code], &address, sizeof(ULONGLONG));
		//填充入口还原地址
		memcpy(&19[code], &entry_addr, sizeof(ULONGLONG));
		rSize = 16;//还原字节的长度
		memcpy(&29[code], &rSize, sizeof(ULONGLONG));
		//写入dll路径
		address = (ULONGLONG)addr + 600;
		WriteProcessMemory(pi.hProcess, (LPVOID)address, _dllFullPath, strlen(_dllFullPath) + 1, &rSize);
		//填充dll路径地址
		memcpy(&41[code], &address, sizeof(ULONGLONG));
		//填充LoadLibraryA地址
		address = (ULONGLONG)&LoadLibraryA;
		memcpy(&52[code], &address, sizeof(ULONGLONG));
		//填充返回地址
		memcpy(&64[code], &entry_addr, sizeof(ULONGLONG));
		WriteProcessMemory(pi.hProcess, addr, code, sizeof(code), &rSize);

		//写入跳转代码
		BYTE jmp[] = {
			0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	//mov rax,0000000000000000 - 跳转地址
			0x50,												//push rax
			0xC3												//ret 
		};
		address = (ULONGLONG)addr;
		memcpy(&2[jmp], &address, sizeof(ULONGLONG));
		//可能需要修改内存属性
		DWORD pro = 0;
		VirtualProtectEx(pi.hProcess, (LPVOID)entry_addr, 0x10, PAGE_EXECUTE_READWRITE, &pro);
		WriteProcessMemory(pi.hProcess, (LPVOID)entry_addr, jmp, sizeof(jmp), &rSize);
		ResumeThread(pi.hThread);
	} while (false);
	if (error != 0) {
		TerminateProcess(pi.hProcess, 0);
	}
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);
	return error;

}

//测试注入

int main() {

	int err = EntryInjectDll("Notepad.exe", "Dll1.dll");
	printf("注入结果: %d\n", err);
	system("pause");
	return 0;
}


*转载请注明出处:原文链接:https://cpp.vin/page/72.html

作者近期文章
  • 随手笔记
  • 主打一个C++   2025-01-11 20:02:01
  • 都2000000025年了。还有不能随意访问guthub的,仔细看。在国内其实是可以正常访问的,gfw并没屏蔽。这里给出其中一个简单直接的方法稳定访问。1. 随便百度一个”dn
提示
×
确定
数据库执行: 8次 总耗时: 0.02s
页面加载耗时: 



wechat +447752296473
wechat cpp-blog