Hello,
I want undestand (with your help) why my IndexOf() routine generate a BSOD. In my tests i noted that is when this routine is executed by second time.
This code was based in this answer and have the goal of find all processes that is using determinated file, but in my case i need that not repeat the same process name because i have another routine that not must be executed when is a repeated process (this is the reason to this ArrayList implementation).
This question is similar to this http://www.kernelmode.info/forum/viewto ... =15&t=4970 that was solved using TStringList (Delphi).
I want undestand (with your help) why my IndexOf() routine generate a BSOD. In my tests i noted that is when this routine is executed by second time.
This code was based in this answer and have the goal of find all processes that is using determinated file, but in my case i need that not repeat the same process name because i have another routine that not must be executed when is a repeated process (this is the reason to this ArrayList implementation).
This question is similar to this http://www.kernelmode.info/forum/viewto ... =15&t=4970 that was solved using TStringList (Delphi).
Code: Select all
Here is result of !analyze -v (on .dump file) from WinDbg x86:#pragma region ArrayList
typedef unsigned char uint8_t;
typedef struct
{
UNICODE_STRING *data;
}Element;
typedef struct
{
int current;
int size;
int increment_rate;
Element *elements;
}ArrayList;
void FreeUString(UNICODE_STRING *src)
{
RtlFreeUnicodeString(src);
src->Length = src->MaximumLength = 0;
}
void initWithSizeAndIncRate(ArrayList *const list, int size, int rate)
{
list->size = size;
list->increment_rate = rate;
list->elements = (Element*)ExAllocatePoolWithTag(NonPagedPool, sizeof(Element), 'Foo');
list->current = -1;
}
void initWithSize(ArrayList *const list, int size)
{
initWithSizeAndIncRate(list, size, 50);
}
void init(ArrayList *const list)
{
initWithSize(list, 100);
}
void arraryCopy(void *dest, int dIndex, const void* src, int sIndex, int len, int destLen, size_t size)
{
uint8_t *udest = (uint8_t*)dest;
uint8_t *usrc = (uint8_t*)src;
dIndex *= size;
sIndex *= size;
len *= size;
destLen *= size;
if (src != dest)
{
memcpy(&udest[dIndex], &usrc[sIndex], len);
}
else
{
if (dIndex > sIndex)
{
uint8_t *tmp = (uint8_t*)ExAllocatePoolWithTag(NonPagedPool, size, 'Foo');
memcpy(tmp, &udest[dIndex], (destLen - dIndex));
memcpy(&udest[dIndex], &usrc[sIndex], len);
memcpy(&udest[dIndex + len], tmp, (destLen - dIndex));
ExFreePoolWithTag(tmp, 'Foo');
}
else if (sIndex > dIndex)
{
memcpy(&udest[dIndex], &usrc[sIndex], (destLen - sIndex) + 1);
}
else
return;
}
}
void clear(ArrayList *const list)
{
while (list->current >= 0)
{
FreeUString(list->elements[list->current].data);
list->current--;
}
}
void wide(ArrayList* const list)
{
list->size += list->increment_rate;
Element *newArr = (Element*)ExAllocatePoolWithTag(NonPagedPool, sizeof(Element), 'Foo');
arraryCopy(newArr, 0, list->elements, 0, list->current, list->size, sizeof(Element));
//ExFreePoolWithTag(list->elements, 'Foo');
list->elements = newArr;
}
int add(ArrayList *const list, Element *e)
{
UNICODE_STRING *dest = { NULL };
if (++list->current < list->size)
{
RtlDuplicateUnicodeString(1, e->data, dest);
list->elements[list->current].data = dest;
return 1;
}
else
{
wide(list);
RtlDuplicateUnicodeString(1, e->data, dest);
list->elements[list->current].data = dest;
return 1;
}
return 0;
}
int indexOf(const ArrayList *const list, Element *e)
{
int index = 0;
while (index <= list->current)
{
if (e->data->Length == list->elements[index].data->Length &&
0 == wcsncmp(e->data->Buffer,
list->elements[index].data->Buffer,
list->elements[index].data->Length))
return index;
index++;
}
return 0;
}
void clean(ArrayList *list)
{
ExFreePoolWithTag(list->elements, 'Foo');
}
ArrayList list;
Element e;
#pragma endregion ArrayList
typedef struct SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
DWORD BasePriority;
HANDLE ProcessId;
HANDLE ParentProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VMCounters;
IO_COUNTERS IOCounters;
SYSTEM_THREAD Threads[1];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
NTSTATUS PrintProcessesUsingFile(PFILE_PROCESS_IDS_USING_FILE_INFORMATION ppiufi)
{
do
{
data.pb += NextEntryOffset;
ULONG NumberOfProcessIdsInList = ppiufi->NumberOfProcessIdsInList;
PULONG_PTR ProcessIdList = ppiufi->ProcessIdList;
do
{
if (*ProcessIdList++ == (ULONG_PTR)data.pspi->ProcessId)
{
DbgPrint("%d %wZ\n", data.pspi->ProcessId, &data.pspi->ImageName);
e.data = &(data.pspi->ImageName);
///////////////////////////////
int i = indexOf(&list, &e);
//////////////////////////////
if (i > 0)
{
DbgPrint("process already in list \n");
}
else
{
add(&list, &e);
clean(&list);
// My another routine here when is a different process name
}
break;
}
} while (--NumberOfProcessIdsInList);
} while (NextEntryOffset = data.pspi->NextEntryOffset);
}
NTSTATUS testPnP(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_REQUEST:
init(&list);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
}
Code: Select all
FAULTING_SOURCE_LINE_NUMBER: 259
FAULTING_SOURCE_CODE:
255: {
256: int index = 0;
257: while (index <= list->current)
258: {
> 259: if (e->data->Length == list->elements[index].data->Length &&
260: 0 == wcsncmp(e->data->Buffer,
261: list->elements[index].data->Buffer,
262: list->elements[index].data->Length))
263: return index;
264: index++;