Microsoft MVP성태의 닷넷 이야기
디버깅 기술: 127. windbg - .NET x64 EXE의 EntryPoint [링크 복사], [링크+제목 복사]
조회: 1230
글쓴 사람
홈페이지
첨부 파일
 

windbg - .NET x64 EXE의 EntryPoint

지난 글에서,

windbg - .NET x86 CLR2/CLR4 EXE의 EntryPoint
; https://www.sysnet.pe.kr/2/0/11861

x86 .NET EXE에 대해 EntryPoint를 실습해 봤는데요. 그럼 x64에서는 어떻게 될까요? 이게 좀 묘합니다. ^^

일단, windbg에서 "bp $exentry"로 걸면 다음과 같은 오류와 함께 디버깅이 진행되지 않습니다.

0:000> bp $exentry
*** WARNING: Unable to verify checksum for ConsoleApp1.exe

0:000> g
Unable to insert breakpoint 0 at 00000212`f3710000, Win32 error 0n998
    "Invalid access to memory location."
The breakpoint was set with BP.  If you want breakpoints
to track module load/unload state you must use BU.
bp0 at 00000212`f3710000 failed
WaitForEvent failed
ntdll!LdrpDoDebuggerBreak+0x31:
00007ff8`970e2cbd eb00            jmp     ntdll!LdrpDoDebuggerBreak+0x33 (00007ff8`970e2cbf)

위와 같은 상황이 되면 아무리 g 키를 눌러도 진행이 안 되므로 설정한 bp를 삭제해야만 합니다. 그런데, windbg가 찾아낸 $exentry의 위치가 재미있습니다.

0:000> u $exentry
ConsoleApp1!Main [C:\temp\ConsoleApplication1\ConsoleApp1\Program.cs @ 12]:
00000001`40000000 4d5a            pop     r10
00000001`40000002 90              nop
00000001`40000003 0003            add     byte ptr [rbx],al
00000001`40000005 0000            add     byte ptr [rax],al
00000001`40000007 000400          add     byte ptr [rax+rax],al
00000001`4000000a 0000            add     byte ptr [rax],al
00000001`4000000c ff              ???
00000001`4000000d ff00            inc     dword ptr [rax]

보는 바와 같이 Native가 아닌 .NET 수준에서의 Main 함수 진입점을 가리키는 걸로 나옵니다. 즉, 저 위치는 기계어가 아니라 .NET Main 함수의 Body 위치라고 봐야 합니다. 더욱 재미있는 것은 $exentry의 주솟값이 모듈의 로딩 주소와 동일하다는 것입니다.

0:000> lm
start             end                 module name
00000001`40000000 00000001`40006000   ConsoleApp1   (pdb symbols)          C:\temp\ConsoleApplication1\x64\Debug\ConsoleApp1.pdb
00007ff8`80a60000 00007ff8`80ac4000   MSCOREE    (deferred)             
00007ff8`935b0000 00007ff8`93843000   KERNELBASE   (deferred)             
00007ff8`96c50000 00007ff8`96d03000   KERNEL32   (deferred)             
00007ff8`97010000 00007ff8`971fd000   ntdll      (pdb symbols)          e:\symbols\ntdll.pdb\BF569FC564FA51D4BFE7B5E47D65792D1\ntdll.pdb

실제로 .NET EXE의 PE 헤더에 있는 "AddressOfEntryPoint"의 값은 0입니다. 이 값이 0이라는 것은 진입점이 없다는 것을 의미합니다.




WinDbg로 조사해보면, x64 CLR2 EXE인 경우 x86에서와 마찬가지로 KERNEL32!BaseThreadInitThunk+0xe에서 멈추는 것을 확인할 수 있습니다.

KERNEL32!BaseThreadInitThunk:
    00007ff8`96c681e0 4883ec28        sub     rsp,28h
    00007ff8`96c681e4 85c9            test    ecx,ecx
    00007ff8`96c681e6 7515            jne     KERNEL32!BaseThreadInitThunk+0x1d (00007ff8`96c681fd)
    00007ff8`96c681e8 498bc8          mov     rcx,r8
    00007ff8`96c681eb 488bc2          mov     rax,rdx
    00007ff8`96c681ee ff1574290600    call    qword ptr [KERNEL32!_guard_dispatch_icall_fptr (00007ff8`96ccab68)] ds:00007ff8`96ccab68={KERNEL32!guard_dispatch_icall_nop (00007ff8`96c73310)}

위의 상태에서 rax == 7ff880a6a510으로 나오고, _guard_dispatch_icall_fptr의 코드는 그 rax로 JMP하는 역할만 합니다.

KERNEL32!guard_dispatch_icall_nop:
00007ff8`96c73310 ffe0            jmp     rax {MSCOREE!CorExeMain_Exported (00007ff8`80a6a510)}

그러니까, 윈도우 시스템은 .NET EXE의 EntryPoint를 7ff880a6a510로 판단하고 있는 것입니다. 왜 이 주소가 구해졌는지 x64의 경우 이해가 안 됩니다. 그나마 x86의 경우에는 mscoree.dll에 대한 참조를 Import Directory에 가지고 있어서 실행 시 CorExeMain_Exported에 대한 점프 주소를 가지고 있었지만, x64는 mscoree.dll에 대한 참조 조차 가지고 있습니다. 다시 말해 표면상 PE 파일 포맷을 지키고는 있지만 내용면에서 보면 일반 데이터 파일과 다를 바가 없는 것입니다.

그렇다면 x64의 경우 윈도우 시스템 측의 로더가 .NET 모듈임을 인식하는 걸까요? 아마도 그럴 것 같은데... 혹시 아시는 분이 있다면 덧글 부탁드립니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]





[최초 등록일: ]
[최종 수정일: 4/9/2019 ]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer@outlook.com

비밀번호

댓글 쓴 사람
 




1  2  3  4  5  6  [7]  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
12058정성태11/19/2019464디버깅 기술: 130. windbg - CoTaskMemFree/FreeCoTaskMem에서 발생한 덤프 분석 사례
12057정성태11/18/2019337오류 유형: 579. Visual Studio - Memory 창에서 유효한 주소 영역임에도 "Unable to evaluate the expression." 오류 출력
12056정성태11/18/2019581개발 환경 구성: 464. "Microsoft Visual Studio Installer Projects" 프로젝트로 EXE 서명 및 MSI 파일 서명 방법파일 다운로드1
12055정성태11/17/2019289개발 환경 구성: 463. Visual Studio의 Ctrl + Alt + M, 1 (Memory 1) 등의 단축키가 동작하지 않는 경우
12054정성태11/15/2019681.NET Framework: 869. C# - 일부러 GC Heap을 깨뜨려 GC 수행 시 비정상 종료시키는 예제
12053정성태11/15/2019367Windows: 164. 윈도우 10 - 명령행 창(cmd.exe) 속성에 (DotumChe, GulimChe, GungsuhChe 등의) 한글 폰트가 없는 경우
12052정성태11/15/2019317오류 유형: 578. Azure - 일정(schedule)에 등록한 runbook이 1년 후 실행이 안 되는 문제(Reason - The key used is expired.)
12051정성태12/2/2019706개발 환경 구성: 462. 시작하자마자 비정상 종료하는 프로세스의 메모리 덤프 - procdump [1]
12050정성태11/14/2019475Windows: 163. AcLayers의 API 후킹과 FaultTolerantHeap
12049정성태11/13/2019381.NET Framework: 868. (닷넷 프로세스를 대상으로) 디버거 방식이 아닌 CLR Profiler를 이용해 procdump.exe 기능 구현
12048정성태11/12/2019490Windows: 163. GUID 이름의 볼륨에 해당하는 파티션을 찾는 방법
12047정성태11/12/2019874Windows: 163. 안전하게 eject시킨 USB 장치를 물리적인 재연결 없이 다시 인식시키는 방법
12046정성태11/9/2019460오류 유형: 577. windbg - The call to LoadLibrary(...\sos.dll) failed, Win32 error 0n193
12045정성태10/27/2019377오류 유형: 576. mstest.exe 실행 시 "Visual Studio Enterprise is required to execute the test." 오류 - 두 번째 이야기
12044정성태10/27/2019483오류 유형: 575. mstest.exe - System.Resources.MissingSatelliteAssemblyException: The satellite assembly named "Microsoft.VisualStudio.ProductKeyDialog.resources.dll, ..."
12043정성태10/27/2019450오류 유형: 574. Windows 10 설치 시 오류 - 0xC1900101 - 0x4001E
12042정성태10/26/2019415오류 유형: 573. OneDrive 하위에 위치한 Documents, Desktop 폴더에 대한 권한 변경 시 "Unable to display current owner"
12041정성태10/23/2019354오류 유형: 572. mstest.exe - The load test results database could not be opened.
12040정성태10/23/2019617오류 유형: 571. Unhandled Exception: System.Net.Mail.SmtpException: Transaction failed. The server response was: 5.2.0 STOREDRV.Submission.Exception:SendAsDeniedException.MapiExceptionSendAsDenied
12039정성태10/22/2019441스크립트: 16. cmd.exe의 for 문에서는 ERRORLEVEL이 설정되지 않는 문제
12038정성태10/17/2019372오류 유형: 570. SQL Server 2019 RC1 - SQL Client Connectivity SDK 설치 오류
12037정성태10/15/2019608.NET Framework: 867. C# - Encoding.Default 값을 바꿀 수 있을까요?파일 다운로드1
12036정성태10/21/20191037.NET Framework: 866. C# - 고성능이 필요한 환경에서 GC가 발생하지 않는 네이티브 힙 사용파일 다운로드1
12035정성태10/13/2019490개발 환경 구성: 461. C# 8.0의 #nulable 관련 특성을 .NET Framework 프로젝트에서 사용하는 방법파일 다운로드1
12034정성태1/31/2020615개발 환경 구성: 460. .NET Core 환경에서 (프로젝트가 아닌) C# 코드 파일을 입력으로 컴파일하는 방법 [1]
12033정성태10/11/2019953개발 환경 구성: 459. .NET Framework 프로젝트에서 C# 8.0 컴파일러를 사용하는 방법
1  2  3  4  5  6  [7]  8  9  10  11  12  13  14  15  ...