x64 플랫폼에서의 System32 디렉터리에 대한 트릭

안녕하세요. Windows Azure MVP 남정현입니다.


 



오늘은 사소하지만 잘 모르고 접근하면 크게 시간을 낭비하게 만들 수 있는 사소한 트릭에 대해서 이야기를 하려고 합니다. 바로 시스템 디렉터리 접근에 관한 규칙인데요, 32비트 플랫폼을 사용하는 컴퓨터에서는 벌어지지 않기 때문에 흔히 간과하고 지나가기 쉬운 부분이라 블로그 글로 올립니다. 지금 올리는 글은 Windows Vista 이후로 계속 적용되는 내용이며, 서버 플랫폼에 대해서도 해당됩니다.


일반적으로 32비트 플랫폼을 타겟으로 작성된 응용프로그램들은 파일 경로 관련 해석 로직을 호출할 때 들어오는 그대로 (as-is) 해석을 하고 적절한 파일을 찾아 핸들을 열어주거나 정보를 조사해줍니다. 그러나 64비트 플랫폼의 경우, 흔히 잘 알려져있는 호환성의 족쇄라는 것에 의해 과거 32비트 시스템이 16비트 시스템에 대해서 지원하던것과 같이 64비트 시스템에서 32비트 시스템에 대한 지원을 Windows on Windows라는 호환 계층을 통하여 지원하고 있습니다. 32비트 플랫폼을 대상으로 만들어진 프로그램이 별 다른 노력 없이 그대로 실행될 수 있는 가장 중요한 원천이라고 할 수 있을 것입니다.


그러나 단순히 바이너리 코드에 대한 호환성 계층 제공을 하는 것을 넘어서서 시스템 파일에 대해서도 트릭이 하나 들어있는데, 특별한 예약명을 사용하지 않는 한, 32비트 프로그램이 x64 환경에서 실행될 때 %WINDIR% 디렉터리 아래의 System32 디렉터리는 절대 System32 디렉터리가 아니라 SysWOW64 디렉터리를 가리키도록 자동으로 의미가 수정됩니다.


가끔 필요에 의하여 32비트 프로그램이 64비트 시스템 구성 요소의 존재 여부를 확인하고 대리로 프로그램을 실행해야 할 필요가 있습니다. 대개의 경우, 중요한 시스템 파일들은 System32와 SYSWOW64 사이에 차이가 없도록 사전에 조율이 되어있으므로 큰 문제는 없습니다. 하지만 시스템이 설치된 이래로 새로 추가되는 새로운 시스템 파일의 경우, 32비트로 컴파일된 프로그램은 이 사실을 파악할 방법이 없습니다.


이를 해결하기 위하여 사용할 수 있는 기술적인 방법으로 API를 이용하여 리디렉션을 켜거나 끌 수 있는 API가 있습니다. 그러나 이 방법보다 더 쉽고 안전하게 갈 수 있는 방법이 있어 소개를 해드리려고 합니다.


바로 %WINDIR%SysNative라는 디렉터리에 관한 내용입니다. 사실 SysNative 디렉터리는 실존하는 디렉터리가 아닙니다. 그러나 32비트 프로그램에서 이 디렉터리에 대한 파일 시스템 동작이 일어날 경우, 32비트 프로그램이 64비트 시스템 구성 요소에 대해 접근할 수 있는 경로로 활용할 수 있습니다. 즉, 실제 시스템 디렉터리로 제대로 리디렉션이 되는 것을 확인할 수 있습니다. 그리고 64비트 프로그램에서는 이 디렉터리에 대한 별칭이 작동하지 않으므로 아래와 같이 쉽게 구분이 가능합니다.



string targetPath = Path.Combine(Environment.GetEnvironmentVariable(“WINDIR”), @”System32mrt.exe”);

if (!Directory.Exists(targetPath)) {
    targetPath = Path.Combine(Environment.GetEnvironmentVariable(“WINDIR”), @”SysNativemrt.exe”);
}

if (!Directory.Exists(targetPath)) {
    // 정말 해당 파일이 시스템 디렉터리에 없는 상황인 경우 여기로 오게 됩니다.
    return;
}
// 파일을 정확하게 찾은 경우 여기로 오게 됩니다.


위와 같이 코드를 작성하면 특수한 스위치나 설정을 건드리지 않고 안전하게 32비트 프로그램에서 64비트 시스템 구성 요소를 검색할 수 있습니다.


감사합니다.

댓글 남기기