> For the complete documentation index, see [llms.txt](https://www.pentestwiki.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.pentestwiki.com/defense-evasion/undefined/cmregistercallbackex.md).

# CmRegisterCallbackEx

CmRegisterCallbackEx는 레지스트리 동작을 관리하기 위한 콜백 루틴을 등록할 때 사용하는 함수입니다.

해당 함수를 통해 레지스트리 기반 권한 상승 및 지속성 등록과 같은 행위를 미리 가로채어 차단하는 드라이버를 생성할 수 있고, Windows Defender에서 악성 레지스트리 등록을 방어하기 위해 사용하기도 합니다.

```cpp
EX_CALLBACK_FUNCTION RegistryCallback;

NTSTATUS RegistryCallback(
  _In_     PVOID CallbackContext,
  _In_opt_ PVOID Argument1,
  _In_opt_ PVOID Argument2
)
{ ... }
```

* CallbackContext : 드라이버가 레지스트리 콜백 루틴을 등록할 때 CmRegisterCallback 또는 CmRegisterCallbackEx의 Context 매개 변수로 전달한 값
* Argument 1 : 수행 중인 레지스트리 작업 유형 및 작업 전/후로 콜백 루틴이 호출되는지 여부를 식별하는 REG\_NOTIFY\_CLASS 형식의 값
* Argument 2 : 레지스트리 작업 유형과 관련된 정보를 포함하는 구조체에 대한 포인터. Argument1에 들어가는 매개 변수 REG\_NOTIFY\_CLASS 형식 값에 따라 달라지는 필드

Argument 1, 2는 연관된 만큼 미리 예약된 테이블이 존재하며, 그에 대한 자세한 정보는 [공식 문서](https://learn.microsoft.com/ko-kr/windows-hardware/drivers/ddi/wdm/nc-wdm-ex_callback_function)에서 더 확인할 수 있습니다.

함수의 return value(NT\_STATUS)에서 False가 반환되면, 구성 관리자는 레지스트리 명령 작업을 중지하고 콜백 루틴을 호출한 쓰레드에 값을 반환합니다.

시스템에서 레지스트리 콜백 루틴이 존재할 때 CMREG\_CALLBACK 구조체에 정보가 담기고, 모든 콜백 루틴을 연결 리스트 구조로 CallbackListHead라는 테이블에 저장합니다.

{% code title="CMREG\_CALLBACK 구조체" %}

```cpp
typedef struct _CMREG_CALLBACK {
    LIST_ENTRY List;
    ULONG Unknown1;
    ULONG Unknown2;
    LARGE_INTEGER Cookie;
    PVOID Unknown3;
    PEX_CALLBACK_FUNCTION Function;
} CMREG_CALLBACK, *PCMREG_CALLBACK;
```

{% endcode %}

## References

{% embed url="<https://blog.naver.com/rlfmalehd/220749232200>" %}

{% embed url="<https://learn.microsoft.com/ko-kr/windows-hardware/drivers/ddi/wdm/nc-wdm-ex_callback_function>" %}

{% embed url="<https://learn.microsoft.com/ko-kr/windows-hardware/drivers/ddi/wdm/ne-wdm-_reg_notify_class?redirectedfrom=MSDN>" %}
