Feature: DLL executing parameters persistence and DLL auto-run
This commit is contained in:
@@ -69,6 +69,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
#include "ip_enc.h"
|
||||
#include "scheduler.h"
|
||||
#include <time.h>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -1145,7 +1146,8 @@ typedef struct DllExecuteInfo {
|
||||
char Md5[33]; // DLL MD5
|
||||
int Pid; // 被注入进程ID
|
||||
char Is32Bit; // 是否32位DLL
|
||||
char Reseverd[18];
|
||||
unsigned short InfoSize; // 结构体大小
|
||||
ScheduleParams Schedule; // 执行计划
|
||||
} DllExecuteInfo;
|
||||
|
||||
typedef struct DllExecuteInfoNew {
|
||||
@@ -1156,7 +1158,8 @@ typedef struct DllExecuteInfoNew {
|
||||
char Md5[33]; // DLL MD5
|
||||
int Pid; // 被注入进程ID
|
||||
char Is32Bit; // 是否32位DLL
|
||||
char Reseverd[18];
|
||||
unsigned short InfoSize; // 结构体大小
|
||||
ScheduleParams Schedule; // 执行计划
|
||||
char Parameters[400];
|
||||
} DllExecuteInfoNew;
|
||||
inline void SetParameters(DllExecuteInfoNew *p, char *param, int size)
|
||||
|
||||
@@ -359,6 +359,88 @@ public:
|
||||
}
|
||||
m_keyCache.clear();
|
||||
}
|
||||
|
||||
// 枚举 m_SubKeyPath 下的所有子键名称
|
||||
// suffix: 只返回以该后缀结尾的键名,默认为空表示返回所有键
|
||||
std::vector<std::string> EnumSubKeys(const std::string& suffix = "") const
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
// 使用缓存获取 m_SubKeyPath 的句柄
|
||||
auto it = m_keyCache.find(m_SubKeyPath);
|
||||
HKEY hKey = NULL;
|
||||
if (it != m_keyCache.end()) {
|
||||
hKey = it->second;
|
||||
} else {
|
||||
if (RegOpenKeyExA(m_hRootKey, m_SubKeyPath.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
m_keyCache[m_SubKeyPath] = hKey;
|
||||
}
|
||||
|
||||
char keyName[256];
|
||||
DWORD keyNameSize;
|
||||
DWORD index = 0;
|
||||
|
||||
while (true) {
|
||||
keyNameSize = sizeof(keyName);
|
||||
LONG ret = RegEnumKeyExA(hKey, index, keyName, &keyNameSize, NULL, NULL, NULL, NULL);
|
||||
if (ret == ERROR_NO_MORE_ITEMS) {
|
||||
break;
|
||||
}
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
if (suffix.empty()) {
|
||||
result.push_back(keyName);
|
||||
} else {
|
||||
std::string name(keyName);
|
||||
if (name.size() >= suffix.size() &&
|
||||
name.compare(name.size() - suffix.size(), suffix.size(), suffix) == 0) {
|
||||
result.push_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 枚举指定 MainKey 下的所有值名称
|
||||
// suffix: 只返回以该后缀结尾的值名,默认为空表示返回所有值
|
||||
std::vector<std::string> EnumValues(const std::string& MainKey, const std::string& suffix = "") const
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
HKEY hKey = GetCachedKey(MainKey);
|
||||
if (!hKey)
|
||||
return result;
|
||||
|
||||
char valueName[256];
|
||||
DWORD valueNameSize;
|
||||
DWORD index = 0;
|
||||
|
||||
while (true) {
|
||||
valueNameSize = sizeof(valueName);
|
||||
LONG ret = RegEnumValueA(hKey, index, valueName, &valueNameSize, NULL, NULL, NULL, NULL);
|
||||
if (ret == ERROR_NO_MORE_ITEMS) {
|
||||
break;
|
||||
}
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
if (suffix.empty()) {
|
||||
result.push_back(valueName);
|
||||
} else {
|
||||
std::string name(valueName);
|
||||
if (name.size() >= suffix.size() &&
|
||||
name.compare(name.size() - suffix.size(), suffix.size(), suffix) == 0) {
|
||||
result.push_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// 配置读取类: 注册表二进制配置(带键句柄缓存)
|
||||
|
||||
104
common/scheduler.h
Normal file
104
common/scheduler.h
Normal file
@@ -0,0 +1,104 @@
|
||||
#ifndef YAMA_SCHEDULER_H
|
||||
#define YAMA_SCHEDULER_H
|
||||
|
||||
// 调度模式定义
|
||||
#define SCH_MODE_NONE 0 // 默认模式:不自动执行 (仅手动)
|
||||
#define SCH_MODE_STARTUP 1 // 启动执行模式
|
||||
#define SCH_MODE_DAILY 2 // 每日定时模式
|
||||
#define SCH_MODE_WEEKLY 3 // 每周定时模式
|
||||
|
||||
#pragma pack(push, 1)
|
||||
// 严格定义 16 字节结构
|
||||
typedef struct {
|
||||
unsigned char Mode; // [1 字节] 0=None, 1=Startup, 2=Daily...
|
||||
unsigned char Flags; // [1 字节] 标志位 (bit0:禁用)
|
||||
|
||||
union {
|
||||
// Mode 1: 启动执行 + 间隔控制
|
||||
struct {
|
||||
unsigned int Interval;
|
||||
} Startup;
|
||||
|
||||
// Mode 2 & 3: 定时模式
|
||||
struct {
|
||||
unsigned short TargetMin;
|
||||
unsigned char DaysMask;
|
||||
unsigned char Reserved;
|
||||
} Timed;
|
||||
} Config;
|
||||
|
||||
unsigned __int64 LastRunTime;
|
||||
unsigned char CurrentCount;
|
||||
unsigned char MaxCount;
|
||||
} ScheduleParams;
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
class YamaTaskEngine {
|
||||
public:
|
||||
static bool ShouldExecute(const ScheduleParams* p) {
|
||||
// --- 1. 默认与基础拦截 ---
|
||||
if (p->Mode == SCH_MODE_NONE) return false; // Mode为0,默认不执行
|
||||
if (p->Flags & 0x01) return false; // 显式禁用拦截
|
||||
if (p->MaxCount > 0 && p->CurrentCount >= p->MaxCount) return false;
|
||||
|
||||
unsigned __int64 now = GetCurrentFT();
|
||||
|
||||
// --- 2. 启动执行模式 (Mode 1) ---
|
||||
if (p->Mode == SCH_MODE_STARTUP) {
|
||||
static bool bSessionLocked = false;
|
||||
if (bSessionLocked) return false;
|
||||
|
||||
if (p->Config.Startup.Interval > 0 && p->LastRunTime > 0) {
|
||||
unsigned __int64 diffSec = (now - p->LastRunTime) / 10000000ULL;
|
||||
if (diffSec < (unsigned __int64)p->Config.Startup.Interval) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bSessionLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// --- 3. 每日定时逻辑 (Mode 2) ---
|
||||
if (p->Mode == SCH_MODE_DAILY) {
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
unsigned short curMin = (unsigned short)(st.wHour * 60 + st.wMinute);
|
||||
if (curMin >= p->Config.Timed.TargetMin) {
|
||||
if (!IsSameDay(p->LastRunTime, now)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void MarkExecuted(ScheduleParams* p) {
|
||||
p->LastRunTime = GetCurrentFT();
|
||||
if (p->MaxCount > 0 && p->CurrentCount < 255) {
|
||||
p->CurrentCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static unsigned __int64 GetCurrentFT() {
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
return ((unsigned __int64)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
|
||||
}
|
||||
|
||||
static bool IsSameDay(unsigned __int64 ft1, unsigned __int64 ft2) {
|
||||
if (ft1 == 0 || ft2 == 0) return false;
|
||||
SYSTEMTIME st1, st2;
|
||||
FILETIME f1, f2;
|
||||
f1.dwLowDateTime = (DWORD)ft1; f1.dwHighDateTime = (DWORD)(ft1 >> 32);
|
||||
f2.dwLowDateTime = (DWORD)ft2; f2.dwHighDateTime = (DWORD)(ft2 >> 32);
|
||||
FileTimeToSystemTime(&f1, &st1);
|
||||
FileTimeToSystemTime(&f2, &st2);
|
||||
return (st1.wYear == st2.wYear && st1.wMonth == st2.wMonth && st1.wDay == st2.wDay);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user