Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 8개 있습니다.)

ionescu007/lxss github repo에 공개된 lxssmanager.dll의 CLSID_LxssUserSession/IID_ILxssSession 사용법

아래의 글을 쓸 때까지만 해도,

Wslhub.Sdk 사용으로 알아보는 CoInitializeSecurity 사용 제약
; https://www.sysnet.pe.kr/2/0/12665

lxssmanager.dll에서 제공하는 CLSID_LxssUserSession/IID_ILxssSession COM 개체가 공개된 건 줄 알았습니다. ^^; 하지만, 비공개였고 그나마 찾은 자료는 github의 개인 repo였습니다.

ionescu007/lxss
; https://github.com/ionescu007/lxss

lxss/inc/lxssmanager.h
; https://github.com/ionescu007/lxss/blob/master/inc/lxssmanager.h

lxss/lxlaunch/lxlaunch.cpp
; https://github.com/ionescu007/lxss/blob/master/lxlaunch/lxlaunch.cpp

저 repo의 저작자는 나름의 역공학을 통해 그 결과를 공유해 주고 있는데요, 해당 자료를 COM 방식으로 정리하면 다음과 같이 요약될 수 있습니다.

#pragma once

#include <initguid.h>

DEFINE_GUID(CLSID_LxssManager, 0x4F476546, 0xB412, 0x4579, 0xB6, 0x4C, 0x12, 0x3D, 0xF3, 0x31, 0xE3, 0xD6);

typedef struct _LXSS_STD_HANDLE
{
    ULONG Handle;
    BOOLEAN Pipe;
} LXSS_STD_HANDLE, * PLXSS_STD_HANDLE;

typedef struct _LXSS_CONSOLE_DATA_V2
{
    ULONG ConsoleHandle;
} LXSS_CONSOLE_DATA_V2, * PLXSS_CONSOLE_DATA_V2;

typedef struct _LXSS_CONSOLE_DATA
{
    ULONG InputHandle;
    ULONG OutputHandle;
    ULONG ControlHandle;
    USHORT Width;
    USHORT Height;
} LXSS_CONSOLE_DATA, * PLXSS_CONSOLE_DATA;

typedef struct _LXSS_STD_HANDLES
{
    LXSS_STD_HANDLE StdIn;
    LXSS_STD_HANDLE StdOut;
    LXSS_STD_HANDLE StdErr;
} LXSS_STD_HANDLES, * PLXSS_STD_HANDLES;

interface ILxInstance;

MIDL_INTERFACE("536A6BCF-FE04-41D9-B978-DCACA9A9B5B9") ILxssSession : IUnknown
{
    STDMETHOD(GetCurrentInstance)(ILxInstance** pInstanceOut);
    STDMETHOD(StartDefaultInstance)(_In_ const IID& InstanceIid, _Out_ PVOID* InstanceOut);
    STDMETHOD(SetState)(/* unknown */);
    STDMETHOD(QueryState)(/* unknown */);
    STDMETHOD(InitializeFileSystem)(/* unknown */);
    STDMETHOD(Destroy)(/* unknown */);
};

MIDL_INTERFACE("8f9e8123-58d4-484a-ac25-7ef7d5f7448f") ILxInstance : IUnknown
{
    STDMETHOD(GetConfiguration)(/* unknown */);
    STDMETHOD(GetId)(/* unknown */);
    STDMETHOD(QueryState)(/* unknown */);
    STDMETHOD(SetState)(/* unknown */);
    STDMETHOD(CreateLxProcess)(_In_ PCCH CommandLine,
        _In_ ULONG ArgumentCount,
        _In_ PCCH* Arguments,
        _In_ ULONG EnvironmentCount,
        _In_ PCCH* Environment,
        _In_ PCCH CurrentDirectory,
        _In_ ULONG Flags,
        _In_ PLXSS_STD_HANDLES StdHandles,
        _In_ PLXSS_CONSOLE_DATA ConsoleData,
        _In_ ULONG Uid,
        _Out_ PULONG ProcessHandle);
    STDMETHOD(RegisterAdssBusServer)(_In_ PCCH ServerName, _Out_ PULONG ServerHandle);
    STDMETHOD(ConnectAdssBusServer)(/* unknown */);
    STDMETHOD(Destroy)(/* unknown */);
    STDMETHOD(GetState)(/* unknown */);
    STDMETHOD(StartSelf)(/* unknown */);
    STDMETHOD(StopSelf)(/* unknown */);
    STDMETHOD(GetSuspendState)(/* unknown */);
};

보는 바와 같이 저작자도 ILxssSession의 GetCurrentInstance, StartDefaultInstance 2개 함수와 ILxInstance의 CreateLxProcess, RegisterAdssBusServer 2개 함수에 대해서만 그 signature를 파악해낸 정도입니다.

어쨌든 이 정도만을 바탕으로 다음과 같이 테스트를 해볼 수 있는데,

#include <Windows.h>
#include <stdio.h>
#include "lxssmanager.h"

HRESULT OleMain();

int main()
{
    HRESULT hr = CoInitializeEx(nullptr, 0);
    if (hr != S_OK)
    {
        return 1;
    }

    hr = OleMain();

    CoUninitialize();

    return hr;
}

HRESULT OleMain()
{
    HRESULT hr = S_FALSE;

    hr = CoInitializeSecurity(nullptr,
        -1,
        nullptr,
        nullptr,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        nullptr,
        EOAC_STATIC_CLOAKING,
        nullptr);

    if (hr != S_OK)
    {
        return hr;
    }

    ILxssSession* pSession = nullptr;
    ILxInsanace* pInstance = nullptr;

    do
    {
        hr = CoCreateInstance(CLSID_LxssManager, nullptr, CLSCTX_LOCAL_SERVER, 
            __uuidof(ILxssSession), (PVOID*)&pSession);
        if (hr != S_OK)
        {
            break;
        }

        printf("pSession == %p\n", pSession);

        hr = pSession->GetCurrentInstance(&pInstance);
        printf("GetCurrentInstance hr == %d(0x%x)\n", hr, hr);

        // -2147024891 == 0x80070005 E_ACCESSDENIED (Access is denied.)
        // -2147024894 == 0x80070002 (The system cannot find the file specified.)
        // -2147024809 == 0x80070057 (The parameter is incorrect.)
        // -2147220734 == 0x80040302

        hr = pSession->StartDefaultInstance(__uuidof(ILxInstance), (PVOID *)&pInstance);
        printf("StartDefaultInstance hr == %d(0x%x)\n", hr, hr);

        if (hr != S_OK)
        {
            break;
        }

    } while (false);

    if (pSession != nullptr)
    {
        pSession->Release();
    }

    if (pInstance != nullptr)
    {
        pInstance->Release();
    }

    return hr;
}

그런데 실제로 실행을 해보면 GetCurrentInstance는 0x80070057(E_INVALIDARG)을 반환하고, StartDefaultInstance 호출은 Get으로 받아온 인스턴스가 유효하지 않은 탓도 있겠지만 아예 crash가 발생합니다.

Faulting application name: ConsoleApplication1.exe, version: 0.0.0.0, time stamp: 0x60c9fe1d
Faulting module name: ntdll.dll, version: 10.0.19041.1023, time stamp: 0x7977b9de
Exception code: 0xc0000005
Fault offset: 0x00000000000a3ef0
Faulting process id: 0x4300
Faulting application start time: 0x01d762b478547e8a
Faulting application path: C:\temp\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe
Faulting module path: C:\WINDOWS\SYSTEM32\ntdll.dll
Report Id: 7e85962d-3fa7-4bea-bd46-992aeee231e9
Faulting package full name: 
Faulting package-relative application ID: 

아마도 그때 당시에는 잘 동작했을지 모르겠지만 지금의 Windows 10에서는 오류가 발생하고 있습니다. 아쉽군요. ^^

(2023-10-20 업데이트) 해당 github의 저자가 작성한 코드도 참고해 보세요.

lxss/lxlaunch/lxlaunch.cpp
; https://github.com/ionescu007/lxss/blob/master/lxlaunch/lxlaunch.cpp


(첨부 파일은 이 글의 예제 코드를 포함합니다.)




이걸 테스트하면서 알게 된 사실이 하나 있는데요, 전에 CoInitializeSecurity가 다른 DLL을 로드하면서 자동 호출이 된다고 했었는데요,

별도 DLL에 포함된 타입을 STAThread Main 메서드에서 사용하는 경우 CoInitializeSecurity 자동 호출
; https://www.sysnet.pe.kr/2/0/12666

이와 유사하게 C++ 프로그램에서도 CoInitializeSecurity가 자동 호출되는 경우가 있었습니다. 재현은 다음과 같이 할 수 있는데요,

HRESULT hr = CoInitializeEx(nullptr, 0);

PVOID* pVoid;
hr = CoCreateInstance(CLSID_ShellDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown,
    (void**)&pVoid);

if (hr != S_OK)
{
    return;
}

hr = CoInitializeSecurity(nullptr,
    -1,
    nullptr,
    nullptr,
    RPC_C_AUTHN_LEVEL_DEFAULT,
    RPC_C_IMP_LEVEL_IMPERSONATE,
    nullptr,
    EOAC_STATIC_CLOAKING,
    nullptr);

// hr == 0x80010119 : Security must be initialized before any interfaces are marshalled or unmarshalled. It cannot be changed once initialized.
//       RPC_E_TOO_LATE (-2147417831) 

확실하게 파고들지는 않았지만, 아마도 CoCreateInstance 내부에서 호출이 되는 것 같습니다. 즉, CoInitializeEx를 호출했다고 하면 COM을 사용하겠다는 의도이고 그럼 당연히 개체 생성을 했을 것이므로 CoCreateInstance를 호출했을 것입니다.

결국 COM Apartment 초기화가 된 스레드를 사용한 응용 프로그램이 있다면 높은 확률로 CoInitializeSecurity API가 호출되었을 것입니다.




C# - CoCreateInstance 관련 Inteop 오류 정리
; https://www.sysnet.pe.kr/2/0/12678

Wslhub.Sdk 사용으로 알아보는 CoInitializeSecurity 사용 제약
; https://www.sysnet.pe.kr/2/0/12665

별도 DLL에 포함된 타입을 STAThread Main 메서드에서 사용하는 경우 CoInitializeSecurity 자동 호출
; https://www.sysnet.pe.kr/2/0/12666

COM+ 서버 응용 프로그램을 이용해 CoInitializeSecurity 제약 해결
; https://www.sysnet.pe.kr/2/0/12667

ionescu007/lxss github repo에 공개된 lxssmanager.dll의 CLSID_LxssUserSession/IID_ILxssSession 사용법
; https://www.sysnet.pe.kr/2/0/12676

역공학을 통한 lxssmanager.dll의 ILxssSession 사용법 분석
; https://www.sysnet.pe.kr/2/0/12677

C# - DLL Surrogate를 이용한 Out-of-process COM 개체 제작
; https://www.sysnet.pe.kr/2/0/12668

DLL Surrogate를 이용한 Out-of-process COM 개체에서의 CoInitializeSecurity 문제
; https://www.sysnet.pe.kr/2/0/12670

CoInitializeSecurity의 전역 설정을 재정의하는 CoSetProxyBlanket 함수 사용법
; https://www.sysnet.pe.kr/2/0/12679




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

[연관 글]






[최초 등록일: ]
[최종 수정일: 10/20/2023]

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

비밀번호

댓글 작성자
 




... 31  32  33  34  35  36  37  38  39  40  41  42  43  [44]  45  ...
NoWriterDateCnt.TitleFile(s)
12530정성태2/4/202113036개발 환경 구성: 536. Wireshark + C#으로 확인하는 TCP 통신의 Receive Window
12529정성태2/4/202110139개발 환경 구성: 535. Wireshark + C#으로 확인하는 TCP 통신의 MIN RTO [1]
12528정성태2/1/20219528개발 환경 구성: 534. Wireshark + C#으로 확인하는 TCP 통신의 MSS(Maximum Segment Size) - 윈도우 환경
12527정성태2/1/20219755개발 환경 구성: 533. Wireshark + C#으로 확인하는 TCP 통신의 MSS(Maximum Segment Size) - 리눅스 환경파일 다운로드1
12526정성태2/1/20217601개발 환경 구성: 532. Azure Devops의 파이프라인 빌드 시 snk 파일 다루는 방법 - Secure file
12525정성태2/1/20217302개발 환경 구성: 531. Azure Devops - 파이프라인 실행 시 빌드 이벤트를 생략하는 방법
12524정성태1/31/20218338개발 환경 구성: 530. 기존 github 프로젝트를 Azure Devops의 빌드 Pipeline에 연결하는 방법 [1]
12523정성태1/31/20218366개발 환경 구성: 529. 기존 github 프로젝트를 Azure Devops의 Board에 연결하는 방법
12522정성태1/31/20219870개발 환경 구성: 528. 오라클 클라우드의 리눅스 VM - 9000 MTU Jumbo Frame 테스트
12521정성태1/31/20219886개발 환경 구성: 527. 이더넷(Ethernet) 환경의 TCP 통신에서 MSS(Maximum Segment Size) 확인 [1]
12520정성태1/30/20218401개발 환경 구성: 526. 오라클 클라우드의 VM에 ping ICMP 여는 방법
12519정성태1/30/20217509개발 환경 구성: 525. 오라클 클라우드의 VM을 외부에서 접근하기 위해 포트 여는 방법
12518정성태1/30/202124947Linux: 37. Ubuntu에 Wireshark 설치 [2]
12517정성태1/30/202112541Linux: 36. 윈도우 클라이언트에서 X2Go를 이용한 원격 리눅스의 GUI 접속 - 우분투 20.04
12516정성태1/29/20219205Windows: 188. Windows - TCP default template 설정 방법
12515정성태1/28/202110418웹: 41. Microsoft Edge - localhost에 대해 http 접근 시 무조건 https로 바뀌는 문제 [3]
12514정성태1/28/202110722.NET Framework: 1021. C# - 일렉트론 닷넷(Electron.NET) 소개 [1]파일 다운로드1
12513정성태1/28/20218733오류 유형: 698. electronize - User Profile 디렉터리에 공백 문자가 있는 경우 빌드가 실패하는 문제 [1]
12512정성태1/28/20218522오류 유형: 697. The program can't start because VCRUNTIME140.dll is missing from your computer. Try reinstalling the program to fix this problem.
12511정성태1/27/20218260Windows: 187. Windows - 도스 시절의 8.3 경로를 알아내는 방법
12510정성태1/27/20218661.NET Framework: 1020. .NET Core Kestrel 호스팅 - Razor 지원 추가 [1]파일 다운로드1
12509정성태1/27/20219606개발 환경 구성: 524. Jupyter Notebook에서 C#(F#, PowerShell) 언어 사용을 위한 환경 구성 [3]
12508정성태1/27/20218203개발 환경 구성: 523. Jupyter Notebook - Slide 플레이 버튼이 없는 경우
12507정성태1/26/20218323VS.NET IDE: 157. Visual Studio - Syntax Visualizer 메뉴가 없는 경우
12506정성태1/25/202111599.NET Framework: 1019. Microsoft.Tye 기본 사용법 소개 [1]
12505정성태1/23/20219357.NET Framework: 1018. .NET Core Kestrel 호스팅 - Web API 추가 [1]파일 다운로드1
... 31  32  33  34  35  36  37  38  39  40  41  42  43  [44]  45  ...