首页
社区
课程
招聘
[原创]创建进程时注入DLL
发表于: 2013-11-7 22:19 37954

[原创]创建进程时注入DLL

2013-11-7 22:19
37954
注入DLL时有可能出现这样的情况,需要在程序运行之前注入,这样就需要一个启动器。
当然可以为添加导入表,或者DLL劫持。问题是 这样万一程序更新又要重新弄一次。

我写了个简单的启动器,创建进程,并且注入一个DLL
#include "windows.h"
#include "stdio.h"

BOOL StartHook(HANDLE hProcess,HANDLE hThread);

BOOL EnableDebugPriv();
int main()
{
	EnableDebugPriv();
	STARTUPINFO sti;
	PROCESS_INFORMATION proci;
	memset(&sti,0,sizeof(STARTUPINFO));
	memset(&proci,0,sizeof(PROCESS_INFORMATION));
	sti.cb=sizeof(STARTUPINFO);

	wchar_t ExeName[]=L"notepad.exe";
	DWORD valc=CreateProcess(ExeName,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL\
		,&sti,&proci);
	if (valc==NULL)
	{
		printf("Creaet Process Failed ERROR=%d\n",GetLastError());
		getchar();
		return 0;
	}
	if (!StartHook(proci.hProcess,proci.hThread))
	{
		TerminateProcess(proci.hProcess,0);
		printf("失败\n");
		getchar();
		return 0;
	}
	ResumeThread(proci.hThread);
	CloseHandle(proci.hProcess);
	CloseHandle(proci.hThread);
	return 0;
}
BYTE ShellCode[64]=
					{
					0x60,
					0x9c,
					0x68,
					0xaa,0xbb,0xcc,0xdd,//dll path
					0xff,0x15,
					0xdd,0xcc,0xbb,0xaa,//call [xxxx]
					0x9d,
					0x61,
					0xff,0x25,
					0xaa,0xbb,0xcc,0xdd,// jmp [xxxxx]
					0xaa,0xaa,0xaa,0xaa,// loadaddr
					0xaa,0xaa,0xaa,0xaa//  jmpaddr
					};
/*
{
00973689 >    60                PUSHAD
0097368A      9C                PUSHFD
0097368B      68 50369700       PUSH notepad.00973650
00973690      FF15 70369700     CALL DWORD PTR DS:[973670]
00973696      9D                POPFD
00973697      61                POPAD
00973698    - FF25 30369700     JMP DWORD PTR DS:[973630]


}
*/
BYTE *DllPath;
BOOL StartHook(HANDLE hProcess,HANDLE hThread)
{


	CONTEXT ctx;
	ctx.ContextFlags=CONTEXT_ALL;
	if (!GetThreadContext(hThread,&ctx))
	{
		printf("GetThreadContext Error\n");
		return FALSE;
	}
	LPVOID LpAddr=VirtualAllocEx(hProcess,NULL,64,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	if (LpAddr==NULL)
	{
		printf("VirtualAlloc Error\n");
		return FALSE;
	}
	DWORD LoadDllAAddr=(DWORD)GetProcAddress(GetModuleHandle(L"kernel32.dll"),"LoadLibraryA");
	if (LoadDllAAddr==NULL)
	{
		printf("LoadDllAddr error\n");
		return FALSE;
	}
	//printf("eip=0x%08x\n",ctx.Eip);
	//printf("lpAddr=0x%08x\n",LpAddr);
	//printf("LoadLibraryAAddr=0x%08x\n",LoadDllAAddr);

	/////////////
	_asm mov esp,esp
	DllPath=ShellCode+29;
	strcpy((char*)DllPath,"SomeHook.dll");//这里是要注入的DLL名字
	*(DWORD*)(ShellCode+3)=(DWORD)LpAddr+29;
	////////////////
	*(DWORD*)(ShellCode+21)=LoadDllAAddr;
	*(DWORD*)(ShellCode+9)=(DWORD)LpAddr+21;
	//////////////////////////////////
	*(DWORD*)(ShellCode+25)=ctx.Eip;
	*(DWORD*)(ShellCode+17)=(DWORD)LpAddr+25;
	////////////////////////////////////
	if (!WriteProcessMemory(hProcess,LpAddr,ShellCode,64,NULL))
	{
		printf("write Process Error\n");
		return FALSE;
	}
	ctx.Eip=(DWORD)LpAddr;
	if (!SetThreadContext(hThread,&ctx))
	{
		printf("set thread context error\n");
		return FALSE;
	}
	return TRUE;
};


BOOL EnableDebugPriv() 
{
	HANDLE   hToken; 
	LUID   sedebugnameValue; 
	TOKEN_PRIVILEGES   tkp;
	if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) 
	{ 
		return   FALSE; 
	} 

	if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&sedebugnameValue)) 
	{ 
		CloseHandle(hToken); 
		return   FALSE; 
	} 
	tkp.PrivilegeCount   =   1; 
	tkp.Privileges[0].Luid   =   sedebugnameValue; 
	tkp.Privileges[0].Attributes   =   SE_PRIVILEGE_ENABLED; 

	if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL)) 
	{ 
		return   FALSE; 
	}   
	CloseHandle(hToken); 
	return TRUE;

} 


把这个exe还有要注入的DLL 和目标程序放在一个目录。
使用这个exe就可以在启动程序时注入DLL.只是目标EXE申请的内存没有释放掉
简单易行。不知道有没有更简单的办法

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (39)
雪    币: 85
活跃值: (51)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
感谢楼主分享,简单的方法有很多,隐蔽才是王道
2013-11-7 22:29
0
雪    币: 27
活跃值: (90)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
感谢楼主分享,应该不错吧。
2013-11-7 22:53
0
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
shellcode有冗余,鉴定完毕
2013-11-7 23:02
0
雪    币: 3017
活跃值: (3060)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
#include "stdafx.h"
#include <Windows.h>

// 函数声明
typedef BOOL (WINAPI* Proc_CreateProcessW)(LPCWSTR lpApplicationName,
										   LPWSTR lpCommandLine,
										   LPSECURITY_ATTRIBUTES lpProcessAttributes,
										   LPSECURITY_ATTRIBUTES lpThreadAttributes,
										   BOOL bInheritHandles,
										   DWORD dwCreationFlags,
										   LPVOID lpEnvironment,
										   LPCWSTR lpCurrentDirectory,
										   LPSTARTUPINFOW lpStartupInfo,
										   LPPROCESS_INFORMATION lpProcessInformation);

typedef HMODULE (WINAPI* Func_LoadLibraryW)(LPCWSTR lpLibFileName);


BYTE* mov_eax_xx(BYTE* lpCurAddres, DWORD eax)
{
	*lpCurAddres = 0xB8;
	*(DWORD*)(lpCurAddres + 1) = eax;
	return lpCurAddres + 5;
}

BYTE* mov_ebx_xx(BYTE* lpCurAddres, DWORD ebx)
{
	*lpCurAddres = 0xBB;
	*(DWORD*)(lpCurAddres + 1) = ebx;
	return lpCurAddres + 5;
}

BYTE* mov_ecx_xx(BYTE* lpCurAddres, DWORD ecx)
{
	*lpCurAddres = 0xB9;
	*(DWORD*)(lpCurAddres + 1) = ecx;
	return lpCurAddres + 5;
}

BYTE* mov_edx_xx(BYTE* lpCurAddres, DWORD edx)
{
	*lpCurAddres = 0xBA;
	*(DWORD*)(lpCurAddres + 1) = edx;
	return lpCurAddres + 5;
}

BYTE* mov_esi_xx(BYTE* lpCurAddres, DWORD esi)
{
	*lpCurAddres = 0xBE;
	*(DWORD*)(lpCurAddres + 1) = esi;
	return lpCurAddres + 5;
}

BYTE* mov_edi_xx(BYTE* lpCurAddres, DWORD edi)
{
	*lpCurAddres = 0xBF;
	*(DWORD*)(lpCurAddres + 1) = edi;
	return lpCurAddres + 5;
}

BYTE* mov_ebp_xx(BYTE* lpCurAddres, DWORD ebp)
{
	*lpCurAddres = 0xBD;
	*(DWORD*)(lpCurAddres + 1) = ebp;
	return lpCurAddres + 5;
}

BYTE* mov_esp_xx(BYTE* lpCurAddres, DWORD esp)
{
	*lpCurAddres = 0xBC;
	*(DWORD*)(lpCurAddres + 1) = esp;
	return lpCurAddres + 5;
}

BYTE* mov_eip_xx(BYTE* lpCurAddres, DWORD eip, DWORD newEip)
{
	if ( !newEip )
	{
		newEip = (DWORD)lpCurAddres;
	}

	*lpCurAddres = 0xE9;
	*(DWORD*)(lpCurAddres + 1) = eip - (newEip + 5);
	return lpCurAddres + 5;
}

BYTE* push_xx(BYTE* lpCurAddres, DWORD dwAdress)
{

	*lpCurAddres = 0x68;
	*(DWORD*)(lpCurAddres + 1) = dwAdress;

	return lpCurAddres + 5;
}

BYTE* Call_xx(BYTE* lpCurAddres, DWORD eip, DWORD newEip)
{
	if ( !newEip )
	{
		newEip = (DWORD)lpCurAddres;
	}

	*lpCurAddres = 0xE8;
	*(DWORD*)(lpCurAddres + 1) = eip - (newEip + 5);
	return lpCurAddres + 5;
}

BOOL SuspendTidAndInjectCode(HANDLE hProcess, HANDLE hThread, DWORD dwFuncAdress, const BYTE * lpShellCode, size_t uCodeSize)
{
	SIZE_T NumberOfBytesWritten = 0;
	BYTE ShellCodeBuf[0x480];
	CONTEXT Context;
	DWORD flOldProtect = 0;
	LPBYTE lpCurESPAddress = NULL;
	LPBYTE lpCurBufAdress = NULL;
	BOOL bResult = FALSE;
	

	// 挂载起线程
	SuspendThread(hThread);

	memset(&Context,0,sizeof(Context));
	Context.ContextFlags = CONTEXT_FULL;

	if ( GetThreadContext(hThread, &Context))
	{
		// 在对方线程中开辟一个 0x480 大小的局部空
		lpCurESPAddress = (LPBYTE)((Context.Esp - 0x480) & 0xFFFFFFE0);
		
		// 获取指针 用指针来操作
		lpCurBufAdress = &ShellCodeBuf[0];

		if (lpShellCode)
		{
			memcpy(ShellCodeBuf + 128, lpShellCode, uCodeSize);
			lpCurBufAdress = push_xx(lpCurBufAdress, (DWORD)lpCurESPAddress + 128); // push
			lpCurBufAdress = Call_xx(lpCurBufAdress, dwFuncAdress, (DWORD)lpCurESPAddress + (DWORD)lpCurBufAdress - (DWORD)&ShellCodeBuf); //Call
		}

		lpCurBufAdress = mov_eax_xx(lpCurBufAdress, Context.Eax);
		lpCurBufAdress = mov_ebx_xx(lpCurBufAdress, Context.Ebx);
		lpCurBufAdress = mov_ecx_xx(lpCurBufAdress, Context.Ecx);
		lpCurBufAdress = mov_edx_xx(lpCurBufAdress, Context.Edx);
		lpCurBufAdress = mov_esi_xx(lpCurBufAdress, Context.Esi);
		lpCurBufAdress = mov_edi_xx(lpCurBufAdress, Context.Edi);
		lpCurBufAdress = mov_ebp_xx(lpCurBufAdress, Context.Ebp);
		lpCurBufAdress = mov_esp_xx(lpCurBufAdress, Context.Esp);
		lpCurBufAdress = mov_eip_xx(lpCurBufAdress, Context.Eip, (DWORD)lpCurESPAddress + (DWORD)lpCurBufAdress - (DWORD)&ShellCodeBuf);
		Context.Esp = (DWORD)(lpCurESPAddress - 4);
		Context.Eip = (DWORD)lpCurESPAddress;
		
		if ( VirtualProtectEx(hProcess, lpCurESPAddress, 0x480, PAGE_EXECUTE_READWRITE, &flOldProtect)
			&& WriteProcessMemory(hProcess, lpCurESPAddress, &ShellCodeBuf, 0x480, &NumberOfBytesWritten)
			&& FlushInstructionCache(hProcess, lpCurESPAddress, 0x480)
			&& SetThreadContext(hThread, &Context) )
		{
			bResult = TRUE;
		}

	}
	
	// 回复线程
	ResumeThread(hThread);

	return TRUE;
}

DWORD GetFuncAdress()
{
	return (DWORD)GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryW");
}

BOOL WINAPI CreateProcessWithDllW(  LPCWSTR lpApplicationName,
									LPWSTR lpCommandLine,
									LPSECURITY_ATTRIBUTES lpProcessAttributes,
									LPSECURITY_ATTRIBUTES lpThreadAttributes,
									BOOL bInheritHandles,
									DWORD dwCreationFlags,
									LPVOID lpEnvironment,
									LPCWSTR lpCurrentDirectory,
									LPSTARTUPINFOW lpStartupInfo,
									LPPROCESS_INFORMATION lpProcessInformation,
									LPWSTR lpDllFullPath,
									Proc_CreateProcessW FuncAdress
									)
{
	BOOL bResult = FALSE;
	size_t uCodeSize = 0;
	DWORD dwCreaFlags;
	PROCESS_INFORMATION pi;
	ZeroMemory( &pi, sizeof(pi) );

	if (FuncAdress == NULL)
	{
		FuncAdress = CreateProcessW;
	}
	

	// 设置创建就挂起进程
	dwCreaFlags = dwCreationFlags | CREATE_SUSPENDED;
	if (CreateProcessW(lpApplicationName, 
						lpCommandLine, 
						lpProcessAttributes, 
						lpThreadAttributes, 
						bInheritHandles, 
						dwCreaFlags, 
						lpEnvironment,
						lpCurrentDirectory,
						lpStartupInfo,
						&pi
					 ))
	{
		if ( lpDllFullPath )
			uCodeSize = 2 * wcslen(lpDllFullPath) + 2;
		else
			uCodeSize = 0;

		// 得到LoadLibraryW 的地址
		DWORD dwLoadDllProc = GetFuncAdress();

		// 挂起线程 写入Shellcode
		if (SuspendTidAndInjectCode(pi.hProcess, pi.hThread, dwLoadDllProc, (BYTE*)lpDllFullPath, uCodeSize))
		{
			if ( lpProcessInformation )
				memcpy(lpProcessInformation, &pi, sizeof(PROCESS_INFORMATION));

			if ( !(dwCreationFlags & CREATE_SUSPENDED) )
				ResumeThread(pi.hThread);

			bResult = TRUE;
		}
	}

	return bResult;
}


int _tmain(int argc, _TCHAR* argv[])
{	
	WCHAR wszPath[] = L"D:\\TestCreateProcessWithDll.exe";
	WCHAR wszDll[] = L"D:\\SampleDLL.dll";

	STARTUPINFOW si;
	PROCESS_INFORMATION pi;
	
	ZeroMemory( &si, sizeof(si) );
	si.cb = sizeof(si);
	ZeroMemory( &pi, sizeof(pi) );
	CreateProcessWithDllW(NULL, wszPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi, wszDll, NULL);

	return 0;
}


我的有比你更舒服,更简洁嘛
2013-11-8 09:15
0
雪    币: 25
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
相比楼主的内容,老兄的ShellCode更人性化一点,免去了调试的过程,不过楼主比你的强的地方在于,至少先拿了个Token,让插入dll更舒服一点~~不过,技术嘛,互相学习~~让我受益匪浅~~
2013-11-8 09:38
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢分享,学习了
2013-11-8 09:53
0
雪    币: 243
活跃值: (169)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看看Detours Express 3.0里的DetourCreateProcessWithDllEx源码也不错,支持64位
2013-11-8 10:20
0
雪    币: 209
活跃值: (138)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
可以同时支持32位和64位进程的启动注入
2013-11-8 10:22
0
雪    币: 563
活跃值: (4404)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
DetourCreateProcessWithDll
2013-11-8 10:54
0
雪    币: 1622
活跃值: (3805)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
5楼的代码写的挺有意思
可以不这样,申请dll需要的内存,按照目标地址重定位好,拷贝过去。
esp里做个 call dllentry,然后抹去PE头
2013-11-8 11:57
0
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
收藏学习。9楼的头像太可怕了,居然会动。
2013-11-8 14:02
0
雪    币: 1392
活跃值: (4862)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
13
稍微留一点空间。。前面的shellcode是固定的,只有后面的DLL名字可变,所以预留多一点点。
2013-11-8 14:56
0
雪    币: 1392
活跃值: (4862)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
14
寄存器的保护多此一举了吧。用PUSHAD POPAD足够了。堆栈内的代码XP下不一定可以执行吧。我记得。要开启DEP。
如果我去掉返回错误代码的调试,应该是比你更加简洁吧
2013-11-8 14:58
0
雪    币: 1392
活跃值: (4862)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
15
惊了个呆。。我不知道出3.0了,我还用的2.0
2013-11-8 14:59
0
雪    币: 148
活跃值: (59)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
shellcode多麻烦,CREATE_SUSPENDED启动的进程内只有exe和一个ntdll.dll,调用ntdll的LdrLoadDll
2013-11-9 22:24
0
雪    币: 18
活跃值: (117)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17
mark....
2013-11-10 08:57
0
雪    币: 124
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
mark一下下
2013-11-10 10:30
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
留个爪,漏洞利用可以用到这个吧?
2014-1-7 16:50
0
雪    币: 77
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
MARK
2014-1-16 14:56
0
雪    币: 1594
活跃值: (113)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
留个脚印
2014-2-23 11:14
0
雪    币: 8
活跃值: (28)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
make 学习了
2014-4-30 00:32
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
看起来和Detouts的代码很相似 话说你代码那里创建进程应该是FuncAdress()吧
2014-6-12 16:27
0
雪    币: 751
活跃值: (2700)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
两段代码都测试了一个,都过不了壳,微软的detours可以
2014-6-12 21:45
0
雪    币: 12037
活跃值: (4758)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
多谢楼主分享,学习鸟
2014-6-12 21:51
0
游客
登录 | 注册 方可回帖
返回
//