Skip to content

Commit ba5fc34

Browse files
committed
Display class driver extension callbacks (disk.sys and so on);
WDbgArkClassDrvObjHelper class implemented;
1 parent 92f25f7 commit ba5fc34

File tree

5 files changed

+533
-49
lines changed

5 files changed

+533
-49
lines changed

src/analyze.cpp

Lines changed: 197 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,15 +179,15 @@ void WDbgArkAnalyzeBase::PrintObjectDmlCmd(const ExtRemoteTyped &object) {
179179
std::stringstream object_command;
180180

181181
try {
182-
const auto [type, cmd_start, cmd_end] = m_object_dml_cmd.at(object_type_name);
183-
object_command << type << std::hex << std::showbase << object.m_Offset;
184-
object_command << cmd_start << std::hex << std::showbase << object.m_Offset << cmd_end;
182+
const auto [cmd_start_open, cmd_start_close, cmd_end] = m_object_dml_cmd.at(object_type_name);
183+
object_command << cmd_start_open << std::hex << std::showbase << object.m_Offset;
184+
object_command << cmd_start_close << std::hex << std::showbase << object.m_Offset << cmd_end;
185185
} catch ( const std::out_of_range& ) {
186186
__noop;
187187
}
188188

189189
if ( object_command.str().empty() ) {
190-
object_command << "<exec cmd=\"!object " << std::hex << std::showbase << object.m_Offset << "\">";
190+
object_command << R"(<exec cmd="!object )" << std::hex << std::showbase << object.m_Offset << R"(">)";
191191
object_command << std::hex << std::showbase << object.m_Offset << "0x39 </exec>";
192192
}
193193

@@ -594,15 +594,26 @@ void WDbgArkAnalyzeDriver::Analyze(const ExtRemoteTyped &object) {
594594
AddTempWhiteList(name);
595595
}
596596

597+
auto driver_extension = loc_object.Field("DriverExtension");
598+
599+
if ( driver_extension.GetPtr() ) {
600+
auto key_name = driver_extension.Field("ServiceKeyName");
601+
const auto [result_service, sevice_name] = UnicodeStringStructToString(key_name);
602+
603+
if ( SUCCEEDED(result_service) ) {
604+
wout << wa::showplus<wchar_t> << L"ServiceKeyName: " << sevice_name << endlout<wchar_t>;
605+
}
606+
}
607+
597608
out << wa::showplus << "Driver routines: " << endlout;
598609
PrintFooter();
599610

600611
display->Analyze(loc_object.Field("DriverInit").GetPtr(), "DriverInit", "");
601612
display->Analyze(loc_object.Field("DriverStartIo").GetPtr(), "DriverStartIo", "");
602613
display->Analyze(loc_object.Field("DriverUnload").GetPtr(), "DriverUnload", "");
603614

604-
if ( loc_object.Field("DriverExtension").GetPtr() ) {
605-
display->Analyze(loc_object.Field("DriverExtension").Field("AddDevice").GetPtr(), "AddDevice", "");
615+
if ( driver_extension.GetPtr() ) {
616+
display->Analyze(driver_extension.Field("AddDevice").GetPtr(), "AddDevice", "");
606617
}
607618

608619
PrintFooter();
@@ -615,8 +626,12 @@ void WDbgArkAnalyzeDriver::Analyze(const ExtRemoteTyped &object) {
615626

616627
// display FsFilterCallbacks
617628
DisplayFsFilterCallbacks(object);
618-
}
619-
catch(const ExtRemoteException &Ex) {
629+
630+
// display classpnp routines
631+
DisplayClassCallbacks(object);
632+
} catch ( const ExtRemoteException &Ex ) {
633+
err << wa::showminus << __FUNCTION__ << ": " << Ex.GetMessage() << endlerr;
634+
} catch ( const ExtException &Ex ) {
620635
err << wa::showminus << __FUNCTION__ << ": " << Ex.GetMessage() << endlerr;
621636
}
622637

@@ -672,6 +687,180 @@ void WDbgArkAnalyzeDriver::DisplayFsFilterCallbacks(const ExtRemoteTyped &object
672687
PrintFooter();
673688
}
674689
}
690+
691+
/*
692+
driverExtension = IoGetDriverObjectExtension(DriverObject, CLASS_DRIVER_EXTENSION_KEY);
693+
#define CLASS_DRIVER_EXTENSION_KEY ((PVOID) ClassInitialize)
694+
695+
NTKERNELAPI
696+
PVOID
697+
IoGetDriverObjectExtension(
698+
IN PDRIVER_OBJECT DriverObject,
699+
IN PVOID ClientIdentificationAddress
700+
)
701+
702+
Routine Description:
703+
704+
This routine returns a pointer to the client driver object extension.
705+
This extension was allocated using IoAllocateDriverObjectExtension. If
706+
an extension with the create Id does not exist for the specified driver
707+
object then NULL is returned.
708+
709+
Arguments:
710+
711+
DriverObject - Pointer to driver object owning the extension.
712+
713+
ClientIdentificationAddress - Supplies the unique identifier which was
714+
used to create the extension.
715+
716+
Return Value:
717+
718+
The function value is a pointer to the client driver object extension,
719+
or NULL.
720+
--
721+
722+
{
723+
KIRQL irql;
724+
PIO_CLIENT_EXTENSION extension;
725+
726+
irql = KeAcquireQueuedSpinLock( LockQueueIoDatabaseLock );
727+
extension = DriverObject->DriverExtension->ClientDriverExtension;
728+
while (extension != NULL) {
729+
730+
if (extension->ClientIdentificationAddress == ClientIdentificationAddress) {
731+
break;
732+
}
733+
734+
extension = extension->NextExtension;
735+
}
736+
737+
KeReleaseQueuedSpinLock( LockQueueIoDatabaseLock, irql );
738+
739+
if (extension == NULL) {
740+
return NULL;
741+
}
742+
743+
return extension + 1;
744+
}
745+
*/
746+
747+
void WDbgArkAnalyzeDriver::DisplayClassCallbacks(const ExtRemoteTyped &object) {
748+
WDbgArkAnalyzeBase* display = this;
749+
750+
WDbgArkClassDrvObjHelper class_ext(m_sym_cache, object);
751+
752+
if ( !class_ext.HasClassDriverExtension() ) {
753+
return;
754+
}
755+
756+
*this << class_ext.GetClassExtensionDmlCommand(); // display DML command for Class Driver Extension
757+
FlushOut();
758+
PrintFooter();
759+
760+
AddTempWhiteList("classpnp");
761+
762+
out << wa::showplus << "Class Driver extension routines: " << endlout;
763+
PrintFooter();
764+
765+
display->Analyze(class_ext.Field("ClassFdoQueryWmiRegInfoEx").GetPtr(), "ClassFdoQueryWmiRegInfoEx", "");
766+
display->Analyze(class_ext.Field("ClassPdoQueryWmiRegInfoEx").GetPtr(), "ClassPdoQueryWmiRegInfoEx", "");
767+
PrintFooter();
768+
769+
const auto init_data = class_ext.GetInitDataTable();
770+
771+
if ( !init_data.empty() ) {
772+
out << wa::showplus << "Class Driver extension InitData routines: " << endlout;
773+
PrintFooter();
774+
775+
for ( const auto [address, type] : init_data ) {
776+
display->Analyze(address, type, "");
777+
}
778+
779+
PrintFooter();
780+
}
781+
782+
// FDO
783+
const auto init_data_fdo = class_ext.GetInitDataFdoDataTable();
784+
785+
if ( !init_data_fdo.empty() ) {
786+
out << wa::showplus << "Class Driver extension InitData.FdoData routines: " << endlout;
787+
PrintFooter();
788+
789+
for ( const auto [address, type] : init_data_fdo ) {
790+
display->Analyze(address, type, "");
791+
}
792+
793+
PrintFooter();
794+
}
795+
796+
const auto init_data_fdo_wmi = class_ext.GetInitDataFdoDataWmiTable();
797+
798+
if ( !init_data_fdo_wmi.empty() ) {
799+
out << wa::showplus << "Class Driver extension InitData.FdoData.ClassWmiInfo routines: " << endlout;
800+
PrintFooter();
801+
802+
for ( const auto [address, type] : init_data_fdo_wmi ) {
803+
display->Analyze(address, type, "");
804+
}
805+
806+
PrintFooter();
807+
}
808+
809+
// PDO
810+
const auto init_data_pdo = class_ext.GetInitDataPdoDataTable();
811+
812+
if ( !init_data_pdo.empty() ) {
813+
out << wa::showplus << "Class Driver extension InitData.PdoData routines: " << endlout;
814+
PrintFooter();
815+
816+
for ( const auto [address, type] : init_data_pdo ) {
817+
display->Analyze(address, type, "");
818+
}
819+
820+
PrintFooter();
821+
}
822+
823+
const auto init_data_pdo_wmi = class_ext.GetInitDataPdoDataWmiTable();
824+
825+
if ( !init_data_pdo_wmi.empty() ) {
826+
out << wa::showplus << "Class Driver extension InitData.PdoData.ClassWmiInfo routines: " << endlout;
827+
PrintFooter();
828+
829+
for ( const auto [address, type] : init_data_pdo_wmi ) {
830+
display->Analyze(address, type, "");
831+
}
832+
833+
PrintFooter();
834+
}
835+
836+
// DeviceMajorFunctionTable
837+
const auto dev_major_table = class_ext.GetDeviceMajorFunctionTable();
838+
839+
if ( !dev_major_table.empty() ) {
840+
out << wa::showplus << "Class Driver extension InitData.DeviceMajorFunctionTable routines: " << endlout;
841+
PrintFooter();
842+
843+
for ( const auto [address, type] : dev_major_table ) {
844+
display->Analyze(address, type, "");
845+
}
846+
847+
PrintFooter();
848+
}
849+
850+
// MpDeviceMajorFunctionTable
851+
const auto mp_dev_major_table = class_ext.GetMpDeviceMajorFunctionTable();
852+
853+
if ( !mp_dev_major_table.empty() ) {
854+
out << wa::showplus << "Class Driver extension InitData.MpDeviceMajorFunctionTable routines: " << endlout;
855+
PrintFooter();
856+
857+
for ( const auto [address, type] : mp_dev_major_table ) {
858+
display->Analyze(address, type, "");
859+
}
860+
861+
PrintFooter();
862+
}
863+
}
675864
//////////////////////////////////////////////////////////////////////////
676865
WDbgArkAnalyzeProcessToken::WDbgArkAnalyzeProcessToken(const std::shared_ptr<WDbgArkSymCache> &sym_cache)
677866
: WDbgArkAnalyzeBase(sym_cache) {

src/analyze.hpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,15 @@ class WDbgArkAnalyzeBase: public WDbgArkBPProxy<char>, public WDbgArkAnalyzeWhit
124124
private:
125125
using ObjDmlCmd = std::tuple<std::string, std::string, std::string>;
126126
std::map<std::string, ObjDmlCmd> m_object_dml_cmd = {
127-
{ "Type", std::make_tuple("<exec cmd=\"dtx nt!_OBJECT_TYPE ", "\">", "</exec>") },
128-
{ "Directory", std::make_tuple("<exec cmd=\"dtx nt!_OBJECT_DIRECTORY ", "\">", "</exec>") },
129-
{ "Process", std::make_tuple("<exec cmd=\"dtx nt!_EPROCESS ", "\">", "</exec>") },
130-
{ "Thread", std::make_tuple("<exec cmd=\"dtx nt!_ETHREAD ", "\">", "</exec>") },
131-
{ "Device", std::make_tuple("<exec cmd=\"dtx nt!_DEVICE_OBJECT ", "\">", "</exec>") },
132-
{ "Driver", std::make_tuple("<exec cmd=\"dtx nt!_DRIVER_OBJECT ", "\">", "</exec>") },
133-
{ "File", std::make_tuple("<exec cmd=\"dtx nt!_FILE_OBJECT ", "\">", "</exec>") },
134-
{ "Section", std::make_tuple("<exec cmd=\"dtx nt!_SECTION ", "\">", "</exec>") },
135-
{ "Key", std::make_tuple("<exec cmd=\"dtx nt!_CM_KEY_BODY ", "\">", "</exec>") }
127+
{ "Type", std::make_tuple(R"(<exec cmd="dtx nt!_OBJECT_TYPE )", R"(">)", "</exec>") },
128+
{ "Directory", std::make_tuple(R"(<exec cmd="dtx nt!_OBJECT_DIRECTORY )", R"(">)", "</exec>") },
129+
{ "Process", std::make_tuple(R"(<exec cmd="dtx nt!_EPROCESS )", R"(">)", "</exec>") },
130+
{ "Thread", std::make_tuple(R"(<exec cmd="dtx nt!_ETHREAD )", R"(">)", "</exec>") },
131+
{ "Device", std::make_tuple(R"(<exec cmd="dtx nt!_DEVICE_OBJECT )", R"(">)", "</exec>") },
132+
{ "Driver", std::make_tuple(R"(<exec cmd="dtx nt!_DRIVER_OBJECT )", R"(">)", "</exec>") },
133+
{ "File", std::make_tuple(R"(<exec cmd="dtx nt!_FILE_OBJECT )", R"(">)", "</exec>") },
134+
{ "Section", std::make_tuple(R"(<exec cmd="dtx nt!_SECTION )", R"(">)", "</exec>") },
135+
{ "Key", std::make_tuple(R"(<exec cmd="dtx nt!_CM_KEY_BODY )", R"(">)", "</exec>") }
136136
};
137137
};
138138
//////////////////////////////////////////////////////////////////////////
@@ -302,6 +302,7 @@ class WDbgArkAnalyzeDriver: public WDbgArkAnalyzeBase {
302302
void DisplayMajorTable(const ExtRemoteTyped &object);
303303
void DisplayFastIo(const ExtRemoteTyped &object);
304304
void DisplayFsFilterCallbacks(const ExtRemoteTyped &object);
305+
void DisplayClassCallbacks(const ExtRemoteTyped &object);
305306
};
306307
//////////////////////////////////////////////////////////////////////////
307308
// Process token analyzer

0 commit comments

Comments
 (0)