Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Driver] Fix failure after first IRP captured #27

Merged
merged 5 commits into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions Common/Headers/IoctlCodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ enum class Ioctl : u32
///
DisableMonitoring = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS),

///
///@brief StoreTestCase
///
StoreTestCase = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS),

// clang-format on
};

Expand Down
106 changes: 47 additions & 59 deletions Driver/Client/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ ToggleMonitoring(HANDLE hFile, std::string const& arg, bool enable)


bool
SendData(std::string const& device_name, const u32 ioctl)
SendData(std::string const& device_name, const u32 ioctl, std::vector<u8>& buffer_in)
{
wil::unique_handle hFile(::CreateFileA(
device_name.c_str(),
Expand All @@ -160,61 +160,44 @@ SendData(std::string const& device_name, const u32 ioctl)
}

DWORD nbBytesReturned = 0;
const usize sz = 0x20;
auto buffer_in = std::make_unique<u8[]>(sz);
::memset(buffer_in.get(), 'A', sz);

bool bSuccess = ::DeviceIoControl(hFile.get(), ioctl, buffer_in.get(), sz, nullptr, 0, &nbBytesReturned, nullptr);
info("SendData('%s', %dB) returned %s", device_name.c_str(), sz, boolstr(bSuccess));
bool bSuccess = ::DeviceIoControl(
hFile.get(),
ioctl,
buffer_in.data(),
buffer_in.size(),
nullptr,
0,
&nbBytesReturned,
nullptr);
info("SendData('%s', %dB) returned %s", device_name.c_str(), buffer_in.size(), boolstr(bSuccess));

return bSuccess;
}

std::optional<u32>
ReceiveData(HANDLE hFile)
{
//
// Try read into empty buffer to probe the size
//
DWORD expectedDataLength = 0;
{
u8* data = nullptr;
bool bRes = ::ReadFile(hFile, data, 0, &expectedDataLength, nullptr);
info("ReceiveData(nullptr) = %s", boolstr(bRes));
if ( bRes )
{
ok(" -> expectedDataLength = %d", expectedDataLength);
}
else
{
err("stopping");
return std::nullopt;
}
}

if ( expectedDataLength == 0 )
{
return 0;
}
DWORD expectedDataLength = 1024;

//
// Get read content
//
while ( true )
{
const DWORD dataLength = expectedDataLength;
auto data = std::make_unique<u8[]>(dataLength);
bool bRes = ::ReadFile(hFile, data.get(), dataLength, &expectedDataLength, nullptr);
info("ReceiveData(data, %d) = %s", dataLength, boolstr(bRes));
if ( bRes )
if ( bRes == false )
{
CFB::Utils::Hexdump(data.get(), dataLength);
return dataLength;
}
else
{
err("stopping");
if ( ::GetLastError() == ERROR_INSUFFICIENT_BUFFER )
{
expectedDataLength = dataLength * 2;
continue;
}
err("ReadFile() failed, GLE %#x", ::GetLastError());
return std::nullopt;
}

CFB::Utils::Hexdump(data.get(), dataLength);
return dataLength;
}
}

Expand All @@ -227,7 +210,7 @@ main(int argc, const char** argv)
argparse::ArgumentParser program("DriverClient");

const std::vector<std::string> valid_actions =
{"hook", "hook-unhook", "unhook", "size", "set-capturing", "send-data", "read-data", "session"};
{"hook", "unhook", "size", "monitor", "unmonitor", "send", "recv", "session"};

program.add_argument("--action")
.default_value(std::string("hook"))
Expand All @@ -244,7 +227,6 @@ main(int argc, const char** argv)
program.add_argument("--driver").default_value(std::string("\\driver\\hevd"));
program.add_argument("--device").default_value(std::string("\\\\.\\HackSysExtremeVulnerableDriver"));
program.add_argument("--ioctl").scan<'i', int>().default_value(0x222003); // BUFFER_OVERFLOW_STACK
program.add_argument("--enable").default_value(false).implicit_value(true);

try
{
Expand All @@ -257,11 +239,10 @@ main(int argc, const char** argv)
std::exit(1);
}

auto action = program.get<std::string>("--action");
auto driver_name = program.get<std::string>("--driver");
auto device_name = program.get<std::string>("--device");
auto ioctl = program.get<int>("--ioctl");
auto enable = program.get<bool>("--enable");
const auto action = program.get<std::string>("--action");
const auto driver_name = program.get<std::string>("--driver");
const auto device_name = program.get<std::string>("--device");
const auto ioctl = program.get<int>("--ioctl");

wil::unique_handle hEvent;

Expand All @@ -271,7 +252,7 @@ main(int argc, const char** argv)
if ( !hFile )
{
err("Failed to open '%S'", CFB_DEVICE_NAME);
// return -1;
return -1;
}

if ( action == "hook" )
Expand All @@ -282,24 +263,26 @@ main(int argc, const char** argv)
{
Driver::Unhook(hFile.get(), driver_name);
}
else if ( action == "hook-unhook" )
{
Driver::Hook(hFile.get(), driver_name);
Driver::Unhook(hFile.get(), driver_name);
}
else if ( action == "size" )
{
Driver::GetNumberOfDrivers(hFile.get());
}
else if ( action == "set-capturing" )
else if ( action == "monitor" )
{
Driver::ToggleMonitoring(hFile.get(), driver_name, enable);
Driver::ToggleMonitoring(hFile.get(), driver_name, true);
}
else if ( action == "send-data" )
else if ( action == "unmonitor" )
{
Driver::SendData(device_name, ioctl);
Driver::ToggleMonitoring(hFile.get(), driver_name, false);
}
else if ( action == "read-data" )
else if ( action == "send" )
{
const usize sz {0x100};
auto buffer_in = std::vector<u8>(sz);
::memset(buffer_in.data(), 'A', sz);
Driver::SendData(device_name, ioctl, buffer_in);
}
else if ( action == "recv" )
{
Driver::ReceiveData(hFile.get());
}
Expand All @@ -315,7 +298,12 @@ main(int argc, const char** argv)

for ( int i = 0; i < 2; i++ )
{
Driver::SendData(device_name, ioctl);
const usize sz {0x100};
auto buffer_in = std::vector<u8>(sz);
auto buffer_out = std::vector<u8>(sz);
::memset(buffer_in.data(), 'A', sz);

Driver::SendData(device_name, ioctl, buffer_in);

u32 Status = ::WaitForSingleObject(hEvent.get(), 1 * 1000);
switch ( Status )
Expand Down
5 changes: 2 additions & 3 deletions Driver/Source/CapturedIrp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ CapturedIrp::CapturePreCallData(_In_ PIRP Irp)
return STATUS_ACCESS_DENIED;
}

NTSTATUS Status = STATUS_UNSUCCESSFUL;
const ULONG Flags = m_DeviceObject->Flags;
const PIO_STACK_LOCATION Stack = ::IoGetCurrentIrpStackLocation(Irp);

Expand Down Expand Up @@ -240,7 +239,7 @@ CapturedIrp::CapturePreCallData(_In_ PIRP Irp)
}
}

return Status;
return STATUS_SUCCESS;
}


Expand Down Expand Up @@ -310,7 +309,7 @@ CapturedIrp::CapturePostCallData(_In_ PIRP Irp, _In_ NTSTATUS ReturnedIoctlStatu
RtlCopyMemory(m_OutputBuffer.get() + Offset, UserBuffer, Count);

#ifdef _DEBUG
ok("Capturing output data:");
dbg("Capturing output data:");
CFB::Utils::Hexdump(m_OutputBuffer.get(), MIN(m_OutputBuffer.size(), CFB_MAX_HEXDUMP_BYTE));
#endif // _DEBUG

Expand Down
37 changes: 30 additions & 7 deletions Driver/Source/Entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,6 @@ _Function_class_(DRIVER_DISPATCH) DriverDeviceControlRoutine(_In_ PDEVICE_OBJECT
break;
}

case CFB::Comms::Ioctl::GetDriverInfo:
warn("TODO");
Status = STATUS_NOT_IMPLEMENTED;
break;

default:
err("Received invalid IOCTL code 0x%08x", IoctlCode);
Status = STATUS_INVALID_DEVICE_REQUEST;
Expand Down Expand Up @@ -290,7 +285,6 @@ _Function_class_(DRIVER_DISPATCH) DriverReadRoutine(_In_ PDEVICE_OBJECT DeviceOb
}

NT_ASSERT(Irp->MdlAddress);

PVOID Buffer = ::MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
if ( Buffer == nullptr )
{
Expand All @@ -308,6 +302,8 @@ _Function_class_(DRIVER_DISPATCH) DriverReadRoutine(_In_ PDEVICE_OBJECT DeviceOb

for ( usize i = 0; i < DumpableIrpNumber; i++ )
{
dbg("Popping IRP %d/%d", i + 1, DumpableIrpNumber);

//
// Pop front the captured IRP
//
Expand All @@ -331,6 +327,13 @@ _Function_class_(DRIVER_DISPATCH) DriverReadRoutine(_In_ PDEVICE_OBJECT DeviceOb

RtlCopyMemory((PVOID)BufferPointer, &Header, DataSize);
BufferPointer += DataSize;

dbg("IRP %d/%d - Copied header: Process='%S', PID=%d, TID=%d",
i + 1,
DumpableIrpNumber,
Header.ProcessName,
Header.Pid,
Header.Tid);
}

//
Expand All @@ -347,6 +350,15 @@ _Function_class_(DRIVER_DISPATCH) DriverReadRoutine(_In_ PDEVICE_OBJECT DeviceOb
RtlCopyMemory((PVOID)BufferPointer, CurrentIrp->InputBuffer(), DataSize);
BufferPointer += DataSize;
}


dbg("IRP %d/%d - Copied input buffer (%d bytes)",
i + 1,
DumpableIrpNumber,
CurrentIrp->InputDataSize());
#ifdef _DEBUG
CFB::Utils::Hexdump(Buffer, MIN(CurrentIrp->InputDataSize(), CFB_MAX_HEXDUMP_BYTE));
#endif // _DEBUG
}

//
Expand All @@ -363,7 +375,17 @@ _Function_class_(DRIVER_DISPATCH) DriverReadRoutine(_In_ PDEVICE_OBJECT DeviceOb
RtlCopyMemory((PVOID)BufferPointer, CurrentIrp->OutputBuffer(), DataSize);
BufferPointer += DataSize;
}

dbg("IRP %d/%d - Copied output buffer (%d bytes)",
i + 1,
DumpableIrpNumber,
CurrentIrp->OutputDataSize());
#ifdef _DEBUG
CFB::Utils::Hexdump(Buffer, MIN(CurrentIrp->OutputDataSize(), CFB_MAX_HEXDUMP_BYTE));
#endif // _DEBUG
}

dbg("IRP %d/%d returned to client", i + 1, DumpableIrpNumber);
}
}

Expand Down Expand Up @@ -467,7 +489,8 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
Globals->DeviceObject = DeviceObject;
Globals->DriverObject = DriverObject;

err("Device initialization for '%S' done, use `%s` for debug logs",
warn(
"Device initialization for '%S' successful, use `%s` for debug logs",
CFB_DEVICE_NAME,
DML("ed nt !Kd_IHVDRIVER_Mask f"));
return Status;
Expand Down
Loading