사이트 이용규칙을 준수하여
닥터몰라 회원과 자유롭게 소통하는 게시판입니다.

Cinebench R15와 Windows 10

Archost   |   조회 수: 66   |   추천 수: 0    작성 일: 2019.05.28 08:49 (2개월 전)
게임  

 

Cinebench R15와 Windows 10

 

win.PNG


Cinebench는 Maxon 사에서 개발한 Cinema 4D R15를 기반으로 내장된 렌더러의 성능과 뷰포트 성능을 테스트할 수 있는 벤치마크 프로그램입니다. 2019년 Cinebench R20 도 릴리즈 되었습니다.
2013년Windows 8.1와 함께 Cinema 4D R15또한 동년 릴리즈 되었지요. 그런데 이 프로그램을 한번 사용하면 뭔가 이상한 점을 하나 발견할 수 있습니다Windows 10에서도 Windows 8로 인식한다는 것인데 왜 이런 현상이 발생하는지 알아봅니다.
먼저 프로그램이 어떻게 동작하는지 이해하기 위해 Cinebench R15를 디스어셈블러로 열어봅시다.

 

01.PNG Figure 1. GetVersionExA()
 

02.PNG

Figure 2. Switch / Case

위의 어셈블리 언어를 토대로 C로 바꾸면 다음과 같이 작성할 수 있습니다.
 

 

code.PNG

Figure 3. In C


“osInfo.dwOSVersionInfoSize”에는 일반적으로 “sizeof(osInfo)”를 쓰는 게 맞겠지만 디스어셈블 코드를 최대한 반영해서 156바이트를 직접 입력하였습니다.

 

 

Cinebench R15는 GetVersionExA() 라는 Windows의 API를 사용해서 시스템의 OS 정보를 불러오게 됩니다. 하지만 Microsoft는 Windows 8.1 부터 해당 기능을 Deprecated(더 이상 사용되지 않고 제거될 수 있음) 처리하였습니다. (https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getversionexa)


그렇기에 해당 기능은 Windows 8을 의미하는 버전 6.2를 초과하는 값을 불러올 수 없습니다. 코드 내부에는 버전 6을 초과하는 경우 “Windows ???” 를 반환하게 되어 있고, Windows 10의 버전은 10이므로 Windows 10에서 Cinebench R15를 실행하게 되면 “Windows ???” 가 나와야 하겠지만 그렇지 않습니다.


Microsoft의 해당 결정은 레거시 프로그램의 호환성으로 한동안 홍역을 치렀던 적이 있기 때문에 아예 직접적으로 버전을 불러올 수 없도록 한 것으로 보입니다. 이를 대체하기 위해서 새로운 API가 등장하였는데 이 기능들은 단순히 Windows가 특정 버전이거나 그 이후의 버전인가 만을 확인할 수 있도록 하였습니다.  예를 들자면 “IsWindows7OrGreater()”를 사용하면 Windows 7또는 그 이후의 버전 인가에 대해서만 확인을 하죠. (https://docs.microsoft.com/en-us/windows/desktop/sysinfo/version-helper-apis)


그렇다면 정확한 Windows의 버전을, 불러올 수는 없을까요?


Microsoft Windows는 Manifests 라는 정보를 사용합니다. 이 Manifests 정보는 프로그램의 정보를 담을 수 있지만 해당 프로그램이 확장 기능들 또한 사용이 가능한지 여부에 대한 정보를 담을 수 있습니다. Manifests 가 없는 프로그램은 기본적으로 가장 기본적인 상태에서 동작하게 됩니다.


이 Manifests에는 HiDPI, 255이상의 파일 경로 지원, UI스킨, 관리자 모드로 실행 등의 정보를 기입할 수 있습니다.
여기서 Microsoft는 Manifests에 프로그램이 해당 OS를 지원하는지에 대한 유무 또한 넣을 수 있도록 하였습니다. 만약 Windows 10에서도 해당 기능이 Deprecated되지 않았다면 만약 Windows 8 당시 개발된 프로그램이 Windows 8 그 이후의 OS를 감지하면 오류를 내도록 설계되었다면 Windows 10에서는 프로그램이 의도한 대로 오류를 낼 것입니다. 하지만 별도의 Manifest 가 없다면 버전 6.2. 즉 Windows 8을 반환하므로 레거시들의 잠재적인 호환성 문제를 해결하려고 한 것으로 보입니다.


https://docs.microsoft.com/en-us/windows/desktop/SysInfo/targeting-your-application-at-windows-8-1
그리고 Cinebench R15에는 Manifests 가 아예 존재하지 않습니다.
 

manifests.PNG

Figure 4. Manifest와 rc 파일
그럼 위의 내용을 증명해 봅시다. 먼저 위의 C 코드 (figure 3)를 별다른 Manifest 없이 실행시키면 다음과 같은 값이 나오게 됩니다.
 

womanifest.PNG

Figure 5. fig3 w/o manifest
Manifest 가 없으면 예상한 대로 6.2, Windows 8, 64 Bit의 값이 나오게 됩니다.
 

wmanifests.PNG

Figure 6. fig3 /w manifest
Figure 5와 달리 Figure 6은 Manifest 정보를 함께 입력하였습니다. GetVersionExA()가 Windows 10이므로 10이라는 값을 정상적으로 가져왔습니다.

Cinebench R15또한 동일한 Manifests를 끼워 넣게 되면 다음과 같이 동작하게 됩니다.
 

winmanifest.PNG

Figure 7. Manifest signed Cinebench R15
이 역시 예상한 결과를 가져옵니다. Cinebench R15에는 Windows 10을 감지하는 코드가 없으므로 Figure 2의 결과와 일치합니다. 하지만 Cinebench R15에서 “Windows ??? 64 Bit”라는 값은 사실상 볼 수 없는 Redundant 한 코드라고 볼 수 있습니다.

 

patch.PNG

Figure 8. ROData 패치

 

patched.PNG

Figure 9. Cinebench R15 + Windows 10

 

 

위와 같이 Manifest 를 추가하고 바이너리를 패치하면 Windows 10이라는 값을 정상적으로 출력할 수 있게 됩니다.

 

보너스


Manifest 없이 정보를 불러오기.


일반적으로 API를 사용해서 개발하는 경우 정식적으로 공개된 정보만을 사용해서 개발을 하는 것이 원칙이고 이는 Windows라고 해서 별반 다르지 않습니다. 하지만 Windows용 응용 프로그램 개발자들은 이런 공식 문서에 존재하지 않는 API들 (Undocumented)을 사용하기도 합니다. 이런 API들은 예고 없이 언제든지 제거되거나 변경될 수 있지만, 특정 기능을 구현하기 위해 사용되기도 합니다. 대표적인 예로 게임들의 안티치트 프로그램들을 꼽을 수 있겠군요.
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-rtlgetversion
RtlGetVersion은 Undocumented된 API는 아니지만 커널 프로그램. 즉 드라이버를 위해 제공되는 API입니다. 일반적인 유저랜드용 프로그램에서 사용하도록 의도되지 않았고 일반적으로 해당 기능을 사용하기 위해서는 프로토타입화 시켜서 사용하거나, ntoskrnl.exe또는 ntdll.dll에서 직접 심볼을 가져와 사용하여야 합니다.

oskernl.PNG

Figure 10. RtlGetVersion()

 

하지만 커널 드라이버가 아닌 위와 같은 유저모드 환경에서 심볼을 직접 로드하거나 위와 같은 방법으로 접근하는 것은 어디까지나 편법이며 권장되는 방법은 아닙니다.

 

oskernlresult.PNG

Figure 11. RtlGetVersion()의 결과


가장 최선의 방법은 Manifests를 사용하는 방법이지만 해당 방법이 사용이 불가능 하거나 위와 같은 커널의 기능을 직접 사용하는 편법이 다소 찝찝하다면 GetFileVersionInfo() 같은 기능을 사용해서 “Kernel32.dll” 파일의 버전을 읽어오는 방법을 사용할 수도 있습니다.

댓글 2

Profile

위네

2개월 전

구버전을 위한 좋은 팁 감사합니다

댓글

Profile

썬업

2개월 전

어우 대박

댓글

잡담

Cinebench R15와 Windows 10

66 2
작성 일: 2개월 전. Archost
질문

저만 그런건지 출첵이 안되는 군요

66 1
작성 일: 2개월 전. 알테리온
잡담

스팀이 봄청소를 시작했습니다.

55 1
작성 일: 2개월 전. 알테리온
꿀팁

디비전2 겜알못을 위한 초보팁

100 1 1
작성 일: 3개월 전. 상곰이
소개

19년 5월 신작 및 기대작 2선

99 1
작성 일: 3개월 전. kerakera
소개

[오늘의 추천곡] Oh my love my darling (사랑과 영혼 ost, 추억의 명곡)

40
작성 일: 3개월 전. kerakera
잡담

오전이 너무 졸립네요..

42 1
작성 일: 3개월 전. 시원한목캔디
영상

[오늘의 추천곡] [이희문, 프렐류드] 한국남자의 청춘가(재즈+민요)

35 2 1
작성 일: 3개월 전. kerakera
잡담

[게임지름 방지만화] 1화 에필로그(글로만 작성)

45 1
작성 일: 4개월 전. kerakera
잡담

[게임지름 방지만화] 오늘도 내가 참는다 1화

120 1
작성 일: 4개월 전. kerakera
소개

멀티 플랫폼 SSH 클라이언트: Terminus

106
작성 일: 4개월 전. iMola
질문

The silent Age 한글 패치 진행중인가요?

207
작성 일: 5개월 전. Hyosungs
잡담

이제 다음달까지는 평일 공휴일이 없네요 ㅠㅠ

67 2 1
작성 일: 5개월 전. 시원한목캔디
소개

음원을 하나 발매했습니다

89 1
작성 일: 6개월 전. 나무노래
꿀팁

PyCharm과 도커를 이용한 딥러닝 개발환경 구축하기: Workstation side

959 4
작성 일: 6개월 전. iMola
서버에 요청 중입니다. 잠시만 기다려 주십시오...