
ãCã䜿çšãããšãè¶³ãç°¡åã«æã€ããšãã§ããŸããC ++ã§ãããè¡ãã®ã¯é£ããã§ãããè¶³å šäœãå€ããŸããã-BjörnStroustrupãC ++ã¯ãªãšãŒã¿ãŒã
ãã®èšäºã§ã¯ãå®å®ãããå®å šã§ä¿¡é Œæ§ã®é«ãã³ãŒããäœæããæ¹æ³ãšãå®éã«æå³ããã«å®å šã«ç Žå£ããããšãããã«ç°¡åã§ãããã瀺ããŸãããã®ããã«ãç§ãã¡ã¯æãæçšã§é åçãªè³æãåéããããšããŸããã

SimbirSoftã§ã¯ãSecure Code Warriorãããžã§ã¯ããšç·å¯ã«é£æºããŠãå®å šãªãœãªã¥ãŒã·ã§ã³ãäœæããããã«ä»ã®éçºè ããã¬ãŒãã³ã°ããŠããŸããç¹ã«Habrã«ã€ããŠã¯ãCodeProject.comããŒã¿ã«çšã«èè ãæžããèšäºã翻蚳ããŸããã
ã ããã³ãŒãã«ïŒ
ããã¯æœè±¡çãªC ++ã³ãŒãã®å°ããªéšåã§ãããã®ã³ãŒãã¯ãéåžžã«å®éã®ãããžã§ã¯ãã§èŠã€ããå¯èœæ§ã®ããããããçš®é¡ã®åé¡ãšè匱æ§ã瀺ãããã«ç¹å¥ã«äœæãããŸãããã芧ã®ãšãããããã¯Windows DLLã³ãŒãã§ãïŒããã¯éèŠãªãã€ã³ãã§ãïŒã誰ãããã®ã³ãŒããäœããã®ïŒãã¡ããå®å šãªïŒãœãªã¥ãŒã·ã§ã³ã§äœ¿çšãããšããŸãã
ã³ãŒãã詳ããèŠãŠã¿ãŸããããããªãã®æèŠã§ã¯ãäœãããŸããããªãå¯èœæ§ããããŸããïŒ
ã³ãŒã
class Finalizer
{
struct Data
{
int i = 0;
char* c = nullptr;
union U
{
long double d;
int i[sizeof(d) / sizeof(int)];
char c [sizeof(i)];
} u = {};
time_t time;
};
struct DataNew;
DataNew* data2 = nullptr;
typedef DataNew* (*SpawnDataNewFunc)();
SpawnDataNewFunc spawnDataNewFunc = nullptr;
typedef Data* (*Func)();
Func func = nullptr;
Finalizer()
{
func = GetProcAddress(OTHER_LIB, "func")
auto data = func();
auto str = data->c;
memset(str, 0, sizeof(str));
data->u.d = 123456.789;
const int i0 = data->u.i[sizeof(long double) - 1U];
spawnDataNewFunc = GetProcAddress(OTHER_LIB, "SpawnDataNewFunc")
data2 = spawnDataNewFunc();
}
~Finalizer()
{
auto data = func();
delete[] data2;
}
};
Finalizer FINALIZER;
HMODULE OTHER_LIB;
std::vector<int>* INTEGERS;
DWORD WINAPI Init(LPVOID lpParam)
{
OleInitialize(nullptr);
ExitThread(0U);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
static std::vector<std::thread::id> THREADS;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
srand(time(nullptr));
OTHER_LIB = LoadLibrary("B.dll");
if (OTHER_LIB = nullptr)
return FALSE;
CreateThread(nullptr, 0U, &Init, nullptr, 0U, nullptr);
break;
case DLL_PROCESS_DETACH:
CoUninitialize();
OleUninitialize();
{
free(INTEGERS);
const BOOL result = FreeLibrary(OTHER_LIB);
if (!result)
throw new std::runtime_error("Required module was not loaded");
return result;
}
break;
case DLL_THREAD_ATTACH:
THREADS.push_back(std::this_thread::get_id());
break;
case DLL_THREAD_DETACH:
THREADS.pop_back();
break;
}
return TRUE;
}
__declspec(dllexport) int Initialize(std::vector<int> integers, int& c) throw()
{
for (int i : integers)
i *= c;
INTEGERS = new std::vector<int>(integers);
}
int Random()
{
return rand() + rand();
}
__declspec(dllexport) long long int __cdecl _GetInt(int a)
{
return 100 / a <= 0 ? a : a + 1 + Random();
}
ããããããã®ã³ãŒãã¯åçŽã§ãæçœã§ãååã«å®å šã ãšæããŸãããïŒãŸãã¯å€åããªãã¯ããã«ããã€ãã®åé¡ãèŠã€ããŸãããïŒãããšãã1ã2ã2ã€ã§ããïŒ
ãã®ã¹ããããã«ã¯ãå®éã«ã¯ããŸããŸãªçšåºŠã®éèŠæ§ãæã€43ãè¶ ããæœåšçãªè åšããããŸãã

泚æãã¹ãç¹
1ïŒsizeofïŒdïŒïŒdã¯long doubleïŒã¯ãå¿ ãããsizeofïŒintïŒã®åæ°ã§ããå¿ èŠã¯ãããŸããã
int i[sizeof(d) / sizeof(int)];
ãã®ç¶æ³ã¯ãããã§ã¯ãã¹ããåŠçããããŠããŸãããããšãã°ãäžéšã®ãã©ãããã©ãŒã ã§ã¯ãlong doubleã10ãã€ãã«ãªãå ŽåããããŸãïŒããã¯ãMS VSã³ã³ãã€ã©ã«ã¯åœãŠã¯ãŸããŸãããã以åã¯C ++ BuilderãšåŒã°ããŠããRADStudioã«ã¯åœãŠã¯ãŸããŸãïŒãintã¯ããã©ãããã©ãŒã ã«å¿ããŠãµã€ãºãç°ãªãå ŽåããããŸãïŒäžèšã®ã³ãŒãã¯ãWindowsçšã§ããããããã®ç¹å®ã®ç¶æ³ã«é¢é£ããŠãåé¡ã¯å€å°äžèªç¶ã§ãããããŒã¿ãã«ã³ãŒãã®å Žåããã®åé¡ã¯éåžžã«é¢é£æ§ããããŸãïŒã ããããã¿ã€ãã³ã°ãã³ã䜿çšãããå Žåãããããã¹ãŠãåé¡ã«ãªãå¯èœæ§ããããŸããã¡ãªã¿ã«ãããã¯æªå®çŸ©ã®åäœãåŒãèµ·ãããŸã
C ++èšèªæšæºã«æºæ ããã ããæè¿ã®ã³ã³ãã€ã©ã¯éåžžãç¹å®ã®ã±ãŒã¹ã«å¯ŸããŠæ£ããäºæ³ãããåäœãå®çŸ©ãããããã¿ã€ãã³ã°ãã³ã䜿çšããã®ãäžè¬çãªæ¹æ³ã§ãïŒããšãã°ãGCCãå®çŸ©ããããã«ïŒãåºå žïŒMedium.com ã¡ãªã¿ã«ãC ++ãšã¯ç°ãªããçŸä»£ã®Cã§ã¯ãã¿ã€ãã³ã°ãã³ã¯å®å šã«åãå ¥ããããŸãïŒC ++ãšCã¯ç°ãªãèšèªã§ãããC ++ãç¥ã£ãŠããå Žåã¯ãCãç¥ã£ãŠãããšæåŸ ãã¹ãã§ã¯ãããŸãããéã§ãããïŒïŒè§£æ±ºçïŒstatic_assertã䜿çšããŸã

ã³ã³ãã€ã«æã«ãã®ãããªãã¹ãŠã®ä»®å®ãå¶åŸ¡ããŸããã¿ã€ããµã€ãºã«åé¡ãããå Žåã¯èŠåã衚瀺ãããŸãã
static_assert(0U == (sizeof(d) % sizeof(int)), âHouston, we have a problemâ);
2ïŒtime_tã¯ãã¯ãã§ãããVisual Studioã§ã¯ã32ãããïŒå€ãïŒãŸãã¯64ãããïŒæ°ããïŒã®æŽæ°åãåç §ã§ããŸãã
time_t time;
2ã€ã®ãã€ããªããã®ã¿ã€ãã®ç°ãªãç©ç衚çŸã§ã³ã³ãã€ã«ãããŠããå Žåãç°ãªãå®è¡å¯èœã¢ãžã¥ãŒã«ïŒããšãã°ãå®è¡å¯èœãã¡ã€ã«ãšãããããŒãããDLLïŒãããã®ã¿ã€ãã®å€æ°ã«ã¢ã¯ã»ã¹ãããšããªããžã§ã¯ãã®å¢çå€ã§èªã¿åã/æžã蟌ã¿ãçºçããå¯èœæ§ããããŸããããã«ãããã¡ã¢ãªã®ç Žæãã¬ããŒãžã®èªã¿åããçºçããŸãã

解決çïŒãã¹ãŠã®ã¢ãžã¥ãŒã«éã®ããŒã¿äº€æã«ãå³å¯ã«å®çŸ©ãããåãã¿ã€ãã®ãµã€ãºã䜿çšãããŠããããšã確èªããŠãã ããã
int64_t time;
3ïŒB.DLLïŒã§æ ŒçŽãããŠããã®ãã³ãã«OTHER_LIB倿°ïŒããŠããªãããŸã ãããŠç§ãã¡ã¯ããã®ã©ã€ãã©ãªã®é¢æ°ã®ã¢ãã¬ã¹ãååŸããããšã¯ã§ããŸããã®ã§ãæã ã¯äžèšã®å€æ°ã«ã¢ã¯ã»ã¹ãããšãã«ããŒãããã
4ïŒéçãªããžã§ã¯ãïŒã®åæåé åºã«åé¡SIOFïŒïŒïŒOTHER_LIBãªããžã§ã¯ãåæåãããåã«ã³ãŒãã§äœ¿çšãããŠããŸããïŒ
func = GetProcAddress(OTHER_LIB, "func");
FINALIZERã¯ãDllMain颿°ãåŒã³åºãåã«äœæãããéçãªããžã§ã¯ãã§ãããã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ã¯ããŸã ããŒããããŠããªãã©ã€ãã©ãªãŒã䜿çšããããšããŠããŸãããã®åé¡ã¯ãéçFINALIZERã«ãã£ãŠäœ¿çšãããéçOTHER_LIBãããŠã³ã¹ããªãŒã ã®å€æãŠãããã«é 眮ããããšããäºå®ã«ãã£ãŠæªåããŸããããã¯ãåŸã§åæåïŒãŒãåïŒãããããšãæå³ããŸããã€ãŸããã¢ã¯ã»ã¹æã«ãç䌌ã©ã³ãã ã¬ããŒãžãå«ãŸããŸããWinAPIäžè¬ã«ãããã«æ£åžžã«åå¿ããã¯ãã§ãããªããªããé«ã確çã§ããã®ãããªèšè¿°åãæã€ããŒããããã¢ãžã¥ãŒã«ããŸã£ããååšããªãããã§ãããããŠã絶察ã«ä¿¡ããããªãã»ã©ã®å¶ç¶ãèµ·ãã£ããšããŠããããããFuncããšããååã®é¢æ°ãå«ãå¯èœæ§ã¯äœãã§ãã
解決çïŒäžè¬çãªã¢ããã€ã¹ã¯ãç¹ã«DLLã§çžäºã«äŸåããŠããå Žåã¯ç¹ã«ãã°ããŒãã«ãªããžã§ã¯ããç¹ã«è€éãªãªããžã§ã¯ãã®äœ¿çšãé¿ããããšã§ãããã ããäœããã®çç±ã§ããã§ãå¿ èŠãªå Žåã¯ãåæåã®é åºã«çްå¿ã®æ³šæãæã£ãŠãã ããããã®é åºãå¶åŸ¡ããã«ã¯ãã°ããŒãã«ãªããžã§ã¯ãã®ãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ïŒå®çŸ©ïŒã1ã€ã® 倿åäœã«é 眮ããŸãããããæ£ããåæåãããããšãä¿èšŒããããã«æ£ããé åºã§ã
5ïŒä»¥åã«è¿ãããçµæã¯äœ¿çšåã«ãã§ãã¯ãããŸãã
auto data = func();
funcã¯é¢æ°ãã€ã³ã¿ã§ãããŸããB.dllã®é¢æ°ãæããŠããå¿ èŠããããŸãããã ããåã®æé ã§ãã¹ãŠãå®å šã«å€±æãããããããã¯nullptrã«ãªããŸãããããã£ãŠãäºæããã颿°åŒã³åºãã®ä»£ããã«ããããéåç §ããããšãããšãã¢ã¯ã»ã¹éåãŸãã¯äžè¬çãªä¿è·é害ãªã©ãçºçããŸãã
解決çïŒå€éšã³ãŒãïŒãã®å Žåã¯WinAPIïŒãæäœãããšãã¯ãåŒã³åºããã颿°ã®æ»ãçµæãåžžã«ç¢ºèªããŠãã ãããä¿¡é Œæ§ãé«ããé害ã«åŒ·ãã·ã¹ãã ã®å Žåããã®ã«ãŒã«ã¯ã[äœããã€è¿ããã«ã€ããŠ]å³å¯ãªå¥çŽãçµã°ããŠããæ©èœã«ãé©çšãããŸãã
6ïŒç°ãªãé 眮/ããã£ã³ã°èšå®ã§ã³ã³ãã€ã«ãããã¢ãžã¥ãŒã«éã§ããŒã¿ã亀æãããšãã®ã¬ããŒãžã®èªã¿åã/æžã蟌ã¿
auto str = data->c;
ããŒã¿æ§é ïŒéä¿¡ã¢ãžã¥ãŒã«éã§æ å ±ã亀æããããã«äœ¿çšãããïŒã«ãããã®åãã¢ãžã¥ãŒã«ãç°ãªãç©çç衚瀺ã§ããå Žåãåè¿°ã®ãã¹ãŠã®ã¢ã¯ã»ã¹éåããšã©ãŒã¡ã¢ãªä¿è·ãé害ã»ã°ã¡ã³ããŒã·ã§ã³ãããŒãç Žæãªã©ãçºçããŸãããŸãã¯ããŽããèªãã ãã§ããæ£ç¢ºãªçµæã¯ããã®ã¡ã¢ãªã®å®éã®äœ¿çšã·ããªãªã«ãã£ãŠç°ãªããŸããæ§é èªäœã«æç€ºçãªé 眮/ããã£ã³ã°èšå®ããªããããããã¯ãã¹ãŠçºçããå¯èœæ§ããããŸãããããã£ãŠãã³ã³ãã€ã«æã®ãããã®ã°ããŒãã«èšå®ãçžäºäœçšããã¢ãžã¥ãŒã«ã§ç°ãªãå Žåãåé¡ãçºçããŸãã

決å®ïŒãã¹ãŠã®å ±æããŒã¿æ§é ã匷åã§æç€ºçã«å®çŸ©ãããæçœãªç©çç衚çŸïŒåºå®ãµã€ãºã¿ã€ããæç€ºçã«æå®ãããé 眮ãªã©ã䜿çšïŒãæã£ãŠããããšãããã³/ãŸãã¯çžäºéçšå¯èœãªãã€ããªãåãã°ããŒãã«é 眮èšå®ã§ã³ã³ãã€ã«ãããŠããããšã確èªããŠãã ãã/ å å¡«ã
ãåç
§ããŠãã ãã
Alignment (C++ Declarations)
Data structure alignment
Struct padding in C++
Data structure alignment
Struct padding in C++
7ïŒé åèªäœã®ãµã€ãºã§ã¯ãªããé åãžã®ãã€ã³ã¿ã®ãµã€ãºã䜿çšãã
memset(str, 0, sizeof(str));
ããã¯éåžžãäºçްãªã¿ã€ããã¹ã®çµæã§ãããã ãããã®åé¡ã¯ãéç倿 æ§ãåŠçããå ŽåããŸãã¯autoããŒã¯ãŒããç¡æèã«äœ¿çšããå ŽåïŒç¹ã«æããã«äœ¿ããããŠããå ŽåïŒã«ãçºçããå¯èœæ§ããããŸãããã ããææ°ã®ã³ã³ãã€ã©ã¯ãå éšéçã¢ãã©ã€ã¶ã®æ©èœã䜿çšããŠãã³ã³ãã€ã«æã«ãã®ãããªåé¡ãæ€åºããã®ã«ååãªã»ã©ã¹ããŒãã§ããããšãæåŸ ããããšæããŸãã
決å®ïŒ
- sizeofïŒ<å®å šãªãªããžã§ã¯ãã¿ã€ã>ïŒãšsizeofïŒ<ãªããžã§ã¯ããã€ã³ã¿ã¿ã€ã>ïŒãæ··åããªãã§ãã ããã
- ã³ã³ãã€ã©ã®èŠåãç¡èŠããªãã§ãã ãã;
- typeidãconstexprãããã³static_assertãçµã¿åãããŠãC ++ãã€ã©ãŒãã¬ãŒãã®éæ³ãå°ã䜿çšããŠãã³ã³ãã€ã«æã«åãæ£ããããšã確èªããããšãã§ããŸãïŒããã§ã¯ãåã®ç¹æ§ãç¹ã«std :: is_pointerã圹ç«ã¡ãŸãïŒã
8ïŒä»¥åã«å€ãèšå®ããããã«äœ¿çšããããã®ãšã¯ç°ãªããŠããªã³ãã£ãŒã«ããèªã¿åãããšãããšãã®æªå®çŸ©ã®åäœ
9ïŒlong doubleã®é·ãããã€ããªã¢ãžã¥ãŒã«éã§ç°ãªãå Žåãç¯å²å€ã§èªã¿åãããšããå¯èœæ§ããããŸã
const int i0 = data->u.i[sizeof(long double) - 1U];
ããã¯ãã§ã«åè¿°ããã®ã§ãããã§åè¿°ã®åé¡ã®å¥ã®ååšç¹ãååŸããŸããã
解決çïŒã³ã³ãã€ã©ãŒãæ£ããåŠçããŠããããšã確å®ã§ãªãéããåã«èšå®ãããã£ãŒã«ã以å€ã®ãã£ãŒã«ããåç §ããªãã§ãã ãããå ±æãªããžã§ã¯ãã¿ã€ãã®ãµã€ãºããçžäºäœçšãããã¹ãŠã®ã¢ãžã¥ãŒã«ã§åãã§ããããšã確èªããŠãã ããã
ãåç
§ããŠãã ãã
Type-punning and strict-aliasing
What is the Strict Aliasing Rule and Why do we care?
What is the Strict Aliasing Rule and Why do we care?
10ïŒB.dllãæ£ããããŒãããããfuncã颿°ãæ£ãããšã¯ã¹ããŒãããã³ã€ã³ããŒããããå Žåã§ãããã®æç¹ã§B.dllã¯ã¡ã¢ãªããã¢ã³ããŒããããŸãïŒFreeLibraryã·ã¹ãã 颿°ã¯ä»¥åã«DllMainã³ãŒã«ããã¯é¢æ°ã®DLL_PROCESS_DETACHã»ã¯ã·ã§ã³ã§åŒã³åºãããŠããããïŒ ïŒ
auto data = func();
以åã«ç Žæ£ãããããªã¢ãŒãã£ãã¯ã¿ã€ãã®ãªããžã§ã¯ãã§ä»®æ³é¢æ°ãåŒã³åºãã ãã§ãªãããã§ã«ã¢ã³ããŒããããŠããåçã©ã€ãã©ãªã§é¢æ°ãåŒã³åºããšãçŽç²ãªä»®æ³åŒã³åºããšã©ãŒãçºçããå¯èœæ§ããããŸãã
解決çïŒã¢ããªã±ãŒã·ã§ã³ã«æ£ãããã¡ã€ãã©ã€ãºæé ãå®è£ ããŠããã¹ãŠã®DLLãæ£ããé åºã§çµäº/ã¢ã³ããŒããããããã«ããŸããé¿ãã«è€éãªããžãã¯ã§éçãªããžã§ã¯ãã䜿çšããŠDLïŒã©ã€ãã©ãªããã®ã©ã€ããµã€ã¯ã«ã®æåŸã®æ®µéã«å ¥ã-ãã®éçãªããžã§ã¯ããç Žå£ããçžïŒã®DllMain / DLL_PROCESS_DETACHãåŒã³åºããåŸãã©ã€ãã©ãªå ã®ä»»æã®æäœãå®è¡L.ã¯é¿ããŠãã ããã
DLLã®ã©ã€ããµã€ã¯ã«ãçè§£ããå¿ èŠããããŸãã
) LoadLibrary
- ( , )
- DllMain -> DLL_PROCESS_ATTACH ( , )
- [] DllMain -> DLL_THREAD_ATTACH / DLL_THREAD_DETACH ( , . 30).
- , , (, ),
- ( / , , )
- , ()
- ( / , , )
- - : ,
) FreeLibrary
- DllMain -> DLL_PROCESS_DETACH ( , )
- ( , )

11ïŒäžéæãªãã€ã³ã¿ã®åé€ïŒã³ã³ãã€ã©ã¯ãã¹ãã©ã¯ã¿ãåŒã³åºãããã«å®å šãªåãç¥ãå¿ èŠããããããäžéæãªãã€ã³ã¿ã䜿çšããŠãªããžã§ã¯ããåé€ãããšãã¡ã¢ãªãªãŒã¯ããã®ä»ã®åé¡ãçºçããå¯èœæ§ããããŸãïŒ
12ïŒDataNewãã¹ãã©ã¯ã¿ãä»®æ³ã®å Žåãã¯ã©ã¹ãæ£ãããšã¯ã¹ããŒãããã³ã€ã³ããŒããããå®å šã§ããå Žåã§ãããã«é¢ããæ å ±ã¯ããšã«ãããã®æ®µéã§ãã®ãã¹ãã©ã¯ã¿ãåŒã³åºãããšã¯åé¡ã§ã-ããã¯ããããçŽç²ã«ä»®æ³ã®é¢æ°åŒã³åºãã«ã€ãªããã§ãããïŒDataNewã¿ã€ãã¯ãã§ã«ã¢ã³ããŒããããB.dllãã¡ã€ã«ããã€ã³ããŒããããããïŒããã®åé¡ã¯ããã¹ãã©ã¯ã¿ãä»®æ³ã§ãªãå Žåã§ãçºçããå¯èœæ§ããããŸãã
13ïŒDataNewã¯ã©ã¹ãæœè±¡å€æ æ§ã¿ã€ãã®å Žåãããã³ãã®åºæ¬ã¯ã©ã¹ã«ã¯ãæ¬äœã®ãªãçŽç²ãªä»®æ³ãã¹ãã©ã¯ã¿ããããŸãããããã®å ŽåããçŽç²ãªä»®æ³é¢æ°åŒã³åºããçºçããŸãã
14ïŒã¡ã¢ãªãnewã䜿çšããŠå²ãåœãŠãããdelete []ã䜿çšããŠåé€ãããå Žåã®æªå®çŸ©ã®åäœ
delete[] data2;
äžè¬ã«ãå€éšã¢ãžã¥ãŒã«ããååŸãããªããžã§ã¯ããè§£æŸãããšãã¯ãåžžã«æ³šæããå¿ èŠããããŸããç Žå£ããããªããžã§ã¯ããžã®ãã€ã³ã¿ããŒãã«ããããš
ãè¯ãç¿æ £ã§ããæ±ºå®ïŒ
- ãªããžã§ã¯ããåé€ãããšãã¯ããã®å®å šãªã¿ã€ããç¥ã£ãŠããå¿ èŠããããŸã
- ãã¹ãŠã®ç Žå£è ã¯äœãæã£ãŠããå¿ èŠããããŸã
- ã³ãŒãã®ãšã¯ã¹ããŒãå ã®ã©ã€ãã©ãªãæ©ãã«ã¢ã³ããŒãããªãã§ãã ãã
- åžžã«æ°ãããã©ãŒã ã䜿çšããŠæ£ããåé€ããæ··åããªãã§ãã ãã
- ãªã¢ãŒããªããžã§ã¯ããžã®ãã€ã³ã¿ã¯ãŒãã«ããå¿ èŠããããŸãã

ãŸããæ¬¡ã®ç¹ã«æ³šæããŠãã ãã
- voidãžã®ãã€ã³ã¿ã«åé€åŒã³åºããšãªããæªå®çŸ©ã®åäœã§
ãçŽç²ä»®æ³é¢æ°ãã¹ãã§ã¯ãªãã³ã³ã¹ãã©ã¯ã¿ããåŒã³åºããã
ã³ã³ã¹ãã©ã¯ã¿ã§ä»®æ³é¢æ°ãåŒã³åºã-ã§ã¯ãããŸããä»®æ³
-åé¿ããããšæåã¡ã¢ãªç®¡çã-䜿çšããã³ã³ãããç§»åã»ãã³ãã£ã¯ã¹ãããããŠã¹ããŒããã€ã³ã¿ãŒ
ãåç
§ããŠãã ãã
Heap corruption: What could the cause be?
15ïŒExitThreadã¯ãCã§ã¹ã¬ãããçµäºããããã®æšå¥šãããæ¹æ³ã§ããC++ã§ã¯ããã®é¢æ°ãåŒã³åºããšãããŒã«ã«ãªããžã§ã¯ãã®ãã¹ãã©ã¯ã¿ïŒããã³ãã®ä»ã®èªåã¯ãªãŒã³ã¢ããïŒãåŒã³åºãåã«ã¹ã¬ãããçµäºãããããC ++ã§ã¹ã¬ãããçµäºããã«ã¯ãã¹ã¬ãã颿°ããæ»ãã ãã§ãã
ExitThread(0U);
解決çïŒ C ++ã³ãŒãã§ãã®é¢æ°ãæåã§äœ¿çšããªãã§ãã ããã
16ïŒDllMainã®æ¬äœã§ãKernel32.dll以å€ã®ã·ã¹ãã DLLãå¿ èŠãšããæšæºé¢æ°ãåŒã³åºããšãããŸããŸãªèšºæãé£ããåé¡ãçºçããå¯èœæ§ããããŸãã
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
DllMainã®ãœãªã¥ãŒã·ã§ã³ïŒ
- è€éãªïŒdeïŒåæåãåé¿ãã
- ä»ã®ã©ã€ãã©ãªãã颿°ãåŒã³åºããªãã§ãã ããïŒãŸãã¯å°ãªããšãããã«ã¯éåžžã«æ³šæããŠãã ããïŒ

17ïŒãã«ãã¹ã¬ããç°å¢ã§ã®ç䌌乱æ°ãžã§ãã¬ãŒã¿ãŒã®èª€ã£ãåæå
18ïŒtime颿°ã«ãã£ãŠè¿ãããæéã®è§£å床ã¯1ç§ã§ããããããã®æéäžã«ãã®é¢æ°ãåŒã³åºãããã°ã©ã å ã®ã¹ã¬ããã¯ãåºåã§åãå€ãåãåããŸãããã®çªå·ã䜿çšããŠPRNGãåæåãããšãè¡çªãçºçããå¯èœæ§ããããŸãïŒããšãã°ãäžæãã¡ã€ã«ã«åãç䌌ã©ã³ãã åãçæããããåãããŒãçªå·ãçæããããããªã©ïŒãèãããã解決çã®1ã€ã¯ãçµæã®çµæããããŒãå ã®ã¹ã¿ãã¯ãŸãã¯ãªããžã§ã¯ãã®ã¢ãã¬ã¹ãããæ£ç¢ºãªæéãªã©ã®ç䌌ã©ã³ãã å€ãšæ··åïŒxorïŒããããšã§ãã
srand(time(nullptr));
解決çïŒ MS VSã§ã¯ãã¹ã¬ããããšã«PRNGã®åæåãå¿ èŠã§ããããã«ãåæååãšããŠUnixæéã䜿çšãããšãšã³ããããŒãäžååã«ãªããããããé«åºŠãªåæåå€ã®çæãæšå¥šãããŸãã
ãåç
§ããŠãã ãã
Is there an alternative to using time to seed a random number generation?
C++ seeding surprises
Getting random numbers in a thread-safe way [C#]
C++ seeding surprises
Getting random numbers in a thread-safe way [C#]
19ïŒãããããã¯ãŸãã¯ã¯ã©ãã·ã¥ããå¯èœæ§ããããŸãïŒãŸãã¯DLLã®ããŒãé åºã§äŸåé¢ä¿ã«ãŒããäœæãããŸãïŒ
OTHER_LIB = LoadLibrary("B.dll");
解決çïŒ DllMainãšã³ããªãã€ã³ãã§LoadLibraryã䜿çšããªãã§ãã ãããè€éãªïŒdeïŒåæåã¯ããInitãããDeintããªã©ã®ç¹å®ã®DLLéçºè ããšã¯ã¹ããŒããã颿°ã§å®è¡ããå¿ èŠããããŸããã©ã€ãã©ãªã¯ãããã®é¢æ°ããŠãŒã¶ãŒã«æäŸãããŠãŒã¶ãŒã¯é©åãªã¿ã€ãã³ã°ã§ããããæ£ããåŒã³åºãå¿ èŠããããŸããäž¡åœäºè ã¯ããã®å¥çŽãå³å®ããå¿ èŠããããŸãã

20ïŒã¿ã€ããã¹ïŒæ¡ä»¶ã¯åžžã«falseïŒãééã£ãããã°ã©ã ããžãã¯ãããã³ãªãœãŒã¹ãªãŒã¯ã®å¯èœæ§ïŒããŠã³ããŒããæåãããšãã«OTHER_LIBãã¢ã³ããŒããããªãããïŒ
if (OTHER_LIB = nullptr)
return FALSE;
ã³ããŒã«ããå²ãåœãŠæŒç®åã¯ãå·ŠåŽã®ã¿ã€ãã®ãªã³ã¯ãè¿ããŸããifã¯OTHER_LIBå€ïŒnullptrã«ãªããŸãïŒããã§ãã¯ããnullptrã¯falseãšããŠè§£éãããŸãã
解決çïŒæ¬¡ã®ãããªã¿ã€ããã¹ãé¿ããããã«ãåžžã«éã®åœ¢åŒã䜿çšããŠãã ããã
if/while (<constant> == <variable/expression>)
21ïŒ_beginthreadã·ã¹ãã 颿°ã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã«æ°ããã¹ã¬ãããäœæããããšããå§ãããŸãïŒç¹ã«ãã¢ããªã±ãŒã·ã§ã³ãéçããŒãžã§ã³ã®Cã©ã³ã¿ã€ã ã©ã€ãã©ãªã«ãªã³ã¯ãããŠããå ŽåïŒãããããªããšãExitThreadãDisableThreadLibraryCallsãåŒã³åºããšãã«ã¡ã¢ãªãªãŒã¯ãçºçããå¯èœæ§ããããŸãã22
ïŒDllMainãžã®ãã¹ãŠã®å€éšåŒã³åºãã¯ã·ãªã¢ã«åããããããæ¬æã§ã¯ãã®é¢æ°ã¯ãã¹ã¬ãã/ããã»ã¹ãäœæããããããããšå¯Ÿè©±ãããããªãã§ãã ãããããããªããšããããããã¯ãçºçããå¯èœæ§ããããŸã
CreateThread(nullptr, 0U, &Init, nullptr, 0U, nullptr);
23ïŒå¯Ÿå¿ããã³ã³ããŒãã³ãããã§ã«ã¢ã³ããŒããããŠããå¯èœæ§ããããããDLLã®çµäºäžã«COM颿°ãåŒââã³åºããšã誀ã£ãã¡ã¢ãªã¢ã¯ã»ã¹ãçºçããå¯èœæ§ããããŸã
CoUninitialize();
24ïŒã€ã³ããã»ã¹COM / OLEãµãŒãã¹ã®ããŒããšã¢ã³ããŒãã®é åºãå¶åŸ¡ããæ¹æ³ããªããããDllMain颿°ããOleInitializeãŸãã¯OleUninitializeãåŒã³åºããªãã§ãã ããã
OleUninitialize();
ãåç
§ããŠãã ãã
COM Clients and Servers
In-process, Out-of-process, and Remote Servers
In-process, Out-of-process, and Remote Servers
25ïŒæ°ããå²ãåœãŠãããã¡ã¢ãªã®ãããã¯ãè§£æŸãã
26ïŒã¢ããªã±ãŒã·ã§ã³ããã»ã¹ããã®äœæ¥ãçµäºããããã»ã¹ã«ããå ŽåïŒlpvReservedãã©ã¡ãŒã¿ã®ãŒã以å€ã®å€ã§ç€ºãããïŒãçŸåšã®ã¹ã¬ãããé€ãããã»ã¹å ã®ãã¹ãŠã®ã¹ã¬ããã¯ããã§ã«çµäºããŠããããæ¬¡ã®å Žåã«åŒ·å¶çã«åæ¢ãããŠããŸãã ExitProcess颿°ãåŒã³åºããšãããŒããªã©ã®äžéšã®ããã»ã¹ãªãœãŒã¹ãäžæŽåãªç¶æ ã®ãŸãŸã«ãªãå¯èœæ§ããããŸãããã®çµæããªãœãŒã¹ãã¯ãªãŒã³ã¢ããããããšã¯DLLã»ãŒãã§ã¯ãããŸããã代ããã«ãDLLã¯ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãã¡ã¢ãªãåå©çšã§ããããã«ããå¿ èŠããããŸãã
free(INTEGERS);
解決çïŒå€ãCã¹ã¿ã€ã«ã®æåã¡ã¢ãªå²ãåœãŠããæ°ãããC ++ã¹ã¿ã€ã«ãšæ··åšããŠããªãããšã確èªããŠãã ãããDllMain颿°ã§ãªãœãŒã¹ã管çãããšãã¯ã现å¿ã®æ³šæãæã£ãŠãã ããã
27ïŒã·ã¹ãã ãçµäºã³ãŒããå®è¡ããåŸã§ããDLLã䜿çšãããå¯èœæ§ããããŸã
const BOOL result = FreeLibrary(OTHER_LIB);
解決çïŒ DllMainãšã³ããªãã€ã³ãã§FreeLibraryãåŒã³åºããªãã§ãã ããã 28ïŒçŸåšã®ïŒããããã¡ã€ã³ã®ïŒã¹ã¬ãããã¯ã©ãã·ã¥ããŸã
throw new std::runtime_error(" ");
解決çïŒ DllMain颿°ã§äŸå€ãã¹ããŒããªãããã«ããŸããäœããã®çç±ã§DLLãæ£ããããŒãã§ããªãå Žåã颿°ã¯åã«FALSEãè¿ãå¿ èŠããããŸãããŸããDLL_PROCESS_DETACHã»ã¯ã·ã§ã³ããäŸå€ãã¹ããŒããªãã§ãã ããã
DLLã®å€éšã§äŸå€ãã¹ããŒãããšãã¯ãåžžã«æ³šæããŠãã ãããè€éãªãªããžã§ã¯ãïŒããšãã°ãæšæºã©ã€ãã©ãªã®ã¯ã©ã¹ïŒã¯ãã©ã³ã¿ã€ã ã©ã€ãã©ãªã®ç°ãªãïŒäºææ§ã®ãªãïŒããŒãžã§ã³ã§ã³ã³ãã€ã«ãããŠããå Žåãç°ãªãå®è¡å¯èœã¢ãžã¥ãŒã«ã§ç°ãªãç©çç衚çŸïŒããã³äœæ¥ã®ããžãã¯ïŒãæã€ããšãã§ããŸãã

ã¢ãžã¥ãŒã«éã§åçŽãªããŒã¿ã¿ã€ãã®ã¿ã亀æããŠã¿ãŠãã ããïŒåºå®ãµã€ãºãšæç¢ºã«å®çŸ©ããããã€ããªè¡šçŸã䜿çšïŒã
ã¡ã€ã³ã¹ã¬ãããçµäºãããšãä»ã®ãã¹ãŠã®ã¹ã¬ãããèªåçã«çµäºããããšã«æ³šæããŠãã ããïŒæ£ããçµäºããªããããã¡ã¢ãªãæå·ããåæããªããã£ãããã®ä»ã®ãªããžã§ã¯ããäºæž¬ã§ããªã誀ã£ãç¶æ ã«ãªããŸããããã«ããããã®ã¹ã¬ããã¯ãæ¬¡ã®æç¹ã§ãã§ã«ååšããªããªããŸããéçãªããžã§ã¯ãã¯ç¬èªã®åè§£ãéå§ãããããéçãªããžã§ã¯ãã®ãã¹ãã©ã¯ã¿ã§ã¹ã¬ãããçµäºããã®ãåŸ ããªãã§ãã ããïŒã
ãåç
§ããŠãã ãã
Top 20 C++ multithreading mistakes and how to avoid them
29ïŒããã§ã¯ãã£ãããããªãäŸå€ïŒããšãã°ãstd :: bad_allocïŒãã¹ããŒã§ããŸãã
THREADS.push_back(std::this_thread::get_id());
DLL_THREAD_ATTACHã»ã¯ã·ã§ã³ã¯äžæãªå€éšã³ãŒãããåŒã³åºããããããããã§æ£ããåäœãèŠããããšã¯æããªãã§ãã ããã
解決çïŒ try / catchã³ãã³ãã䜿çšããŠãæ£ããåŠçã§ããªãå¯èœæ§ãæãé«ãäŸå€ãã¹ããŒããå¯èœæ§ã®ããã¹ããŒãã¡ã³ããå²ã¿ãŸãïŒç¹ã«ãDLLããçµäºããå ŽåïŒã
ãåç
§ããŠãã ãã
How can I handle a destructor that fails?
30ïŒãã®DLLãããŒãããåã«ã¹ããªãŒã ãæç€ºãããå Žåã¯UB
THREADS.pop_back();
æ¢ã«ååšããŠããã¹ã¬ããæã«DLLãïŒçŽæ¥ããŒãããããšãå«ãèªã¿èŸŒãŸããDLLã¯ïŒããŒããããŠåŒã³åºãããšã¯ãããŸããDLLã®ãšã³ããªãã€ã³ã颿°åœŒãã¯ãŸã DLL_THREAD_DETACHã®ã€ãã³ãã§ãããåŒã³åºããŠããéãïŒãããã¯DLL_THREAD_ATTACHã€ãã³ãäžTHREADSãã¯ã¿ãŒã§ç»é²ãããŠããªãçç±ã§ãïŒå®äºæã«ã
ããã¯ãDllMain颿°ã®DLL_THREAD_ATTACHã»ã¯ã·ã§ã³ãšDLL_THREAD_DETACHã»ã¯ã·ã§ã³ãžã®åŒã³åºãã®æ°ãç°ãªãããšãæå³ããŸãã
31ïŒåºå®ãµã€ãºã®æŽæ°åã䜿çšããããšããå§ãããŸã
32ïŒç°ãªããªã³ã¯ããã³ã³ã³ãã€ã«èšå®ãšãã©ã°ïŒç°ãªãããŒãžã§ã³ã®ã©ã³ã¿ã€ã ã©ã€ãã©ãªãªã©ïŒã§ã³ã³ãã€ã«ãããšãã¢ãžã¥ãŒã«éã§è€éãªãªããžã§ã¯ããæž¡ããšã¯ã©ãã·ã¥ããå¯èœæ§ããããŸã
ãã€ã³ã¿ãïŒãããã®ã¢ãžã¥ãŒã«ã«ç°ãªãæ¹æ³ã§åŠçãããŠããå Žåãã¢ãžã¥ãŒã«ã«ãã£ãŠå ±æããããã®ä»®æ³ã¢ãã¬ã¹ïŒïŒã«ãã£ãŠãªããžã§ã¯ãCãžã®ã¢ã¯ã»ã¹33ïŒãåé¡ãåŒãèµ·ããããšãã§ããäŸãã°ãã¢ãžã¥ãŒã«ã¯ç°ãªãé¢é£ä»ããããŠããå ŽåLARGEADDRESSAWAREã®ãã©ã¡ãŒã¿ïŒ
__declspec(dllexport) int Initialize(std::vector<int> integers, int& c) throw()
ãåç
§ããŠãã ãã
Is it possible to use more than 2 Gbytes of memory in a 32-bit program launched in the 64-bit Windows?
Application with LARGEADDRESSAWARE flag set getting less virtual memory
Drawbacks of using /LARGEADDRESSAWARE for 32 bit Windows executables?
how to check if exe is set as LARGEADDRESSAWARE [C#]
/LARGEADDRESSAWARE [Ru]
ASLR (Address Space Layout Randomization) [Ru]
Application with LARGEADDRESSAWARE flag set getting less virtual memory
Drawbacks of using /LARGEADDRESSAWARE for 32 bit Windows executables?
how to check if exe is set as LARGEADDRESSAWARE [C#]
/LARGEADDRESSAWARE [Ru]
ASLR (Address Space Layout Randomization) [Ru]
ãããŠ...
Virtual memory
Physical Address Extension
Tagged pointer
std::ptrdiff_t
What is uintptr_t data type
Pointer arithmetic
Pointer aliasing
What is the strict aliasing rule?
reinterpret_cast conversion
restrict type qualifier
Physical Address Extension
Tagged pointer
std::ptrdiff_t
What is uintptr_t data type
Pointer arithmetic
Pointer aliasing
What is the strict aliasing rule?
reinterpret_cast conversion
restrict type qualifier
äžèšã®ãªã¹ãã¯ã»ãšãã©å®å šã§ã¯ãªãã®ã§ãããããã³ã¡ã³ãã«éèŠãªäœãã远å ããããšãã§ããŸãã
ãã€ã³ã¿ã®æäœã¯ãå®éã«ã¯ã人ã ãéåžžèãããããã¯ããã«è€éã§ããééããªããçµéšè±å¯ãªéçºè ã¯ãä»ã®æ¢åã®ãã¥ã¢ã³ã¹ã埮åŠãªç¹ãèŠããããšãã§ããŸãïŒããšãã°ããªããžã§ã¯ããžã®ãã€ã³ã¿ãšé¢æ°ãžã®ãã€ã³ã¿ã®éãã«ã€ããŠã®äœãããã®ãããããããããã€ã³ã¿ã®ãã¹ãŠã®ãããã䜿çšã§ããããã§ã¯ãããŸãããªã©ã ãïŒã

34ïŒé¢æ°å ã§äŸå€ãã¹ããŒã§ããŸã ïŒ
INTEGERS = new std::vector<int>(integers);
ãã®é¢æ°ã®throwïŒïŒæå®ã¯ç©ºã§ãïŒ
__declspec(dllexport) int Initialize(std::vector<int> integers, int& c) throw()
std ::äºæããªããã®ã¯ãäŸå€ä»æ§ã«éåãããšãã«C ++ã©ã³ã¿ã€ã ã«ãã£ãŠåŒã³åºãããŸããäŸå€ä»æ§ããã®ã¿ã€ãã®äŸå€ãèš±å¯ããªã颿°ãããäŸå€ãã¹ããŒãããŸãã
解決çïŒ try / catchïŒç¹ã«ãç¹ã«DLLã§ãªãœãŒã¹ãå²ãåœãŠãå ŽåïŒãŸãã¯nothrow圢åŒã®newæŒç®åã䜿çšããŸãããããã«ãããããŸããŸãªçš®é¡ã®ãªãœãŒã¹ãå²ãåœãŠããã¹ãŠã®è©Šã¿ãåžžã«æ£åžžã«çµäºãããšããçŽ æŽãªä»®å®ããå§ããªãã§ãã ããã
ãåç
§ããŠãã ãã
RAII
We do not use C++ exceptions
Memory Limits for Windows and Windows Server Releases
We do not use C++ exceptions
Memory Limits for Windows and Windows Server Releases

åé¡1ïŒãã®ãããªãããã©ã³ãã ãªãå€ã®åœ¢æã¯æ£ãããããŸãããäžå€®éçå®çã«ããã°ãç¬ç«ããã©ã³ãã 倿°ã®åèšã¯ãåäžãªååžã§ã¯ãªããæ£èŠã®ååžã«ãªãåŸåããããŸãïŒåæå€èªäœãåäžã«ååžããŠããå Žåã§ãïŒã
åé¡2ïŒæŽæ°åã®ãªãŒããŒãããŒã®å¯èœæ§ïŒç¬Šå·ä»ãæŽæ°åã®æªå®çŸ©ã®åäœïŒ
return rand() + rand();
ç䌌乱æ°ãžã§ãã¬ãŒã¿ãæå·åãªã©ã䜿çšããå Žåã¯ãåžžã«èªå®¶è£œã®ããœãªã¥ãŒã·ã§ã³ãã®äœ¿çšã«æ³šæããŠãã ããããããã®éåžžã«ç¹æ®ãªåéã§å°éçãªæè²ãšçµéšãæã£ãŠããªãéããåã«èªåãè£åã£ãŠç¶æ³ãæªåãããå¯èœæ§ã¯éåžžã«é«ãã§ãã
35ïŒãšã¯ã¹ããŒãããã颿°ã®ååã¯extern "C"ã®äœ¿çšãé²ãããã«è£ 食ïŒå€æŽïŒãããŸã
36ïŒãã®åœåã¹ã¿ã€ã«ã¯STLçšã«äºçŽãããŠããããã '_'ã§å§ãŸãååã¯C ++ã§ã¯æé»çã«çŠæ¢ãããŠããŸã
__declspec(dllexport) long long int __cdecl _GetInt(int a)
ããã€ãã®åé¡ïŒãšãã®å¯èœãªè§£æ±ºçïŒïŒ
37ïŒã©ã³ãããã㊠ããªãã¹ã¬ããã»ãŒãã§ã¯ã䜿çšrand_rã¯ã /ã®ä»£ããã«rand_s
38ïŒã©ã³ããã廿¢ãããŠããæå¹ã«æŽ»çšçŸä»£
C++11 <random>
39ïŒrand颿°ãçŸåšã®ã¹ã¬ããå°çšã«åæåããããšããäºå®ã§ã¯ãããŸããïŒMS VSã§ã¯ãåŒã³åºãããã¹ã¬ããããšã«ãã®é¢æ°ã®åæåãå¿ èŠã§ãïŒ
40ïŒç䌌ã©ã³ãã çªå·ã®ç¹å¥ãªãžã§ãã¬ãŒã¿ãŒãããããããã³ã°ã«åŒ·ããœãªã¥ãŒã·ã§ã³ã§äœ¿çšããããšããå§ãããŸãïŒãããã¯é©åã§ãïŒLibsodium / randombytes_bufãOpenSSL / RAND_bytesãªã©ã®ããŒã¿ãã«ãœãªã¥ãŒã·ã§ã³ïŒ
41ïŒãŒãã«ããæœåšçãªé€ç®ïŒçŸåšã®ã¹ã¬ãããçµäºãããå¯èœæ§ããããŸã
42ïŒåªå é äœã®ç°ãªãæŒç®åãåãè¡ã§äœ¿çšãããŠãããããèšç®ã®é åºã«æ··ä¹±ãçããŸã-æ¬åŒ§ã䜿çšãã /ãŸãã¯ã·ãŒã±ã³ã¹ãã€ã³ãæãããªèšç®é åºãæå®ãã
43ïŒæœåšçãªæŽæ°ãªãŒããŒãããŒ
return 100 / a <= 0 ? a : a + 1 + Random();
ãåç
§ããŠãã ãã
Do not use std::rand() for generating pseudorandom numbers
ãããŠ...
ExitThread function
ExitProcess function
TerminateThread function
TerminateProcess function
ExitProcess function
TerminateThread function
TerminateProcess function
ãããŠãããã ãã§ã¯ãããŸããïŒ
ã¡ã¢ãªã«éèŠãªã³ã³ãã³ãïŒãŠãŒã¶ãŒã®ãã¹ã¯ãŒããªã©ïŒããããšæ³åããŠãã ããããã¡ãããå®éã«å¿ èŠãªæéããé·ãã¡ã¢ãªã«ä¿æããããªãã®ã§ã誰ããããããèªã¿åãå¯èœæ§ãé«ããªããŸãã
ãã®åé¡ã解決ããããã®çŽ æŽãªã¢ãããŒãã¯ã次ã®ããã«ãªããŸãã
bool login(char* const userNameBuf, const size_t userNameBufSize,
char* const pwdBuf, const size_t pwdBufSize) throw()
{
if (nullptr == userNameBuf || '\0' == *userNameBuf || nullptr == pwdBuf)
return false;
// Here some actual implementation, which does not checks params
// nor does it care of the 'userNameBuf' or 'pwdBuf' lifetime,
// while both of them obviously contains private information
const bool result = doLoginInternall(userNameBuf, pwdBuf);
// We want to minimize the time this private information is stored within the memory
memset(userNameBuf, 0, userNameBufSize);
memset(pwdBuf, 0, pwdBufSize);
}
ãããŠãããã¯ç¢ºãã«ç§ãã¡ãæãããã«ã¯æ©èœããŸãããããã§ã¯äœããã¹ãã§ããããïŒ:(
ééã£ãã解決çãïŒ1ïŒmemsetãæ©èœããªãå Žåã¯ãæåã§å®è¡ããŸãããïŒ
void clearMemory(char* const memBuf, const size_t memBufSize) throw()
{
if (!memBuf || memBufSize < 1U)
return;
for (size_t idx = 0U; idx < memBufSize; ++idx)
memBuf[idx] = '\0';
}
ãªããããç§ãã¡ã«åããªãã®ã§ããïŒäºå®ããã®ã³ãŒãã«ã¯ãææ°ã®ã³ã³ãã€ã©ãæé©åã§ããªããããªå¶éã¯ãããŸããïŒã¡ãªã¿ã«ãmemset颿°ããŸã 䜿çšãããŠããå Žåã¯ãããããçµã¿èŸŒã¿ã«ãªããŸãïŒã
ãåç
§ããŠãã ãã
The as-if rule
Are there situations where this rule does not apply?
Copy elision
Atomics and optimization
Are there situations where this rule does not apply?
Copy elision
Atomics and optimization
ééã£ãã解決çãïŒ2ïŒvolatileããŒã¯ãŒããããã£ãŠãåã®ã解決çãããæ¹åãããããšãã
void clearMemory(volatile char* const volatile memBuf, const volatile size_t memBufSize) throw()
{
if (!memBuf || memBufSize < 1U)
return;
for (volatile size_t idx = 0U; idx < memBufSize; ++idx)
memBuf[idx] = '\0';
*(volatile char*)memBuf = *(volatile char*)memBuf;
// There is also possibility for someone to remove this "useless" code in the future
}
ããã¯æ©èœããŸããïŒå€åãããšãã°ããã®ã¢ãããŒãã¯RtlSecureZeroMemoryã§äœ¿çšãããŸãïŒWindows SDKãœãŒã¹ã§ãã®é¢æ°ã®å®éã®å®è£ ã確èªããããšã§èªåã§ç¢ºèªã§ããŸãïŒã
ãã ãããã®ææ³ã¯ãã¹ãŠã®ã³ã³ãã€ã©ã§æåŸ ã©ããã«æ©èœãããšã¯éããŸããã
ãåç
§ããŠãã ãã
volatile member functions
ééã£ãã解決çãïŒ3ïŒäžé©åãªOS API颿°ïŒäŸïŒRtlZeroMemoryïŒãŸãã¯STLïŒäŸïŒstd :: fillãstd :: for_eachïŒã䜿çšãã
RtlZeroMemory(memBuf, memBufSize);
ãã®åé¡ã解決ãã詊ã¿ã®ä»ã®äŸã¯ããã«ãããŸãã
ãããŠãããã¯ã©ã®ããã«æ£ããã®ã§ããïŒ
- æ£ãã䜿çšOSã®APIã®æ©èœãäŸãã°ãRtlSecureZeroMemoryã®ããã«ãWindowsã®
- å©çšæ©èœC11ã® memset_sïŒ
ããã«ã倿°ã®å€ãïŒãã¡ã€ã«ãã³ã³ãœãŒã«ããŸãã¯ãã®ä»ã®ã¹ããªãŒã ã«ïŒåºåããããšã§ãã³ã³ãã€ã©ãŒãã³ãŒããæé©åããã®ãé²ãããšãã§ããŸãããããã¯æããã«ããŸã圹ã«ç«ã¡ãŸããã
ãåç
§ããŠãã ãã
Safe clearing of private Data
ãŸãšã
ãã¡ãããããã¯ãC / C ++ã§ã¢ããªã±ãŒã·ã§ã³ãäœæãããšãã«çºçããå¯èœæ§ã®ãããã¹ãŠã®åé¡ããã¥ã¢ã³ã¹ãããã³åŸ®åŠãªç¹ã®å®å šãªãªã¹ãã§ã¯ãããŸããã
次ã®ãããªçŽ æŽããããã®ããããŸãã
- ã©ã€ãããã¯;
- (, , ABA, , );
- ;
- (- , , );
- GDI ;
- , volatile atomic ;
- (, 0603 603);
- ãã§ãã¯/ã¢ã¯ã»ã¹ã®éåæåã®åé¡ïŒãã§ãã¯æéããäœ¿çšæéïŒ;
- åç §ããããªããžã§ã¯ããããé·çãããã©ã ãåŒã
- printfãã¡ããªãŒã®æ©èœã§ã®èª€ã£ããã©ãŒããã仿§ã®äœ¿çš;
- ãã€ããªãŒããŒãç°ãªã2ã€ã®ããã€ã¹éïŒããšãã°ããããã¯ãŒã¯çµç±ïŒã§ã®ããŒã¿ã®èª€ã£ã亀æãªã©ã
ãããŠãã¯ããã«ã

远å ãããã®ã¯ãããŸããïŒã³ã¡ã³ãã§ããªãã®è峿·±ãçµéšãå ±æããŠãã ããïŒ
PSãã£ãšç¥ãããã§ããïŒ
Software security errors
Common weakness enumeration
Common types of software vulnerabilities
Vulnerability database
Vulnerability notes database
National vulnerability database
Coding standards
Application security verification standard
Guidelines for the use of the C++ language in critical systems
Secure programming HOWTO
32 OpenMP Traps For C++ Developers
A Collection of Examples of 64-bit Errors in Real Programs
Common weakness enumeration
Common types of software vulnerabilities
Vulnerability database
Vulnerability notes database
National vulnerability database
Coding standards
Application security verification standard
Guidelines for the use of the C++ language in critical systems
Secure programming HOWTO
32 OpenMP Traps For C++ Developers
A Collection of Examples of 64-bit Errors in Real Programs