Microsoft MVP성태의 닷넷 이야기
.NET Framework: 509. ELEMENT_TYPE_MODIFIER의 조합 [링크 복사], [링크+제목 복사]
조회: 14592
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 9개 있습니다.)
.NET Framework: 491. 닷넷 Generic 타입의 메타 데이터 토큰 값 알아내는 방법
; https://www.sysnet.pe.kr/2/0/1848

.NET Framework: 494. 값(struct) 형식의 제네릭(Generic) 타입이 박싱되는 경우의 메타데이터 토큰 값
; https://www.sysnet.pe.kr/2/0/1857

.NET Framework: 495. CorElementType의 요소 값 설명
; https://www.sysnet.pe.kr/2/0/1860

.NET Framework: 509. ELEMENT_TYPE_MODIFIER의 조합
; https://www.sysnet.pe.kr/2/0/2894

.NET Framework: 510. 제네릭(Generic) 인자에 대한 메타데이터 등록 확인
; https://www.sysnet.pe.kr/2/0/2907

.NET Framework: 844. C# - 박싱과 언박싱
; https://www.sysnet.pe.kr/2/0/11943

.NET Framework: 955.  .NET 메서드의 Signature 바이트 코드 분석
; https://www.sysnet.pe.kr/2/0/12379

.NET Framework: 1130. C# - ELEMENT_TYPE_INTERNAL 유형의 사용 예
; https://www.sysnet.pe.kr/2/0/12903

.NET Framework: 1174. C# - ELEMENT_TYPE_FNPTR 유형의 사용 예
; https://www.sysnet.pe.kr/2/0/12998




ELEMENT_TYPE_MODIFIER의 조합

ELEMENT_TYPE_MODIFIER 조합을 알다가도 모르겠군요. ^^;

지난 글에서는 SNINativeMethodWrapper.MarshalConsumerInfo 메서드의 signature가 "SIG: 00 02 01 12 20 20 45 0f 11 30" 값이었고, 그중 0x45가 ELEMENT_TYPE_MODIFIER | ELEMENT_TYPE_PINNED의 조합인 것을 알 수 있었습니다.

그런데, .NET 2.0에 정의된 SNINativeMethodWrapper.MarshalConsumerInfo는 signature가 다릅니다.

.method private hidebysig static void  MarshalConsumerInfo(class SNINativeMethodWrapper/ConsumerInfo consumerInfo,
                                                           valuetype SNI_CONSUMER_INFO* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) native_consumerInfo) cil managed
// SIG: 00 02 01 12 1C 20 39 0F 11 28

00 IMAGE_CEE_CS_CALLCONV_DEFAULT (static method)
02 # of arg(s)
01 ELEMENT_TYPE_VOID (return)
12 ELEMENT_TYPE_CLASS (1st arg type)
  1C (1byte - type token)
  20 ELEMENT_TYPE_CMOD_OPT
  39 ????
  0F ELEMENT_TYPE_PTR
11 ELEMENT_TYPE_VALUETYPE (2nd arg type)
  28 (1byte - type token) 

0x39라니...? ELEMENT_TYPE_MODIFIER의 값이 0x40이기 때문에 .NET 2.0 시절에는 ELEMENT_TYPE_MODIFIER로 분류되지도 않았다는 의미가 됩니다. 알수는 없지만, 억지로 조합해보면 다음과 같이 0x39를 만들 수 있습니다.

ELEMENT_TYPE_VALUETYPE = 0x11
ELEMENT_TYPE_PTR = 0x0f
                 == 20
ELEMENT_TYPE_U == 0x19

ELEMENT_TYPE_VALUETYPE | ELEMENT_TYPE_PTR | ELEMENT_TYPE_U

그런데, ".NET 4.0 (x64)"에서는 또 다른 조합이 나옵니다.

.method private hidebysig static void  MarshalConsumerInfo(class SNINativeMethodWrapper/ConsumerInfo consumerInfo,
                                                           valuetype Sni_Consumer_Info* modopt([mscorlib]System.Runtime.CompilerServices.IsImplicitlyDereferenced) native_consumerInfo) cil managed
SIG: 00 02 01 12 20 20 49 0F 11 38

0x49입니다. ELEMENT_TYPE_MODIFIER의 조합을 corhdr.h에서 보면,

ELEMENT_TYPE_MODIFIER       = 0x40,
ELEMENT_TYPE_SENTINEL       = 0x01 | ELEMENT_TYPE_MODIFIER, // sentinel for varargs
ELEMENT_TYPE_PINNED         = 0x05 | ELEMENT_TYPE_MODIFIER,
ELEMENT_TYPE_R4_HFA         = 0x06 | ELEMENT_TYPE_MODIFIER, // used only internally for R4 HFA types
ELEMENT_TYPE_R8_HFA         = 0x07 | ELEMENT_TYPE_MODIFIER, // used only internally for R8 HFA types

0x49는 도저히 나올 수 없는 조합입니다. 게다가, 이번에 공개된 .NET 4.6 Preview의 corhdr.h에 보면 ELEMENT_TYPE_R4_HFA, ELEMENT_TYPE_R8_HFA는 아예 삭제된 것을 볼 수 있습니다.

// C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Include\um\corhdr.h

ELEMENT_TYPE_MODIFIER       = 0x40,
ELEMENT_TYPE_SENTINEL       = 0x01 | ELEMENT_TYPE_MODIFIER, // sentinel for varargs
ELEMENT_TYPE_PINNED         = 0x05 | ELEMENT_TYPE_MODIFIER,

도대체 어떻게 0x49가 나올 수 있을까 싶어 무작위로 검색해 보니, coreclr에 힌트가 나옵니다.

// https://github.com/dotnet/coreclr/blob/master/src/vm/compactlayoutwriter.h

178     enum CorElementTypeMDIL 
179     { 
180         ELEMENT_TYPE_NATIVE_VALUETYPE = 0x08 | ELEMENT_TYPE_MODIFIER 
181     }; 

위의 값을 기반으로 만들어 보면, 0x49를 이렇게 만들어 볼 수 있습니다.

0x49 == ELEMENT_TYPE_MODIFIER | 0x08 | 0x01
     == ELEMENT_TYPE_NATIVE_VALUETYPE | ELEMENT_TYPE_SENTINEL

00 IMAGE_CEE_CS_CALLCONV_DEFAULT (static method)
02 # of arg(s)
01 ELEMENT_TYPE_VOID (return)
12 ELEMENT_TYPE_CLASS (1st arg type)
  20 (1byte - type token)
  20 ELEMENT_TYPE_CMOD_OPT
  49 ELEMENT_TYPE_NATIVE_VALUETYPE | ELEMENT_TYPE_SENTINEL 
  0F ELEMENT_TYPE_PTR
11 ELEMENT_TYPE_VALUETYPE (2nd arg type)
  38 (1byte - type token)

물론, 위의 가정은 어디까지나 제 개인적인 가정입니다. ^^




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







[최초 등록일: ]
[최종 수정일: 10/24/2018]

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

비밀번호

댓글 작성자
 




... 46  47  48  49  50  51  52  53  54  55  56  57  [58]  59  60  ...
NoWriterDateCnt.TitleFile(s)
12171정성태3/6/202010815VS.NET IDE: 143. Visual Studio - ASP.NET Core Web Application의 "Enable Docker Support" 옵션으로 달라지는 점 [1]
12170정성태3/6/20209456오류 유형: 599. "Docker Desktop is switching..." 메시지와 DockerDesktopVM CPU 소비 현상
12169정성태3/5/202011489개발 환경 구성: 473. Windows nanoserver에 대한 docker pull의 태그 사용 [1]
12168정성태3/5/202012153개발 환경 구성: 472. 윈도우 환경에서의 dockerd.exe("Docker Engine" 서비스)가 Linux의 것과 다른 점
12167정성태3/5/202011407개발 환경 구성: 471. C# - 닷넷 응용 프로그램에서 DB2 Express-C 데이터베이스 사용 (3) - ibmcom/db2express-c 컨테이너 사용
12166정성태3/4/202011072개발 환경 구성: 470. Windows Server 컨테이너 - DockerMsftProvider 모듈을 이용한 docker 설치
12165정성태3/2/202010749.NET Framework: 900. 실행 시에 메서드 가로채기 - CLR Injection: Runtime Method Replacer 개선 - 네 번째 이야기(Monitor.Enter 후킹)파일 다운로드1
12164정성태2/29/202011606오류 유형: 598. Surface Pro 6 - Windows Hello Face Software Device가 인식이 안 되는 문제
12163정성태2/27/202010022.NET Framework: 899. 익명 함수를 가리키는 delegate 필드에 대한 직렬화 문제
12162정성태2/26/202012777디버깅 기술: 166. C#에서 만든 COM 객체를 C/C++로 P/Invoke Interop 시 메모리 누수(Memory Leak) 발생 [6]파일 다운로드2
12161정성태2/26/20209464오류 유형: 597. manifest - The value "x64" of attribute "processorArchitecture" in element "assemblyIdentity" is invalid.
12160정성태2/26/202010145개발 환경 구성: 469. Reg-free COM 개체 사용을 위한 manifest 파일 생성 도구 - COMRegFreeManifest
12159정성태2/26/20208355오류 유형: 596. Visual Studio - The project needs to include ATL support
12158정성태2/25/202010158디버깅 기술: 165. C# - Marshal.GetIUnknownForObject/GetIDispatchForObject 사용 시 메모리 누수(Memory Leak) 발생파일 다운로드1
12157정성태2/25/202010007디버깅 기술: 164. C# - Marshal.GetNativeVariantForObject 사용 시 메모리 누수(Memory Leak) 발생 및 해결 방법파일 다운로드1
12156정성태2/25/20209378오류 유형: 595. LINK : warning LNK4098: defaultlib 'nafxcw.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
12155정성태2/25/20208676오류 유형: 594. Warning NU1701 - This package may not be fully compatible with your project
12154정성태2/25/20208553오류 유형: 593. warning LNK4070: /OUT:... directive in .EXP differs from output filename
12153정성태2/23/202011191.NET Framework: 898. Trampoline을 이용한 후킹의 한계파일 다운로드1
12152정성태2/23/202010930.NET Framework: 897. 실행 시에 메서드 가로채기 - CLR Injection: Runtime Method Replacer 개선 - 세 번째 이야기(Trampoline 후킹)파일 다운로드1
12151정성태2/22/202011499.NET Framework: 896. C# - Win32 API를 Trampoline 기법을 이용해 C# 메서드로 가로채는 방법 - 두 번째 이야기 (원본 함수 호출)파일 다운로드1
12150정성태2/21/202011323.NET Framework: 895. C# - Win32 API를 Trampoline 기법을 이용해 C# 메서드로 가로채는 방법 [1]파일 다운로드1
12149정성태2/20/202011077.NET Framework: 894. eBEST C# XingAPI 래퍼 - 연속 조회 처리 방법 [1]
12148정성태2/19/202012280디버깅 기술: 163. x64 환경에서 구현하는 다양한 Trampoline 기법 [1]
12147정성태2/19/202010919디버깅 기술: 162. x86/x64의 기계어 코드 최대 길이
12146정성태2/18/202011172.NET Framework: 893. eBEST C# XingAPI 래퍼 - 로그인 처리파일 다운로드1
... 46  47  48  49  50  51  52  53  54  55  56  57  [58]  59  60  ...