2012-06-20 3 views
10

exe ​​/ dll이 헤더를보고 빌드하는 모드를 찾아야합니다. [편집] 외부 도구없이 C++ 만 사용하기 [편집]실행 파일이나 DLL이 릴리스 또는 디버그 모드에서 빌드되었는지 확인하는 방법 (C++)

dll이 릴리스 또는 디버그 모드에서 빌드되었는지 확인하는 방법에 대한 이전 토론이 있습니다. http://forums.codeguru.com/archive/index.php/t-485996.html

하지만 불행히도 나는 명확한 답을 찾지 못했습니다.

+0

그 토론에서 정확히 무엇이 빠졌는가 또는 무엇을 명확히하고 싶습니까? dll을 가까이서 분석하지 않고서는 이것을 알 수있는 방법이 없기 때문에 이에 대한 분명한 해답은 없습니다. – RedX

+0

Release 또는 Debug 모드로 무엇을 고려합니까? exe/dll에 버전 리소스가 있습니까? – harper

+0

버전이 100 % 보장되어 있지 않습니다. – ChatCloud

답변

6

exe ​​/ dll이 헤더를보고 빌드하는 모드를 찾아야합니다.

뜻 "헤더"에 의한 경우 PE 섹션이나 자원 (헤더는 아무 말도하지 않으며, 프로그램은 보통 개발 헤더와 함께 제공되지 않습니다!)이 가능의 종류이며, 한도 내에서, 그리고 신뢰할 수 없게. 그렇지 않으면, 당신이 직접 프로그램을 작성하지 않는 한 이것은 완전히 불가능한 시도입니다.

일반적으로 "디버그 빌드"는 대부분의 컴파일러 에서처럼 존재하지 않는 Microsoft Visual Studio 단순화이므로 신뢰할 수있는 방법으로 이러한 작업을 수행하는 것은 어렵습니다. 예를 들어, GCC의 경우 디버그 기호가 포함 된 최적화 빌드을 완벽하게 허용 할 수 있습니다. #pragma으로 최적화를 켜고 끄고 (최적화 수준과 대상 시스템을 변경!) 최적화되지 않은 빌드에서 최적화 된 기능 (또는 기능 그룹)을 가질 수도 있고 그 반대의 경우도 가능합니다.

디버그 기호가있는 것은 작성하지 않은 프로그램에 대한 가장 좋은 추측입니다. 생성 된 바이너리가 최적화되었는지 여부를 알려주는 것은 현실적으로 불가능합니다 (단순하지만 자동화 된 방법으로는 어쨌든).

섹션 .debug$S.debug$T은 각각 디버그 기호와 디버그 유형을 포함합니다. .debug으로 시작하는 다른 섹션도 있지만 더 이상 사용되지 않습니다. "디버그 모드"로 빌드되고 이후에 제거되지 않은 프로그램에는이 섹션의 일부 또는 전부가 포함됩니다.
외부 도구없이 C++을 사용하면 DOS "MZ"스텁과 PE 헤더를 건너 뛰고 싶을 것입니다. 이 후 섹션 헤더가 나오면 구문 분석 할 수 있습니다. 파일 형식의 전체 문서는 here에서 다운로드 할 수 있습니다.
아마도 파일을 읽고 .debug에 대한 문자열 일치를 수행하는 것이 좋습니다.

마찬가지로 VERSIONINFO 또는 매니페스트 파일 (프로그램이 디버그 빌드인지 여부도 지정할 수 있음)을 볼 수 있지만 필수는 아닙니다. 원하는 것을 쓸 수 있습니다. 그렇더라도 디버그 기호를 찾는 것보다 덜 신뢰할 수 있습니다.

또 다른 힌트는 신뢰할 수 없지만 프로그램이 연결된 시스템 라이브러리의 버전을 확인하는 것입니다. 디버그 버전이라면 디버그 빌드 일 가능성이 있습니다. 그러나 릴리스 빌드를 수행하고 여전히 디버그 라이브러리와 링크 할 수 있으며 그렇게하지 못하게하는 것은 없습니다.

가장 좋은 추측은 (일반적으로 호출되는) assert 매크로가 빌드에서 완전히 제거되어 CRT assert 함수 (간단한 문자열 일치로 수행 할 수 있음)에 대한 호출이없는 것입니다. NDEBUG이 정의되었습니다. 해당 기호를 사용하지 않으며 2 진수에 문자열이 없습니다.
불행하게도 에 아무런 어설 션이없는 프로그램은 실제 빌드와 관계없이 "릴리스 빌드"로 잘못 식별되며 assert 매크로를 완전히 다른 것으로 다시 정의 할 수 있습니다 (예 : printf a 텍스트 및 계속). 그리고 마지막으로, 당신은 당신이 알지 못하는 assert에 대한 호출을 포함하고있는 정적 인 서드 파티 라이브러리 (이미 전처리기를 통과했다)에 대해 잘 모릅니다.

자신이 작성한 프로그램을 검사하려면 옵티마이 저가 도달 할 가능성이 있거나 사용되지 않는 것을 완전히 제거한다는 사실을 이용할 수 있습니다. 2 ~ 3 회 정도 시도해 볼 수도 있지만, 기본적으로 변수 정의 (또는 컴파일러/링커에서 사용되지 않는 기호를 내 보내지 않은 경우 내 보낸 함수)와 같이 간단하고 2 ~ 3 개를 써야합니다 도달 할 수없는 프로그램 위치에서 마법 값을 가져옵니다. 최적화 컴파일러는 적어도 여러 개의 중복 된 동작을 하나로 축소 시키거나 전체적으로 완전히 제거합니다.
그러면 마법 값에 대한 바이너리 문자열 검색을 할 수 있습니다. 존재하지 않으면 최적화 된 빌드입니다.

+0

내 디버그 컴파일 된 응용 프로그램 (win32, vs2010)의 대부분은'.debug' 문자열을 포함하지 않습니다. 하나의 대안은 응용 프로그램에서 사용하는 C++ 런타임의 버전을 확인하는 것입니다. 예 : MSVCR80D.dll'MSVCR90D.dll'MSVCR100D.dll' ... – smerlin

+0

@smerlin : 네, 찾을 수있는 또 다른 (신뢰할 수는 없지만) 것입니다 (위에서 언급 한 것처럼 6 번 문단을 참조하십시오) . 너는 정말로 말할 수 없다. – Damon

0

Visual Studio에서 C++ 프로젝트를 만들면 두 가지 구성이 생성됩니다. 이러한 구성의 이름은 및 입니다. 디버그 구성에는 디버그 정보가 생성되고 최적화가 덜 이루어지고 편집 & 계속을 지원합니다.

하지만 시작일뿐입니다. 임의의 구성을 생성하고 모든 디버그 정보를 릴리스 구성에 추가 할 수도 있습니다. 따라서 명확한 Debug 또는 Release 빌드가 없습니다.

사전 처리기 기호 _DEBUG이 정의되었는지 확인할 수 있습니다. 이는 거의 변경되지 않고 버전 리소스에서 사용됩니다. FILEFLAGES 필드의 비트 0은 일반적으로 자원을 컴파일 할 때 _DEBUG 심볼이 정의되었음을 나타냅니다.

1

질문은 매우 좋으며 이미 언급 한 것처럼 이미지가 디버그 또는 해제되는지 여부를 나타내는 플래그는 없습니다.

여기에서 explainedhere의 경우 디버그 디렉토리의 존재 여부는 이미지가 릴리스 모드로 작성되었는지 여부를 나타내는 지표가 아닙니다. 릴리스 이미지은 디버그 지원을 통해 빌드됩니다. 사실상, 거의 모든 Windows OS 이미지 파일은 디버그 지원으로 구축됩니다 (그렇지 않으면이 릴리스 된 이미지를 Microsoft Symbols Server의 심볼 파일과 연결할 가능성이 없습니다). 이 이미지는 출시 이미지 임에도 불구하고!

.debug 섹션 (실제로 섹션 이름은 PE 사양에서 역할을하지 않습니다. 섹션 이름은 원하는대로 변경하고 설정할 수 있습니다. 로더는 신경 쓰지 않습니다!)는 릴리스 대 디버그 이미지의 표시자가 아닙니다.

1

LordPE라는 오래된 반전 도구가 있습니다. 그것은 당신이 두 파일을 열고 헤더를 diff 수 있습니다. 릴리스 및 디버그 모드에서 VS2008의 "hello world"프로그램을 컴파일하고 비교했습니다. 다른 포스터에서와 마찬가지로, 나는 지표 역할을 할 어떤 것도 보지 못했습니다.

그러나 내가 지표로 찾은 것은 이진 파일의 .text 섹션에서 패딩이었습니다. 디버그 버전의 .text 섹션에있는 코드의 마지막 바이트 다음에 0xCC 값이있는 백 바이트가 넘습니다. 릴리스 버전에는 0xCC 바이트가 없었습니다. 0xCC 바이트는 디버거에서 int3 또는 중단 점으로 표시됩니다.