Serial number enumeration failed when we cast Descriptor+Descriptor->SerialN

I’ve a kernel driver which is used to find the serial number of storage devices, but there is an issue with the driver.
Descriptor->SerialNumberOffset is 103
but (LPCSTR)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset is NULL

here is my code
NTSTATUS GetDeviceTypeAndUniqueID(IN PDEVICE_OBJECT StorageStackDeviceObject, cwDevices *lDeviceTypeArg, char *pszUidArg)
{
DWORRD lDeviceType=0;

STORAGE_PROPERTY_QUERY Query;
STORAGE_DEVICE_DESCRIPTOR Buffer[4];
NTSTATUS Status = STATUS_SUCCESS;
ULONG uBusType=BusTypeUnknown;
PSTORAGE_DEVICE_DESCRIPTOR Descriptor=NULL;
PIRP NewIrp2=NULL;
PIO_STACK_LOCATION NextIrpStack=NULL;
IO_STATUS_BLOCK IoStatus;
char szSptr[2]={‘_’,‘\0’};

Query.PropertyId = StorageDeviceProperty;// first set the query properties
Query.QueryType = PropertyStandardQuery;

lDeviceType=0;

if (KeGetCurrentIrql() > PASSIVE_LEVEL)
{
return STATUS_SUCCESS;
}
if(StorageStackDeviceObject == NULL)
{
return STATUS_SUCCESS;
}

if((StorageStackDeviceObject->DeviceType != FILE_DEVICE_DISK) &&
(StorageStackDeviceObject->DeviceType != FILE_DEVICE_CD_ROM)&&
(StorageStackDeviceObject->DeviceType != FILE_DEVICE_DVD)&&
(StorageStackDeviceObject->DeviceType !=FILE_DEVICE_TAPE) )
{
return STATUS_SUCCESS;
}

KeInitializeEvent(&WaitEvent_newIrp, NotificationEvent, TRUE);// initialize the waitable event

__try
{

NewIrp2=IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY, StorageStackDeviceObject,
(PVOID)&Query,sizeof(STORAGE_PROPERTY_QUERY),
(PVOID)Buffer,sizeof(STORAGE_DEVICE_DESCRIPTOR)*4,
FALSE,&WaitEvent_newIrp,&IoStatus);

if(NewIrp2==NULL)
{
return STATUS_SUCCESS;
}

Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);// send this irp to the storage device

if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, NULL);
Status =IoStatus.Status;
}
}
__finally
{
if(NT_SUCCESS(Status))
{
if (NT_SUCCESS(Status))
{

if(Buffer!=NULL)
{
char szStart[256];
Descriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
uBusType = Descriptor->BusType; //Get the bus type.

if(Descriptor->SerialNumberOffset!=0)//Is Valid SerialNumberOffset, returns 103
{
strcpy(szStart,(char*)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset);
//szStart is null
}
}
NewIrp2 = NULL;
}
}
}
}

It can’t be NULL unless it wraps around to 0x0 which is unlikely. This is a pointer arithmetic. The code just adds some value to a virtual address.

I see a strange commentary “szStart is null”. It can’t be NULL here unless this code wiped a stack and WinDBG was unable to locate a call frame OR you backtracked a stack for a release build with local variables being optimized out.

BTW, this code has a buffer overflow vulnerability.
I would not comment on 256 bytes array allocated on a kernel mode stack.

HI
Do you have any suggestions to solve this issue and to get the serial
number?

On Tue, Jun 20, 2017 at 4:14 PM, wrote:

> I’ve a kernel driver which is used to find the serial number of storage
> devices, but there is an issue with the driver.
> Descriptor->SerialNumberOffset is 103
> but (LPCSTR)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset
> is NULL
>
> here is my code
> NTSTATUS GetDeviceTypeAndUniqueID(IN PDEVICE_OBJECT
> StorageStackDeviceObject, cwDevices *lDeviceTypeArg, char *pszUidArg)
> {
> DWORRD lDeviceType=0;
>
> STORAGE_PROPERTY_QUERY Query;
> STORAGE_DEVICE_DESCRIPTOR Buffer[4];
> NTSTATUS Status = STATUS_SUCCESS;
> ULONG uBusType=BusTypeUnknown;
> PSTORAGE_DEVICE_DESCRIPTOR Descriptor=NULL;
> PIRP NewIrp2=NULL;
> PIO_STACK_LOCATION NextIrpStack=NULL;
> IO_STATUS_BLOCK IoStatus;
> char szSptr[2]={‘_’,‘\0’};
>
> Query.PropertyId = StorageDeviceProperty;// first set the query
> properties
> Query.QueryType = PropertyStandardQuery;
>
> lDeviceType=0;
>
> if (KeGetCurrentIrql() > PASSIVE_LEVEL)
> {
> return STATUS_SUCCESS;
> }
> if(StorageStackDeviceObject == NULL)
> {
> return STATUS_SUCCESS;
> }
>
> if((StorageStackDeviceObject->DeviceType != FILE_DEVICE_DISK) &&
> (StorageStackDeviceObject->DeviceType !=
> FILE_DEVICE_CD_ROM)&&
> (StorageStackDeviceObject->DeviceType !=
> FILE_DEVICE_DVD)&&
> (StorageStackDeviceObject->DeviceType !=FILE_DEVICE_TAPE)
> )
> {
> return STATUS_SUCCESS;
> }
>
> KeInitializeEvent(&WaitEvent_newIrp, NotificationEvent, TRUE);//
> initialize the waitable event
>
> __try
> {
>
> NewIrp2=IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY,
> StorageStackDeviceObject,
>
> (PVOID)&Query,sizeof(STORAGE_PROPERTY_QUERY),
>
> (PVOID)Buffer,sizeof(STORAGE_DEVICE_DESCRIPTOR)4,
>
> FALSE,&WaitEvent_newIrp,&IoStatus);
>
> if(NewIrp2==NULL)
> {
> return STATUS_SUCCESS;
> }
>
> Status = IoCallDriver(StorageStackDeviceObject,
> NewIrp2);// send this irp to the storage device
>
> if (Status == STATUS_PENDING)
> {
> KeWaitForSingleObject(&WaitEvent_newIrp,
> Executive, KernelMode, FALSE, NULL);
> Status =IoStatus.Status;
> }
> }
>__finally
> {
> if(NT_SUCCESS(Status))
> {
> if (NT_SUCCESS(Status))
> {
>
> if(Buffer!=NULL)
> {
> char szStart[256];
> Descriptor =
> (PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
> uBusType = Descriptor->BusType;
> //Get the bus type.
>
> if(Descriptor->SerialNumberOffset!=0)//Is
> Valid SerialNumberOffset, returns 103
> {
>
> strcpy(szStart,(char
)(UINT_PTR)Descriptor+(DWORD32)Descriptor->
> SerialNumberOffset);
> //szStart is null
> }
> }
> NewIrp2 = NULL;
> }
> }
> }
> }
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
>



Marshal Sebastian.Kmail: xxxxx@outlook.com
: xxxxx@gmail.com call me : +91
9539870826


Think Green – Please do not print this email unless you really need to“</http:>

> Do you have any suggestions to solve this issue

Yes.
Start with K&R( https://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628/ref=sr_1_1?ie=UTF8&qid=1498049059&sr=8-1&keywords=The+C+Programming+Language )