軟體試用版常需限制使用次數。本文介紹一種隱蔽度較高的方法:將計數器儲存在執行檔自身的「最後修改時間」分鐘欄位(FAT/NTFS 時間戳記結構中第 5-10 位元)。每次啟動遞增,超過上限則拒絕執行。示例使用 DOS 中斷 INT 21h 功能,適用於 16 位元環境教學;32/64 位元 VC++ 應改用 Win32 API GetFileTime/SetFileTime。
| 位元 | 15-11 | 10-5 | 4-0 |
|---|---|---|---|
| 含義 | 小時 (0-23) | 分鐘 (0-59) | 秒/2 (0-29) |
分鐘欄位共 6 位元,可儲存 0-63,足夠作為試用計數器。
#include
#include
int CheckTrialCount()
{
union REGS in, out;
struct SREGS seg;
unsigned handle, minutes;
// 1. 開啟自身執行檔
in.h.ah = 0x3D; in.h.al = 0; // 讀取模式
segread(&seg);
in.x.dx = (unsigned)"TEST.EXE"; // 檔名
intdosx(&in, &out, &seg);
if (out.x.cflag) return 0; // 開啟失敗
handle = out.x.ax;
// 2. 讀取檔案時間
in.x.ax = 0x5700; in.x.bx = handle;
intdosx(&in, &out, &seg);
minutes = (out.x.cx & 0x07E0) >> 5; // 取出分鐘位元
if (minutes < 40) { // 試用上限 40 次
// 3. 遞增分鐘並寫回
in.x.ax = 0x5701; in.x.bx = handle;
in.x.cx = out.x.cx + 0x0020; // 分鐘 +1 (bit 5)
in.x.dx = out.x.dx;
intdosx(&in, &out, &seg);
// 4. 關閉檔案
in.h.ah = 0x3E; in.x.bx = handle;
intdosx(&in, &out, &seg);
return 2; // 允許試用
}
// 關閉檔案
in.h.ah = 0x3E; in.x.bx = handle;
intdosx(&in, &out, &seg);
return 1; // 次數用盡
}
int main()
{
int ret = CheckTrialCount();
if (ret == 0) printf("開啟檔案失敗,請勿竄改!\n");
else if (ret == 1) printf("試用次數已達上限!\n");
else printf("歡迎試用!剩餘 %d 次。\n", 40 - (ret==2?1:0));
return 0;
}
#include
bool IncrementTrialCount(LPCTSTR exePath, int maxTrials = 40)
{
HANDLE hFile = CreateFile(exePath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return false;
FILETIME ftCreate, ftAccess, ftWrite;
if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite)) {
CloseHandle(hFile); return false;
}
// 轉為 SYSTEMTIME 方便操作
SYSTEMTIME st;
FileTimeToSystemTime(&ftWrite, &st);
if (st.wMinute < maxTrials) {
st.wMinute += 1;
SystemTimeToFileTime(&st, &ftWrite);
SetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite);
CloseHandle(hFile);
return true; // 允許
}
CloseHandle(hFile);
return false; // 超過上限
}
Touch、Attribute Changer)可輕易修改時間;複製檔案會重置時間。本方法展示了檔案系統中繼資料的結構與底層 API 操作,適合理解 FILETIME、INT 21h、GetFileTime/SetFileTime 機制,實際商業軟體保護請採用成熟授權方案。