ãœãããŠã§ã¢ã®éçºæã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãœãŒã¹ã³ãŒããå€æŽããã«ãæ¢åã®ã¢ããªã±ãŒã·ã§ã³ã«è¿œå ã®æ©èœãçµã¿èŸŒãå¿
èŠãããå ŽåããããŸãã ããã«ãå€ãã®å Žåãã¢ããªã±ãŒã·ã§ã³èªäœã¯ããœãŒã¹ã³ãŒããªãã§ã³ã³ãã€ã«ããããã€ããªåœ¢åŒã§ã®ã¿ååšããŸãã ãã®åé¡ã解決ããåºãç¥ãããæ¹æ³ã¯ãããããã§ãã ãã¹ãã©ã€ã·ã³ã°ãã¯ãã¿ãŒã²ããé¢æ°ã®ã³ãŒããå€æŽããããšã«ããé¢æ°ãã€ã³ã¿ãŒã»ããããæ¹æ³ã§ãã éåžžãã¹ãã©ã€ã·ã³ã°æã«ãã¿ãŒã²ããé¢æ°ã®æåã®ãã€ããä»ã®ã¢ãã¬ã¹ã«ç§»åããã眮æé¢æ°ãžã®ç¡æ¡ä»¶ãžã£ã³ãã³ãã³ãïŒjmpïŒãå
ã®å Žæã«æžã蟌ãŸããŸãã ã¹ãã©ã€ã·ã³ã°ã¯ã¡ã¢ãªã䜿çšããäœã¬ãã«ã®æäœãå¿
èŠãšãããããã¢ã»ã³ããªèšèªãšC / C ++ã䜿çšããŠå®è¡ãããŸããããã¯ã眮æé¢æ°ã®å®è£
ã«ãç¹å®ã®å¶éã課ããŸãã
Windowsã§APIé¢æ°ãã€ã³ã¿ãŒã»ããããã¹ãã©ã€ã·ã³ã°æ¹æ³ã¯ãã€ã³ã¿ãŒããããããŸããŸãªæç®ã§åºã説æãããŠããŸãã ãã®ååã®åçŽãã¯ã次ã®èŠå ã«ãã£ãŠæ±ºãŸããŸãã
- ã¿ãŒã²ããé¢æ°ã¯éçã§ã-ããŒããããã¢ãžã¥ãŒã«ã®ã¡ã¢ãªã«ããã«ååšããŸã;
- ã¿ãŒã²ããé¢æ°ã®ã¢ãã¬ã¹ã¯ç°¡åã«å€å¥ã§ããŸãïŒã¢ãžã¥ãŒã«ãšã¯ã¹ããŒãããŒãã«ãŸãã¯GetProcAddressé¢æ°ã䜿çšïŒã
ãåãã®ããã«ãWindows APIã¯Cã§å®è£
ãããŠããã眮æé¢æ°ã¯çœ®æãããé¢æ°ãšåãæŠå¿µã䜿çšã§ãããããAPIé¢æ°ãã€ã³ã¿ãŒã»ãããããšãã®C / C ++ã§ã®çœ®æé¢æ°ã®å®è£
ãæé©ãªãªãã·ã§ã³ã§ãã
.NETãã¯ãããžãŒã®åºçŸã«ãããç¶æ³ã¯æ ¹æ¬çã«å€ãããŸããã .NETçšã«äœæãããåçãªã³ã¯ã©ã€ãã©ãªã«ã¯ãéçé¢æ°ãå«ãŸããªããªããŸããïŒé¢æ°ã¯ILäžéèšèªã³ãã³ãã«åºã¥ããŠåçã«çæãããŸãïŒã ãã®çµæãåçã³ã³ãã€ã«ïŒJITã³ã³ãã€ã«ïŒåŸã«é¢æ°ãé
眮ãããã¡ã¢ãªå
ã®ã¢ãã¬ã¹ãäºæž¬ããããšãããã³JITã³ã³ãã€ã«èªäœã®ç¬éã远跡ããããšã¯å°é£ã§ãã ããã«ãè¿œå ã®åªåãªãã§ã¯ã.NETé¢æ°ã¯éçã§ã¯ãªããC / C ++ã§å®è£
ãããŠããªãããã眮æé¢æ°ãšããŠäœ¿çšããããšã¯ã§ããŸããã
ãã®èšäºã§ã¯ã.NETæ©èœã.NETç°å¢ã§éçºãããæ©èœã«çœ®ãæããããšãã§ããã¢ããªã±ãŒã·ã§ã³ã®ã¢ã«ãŽãªãºã ã«ã€ããŠèª¬æããŸãã äžããããã¢ã«ãŽãªãºã ãç解ããã«ã¯ãCLRïŒå
±éèšèªã©ã³ã¿ã€ã ïŒ.NETã®å®è£
ã詳ãã調ã¹ãå¿
èŠããããŸãã CLRã®å®è£
ã説æããéã«ãäžè¬çãªæ¬è³ªã®ç解ãè€éã«ããããšãé¿ããããã«ãããã€ãã®è©³çŽ°ãç°¡ç¥åããŸãã
1. CLRã®ã¡ãœããåŒã³åºãã¡ãœãã
CLRã§ã¯ãåé¢æ°ïŒã¡ãœããïŒã¯ILã³ãã³ãã®ã»ããã§ãããããã«é¢ãããã¹ãŠã®æ
å ±ã¯ã¢ãžã¥ãŒã«ã®ã¡ã¿ããŒã¿ã«ä¿åãããŸãã ã¯ã©ã¹ããšã«ã¢ãžã¥ãŒã«ãèªã¿èŸŒããšãCLRã·ã¹ãã ã¯ã¯ã©ã¹ã®ã¡ãœããã«é¢ããæ
å ±ãå«ã
MethodTableããŒãã«ãäœæããŸãã åã¯ã©ã¹ã¡ãœããã¯
MethodDescæ§é ã«ãã£ãŠèšè¿°ããããã®ãã£ãŒã«ãã®1ã€ã«ã¯ã¡ã¢ãªå
ã®ã³ã³ãã€ã«ãããã¡ãœããã®ã¢ãã¬ã¹ãå«ãŸãïŒã¡ãœãããJITã³ã³ãã€ã«ãããå ŽåïŒããã1ã€ã®ãã£ãŒã«ãã«ã¯
MethodTableããŒãã«ã®ã€ã³ããã¯ã¹ãå«ãŸããã¢ããã¿ãŒã®ã¢ãã¬ã¹ïŒãµã³ã¯ïŒãã¡ãœãããã³ã³ãã€ã«ãããŠãããã©ããã«ãã£ãŠç°ãªããŸãã

æåïŒJITã³ã³ãã€ã«åïŒã4ã€ã®ãããããã©ã³ãžã·ã§ã³ã®1ã€ãã¢ããã¿ãŒãšããŠæ©èœããŸãã CLRã¢ããã¿ãŒã®ããªã³ãŒãïŒ
StubPrecode ã
FixupPrecode ã
RemotingPrecodeãŸãã¯
NDirectImportPrecode ã æåŸã®ã¢ããã¿ãŒã¯ãçŽæ¥ååã§ããWindows APIé¢æ°ãåŒã³åºãããã«ã®ã¿äœ¿çšããããããèæ
®ããŸããã
åããªã³ãŒãã¢ããã¿ãŒã®äž»ãªã¿ã¹ã¯ã¯ã
MethodDescæ§é äœã®ã¢ãã¬ã¹ãæž¡ãããšã§ãã
䜿çšãããã¡ãœãããå
éšé¢æ°
ThePreStub ïŒx64ãã©ãããã©ãŒã çšã®
ThePreStubAMD64 ãå³ã§ã¯ã¹ã¿ããšããŠããŒã¯ãããŠããïŒãå®çŸ©ãã次ã®ã¿ã¹ã¯ãå®è¡ããŸãã
- MethodDescæ§é ã«ãã£ãŠèå¥ãããã¡ãœããã®JITã³ã³ãã€ã«ã
- MethodDescæ§é äœã®ãã€ã³ã¿ãŒããçæããããã€ãã£ãã³ãŒãã«èšå®ããŸãã
- çæããããã€ãã£ãã³ãŒããžã®ç¡æ¡ä»¶ãžã£ã³ãïŒjmpïŒãè¡ãããã«ã¢ããã¿ãŒãæžãæããŸãã
- çæããããã€ãã£ãã³ãŒãã®å®è¡ã
ãããã£ãŠãã¿ãŒã²ããã¡ãœãããžã®æåã®åŒã³åºãã®çµæãšããŠãã¡ãœããã³ãŒããçæããã³å®è¡ãããã ãã§ãªããã¢ããã¿ãŒã®ã³ã³ãã³ããå€æŽãããåŸç¶ã®ã¡ãœããåŒã³åºãäžã«çæããããã€ãã£ãã³ãŒããžã®çŽæ¥åŒã³åºãã«ã€ãªãããŸãã
å
±éèšèªã©ã³ã¿ã€ã ããåŒã³åºããã.NETã¡ãœããã¯ãã¯ã©ã¹ã¡ãœããã®
MethodTableããŒãã«ã®ã¢ãã¬ã¹ãééããŸãã ãã ããCLRã¯ãã¢ã³ãããŒãžC / C ++ç°å¢ããã¡ãœãããåŒã³åºãæ©èœãæäŸããŸãã ããã«
ã¯ãRuntimeMethodHandleã¯ã©ã¹ã®
GetFunctionPointerããã³
Marshalã¯ã©ã¹ã®
GetFunctionPointerForDelegateã®é¢æ°ã
䜿çšãããŸãã æå®ãããé¢æ°ã«ãã£ãŠè¿ãããã¢ãã¬ã¹ã¯ã¢ããã¿ãŒã¢ãã¬ã¹ã§ãããããã®äžã§æ¢ã«èšåãããŠãã
StubPrecode ã
FixupPrecodeããã³
RemotingPrecodeããããŸãã ã¡ãœããã®æåã®åŒã³åºãã®çµæãšããŠãã¡ãœããã¯ã³ã³ãã€ã«ããã³å®è¡ãããåŸç¶ã®åŒã³åºãã§ãçæãããã³ãŒããžã®çŽæ¥ã®é·ç§»ãå®è¡ãããŸãã åæã«ãã³ã³ãã€ã«ãããŠããªãã¡ãœããã®å Žåãã¡ãœããããŒãã«ãšäžèšã®é¢æ°ã«ãã£ãŠè¿ããããã€ã³ã¿ãŒã®äž¡æ¹ããåŒã³åºããããšãå
éšé¢æ°
ThePreStubãåŒã³åºãããããšã
éèŠã§ã ã
2. CLRã¢ããã¿ãŒã®ããªã³ãŒã
CLRããªã³ãŒãã¢ããã¿ãŒãåå¥ã«èª¿ã¹ãŠãã¢ããã¿ãŒèªäœã®ãã€ããªã³ãŒãã®ã¿ãç¥ã£ãŠããã®ã¢ããã¿ãŒã«é¢é£ä»ãããã
MethodDescæ§é äœã®ã¢ãã¬ã¹ãšã
ThePreStubå
éšé¢æ°ã®ã¢ãã¬ã¹ã決å®ãã
æ¹æ³ã瀺ããŸãïŒå°æ¥çã«ã¯ãããã圹ç«ã¡ãŸãïŒã ããã«ãJITã³ã³ãã€ã«ãå®è¡ããåŸãæå®ãããã¢ããã¿ãŒã§çæãããã³ãŒãã®ã¢ãã¬ã¹ã決å®ããæ¹æ³ã瀺ããŸãã
- StubPrecode ã äœæã®æç¹ã§ã MethodDescæ§é äœã®ã¢ãã¬ã¹ã®å€ã¯ãCLRã·ã¹ãã ã«ãã£ãŠæå®ãããã¢ããã¿ãŒã«çŽæ¥åã蟌ãŸããŸãïŒ ã¢ã»ã³ãã©ãŒã³ãã³ãã®çŽæ¥å€ãšããŠïŒã ã¢ããã¿ã³ãŒãã¯ããŒããŠã§ã¢ãã©ãããã©ãŒã ã®ã¿ã«äŸåããCLRããŒãžã§ã³ã«ã¯äŸåããŸããã ããŸããŸãªããŒããŠã§ã¢ãã©ãããã©ãŒã ã®å Žåã次ã®åœ¢åŒã«ãªããŸãã
x86: mov eax, pMethodDesc mov ebp, ebp jmp ThePreStub x64: mov r10, pMethodDesc jmp ThePreStub
ãããã£ãŠã MethodDescæ§é äœã®ã¢ãã¬ã¹ã¯ãeaxã¬ãžã¹ã¿ïŒx86ã®å ŽåïŒãŸãã¯r10ïŒx64ã®å ŽåïŒã®ThePreStubé¢æ°ã«æž¡ãããŸãã ã¡ã¢ãªã®åæäžãããã»ããµã®å®¹éãèæ
®ããŠãæå®ãããã¢ãã¬ã¹ãã¢ããã¿ã®ãªãã»ãã1ïŒx86ã®å ŽåïŒãŸãã¯2ïŒx64ã®å ŽåïŒã§æ確ã«èªã¿åãããšãã§ããŸãã ThePreStubé¢æ°ã®ã¢ãã¬ã¹ã¯ãæåŸã®jmpã³ãã³ãã«çµã¿èŸŒãŸããçžå¯Ÿãªãã»ããã«ãæå®ãããã³ãã³ãã®å®äºã¢ãã¬ã¹ãè¿œå ããããšã§èšç®ã§ããŸãã
JITã®ã³ã³ãã€ã«ãå®äºãããšãé·ç§»ã¢ãã¬ã¹ã¯ThePreStubé¢æ°ã®ã¢ãã¬ã¹ããçæãããã³ãŒãã®ã¢ãã¬ã¹ã«çœ®ãæããããã¢ããã¿ãŒã®å
容ã¯æ¬¡ã®ããã«ãªããŸãã
x86: mov eax, pMethodDesc mov ebp, ebp jmp NativeCode x64: mov r10, pMethodDesc jmp NativeCode
JITã³ã³ãã€ã«åŸã«çæãããã³ãŒãã®ã¢ãã¬ã¹ã決å®ããæ¹æ³ã¯ãJITã³ã³ãã€ã«åã«ThePreStubé¢æ°ã®ã¢ãã¬ã¹ã決å®ããæ¹æ³ãšåãã§ãã
- FixupPrecode æå®ãããã¢ããã¿ãŒã¯ãã¡ã¢ãªãŒäœ¿çšéãæé©åããããã«èšèšãããŠããŸãã ãã¹ãŠã®ããŒããŠã§ã¢ãã©ãããã©ãŒã ã§8ãã€ãããããŸããããã¯ã StubPrecodeã¢ããã¿ãŒã®ãµã€ãºïŒx86ã®å Žåã¯12ãã€ããx64ã®å Žåã¯16ãã€ãïŒãããå°ãããªããŸãã ãã¹ãŠã®ããŒããŠã§ã¢ãã©ãããã©ãŒã ãšCLRããŒãžã§ã³ã®ã¢ããã¿ãŒã³ãŒãã¯æ¬¡ã®ãšããã§ãã
call PrecodeFixupThunk db 0x5E db MethodDescChunkIndex db PrecodeChunkIndex call PrecodeFixupThunk db 0x db MethodDescChunkIndex db PrecodeChunkIndex
FixupPrecodeã¢ããã¿ãŒã䜿çšããå Žåã CLRã¯æ¬¡ã®2ã€ã®èŠä»¶ã«æºæ ããŸãã
- ã¢ããã¿åºæã®MethodDescæ§é 㯠ãé£ç¶ããMethodDescChunkã¡ã¢ãªãããã¯ã«çµåãããŸã ã

- FixupPrecode-adaptersãé£ç¶ããã¡ã¢ãªãããã¯ã«çµåããã瀺ããããããã¯ã§ã¯ãã¢ããã¿ãŒã®çµäºåŸãCLRã·ã¹ãã ã¯MethodDescChunkã¡ã¢ãªãããã¯ã« MethodDescæ§é ã®ããŒã¹ã¢ãã¬ã¹pMethodDescChunkBaseãåã蟌ã¿ãŸã ã
call PrecodeFixupThunk db ? db MethodDescChunkIndex db PrecodeChunkIndex ... call PrecodeFixupThunk db ? db MethodDescChunkIndex db 2 call PrecodeFixupThunk db ? db MethodDescChunkIndex db 1 call PrecodeFixupThunk db ? db MethodDescChunkIndex db 0 dd pMethodDescChunkBase (x86) dq pMethodDescChunkBase (x64)
ãã®ã¡ã¢ãªæ§æã§ã¯ãç¹å®ã®FixupPrecodeã¢ããã¿ãŒã®MethodDescæ§é äœã®ã¢ãã¬ã¹ã¯ã次ã®åŒã䜿çšããŠæå®ãããŸãã
ã¢ãã¬ã¹MethodDesc = pMethodDescChunkBase + MethodDescChunkIndex * sizeofïŒvoid *ïŒã
ããã§ãããŒã¹ãªãã»ããïŒ pMethodDescChunkBase ïŒã¯æ¬¡ã®ã¢ãã¬ã¹ã§ååŸãããŸãã
pMethodDescChunkBaseã¢ãã¬ã¹= FixupPrecodeã¢ãã¬ã¹+ 8 + PrecodeChunkIndex * 8
ããã³MethodDescChunkIndexãšPrecodeChunkIndexã¯ã PrecodeFixupThunkã«åã蟌ãŸãããã€ãå€ã§ã ã
CLRã«ããMethodDescæ§é äœã®ã¢ãã¬ã¹ã®å€ã¯ãåæ°åœ¢ã«ååšãããªãã·ã§ã³ã®ã¢ããã¿ãŒPrecodeFixupThunkå
ã§èšç®ãããæå®ãããã¢ãã¬ã¹ãèšç®ããŠeaxïŒx86ïŒãŸãã¯r10ïŒx64ïŒã¬ãžã¹ã¿ã®ThePreStubã«æž¡ãããšã®ã¿ãç®çãšããŠããŸãã ããŸããŸãªããŒããŠã§ã¢ãã©ãããã©ãŒã çšã®PrecodeFixupThunkã¢ããã¿ãŒã®ã³ãŒãã次ã«ç€ºããŸãã
x86: pop eax push esi push edi movzx esi, byte ptr [eax + 0x2] movzx edi, byte ptr [eax + 0x1] mov eax, dword ptr [eax + esi * 8 + 0x3] lea eax, [eax + edi * 4] pop edi pop esi jmp dword ptr [g_dwPreStubAddr] ( CLR 2.0) jmp ThePreStub ( CLR 4.0 ) x64: pop rax movzx r10, byte ptr [rax + 0x2] movzx r11, byte ptr [rax + 0x1] mov rax, qword ptr [rax + r10 * 8 + 0x3] lea r10, [rax + r11 * 8] jmp ThePreStub
FixupPrecodeã¢ããã¿ãŒã䜿çšããThePreStubå
éšé¢æ°ã®ã¢ãã¬ã¹ã¯ã2段éã§èšç®ã§ããŸãã
- åŒã³åºãFixupPrecode-ã¢ããã¿ãŒã®æåã®ã³ãã³ãã«çµã¿èŸŒãŸããçžå¯Ÿãªãã»ããããæå®ãããã³ãã³ãã®å®äºã¢ãã¬ã¹ã«è¿œå ããããšã«ããã PrecodeFixupThunkã¢ããã¿ãŒã®ã¢ãã¬ã¹ãèšç®ããŸãã
- CLR 2.0 x86ãé€ããã¹ãŠã®ãã©ãããã©ãŒã ã§ãæå®ãããã³ãã³ãã®å®äºã¢ãã¬ã¹ã䜿çšããŠã PrecodeFixupThunkã¢ããã¿ãŒã®æåŸã®jmpã³ãã³ãã«çµã¿èŸŒãŸããçžå¯Ÿãªãã»ãããè¿œå ããããšã«ããã ThePreStubã¢ãã¬ã¹ãèšç®ããŸãã
- CLR 2.0 x86ãã©ãããã©ãŒã ã®å Žåã ThePreStubã¢ãã¬ã¹ãæåŸã®jmpã³ãã³ãã«çµã¿èŸŒãŸããŠããã¢ãã¬ã¹ã«æœåºããŸãïŒå
éšå€æ°g_dwPreStubAddrãä»ããéæ¥ã¢ãã¬ã¹æå®ïŒã
FixupPrecodeã¢ããã¿ãŒã§ã®JITã³ã³ãã€ã«ã®å®äºåŸãæåã®åŒã³åºãã³ãã³ããjmpã³ãã³ãã«çœ®ãæãããã PrecodeFixupThunkã¢ããã¿ãŒã®ã¢ãã¬ã¹ããçæãããã³ãŒãã®ã¢ãã¬ã¹ãžã®é·ç§»ã¢ãã¬ã¹ã眮ãæããããŸãã ããã«ãæåã®ã³ãã³ãã®åŸã«ãã€ã0x5Eãç¶ãå Žåãããã¯ãã€ã0x5Fã«çœ®ãæããããŸãïŒç€ºããããã€ãã¯JITã³ã³ãã€ã«ã®æç¡ã®ã€ã³ãžã±ãŒã¿ã§ããããã€ã0xCCã¯æ
å ±ããªãããšãæå³ããŸãïŒã ãããã£ãŠã亀æåŸã®ã¢ããã¿ãŒã®å
容ã¯æ¬¡ã®ãšããã§ãã
jmp NativeCode db 0x5E db MethodDescChunkIndex db PrecodeChunkIndex jmp NativeCode db 0x db MethodDescChunkIndex db PrecodeChunkIndex
JITã®ã³ã³ãã€ã«åŸãçæãããã³ãŒãã®ã¢ãã¬ã¹ã¯ãæå®ãããã³ãã³ãã®å®äºã¢ãã¬ã¹ã«æåã®jmpã³ãã³ãã«çµã¿èŸŒãŸããçžå¯Ÿãªãã»ãããè¿œå ããããšã«ããèšç®ãããŸãã
- RemotingPrecode ã æå®ããã¢ããã¿ãŒã¯ãå¥ã®ã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã³ã«ååšããå¯èœæ§ã®ãããªããžã§ã¯ãã®ã¡ãœãããåŒã³åºããšãã«äœ¿çšãããŸãã ã¢ããã¿ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
x86: mov eax, pMethodDesc nop call PrecodeRemotingThunk jmp ThePreStub x64: test rcx,rcx je Local mov rax, qword ptr [rcx] mov r10, ProxyAddress cmp rax, r10 je Remote Local: mov rax, ThePreStub jmp rax Remote: mov r10, pMethodDesc mov rax, RemotingCheck jmp rax
StubPrecodeã¢ããã¿ãŒãšåæ§ã«ã RemotingPrecodeã§ã®äœææã«ã MethodDescæ§é äœã®ã¢ãã¬ã¹ã®å€ã¯ãCLRã·ã¹ãã ã«ãã£ãŠçŽæ¥ïŒ ã¢ã»ã³ãã©ãŒã³ãã³ãã®çŽæ¥å€ãšããŠïŒåã蟌ãŸããŸãã æå®ããå€ã¯ããªãã»ãã1ïŒx86ã®å ŽåïŒããã³37ïŒx64ã®å ŽåïŒã§æœåºã§ããŸãã ThePreStubé¢æ°ã®ã¢ãã¬ã¹ã¯ãæåŸã®jmpã³ãã³ãã«çµã¿èŸŒãŸããçžå¯Ÿãªãã»ããã«ãæå®ãããã³ãã³ãã®å®äºã¢ãã¬ã¹ïŒx86ã®å ŽåïŒãŸãã¯çŽæ¥ãªãã»ããå€25ïŒx64ã®å ŽåïŒãè¿œå ããçµæã§ãã
ä»ã®ãã¡ã€ã³ã«å±ããªããªããžã§ã¯ãã®å ŽåãJITã³ã³ãã€ã«ãå®äºããåŸãé·ç§»ã¢ãã¬ã¹ã¯ThePreStubé¢æ°ã®ã¢ãã¬ã¹ããçæãããã³ãŒãã®ã¢ãã¬ã¹ã«å€æŽããããããJITã³ã³ãã€ã«åŸã«çæãããã³ãŒãã®ã¢ãã¬ã¹ã決å®ããæ¹æ³ã¯ãJITã³ã³ãã€ã«åã«ThePreStubé¢æ°ã®ã¢ãã¬ã¹ã決å®ããæ¹æ³ãšåãã§ãã ä»ã®ãã¡ã€ã³ã«å±ãããªããžã§ã¯ãã®å ŽåãJITã³ã³ãã€ã«åŸã RemotingPrecodeã¢ããã¿ãŒã®æ¬äœã¯å€æŽãããŸããã ç°¡åã«ããããã«ãã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã³ã«å±ããªããªããžã§ã¯ãã«å¯ŸããŠRemotingPrecodeã䜿çšãããªãã·ã§ã³ã¯èæ
®ããŸããã
3. PreStubé¢æ°
æ¢ã«è¿°ã¹ãããã«ã
ThePreStubã®å
éšé¢æ°ã¯
次ã®ããšãè¡ããŸãã
- MethodDescæ§é ã«ãã£ãŠèå¥ãããã¡ãœããã®JITã³ã³ãã€ã«ã
- MethodDescæ§é äœã®ãã€ã³ã¿ãŒããçæããããã€ãã£ãã³ãŒãã«èšå®ããŸãã
- çæããããã€ãã£ãã³ãŒããžã®ç¡æ¡ä»¶ãžã£ã³ãïŒjmpïŒãè¡ãããã«ã¢ããã¿ãŒãæžãæããŸãã
- çæããããã€ãã£ãã³ãŒãã®å®è¡ã
CLRããã³ããŒããŠã§ã¢ãã©ãããã©ãŒã ã®ãã¹ãŠã®ããŒãžã§ã³ã§ã
The PreStubé¢æ°
㯠ãå
éš
PreStubWorkeré¢æ°ãåŒã³åºããæå®ãããé¢æ°ã«ãã£ãŠè¿ãããã¢ãã¬ã¹ã«å¶åŸ¡ãïŒjmpã³ãã³ãçµç±ã§ïŒè»¢éããããšã«ãããããŒããŠã§ã¢ã¬ãã«ã§CLRã«å®è£
ãããŸãã å®å
šã
æãããã«ãããŸããŸãªãã©ãããã©ãŒã çšã®
ThePreStubé¢æ°ã®ã³ãŒãã
次ã«ç€ºããŸãã
ThePreStubé¢æ°ã³ãŒãïŒx64ïŒ CLR 4.6 : push r15 push r14 push r13 push r12 push rbp push rbx push rsi push rdi sub rsp,68h mov qword ptr [rsp+0B0h],rcx mov qword ptr [rsp+0B8h],rdx mov qword ptr [rsp+0C0h],r8 mov qword ptr [rsp+0C8h],r9 movdqa xmmword ptr [rsp+ 20h],xmm0 movdqa xmmword ptr [rsp+ 30h],xmm1 movdqa xmmword ptr [rsp+ 40h],xmm2 movdqa xmmword ptr [rsp+ 50h],xmm3 lea rcx,[rsp+68h] mov rdx,r10 call PreStubWorker movdqa xmm0,xmmword ptr [rsp+20h] movdqa xmm1,xmmword ptr [rsp+ 30h] movdqa xmm2,xmmword ptr [rsp+ 40h] movdqa xmm3,xmmword ptr [rsp+ 50h] mov rcx,qword ptr [rsp+0B0h] mov rdx,qword ptr [rsp+0B8h] mov r8,qword ptr [rsp+0C0h] mov r9,qword ptr [rsp+0C8h] add rsp,68h pop rdi pop rsi pop rbx pop rbp pop r12 pop r13 pop r14 pop r15 jmp rax CLR 4.0: lea rax, [rsp + 0x08] push r10 push r15 push r14 push r13 push r12 push rbp push rbx push rsi push rdi push rax sub rsp, 0x78 mov qword ptr [rsp + 0xD0], rcx mov qword ptr [rsp + 0xD8], rdx mov qword ptr [rsp + 0xE0], r8 mov qword ptr [rsp + 0xE8], r9 movdqa xmmword ptr [rsp + 0x20], xmm0 movdqa xmmword ptr [rsp + 0x30], xmm1 movdqa xmmword ptr [rsp + 0x40], xmm2 movdqa xmmword ptr [rsp + 0x50], xmm3 lea rcx, qword ptr [rsp + 0x68] call PreStubWorker movdqa xmm0, xmmword ptr [rsp + 0x20] movdqa xmm1, xmmword ptr [rsp + 0x30] movdqa xmm2, xmmword ptr [rsp + 0x40] movdqa xmm3, xmmword ptr [rsp + 0x50] mov rcx, qword ptr [rsp + 0xD0] mov rdx, qword ptr [rsp + 0xD8] mov r8 , qword ptr [rsp + 0xE0] mov r9 , qword ptr [rsp + 0xE8] nop add rsp, 0x80 pop rdi pop rsi pop rbx pop rbp pop r12 pop r13 pop r14 pop r15 pop r10 jmp rax CLR 2.0: lea rax, [rsp + 0x08] push r10 push r15 push r14 push r13 push r12 push rbp push rbx push rsi push rdi push rax sub rsp, 0x78 mov qword ptr [rsp + 0xD0], rcx mov qword ptr [rsp + 0xD8], rdx mov qword ptr [rsp + 0xE0], r8 mov qword ptr [rsp + 0xE8], r9 movdqa xmmword ptr [rsp + 0x20], xmm0 movdqa xmmword ptr [rsp + 0x30], xmm1 movdqa xmmword ptr [rsp + 0x40], xmm2 movdqa xmmword ptr [rsp + 0x50], xmm3 call PrestubMethodFrame::GetMethodFrameVPtr mov qword ptr [rsp + 0x68], rax mov rax, qword ptr [s_gsCookie] mov qword ptr [rsp + 0x60], rax call GetThread mov r12, rax mov rdx, qword ptr [r12 + 0x10] mov qword ptr [rsp + 0x70], rdx lea rcx, [rsp + 0x68] mov qword ptr [r12 + 0x10], rcx call PreStubWorker mov rcx, qword ptr [r12 + 0x10] mov rdx, qword ptr [rcx + 0x08] mov qword ptr [r12 + 0x10], rdx movdqa xmm0, xmmword ptr [rsp + 0x20] movdqa xmm1, xmmword ptr [rsp + 0x30] movdqa xmm2, xmmword ptr [rsp + 0x40] movdqa xmm3, xmmword ptr [rsp + 0x50] mov rcx, qword ptr [rsp + 0xD0] mov rdx, qword ptr [rsp + 0xD8] mov r8 , qword ptr [rsp + 0xE0] mov r9 , qword ptr [rsp + 0xE8] nop add rsp, 0x80 pop rdi pop rsi pop rbx pop rbp pop r12 pop r13 pop r14 pop r15 pop r10 jmp rax
ThePreStubé¢æ°ã³ãŒãïŒx86ïŒ CLR 4.6 : push ebp mov ebp,esp push ebx push esi push edi push ecx push edx mov esi,esp push eax push esi call PreStubWorker pop edx pop ecx pop edi pop esi pop ebx pop ebp jmp eax CLR 4.0: push ebp mov ebp, esp push ebx push esi push edi push ecx push edx push eax sub esp, 0x0C lea esi, [esp + 0x04] push esi call PreStubWorker add esp, 0x10 pop edx pop ecx pop edi pop esi pop ebx pop ebp jmp eax CLR 2.0: push eax push edx push PrestubMethodFrame::'vftable' push ebp push ebx push esi push edi lea esi, [esp + 0x10] push dword ptr [esi + 0x0C] push ebp mov ebp, esp push ecx push edx mov ebx, dword ptr fs:0x0E34 mov edi, dworp ptr [ebx + 0x0C] mov dword ptr [esi + 0x04], edi mov dword ptr [ebx + 0x0C], esi push cookie push esi call PreStubWorker mov dword ptr [ebx + 0x0C], edi mov ecx, dword ptr [esi + 0x08] mov dword ptr [esi + 0x08], eax mov eax, ecx add esp, 0x04 pop edx pop ecx mov esp, ebp pop ebp add esp, 0x04 pop edi pop esi pop ebx pop ebp add esp, 0x08 ret
ããªã³ãŒãã¢ããã¿ãŒã®ãã€ããªæ§é ãããã£ãŠããããã
ThePreStubé¢æ°ã®ã¢ãã¬ã¹ã¯æ¬¡ã®ããã«æ±ºå®ã§ããŸãã
- ä»»æã®éçCLRã¡ãœãããå®çŸ©ãïŒç©ºã«ããããšãã§ããŸãïŒãã€ã³ã©ã€ã³åã蟌ã¿ãšããªã³ã³ãã€ã«ãçŠæ¢ããŸãã
public delegate void EmptyDelegate(); [MethodImplAttribute( MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void Empty() {}
- ã¡ã¢ãªå
ã®ã¡ãœããã®ããªã²ãŒããäœæããŠããã¯ãã RuntimeMethodHandle.GetFunctionPointeré¢æ°ã«ãã£ãŠè¿ãããã¢ãã¬ã¹ãå®çŸ©ããŸãã
EmptyDelegate function = Empty; GCHandle gc = GCHandle.Alloc(function); IntPtr methodPtr = function.Method.MethodHandle.GetFunctionPointer();
- methodPtrã®ã³ãã³ãããµã³ãã«ã¢ããã¿StubPrecodeã«äžèŽããå Žåãã»ã¯ã·ã§ã³2ã®æ®µèœ1ããThePreStubé¢æ°ã®ã¢ãã¬ã¹ãèšç®ããæ¹æ³ã䜿çšããå¿
èŠããããŸããåä¿¡ã¢ãã¬ã¹ã®ã³ãã³ãããµã³ãã«ã¢ããã¿FixupPrecodeã«äžèŽããå Žåãã»ã¯ã·ã§ã³2ã®æ®µèœ2ããThePreStubé¢æ°ã®ã¢ãã¬ã¹ãèšç®ããæ¹æ³ã䜿çšããå¿
èŠããããŸãã
- ã¡ãœããã®ããªã²ãŒãã®ã¡ã¢ãªããã¯ããã£ã³ã»ã«ããã«ã¯ïŒ
gc.Free();
4. PreStubWorkeré¢æ°
PreStubWorkeré¢æ°ã¯ã次ã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸãã
- MethodDescæ§é ã«ãã£ãŠèå¥ãããã¡ãœããã®JITã³ã³ãã€ã«ã
- MethodDescæ§é äœã®ãã€ã³ã¿ãŒããçæããããã€ãã£ãã³ãŒãã«èšå®ããŸãã
- çæããããã€ãã£ãã³ãŒããžã®ç¡æ¡ä»¶ãžã£ã³ãïŒjmpïŒãè¡ãããã«ã¢ããã¿ãŒãæžãæããŸãã
- å€æŽãããã¢ããã¿ãŒã®ã¢ãã¬ã¹ã®ThePreStubé¢æ°ãè¿ããŸãã
PreStubWorkeré¢æ°ã«ã¯ã次ã®C宣èšããããŸãïŒCLRãœãŒã¹ã«ããïŒã
CLR 4.6 : void* __stdcall PreStubWorker(TransitionBlock* pTransitionBlock, MethodDesc* pMD); CLR 4.6: void* __stdcall PreStubWorker(PrestubMethodFrame *pPFrame);
ãã®äºå®ã
ThePreStubé¢æ°ã®ã³ãŒããªã¹ããããã³eaxïŒx86ïŒããã³r10ïŒx64ïŒ
ã¬ãžã¹ã¿ã®
TheDreStubé¢æ°ã«
MethodDescã¢ãã¬ã¹ã®å€ãæž¡ããããšãã
äºå®ã䜿çšããŠã
PreStubWorkeré¢æ°ã
å
éšã®
MethodDescã®å€ã«ã¢ã¯ã»ã¹ããæ¹æ³ã決å®ã§ããŸãïŒ
- CLR 4.6ïŒä»¥éïŒã®å Žåãæå®ãããå€ã¯ãé¢æ°ã«æž¡ããã2çªç®ã®ãã©ã¡ãŒã¿ãŒããæœåºãããŸãã
- 4.6 x86ãã©ãããã©ãŒã æªæºã®CLRã®å Žåãå€ã¯pPFrameãã©ã¡ãŒã¿ãŒã§æå®ãããæ§é ã®ãªãã»ãã8ã«ãããŸãã
- 4.6 x64ãã©ãããã©ãŒã ããäžã®CLRã®å Žåãå€ã¯ã¢ãã¬ã¹ã«ããã pPFrameãã©ã¡ãŒã¿ãŒã§ã¢ãã¬ã¹æå®ãããæ§é äœã®ãªãã»ãã16ã«ããã¢ãã¬ã¹ã®å€ãã16ãã€ãå°ãªãã
ThePreStubå
éšé¢æ°ã®ã¢ãã¬ã¹ãç¥ã£ãŠãããäžèšã®ã³ãŒãã®ãªã¹ãã«åºã¥ããŠã
ThePreStubé¢æ°å
ã®åºå®ãªãã»ããã䜿çšããã«
PreStubWorkerå
éšé¢æ°ã®ã¢ãã¬ã¹ãèšç®ããã¢ã«ãŽãªãºã ãæå®ã§ããŸãïŒããã¯ãCLRã®æ°ããããŒãžã§ã³ããšã«å€æŽãããŸãïŒïŒ
- x86ããã³x64ãã©ãããã©ãŒã ïŒCLR 2.0ãé€ãïŒã®å Žåãæå®ãããã¢ãã¬ã¹ã¯ãæå®ãããã³ãã³ãã®å®äºã¢ãã¬ã¹ã䜿çšããŠãåŒã³åºãã³ãã³ãã«çµã¿èŸŒãŸããçžå¯Ÿãªãã»ãããè¿œå ããçµæã«ãªããŸãã
- x64 CLR 2.0ã®å Žåãæå®ãããã¢ãã¬ã¹ã¯ãleaã³ãã³ããå
è¡ããcallã³ãã³ãã«çµã¿èŸŒãŸããçžå¯Ÿãªãã»ããã«callã³ãã³ãã®çµäºã¢ãã¬ã¹ãè¿œå ããçµæã«ãªããŸãã
å®è¡æã«ã³ãã³ãã®ã³ãŒããšãµã€ãºã決å®ã§ããçµã¿èŸŒã¿ã®éã¢ã»ã³ãã©ãããå Žåãå®è¡äžã«å¿
èŠãªåŒã³åºãã³ãã³ããèŠã€ããããšãã§ããŸãã
5.ååã¢ã«ãŽãªãºã
äžèšã®ãã¹ãŠãèŠçŽãããšã.NETé¢æ°ãã€ã³ã¿ãŒã»ãããã次ã®æ¹æ³ãææ¡ã§ããŸãã
- RuntimeMethodHandle.GetFunctionPointerã®åŒã³åºãã䜿çšããŠã眮æã¡ãœããã®ã¢ãã¬ã¹ãååŸããŸãã
- 眮æãããã¡ãœããããã§ã«JITã³ã³ãã€ã«ãããŠããå Žåãçæããããã€ãã£ãã³ãŒãã®ã¡ã¢ãªå
ã®ã¢ãã¬ã¹ãèŠã€ããæå®ãããã¢ãã¬ã¹ãã€ã³ã¿ãŒã»ããããŠçœ®æã¡ãœãããå®è¡ããŸãã
- 眮ãæããããã¡ãœããããŸã JITã³ã³ãã€ã«ãããŠããªãå Žåã
- MethodDescæ§é ã®ã¢ãã¬ã¹ãèšç®ããŸãã
- å
ã®å®è£
ã代æ¿PreStubWorkerã¡ãœããã§åŒã³åºãããããã«ãã¢ãã¬ã¹ãèšç®ãã PreStubWorkeré¢æ°ãã€ã³ã¿ãŒã»ããããŸãã
- é¢æ°ãå¿
èŠãªã¢ãã¬ã¹ã«äžèŽããMethodDescã¢ãã¬ã¹ã䜿çšããå Žåã«ã代æ¿ã®PreStubWorkeré¢æ°ã«è¿œå ã®ããžãã¯ãè¿œå ããŸãã ãã®å Žåãå
ã®å®è£
ãåŒã³åºããåŸãçæããããã€ãã£ãã¡ãœããã®ã¢ãã¬ã¹ãååŸããåä¿¡ããã¢ãã¬ã¹ãã€ã³ã¿ãŒã»ããããŠçœ®æã¡ãœãããå®è¡ããŸãã
äžèšã®ãã¹ãŠã®åŸãã¢ã«ãŽãªãºã ã®äžèšã®æ®µèœã¯ã段èœ2ããã³3.1ãé€ãã詳现ãªèª¬æãå¿
èŠãšããŸããã
第2ç¯ã§ã¯ãå®éã«çæããããã€ãã£ãã³ãŒãïŒã¢ããã¿ãŒãªãïŒã®ã¢ãã¬ã¹ã®æ±ºå®ã«ã€ããŠèª¬æããŸãã 以äžã®ã¢ã«ãŽãªãºã ã¯ãCLRç°å¢ã§çæãããã¢ããã¿ãŒã®ãã€ããªæ§é ã®ç¥èã«åºã¥ããŠãããæå®ãããã¢ãã¬ã¹ãèšç®ããŸãïŒJITã³ã³ãã€ã«ããªãå Žåã¯NULLãè¿ããŸãïŒã
- RuntimeMethodHandle.GetFunctionPointerãåŒã³åºããŠã.NETã¡ãœããã®ã¢ãã¬ã¹ãååŸããŸãã
- åä¿¡ããã¢ãã¬ã¹ã®ã³ãã³ãããµã³ãã«ã¢ããã¿StubPrecodeãŸãã¯RemotingPrecodeãšäžèŽããå Žåãã»ã¯ã·ã§ã³2ã®ã»ã¯ã·ã§ã³1ããã³3ã§èª¬æãããŠããããã«ã³ã³ãã€ã«æžã¿ã³ãŒãã®ã¢ãã¬ã¹ãæœåºããŸããæå®ãããã¢ãã¬ã¹ãThePreStubé¢æ°ã®ã¢ãã¬ã¹ãšäžèŽããå ŽåãJITã¡ãœããã¯ã³ã³ãã€ã«ãããã nullãè¿ããŸãã ãã以å€ã®å Žåã¯ãã³ã³ãã€ã«ãããã³ãŒãã®ã¢ãã¬ã¹ãè¿ããŸãã
- çŸåšã®ã¢ãã¬ã¹ãThePreStubé¢æ°ã®ã¢ãã¬ã¹ãšäžèŽãããŸã§ã以äžãå®è¡ããŸãã
- çŸåšã®ã¢ãã¬ã¹ãjmpã³ãã³ããæããŠããå Žåãjmpã³ãã³ãã®å®å
ã¢ãã¬ã¹ã«ç§»åããŸãã
- ãã以å€ã®å ŽåãçŸåšã®ã¢ãã¬ã¹ãåŒã³åºãã³ãã³ããæããŠããå Žåã¯ãåŒã³åºãã³ãã³ãã®å®å
ã¢ãã¬ã¹ã確èªããŸãã PrecodeFixupThunkã¢ããã¿ãŒãšçããå ŽåïŒJITã³ã³ãã€ã«åã®FixupPrecode-ã¢ããã¿ãŒã®å ŽåïŒãNULLãè¿ããŸãã ãã以å€ã®å Žåã¯ãåŒã³åºãã³ãã³ããé
眮ãããŠããã¢ãã¬ã¹ïŒãŸãã¯åŒã³åºãã³ãã³ãã®å®å
ã¢ãã¬ã¹ïŒãè¿ããŸãã
- ãã以å€ã®å Žåã¯ãçŸåšã®ã¢ãã¬ã¹ãè¿ããŸãã
- ThePreStubé¢æ°ã®ã¢ãã¬ã¹ã«å°éãããããNULLãè¿ããŸãã
ç¯3.1ã§ã¯ã
ã³ã³ãã€ã«ãããŠããªãã¡ãœããã®
MethodDescæ§é äœã®ã¢ãã¬ã¹ã®å®çŸ©ã«ã€ããŠèª¬æããŠããŸãã 以äžã®ã¢ã«ãŽãªãºã ã¯ãCLRç°å¢ã«ãã£ãŠçæãããã¢ããã¿ãŒã®ãã€ããªãŒæ§é ã®ç¥èã«åºã¥ããŠãããæå®ãããã¢ãã¬ã¹ïŒãŸãã¯JITã³ã³ãã€ã«ã®å Žåã¯NULLïŒãèšç®ããŸãã
- RuntimeMethodHandle.GetFunctionPointerãåŒã³åºããŠã.NETã¡ãœããã®ã¢ãã¬ã¹ãååŸããŸãã
- åä¿¡ããã¢ãã¬ã¹ã®ã³ãã³ãããµã³ãã«ã¢ããã¿StubPrecodeãŸãã¯RemotingPrecodeãšäžèŽããå Žåãã»ã¯ã·ã§ã³2ã®æ®µèœ1ããã³æ®µèœ3ã§èª¬æãããŠããããã«ã MethodDescæ§é äœã®ã¢ãã¬ã¹ãèšç®ããŸãã
- çŸåšã®ã¢ãã¬ã¹ãThePreStubé¢æ°ã®ã¢ãã¬ã¹ãšäžèŽãããŸã§ã以äžãå®è¡ããŸãã
- çŸåšã®ã¢ãã¬ã¹ãjmpã³ãã³ããæããŠããå Žåãjmpã³ãã³ãã®çŽåŸã®ãã€ãã確èªããŸãã 0x5FïŒJITã³ã³ãã€ã«åŸã®FixupPrecodeã®å ŽåïŒã®å Žåãã»ã¯ã·ã§ã³2ãã»ã¯ã·ã§ã³2ã§èª¬æãããŠããããã«ã MethodDescæ§é äœã®ã¢ãã¬ã¹ãèšç®ããŸãããã以å€ã®å Žåã¯ãjmpã³ãã³ãã®ã¢ãã¬ã¹ã«ç§»åããŸãã
- ãã以å€ã®å ŽåãçŸåšã®ã¢ãã¬ã¹ãåŒã³åºãã³ãã³ããæããŠããå Žåã¯ãåŒã³åºãã³ãã³ãã®å®å
ã¢ãã¬ã¹ã確èªããŸãã PrecodeFixupThunkã¢ããã¿ãŒïŒJITã³ã³ãã€ã«åã®FixupPrecode-ã¢ããã¿ãŒã®å ŽåïŒãšçããå Žåãã»ã¯ã·ã§ã³2ãã»ã¯ã·ã§ã³2ã§èª¬æãããŠããããã«ã MethodDescæ§é äœã®ã¢ãã¬ã¹ãèšç®ããŸãããã以å€ã®å Žåã¯ãNULLãè¿ããŸãã
- ãã以å€ã®å Žåã¯ãNULLãè¿ããŸãã
- NULLãè¿ããŸãïŒæå®ãããã¢ã€ãã ã¯å°éäžèœã§ãªããã°ãªããŸããïŒã
6.çµè«
äžèšã®ã¢ã«ãŽãªãºã ã®ããã©ãŒãã³ã¹ã¯ã.NETããã³ããŒããŠã§ã¢ãã©ãããã©ãŒã ã®ããŸããŸãªããŒãžã§ã³ã§å®éã«ïŒç£æ¥éçºãå«ãïŒç¹°ãè¿ããã¹ããããŠããŸãã ããã«åºã¥ããŠã.NETã©ã€ãã©ãªãéçºãããŸãããããã䜿çšãããšã.NETé¢æ°ã®ã€ã³ã¿ãŒã»ãããéåžžã«ç°¡åã«ãªããŸãã éçºããã©ã€ãã©ãªã䜿çšããŠååã䜿çšããäŸã次ã«ç€ºããŸãã
SqlConnectionã¯ã©ã¹ã®
Opené¢æ°ãã€ã³ã¿ãŒã»ãããããšããŸãã 次ã«ãéçºãããã©ã€ãã©ãªã䜿çšããå Žåã®ã€ã³ã¿ãŒã»ããã³ãŒãã¯ãCïŒã§æ¬¡ã®ããã«ãªããŸãã
public static class HookedConnection { public static RTX.NET.HookHandle OpenHandle; [MethodImplAttribute(MethodImplOptions.NoInlining)] public static void Open(SqlConnection connection) {
ããã§ã
OpenHandleå€æ°ã«ã¯ã眮æãããé¢æ°ã®å®è£
ãåŒã³åºãããšãã§ããã€ã³ã¿ãŒã»ãããå²ãåœãŠãçµæãšããŠåæåãããèšè¿°åãå«ãŸããŠããŸãã
using (ConnectionEntry entry = new ConnectionEntry()) { Test(); }
ConnectionEntryã¯ã©ã¹ã¯ããããã ãååãããŒãžã£ãŒãïŒ
public class ConnectionEntry : RTX.NET.HookDispatcher, RTX.NET.IHookLoadHandler {
ãã®åŸã
ãã¹ãæ©èœãå®è¡ãããšã
public static void Test() { SqlConnection connection = new SqlConnection(); connection.ConnectionString = @"Server=(localdb)\v11.0;" + @"AttachDbFileName=C:\MyFolder\MyData.mdf;Integrated Security=true;"; connection.Open (); connection.Close(); }
次ã®ã¡ãã»ãŒãžãã³ã³ãœãŒã«ã«è¡šç€ºãããŸãã
Server=(localdb)\v11.0;AttachDbFileName=C:\MyFolder\MyData.mdf;Integrated Security=true;