C++/CLI 針對所有類型 (含標準 C++ 類別) 新增屬性、事件、垃圾回收、泛型支援。Visual C++ 2005 透過 CLR (Common Language Runtime) 提供記憶體安全保證,旨在從根本上消除緩衝區溢出等經典漏洞。
#include
#include
#include
char buff[1028];
struct user { char *name; size_t len; int uid; };
bool checkpassword() {
char password[10];
puts("Enter 8 character password:");
gets(password); // 危險:無邊界檢查
return strcmp(password, "NCC-1701") == 0;
}
int main() {
struct user *userP = (struct user *)0xcdcdcdcd;
size_t userNameLen = 0xdeadbeef;
userP = (struct user *)malloc(sizeof(user));
puts("Enter user name:");
gets(buff); // 危險:堆疊緩衝區溢出
if (!checkpassword()) {
userNameLen = strlen(buff) + 1;
userP->len = userNameLen;
userP->name = (char *)malloc(userNameLen);
strcpy(userP->name, buff); // 記錄失敗嘗試
exit(-1);
}
}
漏洞點:第 13、26 行 gets() 不檢查輸入長度,導致堆疊 (password[10]) 與全域 (buff[1028]) 緩衝區溢出;第 31 行 strcpy 同樣無長度限制。
#using
using namespace System;
int main() {
Console::Write("Enter user name: ");
String^ userName = Console::ReadLine(); // 自動管理長度,無溢出風險
Console::Write("Enter 8 character password: ");
String^ password = Console::ReadLine();
if (password != "NCC-1701") {
// 記錄失敗嘗試,String 類別內建邊界檢查
Console::WriteLine("Failed login: {0}", userName);
return -1;
}
return 0;
}
| 特性 | 傳統 C++ | C++/CLI (CLR) |
|---|---|---|
| 緩衝區溢出 | 高風險 (手工管理) | 不可能 (執行時檢查) |
| 記憶體洩漏 | 常見 | 垃圾回收自動管理 |
| 懸空指標 | 常見 | 不可產生 (追蹤參考) |
| 非受控互操作 | 原生 | 需 pin_ptr, marshal_as 等顯式封送 |
Marshal 類別或 pin_ptr 固定記憶體。C++/CLI 配合 CLR 從語言與執行時雙重層面消除了緩衝區溢出根因。對於新專案或高安全需求的現有專案遷移,是極具吸引力的選擇。但需注意:非受控互操作邊界仍需謹慎處理,安全不是銀彈,而是系統性工程。