DLL注入示例(一)

#include<Windows.h>
#include<tchar.h>

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
	HANDLE hProcess = NULL, hThread = NULL;
	HMODULE hMod = NULL;
	LPVOID pRemoteBuf = NULL;
	DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
	LPTHREAD_START_ROUTINE pThreadProc;

	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
	{
		_tprintf(L"OpenProcess(%d) failed!!! [%d]
", dwPID, GetLastError());
		return false;
	}
	pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

	WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);

	hMod = GetModuleHandle(L"kernel32.dll");
	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
	CloseHandle(hProcess);
	return TRUE;
}
int _tmain(int argc, TCHAR* argv[])
{
	if(argc!=3)
	{
		_tprintf(L"USAGE:%s pid dll_path
", argv[0]);
		return 1;
	}

	if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))
		_tprintf(L"InjectDll("%s") success!!!
", argv[2]);
	else
		_tprintf(L"InjectDll("%s") failed!!!
", argv[2]);
	return 0;
}

  

_tmain:经过宏定义,为了支持Unicode的一个main的别名。

int argc:传入main函数的参数个数。

TCHAR *argv[]:每一个元素指向一个函数参数;共argc个元素;argv[0]为编译后产生的exe路径…xxx.exe;argv[1]为程序执行的第一个字符串参数;argv[2]为第二个字符串参数;argv[3]为第三个字符串参数;argv[argc]为字符串的null空字符;

_tstol:字符串转32位整型。

HANDLE:句柄类型。

HWND是线程相关的,你可以通过HWND找到该窗口所属进程和线程

Handle 是代表系统的内核对象,如文件句柄,线程句柄,进程句柄。
系统对内核对象以链表的形式进行管理,载入到内存中的每一个内
核对象都有一个线性地址,同时相对系统来说,在串列中有一个索引位置,这个索引位置就是内核对象的handle。

HINSTANCE的本质是模块基地址,他仅仅在同一进程中才有意义,跨进程的HINSTANCE是没有意义

HMODULE 是代表应用程序载入的模块,win32系统下通常是被载入模块的线性地址。

HINSTANCE 在win32下与HMODULE是相同的东西(只有在16位windows上,二者有所不同).

sizeof(TCHAR) //求出的TCHAR类型占的字节数

OpenProcess 函数用来打开一个已存在的进程对象,并返回进程的句柄。

HANDLE CreateRemoteThread(
     HANDLE hProcess,
     LPSECURITY_ATTRIBUTES lpThreadAttributes,
     SIZE_T dwStackSize,
     LPTHREAD_START_ROUTINE lpStartAddress,
     LPVOID lpParameter,
     DWORD dwCreationFlags,
     LPDWORD lpThreadId
);

参数说明:
hProcess:目标进程的句柄
lpThreadAttributes:指向线程的安全描述结构体的指针,一般设置为NULL,表示使用默认的安全级别
dwStackSize:线程堆栈大小,一般设置为0,表示使用默认的大小,一般为1M
lpStartAddress:线程函数的地址
lpParameter:线程参数
dwCreationFlags:线程的创建方式
                  CREATE_SUSPENDED 线程以挂起方式创建
lpThreadId:输出参数,记录创建的远程线程的ID

WaitForSingleObject函数用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。

参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。

#include<Windows.h>
#include<tchar.h>

#define DEF_CMD L"c:\Program Files\Internet Explorer\ieplore.exe"
#define DEF_ADDR L"http://www.naver.com"
#define DEF_DST_PROC L"notepad.exe"

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
	TCHAR szCmd[MAX_PATH] = { 0, };
	TCHAR szPath[MAX_PATH] = { 0, };
	TCHAR* p = NULL;
	STARTUPINFO si = { 0, };
	PROCESS_INFORMATION pi = { 0, };

	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;

	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		if (!GetModuleFileName(NULL, szPath, MAX_PATH))
			break;
		if (!(p = _tcsrchr(szPath, '\')))
			break;
		if (_tcsicmp(p + 1, DEF_DST_PROC))
			break;
		wsprintf(szCmd, L"%s %s", DEF_CMD, DEF_ADDR);
		if (!CreateProcess(NULL, (LPTSTR)(LPCSTR)szCmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS
			, NULL, NULL, &si, &pi))
			break;
		if (pi.hProcess != NULL)
			CloseHandle(pi.hProcess);
		break;
	}
	return TRUE;
}

  

typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess; //存放每个对象的与进程相关的句柄
    HANDLE hThread;        //返回的线程句柄。
    DWORD dwProcessId;    //用来存放进程ID号
    DWORD dwThreadId;      //用来存放线程ID号
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;

调用Createprocess ()函数后,会自动地对该结构进行填充.

DWORD WINAPI GetModuleFileName(
HMODULE hModule,
LPTSTR lpFileName,
DWORD nSize
);

hModule:要获取文件名的模块名柄,null表示当前模块

 

lpFileName:输出参数,存放取得的文件名
nSize:lpFileName参数的长度

_tcsrchr(str, ch):

参数寻找宽字符 chstr 所指向的空终止宽字符串中的最后一次出现。

返回指向 str 中找到的字符的指针,或若找不到这种字符则为 NULL 。 

CreateProcess:https://www.cnblogs.com/Gotogoo/p/5262536.html

原文地址:https://www.cnblogs.com/whitehawk/p/11152329.html