远程线程注入Dll时,有时DllMain里的代码没有执行。用procexp看目标进程,dll的确被加载了。
注入和dll的代码看起来都没问题。不知有没deadlock的可能性。请大家指点。
可以确定的是,目标进程没有保护。。拿notepad来动手也是一样的结果。也不是杀软的原因,裸奔的。UAC也没开。不是权限问题。
注入程序和dll和目标进程都是x64。。编译成32的。到32位系统上测试也时同样的问题。
dll代码:
/*******************************************************************************
* File: dllmain.cpp
* Author: HwangBae
* Created: 1/5/2013
* Blog: http://hwangbae.cnblogs.com/
* Email: hwangbae@live.cn
* Description: dll entry point and subproc
********************************************************************************/
#include "stdafx.h"
#pragma once
// Key atcion define
enum KEY_ACTION
{
ACTION_NONE,
ACTION_OPEN_COMPUTER,
ACTION_OPEN_LIBRARIES,
ACTION_OPEN_DOCUMENTS,
ACTION_OPEN_CALCULATOR,
ACTION_OPEN_NOTEPAD,
ACTION_OPEN_TASKMANAGER,
ACTION_OPEN_CMD,
ACTION_OPEN_MUSICPLAYER,
ACTION_OPEN_VIDEOPLAYER,
ACTION_OPEN_BROWSER,
ACTION_OPEN_EMAIL,
ACTION_OPEN_APPLICATION
};
// key setting struct
typedef struct tagKEYSETTING
{
KEY_ACTION action;
TCHAR pszAtcionParameter[MAX_PATH];
}KEYSETTING, *PKEYSETTING;
// Forward declarations of functions included in this code module:
WNDPROC g_pfnOldWndProc; // The original window procedure
TCHAR g_szCfgPath[MAX_PATH]; // The config file path
/* The action string array as ShellExecute parameter,
some elements is initialized to zero,
it will be assigned values in the window message handler*/
TCHAR g_szAction[][MAX_PATH]
= {
{0}, // ACTION_OPEN_NONE
{TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")}, // ACTION_OPEN_COMPUTER
{TEXT("::{031E4825-7B94-4dc3-B131-E946B44C8DD5}")}, // ACTION_OPEN_LIBRARIES
{TEXT("::{450D8FBA-AD25-11D0-98A8-0800361B1103}")}, // ACTION_OPEN_DOCUMENTS
{TEXT("calc.exe")}, // ACTION_OPEN_CALCULATOR
{TEXT("notepad.exe")}, // ACTION_OPEN_NOTEPAD
{TEXT("taskmgr.exe")}, // ACTION_OPEN_TASKMANAGER
{TEXT("cmd.exe")}, // ACTION_OPEN_CMD
{0}, // ACTION_OPEN_MUSICPLAYER
{0}, // ACTION_OPEN_VIDEOPLAYER
{TEXT("::{871C5380-42A0-1069-A2EA-08002B30309D}")}, // ACTION_OPEN_BROWSER
{TEXT("mailto:")}, // ACTION_OPEN_EMAIL
{0} // ACTION_OPEN_APPLICATION
};
BOOL DoAction(KEYSETTING& ks);
BOOL GetAssociatedApp(LPCTSTR pszExt, LPTSTR pszPath);
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL SubWindowClass(void);
BOOL UnSubWindowClass(void);
// Dll entry point
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
OutputDebugString(TEXT("DllMain\n"));
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
::GetModuleFileName(hModule, g_szCfgPath, MAX_PATH);
::lstrcpy(PathFindExtension(g_szCfgPath) - 3, TEXT(".cfg"));
::SubWindowClass();
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
{
::UnSubWindowClass();
break;
}
}
return TRUE;
}
//************************************
// Method: DoAction
// Returns: BOOL
// Parameter: KEYSETTING & ks
// Description: process the key action
//************************************
BOOL DoAction(KEYSETTING& ks)
{
switch (ks.action)
{
case ACTION_OPEN_MUSICPLAYER:
{
::OutputDebugString(TEXT("case ACTION_OPEN_MUSICPLAYER\n"));
::GetAssociatedApp(TEXT(".mp3"), g_szAction[ACTION_OPEN_MUSICPLAYER]);
break;
}
case ACTION_OPEN_VIDEOPLAYER:
{
::OutputDebugString(TEXT("case ACTION_OPEN_VIDEOPLAYER\n"));
::GetAssociatedApp(TEXT(".mp4"), g_szAction[ACTION_OPEN_VIDEOPLAYER]);
break;
}
case ACTION_OPEN_APPLICATION:
{
::OutputDebugString(TEXT("case ACTION_OPEN_APPLICATION\n"));
::lstrcpy(g_szAction[ACTION_OPEN_APPLICATION], ks.pszAtcionParameter);
break;
}
}
return 32 < reinterpret_cast<int>(::ShellExecute(NULL, NULL, g_szAction[ks.action], NULL, NULL, SW_NORMAL));
}
//************************************
// Method: GetAssociatedApp
// Returns: BOOL
// Parameter: LPCTSTR pszExt
// Parameter: LPTSTR pszPath
// Description: Get the associated app by file extension
//************************************
BOOL GetAssociatedApp( LPCTSTR pszExt, LPTSTR pszPath )
{
HKEY hKey;
LONG lRet;
lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, pszExt, 0, KEY_QUERY_VALUE, &hKey);
if (ERROR_SUCCESS != lRet) return FALSE;
DWORD dwData = MAX_PATH;
lRet = ::RegQueryValueEx(hKey, NULL, 0, NULL, reinterpret_cast<LPBYTE>(pszPath), &dwData);
if (ERROR_SUCCESS != lRet) return FALSE;
lRet = ::RegCloseKey(hKey);
if (ERROR_SUCCESS != lRet) return FALSE;
TCHAR szSubKey[MAX_PATH];
::wsprintf(szSubKey, TEXT("%s\\Shell\\Open\\Command"), pszPath);
lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, szSubKey, 0, KEY_QUERY_VALUE, &hKey);
if (ERROR_SUCCESS != lRet) return FALSE;
dwData = MAX_PATH;
lRet = ::RegQueryValueEx(hKey, NULL, 0, NULL, reinterpret_cast<LPBYTE>(pszPath), &dwData);
if (ERROR_SUCCESS != lRet) return FALSE;
lRet = ::RegCloseKey(hKey);
if (ERROR_SUCCESS != lRet) return FALSE;
::PathRemoveArgs(pszPath);
return TRUE;
}
//************************************
// Method: NewWndProc
// Returns: LRESULT CALLBACK
// Parameter: HWND hwnd
// Parameter: UINT uMsg
// Parameter: WPARAM wParam
// Parameter: LPARAM lParam
// Description: the custom window proc, then u can rider oughshod over it, ahh.
//************************************
LRESULT CALLBACK NewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bHandled = FALSE; // msg is handled?
switch (uMsg)
{
case WM_USER + 1002:
{
::OutputDebugString(TEXT("case WM_USER + 1002\n"));
if (wParam == 0x05u)
{
::OutputDebugString(TEXT("wParam == 0x05u\n"));
KEYSETTING ks;
::GetPrivateProfileStruct(TEXT("KeyConfig"), TEXT("TheaterKey"),
&ks, sizeof(KEYSETTING), g_szCfgPath);
if (ks.action == ACTION_NONE) break;
bHandled = ::DoAction(ks);
}
else if (wParam == 0x0bu)
{
::OutputDebugString(TEXT("wParam == 0x0bu\n"));
KEYSETTING ks;
::GetPrivateProfileStruct(TEXT("KeyConfig"), TEXT("RecoveryKey"),
&ks, sizeof(KEYSETTING), g_szCfgPath);
if (ks.action == ACTION_NONE) break;
bHandled = ::DoAction(ks);
}
}
}
return bHandled || ::CallWindowProc(g_pfnOldWndProc, hwnd, uMsg, wParam, lParam);
}
//************************************
// Method: SubWindowClass
// Returns: BOOL
// Parameter: void
// Description: Call this function to change the window proc
//************************************
BOOL SubWindowClass(void)
{
HWND hWnd = ::FindWindow(TEXT("Utility_Window"), NULL);
if (hWnd != NULL)
{
g_pfnOldWndProc = reinterpret_cast<WNDPROC>(
::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(NewWndProc)));
if (g_pfnOldWndProc == 0)
{
MessageBox(hWnd, TEXT("SetWindowSubclass Faild\n"), TEXT("Error"), MB_OK | MB_ICONERROR);
}
}
return g_pfnOldWndProc != 0;
}
//************************************
// Method: UnSubWindowClass
// Returns: BOOL
// Parameter: void
// Description: Call this function to restore the default window proc
//************************************
BOOL UnSubWindowClass(void)
{
HWND hWnd = ::FindWindow(TEXT("Utility_Window"), NULL);
if (hWnd != NULL)
{
return ::SetWindowLongPtr(hWnd, GWLP_WNDPROC , reinterpret_cast<LONG_PTR>(g_pfnOldWndProc));
}
return FALSE;
}
注入的代码摘自windows核心编程一书
//************************************
// Method: InjectLib
// Returns: BOOL
// Parameter: DWORD dwProcessId
// Parameter: LPCTSTR pszLibFileName
// Description: Inject dll to target process
//************************************
BOOL InjectLib( DWORD dwProcessId, LPCTSTR pszLibFileName )
{
// TODO: Inject dll to process
BOOL bOk = FALSE; // Assume that the function fails
HANDLE hProcess = NULL;
HANDLE hThread = NULL;
LPVOID pszLibFileRemote = NULL;
__try
{
// Get a handle for the target process.
hProcess = ::OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Calculate the number of bytes needed for the DLL's pathname
int cb = (::lstrlen(pszLibFileName) + 1) * sizeof(TCHAR);
// Allocate space in the remote process for the pathname
pszLibFileRemote = ::VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL) __leave;
// Copy the DLL's pathname to the remote process' address space
if (!::WriteProcessMemory(hProcess, pszLibFileRemote,
pszLibFileName, cb, NULL)) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = reinterpret_cast<PTHREAD_START_ROUTINE>(
::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW"));
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
::WaitForSingleObject(hThread, INFINITE);
bOk = TRUE; // Everything executed successfully
}
__finally
{ // Now, we can clean everything up
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL) ::VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
CLOSE_HANDLE(hThread);
CLOSE_HANDLE(hProcess);
}
return bOk;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课