# ObRegisterCallbacks

ObRegisterCallbacks는 쓰레드와 프로세스 핸들 작업에 대한 콜백 루틴을 등록할 수 있는 함수입니다.

콜백 루틴은 프로세스의 실행 전/후로 나누어 프리/포스트 콜백 두 종류가 있는데, 프리 콜백의 멤버변수인 POB\_PRE\_OPERATION\_INFORMATION 구조체의 안에서 ACCESS\_MASK는 생성될 핸들에 대해 요청된 접근 권한을 비트로 나타냅니다.

이 콜백 루틴은 프로세스를 보호하거나 숨기기 위한 용도로 사용되기도 하는데, 이때 보호하는 방법으로 생성될 핸들의 프로세스에 대한 권한(ACCESS\_MASK)을 확인하는 방법이 있습니다.

ObTypeIndexTable은 첫번째와 두번째 값을 제외하고 오프젝트 타입 구조체들의 포인터를 담고있는 테이블이며 7번째 인덱스의 구조체는 프로세스를 나타냅니다.

<div><figure><img src="/files/dIyjydqvIK1Pq4pvDELC" alt=""><figcaption></figcaption></figure> <figure><img src="/files/JdJqNikbo6IFtCst23XY" alt=""><figcaption></figcaption></figure></div>

CallbackList는 이중 연결 리스트의 자료 구조이며, 각 노드는 64바이트 크기의 CALLBACK\_ENTRY\_ITEM 구조체를 갖습니다.

```cpp
typedef struct _CALLBACK_ENTRY_ITEM {
    LIST_ENTRY EntryItemList; // 0x0
    OB_OPERATION Operations; // 0x10
    DWORD Active; // 0x14
    CALLBACK_ENTRY * CallbackEntry; //0x18
    PVOID ObjectType; //0x20
    POB_PRE_OPERATION_CALLBACK PreOperation; //0x28
    POB_POST_OPERATION_CALLBACK PostOperation; //0x30
    QWORD unk; //0x38
} CALLBACK_ENTRY_ITEM, * PCALLBACK_ENTRY_ITEM; //0x40
```

다음 사진에서 확인할 수 있듯이 각 노드는 앞/뒤 노드간의 연결을 위하여 노드 주소를 공유해야 합니다.&#x20;

<figure><img src="/files/X2IdoidMU1NPCWU6PqXF" alt=""><figcaption><p><a href="https://velog.io/@lsy000626/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%EC%A4%91-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8Doubly-Linked-List">https://velog.io/@lsy000626/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%EC%A4%91-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8Doubly-Linked-List</a></p></figcaption></figure>

때문에 위 사진에서 CallbackList 변수는 주소 범위를 갖고있는 것이며, 현재 상황에서는 노드가 1개이기 때문에 주소의 시작과 끝이 일치합니다.

<figure><img src="/files/5BJ0o1Tp2kDlmY5xJTHg" alt=""><figcaption></figcaption></figure>

사진 속 네모를 순서로 구조체에 대한 값이 나타나는데, 각 필드에 대한 설명은 다음과 같습니다.

* LIST\_ENTRY는 각각 두개의 주소값이 필요하기 때문에 16바이트를 차지하며, 노드가 1개인 상황이기 때문에 양 값이 같습니다.
* Active는 1로 설정되어 활성화 상태입니다.
* Operations는 3으로 설정되어 핸들 생성 및 복제에 대한 콜백 루틴임을 나타냅니다.
* PRE\_OPERATION\_CALLBACK은 프로세스 실행 전 콜백 함수 포인터 주소입니다.
* POST\_OPERATION\_CALLBACK은 설정되어 있지 않습니다.

{% hint style="info" %}
구조체의 OB\_OPERATION과 Active가 바이트에서 순서가 바뀌어 나온 이유는 리틀 엔디안 방식 때문입니다.
{% endhint %}

<figure><img src="/files/hzdAyA98yg4WCSMzyyAC" alt=""><figcaption></figcaption></figure>

현재 프리 콜백을 호출하는 주소가 어떤 드라이버에 속하는지 확인하기 위해 lm m 명령으로 확인하면 WdFilter(Windows Defender) 드라이버에서 호출하는 것이 확인됩니다.

목적은 디펜더에서 호출하는 프리 콜백 루틴을 무력화하는 것이기 때문에 `_CALLBACK_ENTRY_ITEM` 구조체의 Active 비트를 0으로 변경하면 됩니다.

<figure><img src="/files/Dg22pL4SR23QA8zk6jZK" alt=""><figcaption></figcaption></figure>

## References

{% embed url="<https://shhoya.github.io/antikernel_processprotect.html#--obregistercallbacks>" %}

{% embed url="<https://medium.com/@ashabdalhalim/a-light-on-windows-10s-object-header-typeindex-value-e8f907e7073a>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.pentestwiki.com/defense-evasion/undefined/obregistercallbacks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
