基本步骤
- 获取目标进程句柄
- 将要注入的dll路径写入目标进程内存
- 获取LoadLibraryW()API地址
- 在目标进程中运行远程线程
代码
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法基本步骤代码注入示例总结内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复