我是靠谱客的博主 隐形月光,这篇文章主要介绍DLL注入之CreateRemoteThread法基本步骤代码注入示例总结,现在分享给大家,希望可以做个参考。

基本步骤

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

代码

MsgDLL.dll

当dll注入成功后,填出一个消息框

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include<stdio.h>
//extern "C" _declspec(dllexport)
DWORD APIENTRY Msg(LPVOID lpParameter)
{
	char szPath[MAX_PATH] = { 0 };
	char szBuf[1024] = { 0 };
	GetModuleFileName(NULL, LPWSTR(szPath), MAX_PATH);
	sprintf_s(szBuf, "DLL已注入到进程 %s [Pid = %d]n", szPath, GetCurrentProcessId());
	MessageBoxA(NULL, szBuf, "DLL Inject", MB_OK);
	printf("%sn", szBuf);
	OutputDebugString(LPWSTR(szBuf));
	return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	{
		CreateThread(NULL, 0, Msg, NULL, 0, NULL);
		break;
	}
	case DLL_THREAD_ATTACH:
	
	case DLL_THREAD_DETACH:
	
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

输出函数为Msg:

//Source.def
LIBRARY "MsgDll"

EXPORTS
	Msg

inject

  • 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:VSMsgDllx64Release
#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: %sn",szProcName);
	printf("The InJect DllPath: %sn", 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 = %dn",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: %dn", 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:VSx64sir
λ 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注入的时候开始调试非常有用的…

最后

以上就是隐形月光最近收集整理的关于DLL注入之CreateRemoteThread法基本步骤代码注入示例总结的全部内容,更多相关DLL注入之CreateRemoteThread法基本步骤代码注入示例总结内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部