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("%s\n", 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:\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注入的时候开始调试非常有用的…

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
易语言是一种基于Visual Basic语的编程语言,通过易语言可以方便地实现Windows下的各种功能。DLL注入是一种实现程序代码注入进程的技术,通过DLL注入可以在目标进程中运行自己编写的代码,以达到扩展或修改目标进程功能的目的。 下面是一个简单的易语言DLL注入源码示例: 函数 Declare函数名 CDECL别名 函数类型 字符串 文件名 参数列表 函数库文件名 参数类型 结果; // 声明LoadLibrary函数 Declare Function LoadLibraryA cdecl alias "LoadLibraryA" (sLibName As String) As Long // 声明GetProcAddress函数 Declare Function GetProcAddress cdecl alias "GetProcAddress" (hModule As Long, sProcName As String) As Long // 声明CreateRemoteThread函数 Declare Function CreateRemoteThread cdecl alias "CreateRemoteThread" (hProcess As Long, lpThreadAttributes As Long, dwStackSize As Long, lpStartAddress As Long, lpParameter As Long, dwCreationFlags As Long, lpThreadId As Long) As Long Sub 注入DLL() Dim lProcessHandle As Long Dim lRemoteThread As Long Dim lModuleName As Long Dim lProcAddress As Long ' 打开目标进程,获取进程句柄 lProcessHandle = OpenProcess(&H1F0FFF, False, 目标进程ID) ' 在目标进程中申请一块内存,用于存放DLL路径 lModuleName = VirtualAllocEx(lProcessHandle, 0, Len(DLL路径), 4096, 4) ' 将DLL路径写入到目标进程的内存中 WriteProcessMemory lProcessHandle, lModuleName, DLL路径, Len(DLL路径), NumBytesWritten ' 获取LoadLibrary函数的地址 lProcAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA") ' 在目标进程中创建远程线程,回调到LoadLibrary函数 lRemoteThread = CreateRemoteThread(lProcessHandle, 0, 0, lProcAddress, lModuleName, 0, 0) ' 关闭进程句柄 CloseHandle lProcessHandle End Sub 以上是一个基本的易语言DLL注入源码示例。通过调用相关的Windows API函数,实现了在目标进程中注入DLL的流程。需要替换相应的目标进程ID和DLL路径,即可实现DLL注入的功能。这段源码具有一定的通用性,但是需要根据实际情况进行修改和调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值