DLL注入之CreateRemoteThread法

基本步骤

  1. 获取目标进程句柄
  2. 将要注入的dll路径写入目标进程内存
  3. 获取LoadLibraryW()API地址
  4. 在目标进程中运行远程线程

代码

  • stdafx.h:
#if !defined(AFX_STDAFX_H__BDB235D7_5A28_46BE_B3ED_30F25A462A9A__INCLUDED_)
#define AFX_STDAFX_H__BDB235D7_5A28_46BE_B3ED_30F25A462A9A__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers

#if _MSC_VER > 1400
#pragma warning (disable: 4996)   //safestring
#endif // _MSC_VER > 1400

#include <stdio.h>

// TODO: reference additional headers your program requires here

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__BDB235D7_5A28_46BE_B3ED_30F25A462A9A__INCLUDED_)
  • inject.cpp:
#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.h>

BOOL WINAPI InjectDllToProcess(DWORD dwTargetPid ,LPCTSTR DllPath );
DWORD ProcesstoPid(char *Processname);
BOOL EnableDebugPrivilege();

int main(int argc, char* argv[])
{
/*
#ifdef 	_WIN64
	char szProcName[MAX_PATH] = "test.exe";//"HostProc64.exe";
	char szDllPath[MAX_PATH] = "E:\\VS\\MsgDll\\x64\\Release\\MsgDll.dll"; //E:\VS\MsgDll\x64\Release
#else
	char szProcName[MAX_PATH] = "HostProc.exe";
	char szDllPath[MAX_PATH] = "E:\\VS\\MsgDll\\x32\\Release\\MsgDll.dll";
#endif
*/
	char *szProcName; 
	char *szDllPath;
	szProcName = argv[1];
	szDllPath = argv[2];
	printf("The InJected ProcName: %s\n",szProcName);
	printf("The InJect DllPath: %s\n", szDllPath);
	DWORD dwPid = ProcesstoPid(szProcName);
	EnableDebugPrivilege();
	InjectDllToProcess(dwPid,szDllPath);
	return 0;
}

//注入主函数
BOOL WINAPI InjectDllToProcess(DWORD dwTargetPid ,LPCTSTR DllPath )
{
    HANDLE hProc = NULL;
	hProc=OpenProcess(PROCESS_ALL_ACCESS,//Win7下要求的权限较高
		FALSE,
		dwTargetPid
		);

    if(hProc == NULL)
    {
        printf("[-] OpenProcess Failed.\n");
        return FALSE;
    }
	
    LPTSTR psLibFileRemote = NULL;
	
    //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲
    psLibFileRemote=(LPTSTR)VirtualAllocEx(hProc, NULL, lstrlen(DllPath)+1,
		MEM_COMMIT, PAGE_READWRITE);
	
    if(psLibFileRemote == NULL)
    {
        printf("[-] VirtualAllocEx Failed.\n");
        return FALSE;
    }
	
    //使用WriteProcessMemory函数将DLL的路径名复制到远程的内存空间
    if(WriteProcessMemory(hProc, psLibFileRemote, (void *)DllPath, lstrlen(DllPath)+1, NULL) == 0)
    {
        printf("[-] WriteProcessMemory Failed.\n");
        return FALSE;
    }
	
    //计算LoadLibraryA的入口地址
    PTHREAD_START_ROUTINE pfnStartAddr=(PTHREAD_START_ROUTINE)
        GetProcAddress(GetModuleHandle("Kernel32"),"LoadLibraryA");
	
    if(pfnStartAddr == NULL)
    {
        printf("[-] GetProcAddress Failed.\n");
        return FALSE;
    }

    //pfnStartAddr地址就是LoadLibraryA的入口地址
    HANDLE hThread = CreateRemoteThread(hProc,
        NULL,
        0,
        pfnStartAddr,
        psLibFileRemote,
        0,
        NULL);
	
    if(hThread == NULL)
    {
        printf("[-] CreateRemoteThread Failed. ErrCode = %d\n",GetLastError());
        return FALSE;
    }

	printf("[*]Inject Succesfull.\n");
    return TRUE;
}


DWORD ProcesstoPid(char *Processname) //查找指定进程的PID(Process ID)
{
	HANDLE hProcessSnap=NULL;
	DWORD ProcessId=0;
	PROCESSENTRY32 pe32={0};
	hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //打开进程快照
	if(hProcessSnap==(HANDLE)-1)
	{
		printf("\nCreateToolhelp32Snapshot() Error: %d",GetLastError());
		return 0;
	}
	pe32.dwSize=sizeof(PROCESSENTRY32);
	if(Process32First(hProcessSnap,&pe32)) //开始枚举进程
	{
		do
		{
			if(!stricmp(Processname,pe32.szExeFile)) //判断是否和提供的进程名相等,是,返回进程的ID
			{
				ProcessId=pe32.th32ProcessID;
				printf("The InJected ProcessId: %d\n", ProcessId);
				break;
			}
		}
		while(Process32Next(hProcessSnap,&pe32)); //继续枚举进程
	}
	else
	{
		printf("\nProcess32First() Error: %d",GetLastError());
		return 0;
	}
	CloseHandle(hProcessSnap); //关闭系统进程快照的句柄
	return ProcessId;
}

BOOL EnableDebugPrivilege() //本函数用于提升权限,提升到SE_DEBUG_NAME
{ 
	TOKEN_PRIVILEGES tkp; 
	HANDLE hToken; 
	if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))     //打开当前进程失败 
		return FALSE; 
	LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid); //查看当前权限
	tkp.PrivilegeCount = 1; 
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); //调整权限,如上设置
	return TRUE; 
}

注入示例

E:\VS\x64\sir
λ InjectDll.exe test.exe E:\\VS\\MsgDll\\x64\\Release\\MsgDll.dll
The InJected ProcName: test.exe
The InJect DllPath: E:\\VS\\MsgDll\\x64\\Release\\MsgDll.dll
The InJected ProcessId: 130088
[*]Inject Succesfull.

注入结果

总结

od可以对注入的dll进行相应的分析,调试按钮的optiong->debugging optio->events->break on new module(DLL)开启相应的选项之后,每次当新的dll被装入被调试(debuggee)进程的时候就会自动暂停调试,这从dll注入的时候开始调试非常有用的…

发布了58 篇原创文章 · 获赞 19 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_40827990/article/details/89367045