유용한 정보

[MFC]XP 버전의 ActiveX를 Vista 이상버전으로 권한상승시키는 방법

DevReff 2024. 12. 26. 21:17




728x90
반응형

<< 프로젝트 만들기 >>

 

 

 

 

<< 프로젝트 속성 설정 >>

 

 

 

 

<< 클래스 추가 >>

 

 

Events 를 발생시킬 때 사용됨

 

 

 

 

<< 컨트롤을 제대로 로드하려면 IObjectSafety가 필요함 >>-.추가한 컨트롤의 헤더파일에서 IObjectSafety 를 사용가능하게 한다. 예를들면

class ATL_NO_VTABLE CDMWebAgentCtrl :

public CComObjectRootEx<CComSingleThreadModel>,

public IDispatchImpl<IDMWebAgentCtrl, &IID_IDMWebAgentCtrl, &LIBID_DMWebAgentLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,

public IPersistStreamInitImpl<CDMWebAgentCtrl>,

public IOleControlImpl<CDMWebAgentCtrl>,

public IOleObjectImpl<CDMWebAgentCtrl>,

public IOleInPlaceActiveObjectImpl<CDMWebAgentCtrl>,

public IViewObjectExImpl<CDMWebAgentCtrl>,

public IOleInPlaceObjectWindowlessImpl<CDMWebAgentCtrl>,

public ISupportErrorInfo,

public IConnectionPointContainerImpl<CDMWebAgentCtrl>,

public CProxy_IDMWebAgentCtrlEvents<CDMWebAgentCtrl>,

public IPersistStorageImpl<CDMWebAgentCtrl>,

public ISpecifyPropertyPagesImpl<CDMWebAgentCtrl>,

public IQuickActivateImpl<CDMWebAgentCtrl>,

#ifndef _WIN32_WCE

public IDataObjectImpl<CDMWebAgentCtrl>,

#endif

public IProvideClassInfo2Impl<&CLSID_DMWebAgentCtrl, &__uuidof(_IDMWebAgentCtrlEvents), &LIBID_DMWebAgentLib>,

//#ifdef _WIN32_WCE // 컨트롤을제대로로드하려면Windows CEIObjectSafety가필요합니다.

public IObjectSafetyImpl<CDMWebAgentCtrl, INTERFACESAFE_FOR_UNTRUSTED_CALLER>,

//#endif

public CComCoClass<CDMWebAgentCtrl, &CLSID_DMWebAgentCtrl>,

public CComControl<CDMWebAgentCtrl>

{

public:

 

 

CDMWebAgentCtrl()

{

}

 

DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE |

OLEMISC_INVISIBLEATRUNTIME |

OLEMISC_CANTLINKINSIDE |

OLEMISC_INSIDEOUT |

OLEMISC_ACTIVATEWHENVISIBLE |

OLEMISC_SETCLIENTSITEFIRST

)

 

DECLARE_REGISTRY_RESOURCEID(IDR_DMWEBAGENTCTRL)

 

 

BEGIN_COM_MAP(CDMWebAgentCtrl)

COM_INTERFACE_ENTRY(IDMWebAgentCtrl)

COM_INTERFACE_ENTRY(IDispatch)

COM_INTERFACE_ENTRY(IViewObjectEx)

COM_INTERFACE_ENTRY(IViewObject2)

COM_INTERFACE_ENTRY(IViewObject)

COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)

COM_INTERFACE_ENTRY(IOleInPlaceObject)

COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)

COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)

COM_INTERFACE_ENTRY(IOleControl)

COM_INTERFACE_ENTRY(IOleObject)

COM_INTERFACE_ENTRY(IPersistStreamInit)

COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)

COM_INTERFACE_ENTRY(ISupportErrorInfo)

COM_INTERFACE_ENTRY(IConnectionPointContainer)

COM_INTERFACE_ENTRY(ISpecifyPropertyPages)

COM_INTERFACE_ENTRY(IQuickActivate)

COM_INTERFACE_ENTRY(IPersistStorage)

#ifndef _WIN32_WCE

COM_INTERFACE_ENTRY(IDataObject)

#endif

COM_INTERFACE_ENTRY(IProvideClassInfo)

COM_INTERFACE_ENTRY(IProvideClassInfo2)

//#ifdef _WIN32_WCE // 컨트롤을제대로로드하려면Windows CEIObjectSafety가필요합니다.

COM_INTERFACE_ENTRY_IID(IID_IObjectSafety, IObjectSafety)

//#endif

END_COM_MAP()

 

 

<< 이벤트 추가 >>

 

 

 

 

 

 

 

 

 

 

예제)

// DMWebAgent.idl : DMWebAgentIDL 소스입니다.

//

 

// 이파일은MIDL 도구에의해처리되어

// 형식라이브러리(DMWebAgent.tlb) 및마샬링코드가생성됩니다.

 

#include "olectl.h"

import "oaidl.idl";

import "ocidl.idl";

 

[

object,

uuid(C80C705A-83A5-4A54-81D5-64CEC3DC4DCF),

dual,

nonextensible,

helpstring("IDMWebAgentCtrl 인터페이스"),

pointer_default(unique)

]

interface IDMWebAgentCtrl : IDispatch{

};

 

[

uuid(3E25C610-B32F-4950-9B1C-624FB92521B0),

version(1.0),

helpstring("DMWebAgent 1.0 형식라이브러리")

]

library DMWebAgentLib

{

importlib("stdole2.tlb");

[

uuid(61488909-2456-43A3-A7F6-9EA86878DEFA),

helpstring("_IDMWebAgentCtrlEvents Interface")

]

dispinterface _IDMWebAgentCtrlEvents

{

properties:

methods:

[id(1), helpstring("메서드CompleteTransfer")] void CompleteTransfer(void);

[id(2), helpstring("메서드SelectedUploadFile")] void SelectedUploadFile([in] BSTR bstrPathName, [in] LONG nFileSize);

};

[

uuid(0013EF30-C14F-4DD1-A9E4-A0C962AE43A1),

control,

helpstring("DMWebAgentCtrl Class")

]

coclass DMWebAgentCtrl

{

[default] interface IDMWebAgentCtrl;

[default, source] dispinterface _IDMWebAgentCtrlEvents;

};

};

 

 

#pragma once

 

template<class T>

class CProxy_IDMWebAgentCtrlEvents :

public IConnectionPointImpl<T, &__uuidof(_IDMWebAgentCtrlEvents)>

{

public:

 

void Fire_CompleteTransfer(void)

{

HRESULT hr = S_OK;

T * pThis = static_cast<T *>(this);

int cConnections = m_vec.GetSize();

 

for (int iConnection = 0; iConnection < cConnections; iConnection++)

{

pThis->Lock();

CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

pThis->Unlock();

 

IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

 

if (pConnection)

{

DISPPARAMS params = { NULL, NULL, 0, 0 };

hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

}

}

}

 

void Fire_SelectedUploadFile(BSTR bstrPathName, long nFileSize)

{

HRESULT hr = S_OK;

T * pThis = static_cast<T *>(this);

int cConnections = m_vec.GetSize();

 

for (int iConnection = 0; iConnection < cConnections; iConnection++)

{

pThis->Lock();

CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

pThis->Unlock();

 

IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

 

if (pConnection)

{

CComVariant avarParams[2];

avarParams[1] = bstrPathName; avarParams[1].vt = VT_BSTR;

avarParams[0] = nFileSize; avarParams[0].vt = VT_I4;

DISPPARAMS params = { avarParams, NULL, 2, 0 };

hr = pConnection->Invoke(2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

 

}

}

}

};

 

 

 

<< 권한상승을 위한 처리 >>1) 리소스에 다음 코드를 추가한다.A. #define APP_MANIFEST 1B. #define RT_MANIFEST 24 C. APP_MANIFEST RT_MANIFEST 화일명.확장자명.manifestD. Manifest 파일 내용

<?xml version="1.0" encoding="utf-8" ?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity version="1.0.0.0"

processorArchitecture="X86"

name="PrivilegedExe"

type="win32" />

<description>ActiveX Module</description>

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">

<security>

<requestedPrivileges>

<requestedExecutionLevel level="requireAdministrator" />

</requestedPrivileges>

</security>

</trustInfo>

</assembly>

 

2) ID 101 인 스트링 리소스가 있어야 한다.

 

3) 레지스트리 등록 파일(.rgs)에 다음과 같이 빨강색의 코드를 추가

HKCR

{

NoRemove AppID

{

'%APPID%' = s 'DMWebAgent'

{

val DllSurrogate = s ''

}

'DMWebAgent.DLL'

{

val AppID = s '%APPID%'

}

}

}

 

HKCR

{

DMWebAgent.DMWebAgentCtrl.1 = s 'DMWebAgentCtrl Class'

{

CLSID = s '{0013EF30-C14F-4DD1-A9E4-A0C962AE43A1}'

}

DMWebAgent.DMWebAgentCtrl = s 'DMWebAgentCtrl Class'

{

CLSID = s '{0013EF30-C14F-4DD1-A9E4-A0C962AE43A1}'

CurVer = s 'DMWebAgent.DMWebAgentCtrl.1'

}

NoRemove CLSID

{

ForceRemove {0013EF30-C14F-4DD1-A9E4-A0C962AE43A1} = s 'DMWebAgentCtrl Class'

{

ProgID = s 'DMWebAgent.DMWebAgentCtrl.1'

VersionIndependentProgID = s 'DMWebAgent.DMWebAgentCtrl'

ForceRemove 'Programmable'

InprocServer32 = s '%MODULE%'

{

val ThreadingModel = s 'Apartment'

}

val AppID = s '%APPID%'

Elevation

{

val Enabled = d 1

}

val LocalizedString = s '@%MODULE%,-101'

ForceRemove 'Control'

ForceRemove 'ToolboxBitmap32' = s '%MODULE%, 103'

'MiscStatus' = s '0'

{

'1' = s '%OLEMISC%'

}

'TypeLib' = s '{3E25C610-B32F-4950-9B1C-624FB92521B0}'

'Version' = s '1.0'

}

}

}

 

4) 제작된 ActiveX Object (Interface) 변수 (앞으로 ‘Obj변수라 함)Obj변수가 전역변수로 되어 있으면 비스타 이상에서는 윈도우 창이 바뀌어도 그 값이 계속 남아 있어서 새롭게 권한상승된 Object를 구하지 않고 기존의 Object를 사용한다.이로 인하여 Exe 파일에 다운로드해야할 파일의 정보가 전달되지 않는 문제가 발생한다.이를 해결하기 위해서는 전역변수로 사용하지 않고 클래스의 멤버변수로 선언을 하여 사용하여야 윈도우창이 바뀔때마다 새로운 Object를 구하게 되고 정상적으로 작동을 한다.

 

5) 1번과 2번의 수정 후의 리소스

 

 

 

 

 

 

 

<< 권한상승이 필요한 부분 >>1) 파일 및 폴더의 복사/삭제2) HKLM 레지스트리의 제어(등록/수정/삭제)3) 메세지 전송(SendMessage, PostMessage, ...)

 

출처: https://use1348.tistory.com/38 [유용한 정보:티스토리]