CodeQL 및 정적 도구 로고 테스트
Microsoft는 Windows 운영 체제에 대한 공격 표면을 완화하기 위해 최선을 다하고 있으며, 타사 드라이버가 강력한 보안 표시줄을 충족하는지 확인하는 것은 해당 목표를 달성하는 데 매우 중요합니다. Microsoft에서 수행하는 이 보안 표시줄을 설정하는 한 단계는 Windows 하드웨어 호환성 프로그램(WHCP)에 새 요구 사항을 추가하는 것입니다. 이 요구 사항에 따르면 모든 드라이버 제출은 드라이버 소스 코드에서 CodeQL 엔진을 사용하고 "반드시 수정해야 함"으로 간주되는 위반을 수정해야 합니다.
codeQL은 GitHub 소프트웨어 보안을 위한 강력한 정적 분석 기술입니다. 가치가 높은 보안 쿼리의 광범위한 모음과 강력한 플랫폼의 조합으로 타사 드라이버 코드를 보호하는 데 매우 중요한 도구가 됩니다.
WHCP 테스트를 위한 CodeQL 사용은 HLK(하드웨어 랩 키트) 최종 사용자 사용권 계약에 따라 허용됩니다. WHCP 참가자의 경우 HLK의 EULA는 GitHub CodeQL 사용 약관을 덮어씁니다. HLK EULA는 WHCP의 일부로 제출 및 인증할 드라이버를 분석하기 위해 일반적인 엔지니어링 프로세스의 일부로 자동화된 분석, CI 또는 CD 중에 CodeQL을 사용할 수 있다고 명시하고 있습니다.
드라이버 소스 코드를 분석하고 "반드시 수정해야 하는" 위반을 수정하기 위한 요구 사항은 정적 도구 로고 테스트에 의해 적용됩니다.
이 항목에서는 이러한 방법에 대해 설명합니다.
- CodeQL을 사용하여 알려진 높은 영향 보안 문제에 대한 드라이버 소스 코드를 분석합니다.
- 정적 도구 로고 테스트가 CodeQL 실행 결과를 사용할 수 있는지 확인합니다.
- WHCP의 일부로 인증을 위해 오류 없이 실행해야 하는 "반드시 수정해야 하는" 쿼리를 결정합니다.
CodeQL에 대한 개념
CodeQL 은 개발자가 보안 분석을 수행하는 데 사용하는 분석 엔진입니다. CodeQL 데이터베이스는 다음을 포함하는 디렉터리입니다.
- 드라이버 소스 코드에서 추출된 쿼리 가능한 데이터입니다.
- 소스 코드에 직접 쿼리 결과를 표시하기 위한 소스 참조입니다. 쿼리는 "check" 또는 "rule"으로 간주할 수 있습니다. 각 쿼리는 검색되는 고유한 보안 취약성을 나타냅니다. 자세한 내용은 CodeQL 문서에서 쿼리 작성 을 참조하세요.
- 쿼리 결과
- 데이터베이스 만들기, 쿼리 실행 및 기타 작업 중에 생성된 로그 파일입니다.
이 항목에서는 Windows 위해 드라이버 개발자를 중심으로 CodeQL CLI(명령줄 인터페이스)를 사용하여 분석을 수행하는 방법을 자세히 설명합니다. 추가 설명서는 CodeQL 시작 찾을 수 있습니다.
CodeQL CLI(명령줄 도구)를 사용하여 다양한 컴파일 및 해석된 언어에서 CodeQL 데이터베이스를 만든 다음 드라이버별 쿼리 제품군을 사용하여 해당 데이터베이스를 분석합니다.
CodeQL Windows 설정
CodeQL 다운로드, 설치 및 테스트
첫 번째 작업은 CodeQL을 포함할 디렉터리를 만드는 것입니다. 이 예제에서는
C:\codeql-home\C:\> mkdir C:\codeql-homeMicrosoft QL 라이브러리의 원하는 분기와 함께 사용하는 데 필요한 CodeQL 도구 버전에 대한 Windows 드라이버 개발자 추가 도구를 참조하세요. 사용 가능한 분기를 보여 주는 테이블에 대한 드라이버별 쿼리에 액세스하려면 리포지토리 복제 를 참조하세요. 다른 버전을 사용하면 데이터베이스가 이러한 라이브러리와 호환되지 않을 수 있습니다.
필요한 릴리스에 대한 Github CodeQL 다운로드 페이지 로 이동합니다.
Windows 하드웨어 호환성 프로그램에 대한 드라이버를 인증하는 경우 zip 파일을 다운로드합니다. 예를 들어 64비트 Windows "codeql-win64.zip"입니다.
예를 들어
C:\codeql-home\codeql\zip 파일의 codeql 폴더를 디렉터리로 압축 해제합니다.도움말을 표시하여 CodeQL 명령이 작동하는지 확인합니다.
C:\codeql-home\codeql\>codeql --help Usage: codeql <command> <argument>... Create and query CodeQL databases, or work with the QL language. GitHub makes this program freely available for the analysis of open-source software and certain other uses, but it is not itself free software. Type codeql --license to see the license terms. --license Show the license terms for the CodeQL toolchain. Common options: -h, --help Show this help text. -v, --verbose Incrementally increase the number of progress messages printed. -q, --quiet Incrementally decrease the number of progress messages printed. Some advanced options have been hidden; try --help -v for a fuller view. Commands: query Compile and execute QL code. bqrs Get information from .bqrs files. database Create, analyze and process CodeQL databases. dataset [Plumbing] Work with raw QL datasets. test Execute QL unit tests. resolve [Deep plumbing] Helper commands to resolve disk locations etc. execute [Deep plumbing] Low-level commands that need special JVM options. version Show the version of the CodeQL toolchain. generate Generate formatted QL documentation.
리포지토리를 복제하여 드라이버별 쿼리에 액세스
Microsoft CodeQL GitHub 리포지토리로 이동합니다.
리포지토리를 복제하여 드라이버별 쿼리를 사용하여 모든 CodeQL 쿼리 및 쿼리 그룹을 다운로드합니다.
C:\codeql-home\>git clone https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools.git --recursive -b RELEASE_BRANCH
다음 표에 따라 인증하는 OS에 따라 RELEASE_BRANCH 적절한 분기로 바꿉니다.
| 해제 | 사용할 분기 |
|---|---|
| Windows Server 2022 | WHCP_21H2 |
| Windows 11 | WHCP_21H2 |
이미 리포지토리를 복제하고 다른 분기로 전환해야 하는 경우 리포지토리의 로컬 복사본에서 git fetch 및 git 체크 아웃을 실행하여 적절한 분기로 전환할 수 있습니다.
C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools>git fetch --all
C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools>git checkout RELEASE_BRANCH
참고
WHCP 테스트를 위한 CodeQL 사용은 HLK(하드웨어 랩 키트) 최종 사용자 사용권 계약에 따라 허용됩니다. WHCP 참가자의 경우 HLK의 EULA는 GitHub CodeQL 사용 약관을 덮어씁니다. HLK EULA는 WHCP의 일부로 제출 및 인증할 드라이버를 분석하기 위해 일반적인 엔지니어링 프로세스의 일부로 자동화된 분석, CI 또는 CD 중에 CodeQL을 사용할 수 있다고 명시하고 있습니다.
이 페이지에서는 Windows 개발 환경을 가정하고 리포지토리가 C:\codeql-home 아래에 설치된다고 가정합니다.
CodeQL 데이터베이스 빌드
다음 단계에서는 분석에 사용할 수 있는 CodeQL 데이터베이스를 만듭니다.
CodeQL 데이터베이스(데이터베이스 폴더)를 유지하는 디렉터리를 만듭니다. 이 예제에서는 C:\codeql-home\databases를 사용합니다.
mkdir C:\codeql-home\databases
일반적으로 CodeQL 데이터베이스를 만드는 데 사용되는 명령은 다음과 같습니다.
codeql database create -l=[cpp/csharp/python/java/javascript/go/xml] -s=<path to source code> -c=<command to build> <database folder>\<project name> -j 0
데이터베이스 만들기 명령을 사용하는 데 도움이 되도록 다음을 입력합니다.
codeql database create --help
이 예제에서 CodeQL은 MSBuild 컴파일러를 사용하여 C++ 코드를 처리하여 분석할 준비를 합니다.
참고
CodeQL은 MSBuild 또는 Visual Studio 사용할 필요가 없습니다. 지원되는 컴파일러 목록은 지원되는 랭거 및 프레임워크 를 참조하세요.
예
Enterprise Windows 드라이버 키트(EWDK)와 같은 드라이버 소스 코드를 빌드하는 데 사용되는 명령줄 환경을 사용하여 리포지토리가 복제된 CodeQL 도구 폴더로 이동합니다. Visual Studio 사용하여 드라이버를 빌드하는 경우 이 항목의 Visual Studio 빌드 후 이벤트에 설명된 대로 빌드 후 이벤트로 실행되도록 CodeQL 쿼리를 구성할 수 있습니다.
이 예제에서는 GitHub 사용할 수 있는 kmdfecho.sln 드라이버 샘플을 평가합니다. 아래 예제에서는 디렉터리에 kmdf 샘플을 C:\codeql-home\drivers\kmdf 배치합니다.
다음 명령을 실행하여 C:\codeql-home\databases\kmdf 아래에 새 CodeQL 데이터베이스를 만듭니다.
C:\codeql-home>C:\codeql-home\codeql\codeql.cmd database create -l=cpp -s=C:\codeql-home\drivers\kmdf -c "msbuild /t:rebuild "C:\codeql-home\drivers\kmdf\kmdfecho.sln" /p:UseSharedCompilation=false" "C:\codeql-home\databases\kmdf" -j 0
"-j 0" 플래그는 데이터베이스를 만드는 가져오기 단계에서 CPU만큼 많은 스레드를 사용했음을 나타냅니다.
이 예제에서는 이 인수를 사용하여 드라이버 프로젝트를 찾고 빌드합니다. msbuild 명령은 경로에서 사용할 수 있어야 합니다.
msbuild /t:rebuild "C:\codeql-home\drivers\kmdf\kmdfecho.sln"
디렉터리 위치 요약
예제 설정의 이 시점에서 다음 디렉터리를 표시합니다.
| Description | 위치 |
|---|---|
| Codeql.exe | C:\codeql-home\codeql\codeql |
| C++ 규칙 | C:\codeql-home\codeql\cpp |
| 데이터베이스 | C:\codeql-home\databases |
| 테스트 중인 드라이버 코드 | C:\codeql-home\drivers\kmdf |
| 드라이버별 쿼리를 사용하는 쿼리 도구 모음 | C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\windows-drivers\suites |
분석 수행
이 시점에서 설정이 완료되고 다음 단계는 드라이버 소스 코드에 대한 실제 분석을 수행하는 것입니다.
CodeQL CLI 도구는 이전 단계에서 만든 데이터베이스의 분석을 수행할 수 있으며 쿼리 또는 쿼리 제품군을 실행할 수 있습니다. 조사 결과는 CSV 또는 SARIF 형식의 출력으로 보고됩니다.
이 예제에서는 드라이버 소스 코드에서 실행할 쿼리 모음이 Microsoft CodeQL 리포지토리가 복제될 때 포함된 windows_driver_recommended.qls 제품군이라고 가정합니다.
분석을 실행하는 "데이터베이스 분석" 명령은 다음 구문을 사용합니다.
codeql database analyze <database> <path to query, suite or directory>
--search-path=<path to search for packages>
--format=[csv/sarif-latest/sarifv1/sarifv2/sarifv2.1.0/graphtext/dgml]
--output=<output file directory>\output file name>
-j 0
"-j 0" 플래그는 분석 부분에 CPU가 있는 만큼 많은 스레드를 사용했음을 나타냅니다.
매개 변수를 사용하여 codeql 데이터베이스 분석 명령에 대한 도움말을 표시합니다 --help .
C:\codeql-home\codeql>codeql database analyze --help
Usage: codeql database analyze [OPTIONS] <database> [<query|dir|suite>...]
Analyze a database, producing meaningful results in the context of the source code.
Run a query suite (or some individual queries) against a CodeQL database, producing results, styled as alerts or paths,
in SARIF or another interpreted format.
...
SARIF 형식으로 반환된 결과가 있는 kmdf 에코 드라이버에 대해 windows_driver_recommended.qls 쿼리 제품군을 평가하려면 아래 명령을 사용합니다. windows_driver_recommended.qls 쿼리 도구 모음은 Microsoft가 드라이버 개발자에게 유용하다고 판단한 모든 쿼리의 상위 집합입니다. 아래 의 "Query Suites" 섹션에서 쿼리 도구 모음 에 대해 자세히 알아보세요.
cd /d C:\codeql-home
c:\codeql-home\codeql\codeql.cmd database analyze "C:\codeql-home\databases\kmdf" windows_driver_recommended.qls --format=sarifv2.1.0 --output=C:\codeql-home\databases\kmdfecho1.sarif -j 0
다음과 유사한 출력이 표시 됩니다.
Running queries.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Best Practices\Likely Errors\OffsetUseBeforeRangeCheck.ql.
[1/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Best Practices\Likely Errors\OffsetUseBeforeRangeCheck.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Arithmetic\IntMultToLong.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Arithmetic\BadAdditionOverflowCheck.ql.
[2/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Arithmetic\BadAdditionOverflowCheck.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Arithmetic\SignedOverflowCheck.ql.
[3/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Arithmetic\IntMultToLong.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Conversion\CastArrayPointerArithmetic.ql.
[4/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Conversion\CastArrayPointerArithmetic.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Likely Typos\IncorrectNotOperatorUsage.ql.
[5/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Likely Typos\IncorrectNotOperatorUsage.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Memory Management\PointerOverflow.ql.
[6/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Arithmetic\SignedOverflowCheck.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Memory Management\SuspiciousSizeof.ql.
[7/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Memory Management\SuspiciousSizeof.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Memory Management\UninitializedLocal.ql.
[8/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Memory Management\PointerOverflow.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Underspecified Functions\TooFewArguments.ql.
[9/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Memory Management\UninitializedLocal.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-121\UnterminatedVarargsCall.ql.
[10/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Underspecified Functions\TooFewArguments.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-190\ComparisonWithWiderType.ql.
[11/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-121\UnterminatedVarargsCall.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-253\HResultBooleanConversion.ql.
[12/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-190\ComparisonWithWiderType.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-457\ConditionallyUninitializedVariable.ql.
[13/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-253\HResultBooleanConversion.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-468\IncorrectPointerScaling.ql.
[14/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-468\IncorrectPointerScaling.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-468\IncorrectPointerScalingVoid.ql.
[15/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-468\IncorrectPointerScalingVoid.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-468\SuspiciousAddWithSizeof.ql.
[16/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-468\SuspiciousAddWithSizeof.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-676\PotentiallyDangerousFunction.ql.
[17/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-676\PotentiallyDangerousFunction.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-704\WcharCharConversion.ql.
[18/22] Found in cache: C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-704\WcharCharConversion.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\windows-drivers\queries\Likely Bugs\Memory Management\UseAfterFree\ProbableUseAfterFree.ql.
[19/22 comp 1m39s] Compiled C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Security\CWE\CWE-457\ConditionallyUninitializedVariable.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\windows-drivers\queries\Likely Bugs\Memory Management\UseAfterFree\UseAfterFree.ql.
[20/22 comp 2m24s] Compiled C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\windows-drivers\queries\Likely Bugs\Memory Management\UseAfterFree\ProbableUseAfterFree.ql.
Compiling query plan for C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\windows-drivers\queries\Windows\wdk\wdk-deprecated-api.ql.
[21/22 comp 1m1s] Compiled C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\windows-drivers\queries\Likely Bugs\Memory Management\UseAfterFree\UseAfterFree.ql.
[22/22 comp 9.6s] Compiled C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\windows-drivers\queries\Windows\wdk\wdk-deprecated-api.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Arithmetic\BadAdditionOverflowCheck.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Memory Management\PointerOverflow.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Memory Management\SuspiciousSizeof.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Arithmetic\SignedOverflowCheck.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Likely Typos\IncorrectNotOperatorUsage.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Conversion\CastArrayPointerArithmetic.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Arithmetic\IntMultToLong.ql.
Starting evaluation of codeql-cpp\Best Practices\Likely Errors\OffsetUseBeforeRangeCheck.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Memory Management\UninitializedLocal.ql.
Starting evaluation of codeql-cpp\Likely Bugs\Underspecified Functions\TooFewArguments.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-121\UnterminatedVarargsCall.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-190\ComparisonWithWiderType.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-253\HResultBooleanConversion.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-468\IncorrectPointerScaling.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-468\IncorrectPointerScalingVoid.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-468\SuspiciousAddWithSizeof.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-676\PotentiallyDangerousFunction.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-704\WcharCharConversion.ql.
Starting evaluation of codeql-cpp\Security\CWE\CWE-457\ConditionallyUninitializedVariable.ql.
Starting evaluation of windows-drivers\queries\Likely Bugs\Memory Management\UseAfterFree\ProbableUseAfterFree.ql.
Starting evaluation of windows-drivers\queries\Likely Bugs\Memory Management\UseAfterFree\UseAfterFree.ql.
Starting evaluation of windows-drivers\queries\Windows\wdk\wdk-deprecated-api.ql.
[1/22 eval 16.1s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-676\PotentiallyDangerousFunction.bqrs.
[2/22 eval 16.3s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-704\WcharCharConversion.bqrs.
[3/22 eval 17.5s] Evaluation done; writing results to codeql-cpp\Best Practices\Likely Errors\OffsetUseBeforeRangeCheck.bqrs.
[4/22 eval 17.6s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Memory Management\SuspiciousSizeof.bqrs.
[5/22 eval 16.5s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-468\SuspiciousAddWithSizeof.bqrs.
[6/22 eval 17.6s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Arithmetic\BadAdditionOverflowCheck.bqrs.
[7/22 eval 17.7s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Likely Typos\IncorrectNotOperatorUsage.bqrs.
[8/22 eval 16.9s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-253\HResultBooleanConversion.bqrs.
[9/22 eval 18.5s] Evaluation done; writing results to windows-drivers\queries\Windows\wdk\wdk-deprecated-api.bqrs.
[10/22 eval 19.4s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Underspecified Functions\TooFewArguments.bqrs.
[11/22 eval 19.2s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-121\UnterminatedVarargsCall.bqrs.
[12/22 eval 23.4s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-468\IncorrectPointerScaling.bqrs.
[13/22 eval 23.2s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-468\IncorrectPointerScalingVoid.bqrs.
[14/22 eval 26.3s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Memory Management\UninitializedLocal.bqrs.
[15/22 eval 31.7s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Conversion\CastArrayPointerArithmetic.bqrs.
[16/22 eval 32s] Evaluation done; writing results to windows-drivers\queries\Likely Bugs\Memory Management\UseAfterFree\ProbableUseAfterFree.bqrs.
[17/22 eval 33.5s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Arithmetic\IntMultToLong.bqrs.
[18/22 eval 33.5s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-190\ComparisonWithWiderType.bqrs.
[19/22 eval 33.8s] Evaluation done; writing results to codeql-cpp\Security\CWE\CWE-457\ConditionallyUninitializedVariable.bqrs.
[20/22 eval 36.5s] Evaluation done; writing results to windows-drivers\queries\Likely Bugs\Memory Management\UseAfterFree\UseAfterFree.bqrs.
[21/22 eval 38.9s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Memory Management\PointerOverflow.bqrs.
[22/22 eval 46.1s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Arithmetic\SignedOverflowCheck.bqrs.
Shutting down query evaluator.
Interpreting results.
"–timeout=[seconds]" 플래그를 사용하여 전체 작업에 대한 시간 제한을 지정할 수 있습니다. 이는 장기 실행된 단일 쿼리로 제한되지 않고 쿼리를 분석하는 데 유용할 수 있습니다. 데이터베이스 분석에서 분석 최적화를 조정하는 추가 옵션에 대해 설명합니다.
Query Suites
Microsoft CodeQL GitHub 리포지토리의 일부로 Microsoft는 엔드투엔드 드라이버 개발자 워크플로를 간소화하기 위해 두 개의 쿼리 도구 모음을 제공했습니다. windows_driver_recommended.qls 쿼리 도구 모음에는 Microsoft가 드라이버 개발자에게 유용하다고 판단한 모든 쿼리의 상위 집합이 포함되어 있습니다.
windows_driver_mustfix.qls 쿼리 도구 모음에는 현재 WHCP 인증을 위해 "반드시 수정해야 함"으로 간주되는 쿼리가 포함되어 있습니다. Microsoft가 사용 가능한 쿼리 목록과 WHCP 인증에 필요한 "반드시 수정해야 하는" 쿼리 목록을 마무리함에 따라 이러한 두 쿼리 도구 모음이 정기적으로 업데이트됩니다. 따라서 "git pull" 명령을 사용하여 리포지토리를 정기적으로 동기화하는 것이 중요합니다.
문제 해결
데이터베이스 버전 불일치 문제의 경우 다음 도구가 유용할 수 있습니다.
codeql 버전 명령을 사용하여 codeql exe의 버전을 표시합니다.
C:\codeql-home\codeql\>codeql version
CodeQL command-line toolchain release 2.4.0.
Copyright (C) 2019-2020 GitHub, Inc.
Unpacked in: C:\codeql-home\codeql\
Analysis results depend critically on separately distributed query and
extractor modules. To list modules that are visible to the toolchain,
use 'codeql resolve qlpacks' and 'codeql resolve languages'.
데이터베이스 업그레이드 명령은 데이터베이스를 업데이트합니다. 이는 단방향 업그레이드이며 되돌릴 수 없다는 점에 유의하세요. 자세한 내용은 데이터베이스 업그레이드를 참조하세요.
쿼리
이 페이지는 WHCP 인증을 위해 공식적으로 "수정해야 함" 으로 간주되는 쿼리를 나타내도록 업데이트됩니다.
모든 드라이버 소스 코드에서 실행하기 위해 Microsoft에서 권장하는 쿼리는 다음과 같습니다.
| ID | 위치 | 공통 약점 열거형 |
|---|---|---|
| cpp/too-few-arguments | cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql | 해당 없음 |
| cpp/bad-addition-overflow-check | cpp/ql/src/Likely Bugs/Arithmetic/BadAdditionOverflowCheck.ql | CWE-190, CWE-192 |
| cpp/pointer-overflow-check | cpp/ql/src/Likely Bugs/Memory Management/PointerOverflow.ql | 해당 없음 |
| cpp/hresult-boolean-conversion | cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql | CWE-253 |
| cpp/incorrect-string-type-conversion | cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | CWE-704 |
| cpp/integer-multiplication-cast-to-long | cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql | CWE-190, CWE-192, CWE-197, CWE-681 |
| cpp/signed-overflow-check | cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql | 해당 없음 |
| cpp/upcast-array-pointer-arithmetic | cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql | CWE-119, CWE-843 |
| cpp/comparison-with-wider-type | cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql | CWE-190, CWE-197, CWE-835 |
| cpp/suspicious-add-sizeof | cpp/ql/src/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql | CWE-468 |
| cpp/잠재적으로 위험한 함수 | cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql | CWE-676 |
| cpp/incorrect-not-operator-usage | cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql | CWE-480 |
| cpp/offset-use-before-range-check | cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql | 해당 없음 |
| cpp/suspicious-add-sizeof | cpp/ql/src/Likely Bugs/Memory Management/SuspiciousSizeof.ql | CWE-468 |
| cpp/uninitialized-local | cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql | CWE-457, CWE-665 |
| cpp/unterminated-variadic-call | cpp/ql/src/Security/CWE/CWE-121/UnterminatedVarargsCall.ql | CWE-121 |
| cpp/suspicious-pointer-scaling | cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql | CWE-468 |
| cpp/suspicious-pointer-scaling-void | cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScalingVoid.ql | CWE-468 |
| cpp/conditionally-uninitialized-variable | cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql. | CWE-457 |
| cpp/use-after-free | Windows-Driver-Developer-Supplemental-Tools/codeql/windows-drivers/queries/Likely Bugs/Memory Management/UseAfterFree\UseAfterFree.ql | 해당 없음 |
| cpp/windows/wdk/deprecated-api | Windows-Driver-Developer-Supplemental-Tools/codeql/windows-drivers/queries/Windows/wdk/wdk-deprecated-api.ql | 해당 없음 |
| 가능한 버그/경계 위반/PaddingByteInformationDisclosure.ql | Windows-Driver-Developer-Supplemental-Tools/codeql/windows-drivers/queries/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.ql | 해당 없음 |
| 가능한 버그/변환/BadOverflowGuard.ql | Windows-Driver-Developer-Supplemental-Tools/codeql/windows-drivers/queries/Likely Bugs/Conversion/BadOverflowGuard.ql | 해당 없음 |
| 가능한 버그/변환/InfiniteLoop.ql | Windows-Driver-Developer-Supplemental-Tools/codeql/windows-drivers/queries/Likely Bugs/Conversion/InfiniteLoop.ql | 해당 없음 |
| 가능성이 있는 버그/UninitializedPtrField.ql | Windows-Driver-Developer-Supplemental-Tools/codeql/windows-drivers/queries/Likely Bugs/UninitializedPtrField.ql | 해당 없음 |
| cpp/Security/Cryptography/HardcodedIVCNG.ql | Windows-Driver-Developer-Supplemental-Tools/codeql/windows-drivers/queries/Security/Crytpography/HardcodedIVCNG.ql | 해당 없음 |
이러한 쿼리는 Microsoft GitHub CodeQL 리포지토리의 windows_driver_recommended.qls 쿼리 도구 모음의 일부입니다. "CWE(Common Weakness Enumeration)" 열은 지정된 쿼리에서 검색하는 보안 문제의 종류를 지정합니다. CWE에 대한 자세한 내용은 CWE의 Mitre 페이지를 참조하세요.
Must-Fix 쿼리
아래 쿼리의 하위 집합은 현재 WHCP 인증을 위해 "수정해야 함" 으로 간주됩니다.
| ID | 위치 | 일반적인 약점 열거형 |
|---|---|---|
| cpp/too-few-arguments | cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql | 해당 없음 |
| cpp/bad-addition-overflow-check | cpp/ql/src/Likely Bugs/Arithmetic/BadAdditionOverflowCheck.ql | CWE-190, CWE-192 |
| cpp/pointer-overflow-check | cpp/ql/src/Likely Bugs/Memory Management/PointerOverflow.ql | 해당 없음 |
| cpp/hresult-boolean-conversion | cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql | CWE-253 |
| cpp/incorrect-string-type-conversion | cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | CWE-704 |
| cpp/comparison-with-wider-type | cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql | CWE-190, CWE-197, CWE-835 |
| cpp/windows/wdk/deprecated-api | Windows-Driver-Developer-Supplemental-Tools/codeql/windows-drivers/queries/Windows/wdk/wdk-deprecated-api.ql | 해당 없음 |
이러한 쿼리는 Microsoft GitHub CodeQL 리포지토리의 windows_driver_mustfix.qls 쿼리 도구 모음의 일부입니다.
분석 보기
이전 섹션에서 분석 명령을 실행한 결과를 SARIF 파일 형식으로 볼 수 있습니다. SARIF 출력에 대한 자세한 내용은 SARIF 출력에서 확인할 수 있습니다. SARIF 표준에 대한 정보는 OASIS SARIF(정적 분석 결과 교환 형식)에서 확인할 수 있습니다.
SARIF 파일에는 실행된 각 쿼리에 대한 결과 섹션이 포함되어 있으며 완료된 분석에 대한 세부 정보가 포함됩니다. 예를 들어 쿼리에서 취약성을 발견한 경우 SARIF 파일에는 취약성의 정의 및 결함을 발견한 위치에 대한 세부 정보가 포함됩니다. 취약성이 없으면 결과 섹션이 비어 있습니다.
"results" : [ ],
결과를 검토하려면 Visual Studio Microsoft SARIF 뷰어를 설치하고 해당 페이지의 지침을 따릅니다. 또는 Visual Studio Code 위해 SARIF 확장을 설치할 수 있습니다.
참고
정적 도구 로고 테스트를 사용하여 인증하는 드라이버에 대해 쿼리의 "오류", "경고" 또는 "문제" 분류는 무시해야 합니다 . "Must-Fix"로 표시된 쿼리의 결함이 있는 드라이버는 원시 쿼리 파일의 쿼리 분류에 관계없이 정적 도구 로고 테스트를 통과하지 않습니다(예: "warning").
DVL(드라이버 확인 로그) SARIF 출력 사용량
Microsoft는 정적 도구 로고 테스트를 사용하여 CodeQL 쿼리를 실행해야 한다는 요구 사항을 적용합니다. 정적 도구 로고 테스트는 DVL(드라이버 확인 로그)을 사용하여 드라이버 소스 코드에서 실행되는 다양한 정적 분석의 결과를 수집합니다. 그런 다음, 이 DVL은 HLK 테스트에 사용되는 정적 도구 로고 테스트의 일부로 구문 분석됩니다.
CodeQL 결과는 DVL을 사용하는 동일한 모델을 따라 인증되는 드라이버가 인증을 위해 HLK 테스트를 통과하기 위해 적절한 CodeQL 쿼리를 실행했음을 보여 줍니다.
.sarif 파일을 DVL이 생성되는 .vcxproj 파일과 동일한 디렉터리에 배치합니다. 파일이 ".sarif"로 끝나는 한 결과 파일의 정확한 이름은 중요하지 않습니다. SARIF 결과 파일을 제출하는 기능은 WDK, 미리 보기 빌드 20190 이상에서 사용할 수 있습니다.
DVL을 생성하는 방법에 대한 지침은 드라이버 확인 로그 만들기에서 찾을 수 있습니다. 정적 도구 로고 HLK 테스트에서 사용할 DVL을 배치할 위치에 대한 지침은 테스트 실행에서 찾을 수 있습니다.
빌드 후 이벤트 Visual Studio
Visual Studio 사용하여 드라이버를 빌드하는 경우 빌드 후 이벤트로 실행되도록 CodeQL 쿼리를 구성할 수 있습니다.
이 예제에서는 작은 일괄 처리 파일이 대상 위치에 만들어지고 빌드 후 이벤트로 호출됩니다. Visual Studio C++ 빌드 이벤트에 대한 자세한 내용은 빌드 이벤트 지정을 참조하세요.
CodeQL 데이터베이스를 다시 만든 다음 해당 최신 데이터베이스를 사용하여 원하는 쿼리를 실행하는 작은 일괄 처리 파일을 만듭니다. 이 예제에서는 일괄 처리 파일의 이름을 지정
RunCodeQLRebuildQuery.bat합니다. 디렉터리 위치와 일치하도록 예제 일괄 처리 파일에 표시된 경로를 수정합니다.ECHO ">>> Running CodeQL Security Rule V 1.0 <<<" ECHO ">>> Removing previously created rules database <<<" rmdir /s/q C:\codeql-home\databases\kmdf CALL C:\codeql-home\codeql\codeql\codeql.cmd database create -l=cpp -s="C:\codeql-home\drivers\kmdf" -c "msbuild /p:Configuration=Release /p:Platform=x64 C:\codeql-home\drivers\kmdf\kmdfecho.sln /t:rebuild /p:PostBuildEventUseInBuild=false " "C:\codeql-home\databases\kmdf" -j 0 CALL C:\codeql-home\codeql\codeql\codeql database analyze "C:\codeql-home\databases\kmdf" "C:\codeql-home\Windows-Driver-Developer-Supplemental-Tools\codeql\codeql-queries\cpp\ql\src\Likely Bugs\Underspecified Functions" --format=sarifv2.1.0 --output=C:\codeql-home\databases\kmdf.sarif -j 0 --rerun ECHO ">>> Loading SARIF Results in Visual Studio <<<" CALL devenv /Edit C:\codeql-home\databases\kmdf.sarif SET ERRORLEVEL = 0devenv.exe/편집 옵션은 배치 파일에서 기존 Visual Studio 인스턴스에서 SARIF 결과 파일을 여는 데 사용됩니다. SARIF 결과를 보려면 Visual Studio Microsoft SARIF 뷰어를 설치합니다. 자세한 내용은 해당 페이지의 지침을 참조하세요.
드라이버 프로젝트에서 프로젝트 속성으로 이동합니다. 구성 풀다운에서 CodeQL로 확인하려는 빌드 구성을 선택합니다. 예를 들어 릴리스 구성에 대한 예입니다. CodeQL 데이터베이스를 만들고 쿼리를 실행하는 데 몇 분 정도 걸리므로 프로젝트의 디버그 구성에서 CodeQL을 실행하지 않기로 결정할 수 있습니다.
드라이버 프로젝트 속성에서 빌드 이벤트 및 빌드 후 이벤트를 선택합니다.
일괄 처리 파일의 경로와 빌드 후 이벤트에 대한 설명을 제공합니다.

프로젝트가 빌드될 때 빌드 출력이 끝날 때 실행 중인 일괄 처리 파일의 결과가 표시됩니다.
... 1>Starting evaluation of codeql-cpp\Likely Bugs\Underspecified Functions\MistypedFunctionArguments.ql. 1>Starting evaluation of codeql-cpp\Likely Bugs\Underspecified Functions\TooManyArguments.ql. 1>Starting evaluation of codeql-cpp\Likely Bugs\Underspecified Functions\TooFewArguments.ql. 1>Starting evaluation of codeql-cpp\Likely Bugs\Underspecified Functions\ImplicitFunctionDeclaration.ql. 1>[1/4 eval 4.4s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Underspecified Functions\TooManyArguments.bqrs. 1>[2/4 eval 4.4s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Underspecified Functions\TooFewArguments.bqrs. 1>[3/4 eval 4.5s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Underspecified Functions\ImplicitFunctionDeclaration.bqrs. 1>[4/4 eval 5.2s] Evaluation done; writing results to codeql-cpp\Likely Bugs\Underspecified Functions\MistypedFunctionArguments.bqrs. 1>Shutting down query evaluator. 1>Interpreting results. 1>">>> Loading SARIF Results in Visual Studio <<<"SARIF 파일 결과를 검토하고 식별된 문제를 해결하는 작업을 수행합니다. 자세한 내용은 이 항목의 앞부 분에 있는 분석 보기를 참조하세요.
질문과 대답(FAQ)
디바이스 인증에 필요한 시기는 언제인가요?
이 요구 사항이 적용되는 시기에 대한 자세한 내용은 최신 WHCP 요구 사항을 참조하세요.
드라이버 소스 코드에서 CodeQL을 실행하도록 요구하는 동기는 무엇인가요?
CodeQL을 드라이버 소스 코드에서 실행하도록 요구하는 동기는 다음 두 가지 주요 이유로 요약할 수 있습니다.
- Windows 보안이 가장 중요합니다. 드라이버 소스 코드에서 CodeQL을 실행하도록 요구하는 것은 Microsoft에서 인증을 받은 구성 요소의 보안을 개선하는 데 도움이 되는 한 단계입니다.
- CodeQL은 Microsoft에서 보안 결함을 찾는 데 사용되며 CodeQL 쿼리는 Microsoft의 보안 엔지니어가 적극적으로 개발합니다. Microsoft는 Microsoft에서 사용되는 것과 동일한 고품질 도구에서 하드웨어 에코시스템의 이점을 보장하기 위해 최선을 다하고 있습니다.
드라이버 개발자를 위한 CodeQL 사용을 제어하는 라이선스는 무엇인가요?
WHCP 테스트를 위한 CodeQL 사용은 HLK(하드웨어 랩 키트) 최종 사용자 사용권 계약에 따라 허용됩니다. WHCP 참가자의 경우 HLK의 EULA는 GitHub CodeQL 사용 약관을 덮어씁니다. HLK EULA는 WHCP의 일부로 제출 및 인증할 드라이버를 분석하기 위한 일반적인 엔지니어링 프로세스의 일부로 자동화된 분석, CI 또는 CD 중에 CodeQL을 사용할 수 있다고 명시하고 있습니다.
codeQL을 실행하려면 Visual Studio 또는 msbuild를 사용해야 하나요?
CodeQL은 MSBuild 또는 Visual Studio 사용할 필요가 없습니다. 지원되는 컴파일러 목록은 지원되는 랭거 및 프레임워크 를 참조하세요.
HLK는 CodeQL에서 내 드라이버를 스캔했는지 어떻게 확인하나요?
HLK의 정적 도구 로고 테스트는 이 요구 사항을 적용하는 테스트입니다. 정적 도구 로고 테스트를 통과하는 방법에 대한 자세한 내용은 MS 문서 페이지에서 찾을 수 있습니다.
CodeQL에서 모든 결함을 보고합니까?
모든 CodeQL 쿼리의 전체 자릿수는 다양합니다. 목표는 가양성 최소화이지만 정의에 따라 발생합니다. 광범위한 테스트 후 거의 0개의 거짓 긍정이 관찰되었기 때문에 "반드시 수정해야 하는" 쿼리 집합이 직접 선택되었습니다. "반드시 수정해야 하는" 쿼리 집합의 쿼리에서 가양성 표시가 표시되면 즉시 이메일을 보내 stlogohelp@microsoft.com 세요.
정적 도구 로고 테스트를 위해 쿼리의 "경고" 또는 "오류" 분류가 중요합니까?
정적 도구 로고 테스트를 사용하여 인증하는 드라이버에 대해 쿼리의 "오류", "경고" 또는 "문제" 분류는 무시해야 합니다 . "Must-Fix"로 표시된 쿼리에서 결함이 있는 드라이버는 원시 쿼리 파일의 쿼리 분류에 관계없이 정적 도구 로고 테스트를 통과하지 않습니다(예: "warning").
Visual Studio 솔루션에서 DVL을 생성할 수 있나요?
아니요, DVL 생성은 프로젝트 수준에서 실행되어야 하며 Visual Studio 솔루션에서 실행할 수 없습니다. DVL을 생성하는 방법에 대한 지침은 드라이버 확인 로그 만들기에서 찾을 수 있습니다.
msbuild 또는 Visual Studio 컨텍스트 외부에서 DVL(드라이버 확인 로그)을 생성할 수 있나요?
Microsoft는 WINDOWS 드라이버 키트(WDK)의 일부로 제공하고 Enterprise WDK(eWDK)는 DVL(드라이버 확인 로그)을 생성하는 데 사용할 수 있는dvl.exe라는 구성 요소를 제공합니다. WDK/eWDK 미리 보기 버전 21342 이상부터 드라이버 이름 및 아키텍처를 전달하여 msbuild 또는 Visual Studio 컨텍스트 외부에서 명령줄에서 DVL을 생성할 수 있습니다. 자세한 내용은 드라이버 확인 로그 만들기 를 참조하세요.
드라이버에서 CodeQL을 사용하는 방법에 대한 의견이나 질문이 있습니다. 피드백을 보낼 수 있는 위치는 어디인가요?
에 모든 피드백 및 질문을 보냅니다 stlogohelp@microsoft.com.