远程注入DLL并自动显示DLL的窗口
来源:互联网 发布:易烊千玺长相知乎 编辑:程序博客网 时间:2024/06/14 18:37
以前也可以注入并显示窗口,但是一旦卸载则会导致宿主进程也被关闭,今天终于搞定卸载注入的DLL后不影响宿主进程。
源码在http://wooddoor.ys168.com的VC目录下的“远程注入、卸载.rar”【VC2008的工程】
注入器源码部分:
#include <tlhelp32.h>
namespace pathfileFun
{
//**************************************************************
//* GetCurrentDirectory得到的不一定是应用程序所在的目录!要得到应用程序所在的目录,这里有一个函数:
//*函数名: GetAppPath()
//*
//*
//*返回值 CString - 返回路径的形式是 C:/temp/
//功能 - 得到应用程序所在的路径,保存到strPathBuffer中
//*
//**************************************************************
inline CString WINAPI GetAppPath()
{
CString strPathBuffer;
TCHAR PathBuffer[MAX_PATH];
GetModuleFileName(AfxGetInstanceHandle(), PathBuffer, MAX_PATH);
strPathBuffer.Format(_T("%s"),PathBuffer);
CString strAppPath=strPathBuffer.Mid(0,strPathBuffer.ReverseFind(_T('//'))+1);
return strAppPath;
};
//格式化路径,使得路径统一成以“/”结尾
inline CString FormatPath(CString strPath)
{
if ( strPath.Right(1) != _T("//") )
strPath += _T("//");
return strPath;
};
//从文件的全路径中获取文件所在的文件夹路径,返回的路径以“/”结尾
inline CString GetPathFromFile(CString FilePath)
{
return FilePath.Mid(0,FilePath.ReverseFind(_T('//'))+1);
};
//从文件的全路径中获取文件名(含后缀)
inline CString GetFileNameFromFilePath(CString FilePath)
{
return FilePath.Right(FilePath.GetLength() - FilePath.ReverseFind(_T('//'))+1);
};
}
//===========================================
//调整进程权限
bool EnablePrivilege(TCHAR* PrivilegeName,BOOL IsEnable)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ,&hToken))
{
return false;
}
if(!LookupPrivilegeValue(NULL, PrivilegeName, &luid))
{
return false;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = (IsEnable) ? SE_PRIVILEGE_ENABLED : 0;
BOOL bSucc = AdjustTokenPrivileges(hToken,FALSE,&tp,NULL,NULL,NULL);
CloseHandle(hToken);
return (GetLastError() == ERROR_SUCCESS);
}
//将指定dll注入指定进程
bool HookProcess(DWORD dwProcessId,CStringA szDllPath)
{
HANDLE hRemoteProcess = NULL;
HANDLE hRemoteThread = NULL;
HANDLE hRemoteFunc = NULL;
PVOID pRemoteParam = NULL;
DWORD dwWriten = 0;
BOOL bRet = FALSE;
char szDllPathCopy[256] = {0};
lstrcpyA(szDllPathCopy,szDllPath);
EnablePrivilege(SE_DEBUG_NAME,true);
hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
if(hRemoteProcess == NULL)
{
EnablePrivilege(SE_DEBUG_NAME,false);
return false;
}
int iSize = (int)strlen(szDllPath);
pRemoteParam = VirtualAllocEx(hRemoteProcess,NULL,iSize,MEM_COMMIT,PAGE_READWRITE);
if(pRemoteParam == NULL)
{
EnablePrivilege(SE_DEBUG_NAME,false);
return false;
}
bRet = WriteProcessMemory(hRemoteProcess,pRemoteParam,(LPVOID)szDllPathCopy,iSize,&dwWriten);
if(!bRet)
{
if (pRemoteParam)
VirtualFreeEx(hRemoteProcess,pRemoteParam,0,MEM_RELEASE);
EnablePrivilege(SE_DEBUG_NAME,false);
return false;
}
hRemoteFunc = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "LoadLibraryA");
// #ifdef UNICODE
// hRemoteFunc = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryW");
// #else
// hRemoteFunc = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
// #endif
hRemoteThread = CreateRemoteThread(hRemoteProcess,0,0,(LPTHREAD_START_ROUTINE)hRemoteFunc,pRemoteParam,0,&dwWriten);
EnablePrivilege(SE_DEBUG_NAME,false);
// 等待线程结束
if (hRemoteThread)
{
WaitForSingleObject(hRemoteThread,INFINITE);
HMODULE g_hRemoteHandle;
GetExitCodeThread(hRemoteThread,(DWORD*)&g_hRemoteHandle);
}
// 清理工作
if(pRemoteParam)
VirtualFreeEx(hRemoteProcess, pRemoteParam,0,MEM_RELEASE);
CloseHandle(hRemoteProcess);
return true;
}
//查找dll实例句柄
HMODULE GetProcessModuleByName(DWORD dwProcessId,CString lpStrName)
{
HANDLE hModuleSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,dwProcessId);
//查找相关的DLL
MODULEENTRY32 me32 = {sizeof(MODULEENTRY32)};
for(BOOL fok=::Module32First(hModuleSnap,&me32); fok ;fok=::Module32Next(hModuleSnap,&me32))
{
if(lstrcmpi(me32.szExePath , lpStrName) == 0 || lstrcmpi(me32.szModule , lpStrName) == 0)
{
return me32.hModule;
}
}
return 0;
}
//卸载注入的DLL
bool UnhookProcess(DWORD dwProcessId,CString szDllPath)
{
HANDLE hRemoteProcess = NULL;
HANDLE hRemoteThread = NULL;
HANDLE hRemoteFunc = NULL;
PVOID pRemoteParam = NULL;
DWORD dwWriten = 0;
BOOL bRet = FALSE;
//char szDllPathCopy[256] = {0};
//lstrcpyA(szDllPathCopy,szDllPath);
EnablePrivilege(SE_DEBUG_NAME,true);
hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
if(hRemoteProcess == NULL)
{
EnablePrivilege(SE_DEBUG_NAME,false);
return false;
}
//此dll句柄地址就已经是dwProcessId中的地址,所有不需要写入
HMODULE hDllModule = GetProcessModuleByName(dwProcessId,szDllPath);
if (!hDllModule)
{
EnablePrivilege(SE_DEBUG_NAME,false);
return false;
}
pRemoteParam = hDllModule;
hRemoteFunc = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "FreeLibrary");
hRemoteThread = CreateRemoteThread(hRemoteProcess,0,0,(LPTHREAD_START_ROUTINE)hRemoteFunc,pRemoteParam,0,&dwWriten);
EnablePrivilege(SE_DEBUG_NAME,false);
// 等待线程结束
if (hRemoteThread)
{
WaitForSingleObject(hRemoteThread,INFINITE);
}
CloseHandle(hRemoteProcess);
return true;
}
//获取进程列表
void GetProcessList(CArray<PROCESSENTRY32>& arrProcess)
{
arrProcess.RemoveAll();
PROCESSENTRY32 stProcess;
HANDLE hSnapShot;
BOOL b;
RtlZeroMemory(&stProcess, sizeof(stProcess));
stProcess.dwSize = sizeof(stProcess);
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
b = Process32First(hSnapShot, &stProcess);
while ( b )
{
arrProcess.Add(stProcess);
b = Process32Next(hSnapShot, &stProcess);
}
CloseHandle(hSnapShot);
}
//======================================================
//点击“注入”按钮
void CwooddoorDlg::OnBnClickedButtonHook()
{
// TODO: 在此添加控件通知处理程序代码
if (m_ProcessList.GetCurSel() == -1)
{
AfxMessageBox(_T("请先选择目标进程!"));
}
else
{
CString strDllFile = pathfileFun::GetAppPath() + _T("HookRXJH.dll");
if ( HookProcess( m_ProcessList.GetItemData(m_ProcessList.GetCurSel()), CStringA(strDllFile.LockBuffer()) ) == false )
{
AfxMessageBox(_T("注入失败!"));
}
strDllFile.UnlockBuffer();
}
}
//点击“卸载”按钮
void CwooddoorDlg::OnBnClickedButtonUnhook()
{
// TODO: 在此添加控件通知处理程序代码
if (m_ProcessList.GetCurSel() == -1)
{
AfxMessageBox(_T("请先选择目标进程!"));
}
else
{
CString strDllFile = pathfileFun::GetAppPath() + _T("HookRXJH.dll");
if ( UnhookProcess( m_ProcessList.GetItemData(m_ProcessList.GetCurSel()), strDllFile ) == false )
{
AfxMessageBox(_T("卸载失败!"));
}
}
}
//在组合框内显示进程列表
void CwooddoorDlg::OnCbnDropdownComboProcesslist()
{
// TODO: 在此添加控件通知处理程序代码
m_ProcessList.ResetContent();//清空列表
CArray<PROCESSENTRY32> arrProcess;
GetProcessList(arrProcess);
CString strProcessInfo;
for (int i=arrProcess.GetCount()-1; i>=0; i--)
//for (int i=0; i<arrProcess.GetCount(); i++)
{
strProcessInfo=_T("");
strProcessInfo.Format( _T("[%d]%s"),arrProcess[i].th32ProcessID,pathfileFun::GetFileNameFromFilePath(arrProcess[i].szExeFile) );
//m_ProcessList.AddString(pathfileFun::GetFileNameFromFilePath(arrProcess[i].szExeFile));
m_ProcessList.SetItemData( m_ProcessList.AddString(strProcessInfo), arrProcess[i].th32ProcessID );
}
}
DLL部分:
创建MFC DLL,名为HookRXJH。
在DLL中插入一个对话框,并给该对话框创建一个类如:
class CMainDialog : public CDialog
在DLL的CHookRXJHApp内创建一个成员变量:
public:
CMainDialog *m_pMainDialog;
CFrameWnd *m_pFrame;
给CHookRXJHApp添加成员函数:virtual int ExitInstance();
然后在InitInstance内添加代码:
BOOL CHookRXJHApp::InitInstance()
{
CWinApp::InitInstance();
//在dll注入之后显示主对话框:
m_pMainDialog = new CMainDialog;
m_pFrame = new CFrameWnd();
m_pMainWnd = m_pFrame;//用于自动处理消息,省去手动写消息循环,从而不至于对话框刚出现就关闭
m_pMainWnd = m_pMainDialog;
::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ShowDialog,(LPVOID)m_pMainDialog,NULL,NULL);
return TRUE;
}
在ExitInstance内添加代码:
int CHookRXJHApp::ExitInstance()
{
SendMessage(m_pMainDialog->m_hWnd, WM_CLOSE, NULL, NULL);
return CWinApp::ExitInstance();
}
另外定义一个函数用于显示窗口:
void ShowDialog(CMainDialog *pMainDialog)
{
pMainDialog->DoModal(); //显示对话框
}
- 远程注入DLL并自动显示DLL的窗口
- DLL的远程注入
- DLL的远程注入技术
- DLL的远程注入技术
- DLL的远程注入技术
- DLL的远程注入技术
- 远程注入DLL的例子
- DLL的远程注入技术
- DLL的远程注入技术
- DLL的远程注入技术
- DLL的远程注入技术
- DLL的远程注入技术
- DLL的远程注入技术
- DLL的远程注入技术
- DLL的远程注入技术
- 远程注入Dll,在Dll中显示对话框
- C++:远程注入DLL
- zz - DLL远程注入
- CBitmapButton的使用 (转)
- 也来博客!
- Oracle表和索引移动表空间
- 2009年下半年学习计划
- CSIDL对照表
- 远程注入DLL并自动显示DLL的窗口
- 第一篇blog~~
- Debian下载内核源码的方法
- GDB中文手册
- MsSql存储过程分页代码
- url中文参数问题
- 用libsvm做模式识别
- 好像很模糊的题目
- SSHSQAjax总述