Driver Problems? Questions? Issues?
Put OSR's experience to work for you! Contact us for assistance with:
  • Creating the right design for your requirements
  • Reviewing your existing driver code
  • Analyzing driver reliability/performance issues
  • Custom training mixed with consulting and focused directly on your specific areas of interest/concern.
Check us out. OSR, the Windows driver experts.

OSR Seminars


Go Back   OSR Online Lists > ntdev
Welcome, Guest
You must login to post to this list
  Message 1 of 11  
15 Apr 18 08:23
flash mark
xxxxxx@hotmail.com
Join Date: 23 Jan 2017
Posts To This List: 10
C: ArrayList implementation in kernel mode

I trying make a code example where i want insert in a arrylist only process names that still not exists in this list, my trouble that show here is that comes bsod in the following line. This following code is based on usermode version present in this answer (https://stackoverflow.com/questions/49765716/c-how-make-a-arraylist-implementati on-compatible-with-unicode-string-data/49765864#49765864). Before i tried make with same usermode code of arraylist, but already that some routines not is avaiable in kernel mode i decided use somes similar like ExAllocatePoolWithTag (malloc/calloc), RtlFreeUnicodeString (void FreeUString()), RtlDuplicateUnicodeString,this last can be better change to RtlUnicodeStringCopy already that RtlDuplicateUnicodeString is not always exported in Windows. --------------------------------------------------------------------------------- ---------- FAULTING_SOURCE_LINE_NUMBER: 128 FAULTING_SOURCE_CODE: 124: { 125: int index = 0; 126: while (index <= list->current) 127: { > 128: if (e->data->Length == list->elements[index].data->Length && 129: 0 == wcsncmp(e->data->Buffer, 130: list->elements[index].data->Buffer, 131: list->elements[index].data->Length)) 132: return index; 133: index++; Here is a minimal and compilable example: #include <ntddk.h> #include <WinDef.h> #define NTOSAPI __declspec(dllimport) NTSTATUS NTAPI RtlDuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString); ///////////////////////////////////// START 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), 'Fo'); 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, 'F'); memcpy(tmp, &udest[dIndex], (destLen - dIndex)); memcpy(&udest[dIndex], &usrc[sIndex], len); memcpy(&udest[dIndex + len], tmp, (destLen - dIndex)); ExFreePoolWithTag(tmp, 'F'); } 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), 'T'); 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 }; NTSTATUS status = STATUS_SUCCESS; if (++list->current < list->size) { status = RtlDuplicateUnicodeString(1, e->data, dest); DbgPrint("RtlDuplicateUnicodeString() status: 0x%x", status); list->elements[list->current].data = dest; return 1; } else { wide(list); status = RtlDuplicateUnicodeString(1, e->data, dest); DbgPrint("RtlDuplicateUnicodeString() status: 0x%x", status); 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, 'Fo'); } ArrayList list; Element e; ///////////////////////////////// END ARRAYLIST /////////////////////////////////// typedef enum _THREAD_STATE { StateInitialized, StateReady, StateRunning, StateStandby, StateTerminated, StateWait, StateTransition, StateUnknown } THREAD_STATE; typedef struct _SYSTEM_THREAD { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; KPRIORITY BasePriority; ULONG ContextSwitchCount; THREAD_STATE State; LONG WaitReason; } SYSTEM_THREAD, *PSYSTEM_THREAD; 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; typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, SystemProcessorInformation = 1, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, SystemPathInformation = 4, SystemProcessInformation = 5, SystemCallCountInformation = 6, SystemDeviceInformation = 7, SystemProcessorPerformanceInformation = 8, SystemFlagsInformation = 9, SystemCallTimeInformation = 10, SystemModuleInformation = 11, SystemLocksInformation = 12, SystemStackTraceInformation = 13, SystemPagedPoolInformation = 14, SystemNonPagedPoolInformation = 15, SystemHandleInformation = 16, SystemObjectInformation = 17, SystemPageFileInformation = 18, SystemVdmInstemulInformation = 19, SystemVdmBopInformation = 20, SystemFileCacheInformation = 21, SystemPoolTagInformation = 22, SystemInterruptInformation = 23, SystemDpcBehaviorInformation = 24, SystemFullMemoryInformation = 25, SystemLoadGdiDriverInformation = 26, SystemUnloadGdiDriverInformation = 27, SystemTimeAdjustmentInformation = 28, SystemSummaryMemoryInformation = 29, SystemMirrorMemoryInformation = 30, SystemPerformanceTraceInformation = 31, SystemObsolete0 = 32, SystemExceptionInformation = 33, SystemCrashDumpStateInformation = 34, SystemKernelDebuggerInformation = 35, SystemContextSwitchInformation = 36, SystemRegistryQuotaInformation = 37, SystemExtendServiceTableInformation = 38, SystemPrioritySeperation = 39, SystemVerifierAddDriverInformation = 40, SystemVerifierRemoveDriverInformation = 41, SystemProcessorIdleInformation = 42, SystemLegacyDriverInformation = 43, SystemCurrentTimeZoneInformation = 44, SystemLookasideInformation = 45, SystemTimeSlipNotification = 46, SystemSessionCreate = 47, SystemSessionDetach = 48, SystemSessionInformation = 49, SystemRangeStartInformation = 50, SystemVerifierInformation = 51, SystemVerifierThunkExtend = 52, SystemSessionProcessInformation = 53, SystemLoadGdiDriverInSystemSpace = 54, SystemNumaProcessorMap = 55, SystemPrefetcherInformation = 56, SystemExtendedProcessInformation = 57, SystemRecommendedSharedDataAlignment = 58, SystemComPlusPackage = 59, SystemNumaAvailableMemory = 60, SystemProcessorPowerInformation = 61, SystemEmulationBasicInformation = 62, SystemEmulationProcessorInformation = 63, SystemExtendedHandleInformation = 64, SystemLostDelayedWriteInformation = 65, SystemBigPoolInformation = 66, SystemSessionPoolTagInformation = 67, SystemSessionMappedViewInformation = 68, SystemHotpatchInformation = 69, SystemObjectSecurityMode = 70, SystemWatchdogTimerHandler = 71, SystemWatchdogTimerInformation = 72, SystemLogicalProcessorInformation = 73, SystemWow64SharedInformation = 74, SystemRegisterFirmwareTableInformationHandler = 75, SystemFirmwareTableInformation = 76, SystemModuleInformationEx = 77, SystemVerifierTriageInformation = 78, SystemSuperfetchInformation = 79, SystemMemoryListInformation = 80, SystemFileCacheInformationEx = 81, MaxSystemInfoClass = 82 } SYSTEM_INFORMATION_CLASS; NTOSAPI NTSTATUS NTAPI ZwQuerySystemInformation(/*IN*/ SYSTEM_INFORMATION_CLASS SystemInformationClass, /*IN OUT*/ PVOID SystemInformation, /*IN*/ ULONG SystemInformationLength, /*OUT*/ PULONG ReturnLength OPTIONAL); NTSTATUS EnumProcesses() { NTSTATUS status; ULONG cb = 0x8000; do { status = STATUS_INSUFFICIENT_RESOURCES; PVOID buf = ExAllocatePoolWithTag(PagedPool, cb, 'tset'); if (buf) { if (0 <= (status = ZwQuerySystemInformation(SystemProcessInformation, buf, cb, &cb))) { union Data { PVOID pv; PBYTE pb; PSYSTEM_PROCESS_INFORMATION pspi; }; union Data data; data.pv = buf; ULONG NextEntryOffset = 0; do { data.pb += NextEntryOffset; 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); } } while (NextEntryOffset = data.pspi->NextEntryOffset); } ExFreePoolWithTag(buf, 'tset'); } } while (status == STATUS_INFO_LENGTH_MISMATCH); clean(&list); return status; } void EnumProcUnload(IN PDRIVER_OBJECT DriverObject) { DbgPrint("Goodbye from EnumProc!\n"); } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { init(&list); EnumProcesses(); DriverObject->DriverUnload = EnumProcUnload; DbgPrint("Hello from EnumProc!\n"); return STATUS_SUCCESS; }
  Message 2 of 11  
15 Apr 18 09:20
Don Burn
xxxxxx@windrvr.com
Join Date: 23 Feb 2011
Posts To This List: 1406
C: ArrayList implementation in kernel mode

Before answering people might want to look at the responses he has gotten elsewhere: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/9640e6cc-d4e9- 4ce5-970c-158df932951a/arraylist-implementation-bsod-on-indexof-routine?foru m=wdk Don Burn Windows Driver Consulting Website: http://www.windrvr.com -----Original Message----- From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com Sent: Sunday, April 15, 2018 8:22 AM To: Windows System Software Devs Interest List <xxxxx@lists.osr.com> Subject: [ntdev] C: ArrayList implementation in kernel mode I trying make a code example where i want insert in a arrylist only process names that still not exists in this list, my trouble that show here is that comes bsod in the following line. This following code is based on usermode version present in this answer (https://stackoverflow.com/questions/49765716/c-how-make-a-arraylist-impleme ntation-compatible-with-unicode-string-data/49765864#49765864). Before i tried make with same usermode code of arraylist, but already that some routines not is avaiable in kernel mode i decided use somes similar like ExAllocatePoolWithTag (malloc/calloc), RtlFreeUnicodeString (void FreeUString()), RtlDuplicateUnicodeString,this last can be better change to RtlUnicodeStringCopy already that RtlDuplicateUnicodeString is not always exported in Windows. ---------------------------------------------------------------------------- --------------- FAULTING_SOURCE_LINE_NUMBER: 128 FAULTING_SOURCE_CODE: 124: { 125: int index = 0; 126: while (index <= list->current) 127: { > 128: if (e->data->Length == list->elements[index].data->Length && 129: 0 == wcsncmp(e->data->Buffer, 130: list->elements[index].data->Buffer, 131: list->elements[index].data->Length)) 132: return index; 133: index++; Here is a minimal and compilable example: #include <ntddk.h> #include <WinDef.h> #define NTOSAPI __declspec(dllimport) NTSTATUS NTAPI RtlDuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString); ///////////////////////////////////// START 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), 'Fo'); 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, 'F'); memcpy(tmp, &udest[dIndex], (destLen - dIndex)); memcpy(&udest[dIndex], &usrc[sIndex], len); memcpy(&udest[dIndex + len], tmp, (destLen - dIndex)); ExFreePoolWithTag(tmp, 'F'); } 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), 'T'); 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 }; NTSTATUS status = STATUS_SUCCESS; if (++list->current < list->size) { status = RtlDuplicateUnicodeString(1, e->data, dest); DbgPrint("RtlDuplicateUnicodeString() status: 0x%x", status); list->elements[list->current].data = dest; return 1; } else { wide(list); status = RtlDuplicateUnicodeString(1, e->data, dest); DbgPrint("RtlDuplicateUnicodeString() status: 0x%x", status); 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, 'Fo'); } ArrayList list; Element e; ///////////////////////////////// END ARRAYLIST /////////////////////////////////// typedef enum _THREAD_STATE { StateInitialized, StateReady, StateRunning, StateStandby, StateTerminated, StateWait, StateTransition, StateUnknown } THREAD_STATE; typedef struct _SYSTEM_THREAD { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; KPRIORITY BasePriority; ULONG ContextSwitchCount; THREAD_STATE State; LONG WaitReason; } SYSTEM_THREAD, *PSYSTEM_THREAD; 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; typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, SystemProcessorInformation = 1, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, SystemPathInformation = 4, SystemProcessInformation = 5, SystemCallCountInformation = 6, SystemDeviceInformation = 7, SystemProcessorPerformanceInformation = 8, SystemFlagsInformation = 9, SystemCallTimeInformation = 10, SystemModuleInformation = 11, SystemLocksInformation = 12, SystemStackTraceInformation = 13, SystemPagedPoolInformation = 14, SystemNonPagedPoolInformation = 15, SystemHandleInformation = 16, SystemObjectInformation = 17, SystemPageFileInformation = 18, SystemVdmInstemulInformation = 19, SystemVdmBopInformation = 20, SystemFileCacheInformation = 21, SystemPoolTagInformation = 22, SystemInterruptInformation = 23, SystemDpcBehaviorInformation = 24, SystemFullMemoryInformation = 25, SystemLoadGdiDriverInformation = 26, SystemUnloadGdiDriverInformation = 27, SystemTimeAdjustmentInformation = 28, SystemSummaryMemoryInformation = 29, SystemMirrorMemoryInformation = 30, SystemPerformanceTraceInformation = 31, SystemObsolete0 = 32, SystemExceptionInformation = 33, SystemCrashDumpStateInformation = 34, SystemKernelDebuggerInformation = 35, SystemContextSwitchInformation = 36, SystemRegistryQuotaInformation = 37, SystemExtendServiceTableInformation = 38, SystemPrioritySeperation = 39, SystemVerifierAddDriverInformation = 40, SystemVerifierRemoveDriverInformation = 41, SystemProcessorIdleInformation = 42, SystemLegacyDriverInformation = 43, SystemCurrentTimeZoneInformation = 44, SystemLookasideInformation = 45, SystemTimeSlipNotification = 46, SystemSessionCreate = 47, SystemSessionDetach = 48, SystemSessionInformation = 49, SystemRangeStartInformation = 50, SystemVerifierInformation = 51, SystemVerifierThunkExtend = 52, SystemSessionProcessInformation = 53, SystemLoadGdiDriverInSystemSpace = 54, SystemNumaProcessorMap = 55, SystemPrefetcherInformation = 56, SystemExtendedProcessInformation = 57, SystemRecommendedSharedDataAlignment = 58, SystemComPlusPackage = 59, SystemNumaAvailableMemory = 60, SystemProcessorPowerInformation = 61, SystemEmulationBasicInformation = 62, SystemEmulationProcessorInformation = 63, SystemExtendedHandleInformation = 64, SystemLostDelayedWriteInformation = 65, SystemBigPoolInformation = 66, SystemSessionPoolTagInformation = 67, SystemSessionMappedViewInformation = 68, SystemHotpatchInformation = 69, SystemObjectSecurityMode = 70, SystemWatchdogTimerHandler = 71, SystemWatchdogTimerInformation = 72, SystemLogicalProcessorInformation = 73, SystemWow64SharedInformation = 74, SystemRegisterFirmwareTableInformationHandler = 75, SystemFirmwareTableInformation = 76, SystemModuleInformationEx = 77, SystemVerifierTriageInformation = 78, SystemSuperfetchInformation = 79, SystemMemoryListInformation = 80, SystemFileCacheInformationEx = 81, MaxSystemInfoClass = 82 } SYSTEM_INFORMATION_CLASS; NTOSAPI NTSTATUS NTAPI ZwQuerySystemInformation(/*IN*/ SYSTEM_INFORMATION_CLASS SystemInformationClass, /*IN OUT*/ PVOID SystemInformation, /*IN*/ ULONG SystemInformationLength, /*OUT*/ PULONG ReturnLength OPTIONAL); NTSTATUS EnumProcesses() { NTSTATUS status; ULONG cb = 0x8000; do { status = STATUS_INSUFFICIENT_RESOURCES; PVOID buf = ExAllocatePoolWithTag(PagedPool, cb, 'tset'); if (buf) { if (0 <= (status = ZwQuerySystemInformation(SystemProcessInformation, buf, cb, &cb))) { union Data { PVOID pv; PBYTE pb; PSYSTEM_PROCESS_INFORMATION pspi; }; union Data data; data.pv = buf; ULONG NextEntryOffset = 0; do { data.pb += NextEntryOffset; 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); } } while (NextEntryOffset = data.pspi->NextEntryOffset); } ExFreePoolWithTag(buf, 'tset'); } } while (status == STATUS_INFO_LENGTH_MISMATCH); clean(&list); return status; } void EnumProcUnload(IN PDRIVER_OBJECT DriverObject) { DbgPrint("Goodbye from EnumProc!\n"); } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { init(&list); EnumProcesses(); DriverObject->DriverUnload = EnumProcUnload; DbgPrint("Hello from EnumProc!\n"); return STATUS_SUCCESS; } --- NTDEV is sponsored by OSR Visit the list online at: <http://www.osronline.com/showlists.cfm?list=ntdev> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at <http://www.osr.com/seminars> To unsubscribe, visit the List Server section of OSR Online at <http://www.osronline.com/page.cfm?name=ListServer>
  Message 3 of 11  
15 Apr 18 16:08
anton bassov
xxxxxx@hotmail.com
Join Date: 16 Jul 2006
Posts To This List: 4505
C: ArrayList implementation in kernel mode

> Before answering people might want to look at the responses he has gotten elsewhere: <ironical mode> Well done, Don..... However, you seem to have overlooked the part concerning the OP's name and company. Could you please fix it (preferably with Caps Lock key on). Thanks in advance </ironical mode> PS. Sorry, Peter, but I just cannot resist a temptation this time... Anton Bassov
  Message 4 of 11  
15 Apr 18 18:04
Don Burn
xxxxxx@windrvr.com
Join Date: 23 Feb 2011
Posts To This List: 1406
C: ArrayList implementation in kernel mode

Anton, Assholes like you can never resist, or learn. In this case if you had looked at the history of the OP on the Microsoft forum you would have seen it is obvious his forward progress is essentially NIL. Don Burn Windows Driver Consulting Website: http://www.windrvr.com -----Original Message----- From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com Sent: Sunday, April 15, 2018 4:08 PM To: Windows System Software Devs Interest List <xxxxx@lists.osr.com> Subject: RE:[ntdev] C: ArrayList implementation in kernel mode > Before answering people might want to look at the responses he has gotten elsewhere: <ironical mode> Well done, Don..... However, you seem to have overlooked the part concerning the OP's name and company. Could you please fix it (preferably with Caps Lock key on). Thanks in advance </ironical mode> PS. Sorry, Peter, but I just cannot resist a temptation this time... Anton Bassov --- NTDEV is sponsored by OSR Visit the list online at: <http://www.osronline.com/showlists.cfm?list=ntdev> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at <http://www.osr.com/seminars> To unsubscribe, visit the List Server section of OSR Online at <http://www.osronline.com/page.cfm?name=ListServer>
  Message 5 of 11  
15 Apr 18 19:36
anton bassov
xxxxxx@hotmail.com
Join Date: 16 Jul 2006
Posts To This List: 4505
C: ArrayList implementation in kernel mode

>Assholes like you can never resist, or learn. Sorry, Don, but you have provoked me yourself. Look - you reacted to the OP's question in.....well, lets say "not-so-adequate", way, that is so typical of you, did it in another NG...and then had proudly posted a link to it on NTDEV so that we could all see and "appreciate" your "accomplishments". I know I should have kept my opinion to myself, but in this particular case the whole thing looked so funny to me that I just could not resist the temptation of speaking ironically to you yet another time > In this case if you had looked at the history of the OP on the Microsoft forum >you would have seen it is obvious his forward progress is essentially NIL. Yes, but what is the point of reacting to his questions in ANY way then??? It is pretty obvious that he is a part of "please guide me in the same" crowd, so that nothing is ever going to change. In the end of the day, if he does not like your reply he is just going to post his question to another NG in an apparent expectation of a more "suitable" one, i.e. do things the way they always do. Anton Bassov
  Message 6 of 11  
16 Apr 18 02:53
Tim Roberts
xxxxxx@probo.com
Join Date: 28 Jan 2005
Posts To This List: 11997
C: ArrayList implementation in kernel mode

On Apr 15, 2018, at 5:22 AM, xxxxx@hotmail.com <xxxxx@lists.osr.com> wrote: > > I trying make a code example where i want insert in a arrylist only process names that still not exists in this list, my trouble that show here is that comes bsod in the following line. This following code is based on usermode version present in this answer This code is totally broken. You should throw this out and start from scratch. Make the code work in user-mode before you try to move this to the kernel, because you aren't ready for kernel coding yet. > ///////////////////////////////////// START ARRAYLIST ///////////////////////////////////////// > > typedef unsigned char uint8_t; > > typedef struct > { > UNICODE_STRING *data; > }Element; Why does this contain s POINTER to a UNICODE_STRING? This is just going to confuse you. You have to allocate an Element, and then allocate a UNICODE_STRING, and then allocate a character buffer inside of that. This is a disaster of a design. Your memory fragmentation will kill the performance. If you want your list to contain UNICODE_STRINGs, then just make it contain UNICODE_STRINGs. > typedef struct > { > int current; > int size; > int increment_rate; > Element *elements; > }ArrayList; Why do you have a "current" element? I suspect you can't actually answer that question, because you don't use the "current" value correctly in any of your functions here. I have a hunch this was an attempt to emulate the size() and capacity() methods in the C++ STL containers, but they aren't used that way. > void FreeUString(UNICODE_STRING *src) > { > RtlFreeUnicodeString(src); > src->Length = src->MaximumLength = 0; > } > > void initWithSizeAndIncRate(ArrayList *const list, int size, int rate) > { > list->size = size; <...excess quoted lines suppressed...> Here's your biggest problem. When this is done, the structure will claim to have "size" elements. But how many elements are really in the array? Here's a hint: you only allocated 1. Why would you set "current" to -1? An empty container has 0 elements, not -1. > void initWithSize(ArrayList *const list, int size) > { > initWithSizeAndIncRate(list, size, 50); > } > > void init(ArrayList *const list) > { > initWithSize(list, 100); > } This will result in an array that says it has 100 elements, but in reality only contains 1. > void arraryCopy(void *dest, int dIndex, const void* src, int sIndex, int len, int destLen, size_t size) > { > ... > if (src != dest) > { > memcpy(&udest[dIndex], &usrc[sIndex], len); > } > else > { This whole function is totally idiotic. Whoever wrote this doesn't know the C library at all. It's true that memcpy doesn't guarantee correct handling of overlapping regions, but memmove certainly does. You can replace this ENTIRE FUNCTION with one line: memmove( &udest[dIndex*size], &usrc[sindex*size], len * size ); Or, even better: RtlMoveMemory( &udest[dIndex*size], &usrc[sindex*size], len * size ); Stepping back further, however, the DESIGN of the function is stupid. Your ArrayList is not generic. It can only contain Elements. So, why have a generic copy? Use type safety by passing ArrayList pointers and use sizeof(Element). An even better solution would be to convert this all to C++, where you can make this a generic template. > void wide(ArrayList* const list) > { > list->size += list->increment_rate; > Element *newArr = (Element*)ExAllocatePoolWithTag(NonPagedPool, sizeof(Element), 'T'); > arraryCopy(newArr, 0, list->elements, 0, list->current, list->size, sizeof(Element)); > //ExFreePoolWithTag(list->elements, 'Foo'); > list->elements = newArr; > } This will explode the first time you call it. Why? Two reasons. First, because list->current is going to be -1 for an empty list. Second, because the new array you allocate here still only contains 1 element, so the copy is going to run off the end. And, because of your comment, you are going to leak memory every time this runs. > 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)) I hope it is clear now why this exploded. list->elements[1] does not exist. You didn't allocate it. Philosophically, there is another problem. This does not return the index of Element "e" within the list. Instead, it returns the index of the element within the list that happens to contain the same string as "e". That may be the intend, but that's not want someone accustomed to the MFC CArrayList is going to expect. > void clean(ArrayList *list) > { > ExFreePoolWithTag(list->elements, 'Fo'); > } This only frees the Element structure. It does not free the UNICODE_STRINGs that the Element points to, nor does it free the character buffers that the UNICODE_STRINGs point to. All of that memory will leak. When you're writing containers like this, you ALWAYS have to think about "who owns this memory? Who is responsible for allocating it, and who is responsible for freeing it?" You certainly have not done that here. ??? Tim Roberts, xxxxx@probo.com Providenza & Boekelheide, Inc.
  Message 7 of 11  
16 Apr 18 10:54
Peter Viscarola
xxxxxx@osr.com
Join Date:
Posts To This List: 6237
List Moderator
C: ArrayList implementation in kernel mode

You know, in addition to Troll Mode (where the troll can see his own posts but nobody else can), the new forum software has a "warning" mode... It allows mods to give annoying people warning points, and when the max number of points is exceeded, the person is temporarily banned for a period of time. This is, of course, in addition to the ability to put people on moderation. I, for one, am looking forward to the new features. Peter OSR @OSRDrivers
  Message 8 of 11  
16 Apr 18 15:28
anton bassov
xxxxxx@hotmail.com
Join Date: 16 Jul 2006
Posts To This List: 4505
C: ArrayList implementation in kernel mode

> It allows mods to give annoying people warning points, and when the max number > of points is exceeded, the person is temporarily banned for a period of time. Wow!!! This one already seems, indeed, exciting and promising. Just a couple of questions 1. Can the suspect actually see his current standing? 2. Is it sort of "low-pass filtered" over the time by some statistical means ( moving average seems to be the easiest possible but most definitely NOT the only possible method - in the most extreme cases it may utilise a wide array of DSP techniques with parameters like filter type, coefficients and sample size being under the control of list moderators)? With features like that I would be able to take the piss out of the "funny characters" all the way along and, at the same time, always be in a position to adjust my current behavior in a way that allows me to stay off the moderation list Anton Bassov
  Message 9 of 11  
16 Apr 18 17:06
Mark Roddy
xxxxxx@gmail.com
Join Date: 25 Feb 2000
Posts To This List: 4099
C: ArrayList implementation in kernel mode

You forgot about "administrative override". Perhaps instead of worrying about how to game the system, just don't try so hard to be a jerk. Mark Roddy On Mon, Apr 16, 2018 at 3:27 PM, xxxxx@hotmail.com < xxxxx@lists.osr.com> wrote: > > It allows mods to give annoying people warning points, and when the max > number > > of points is exceeded, the person is temporarily banned for a period of > time. > > > Wow!!! This one already seems, indeed, exciting and promising. Just a > couple of questions > > 1. Can the suspect actually see his current standing? <...excess quoted lines suppressed...> --
  Message 10 of 11  
16 Apr 18 21:05
anton bassov
xxxxxx@hotmail.com
Join Date: 16 Jul 2006
Posts To This List: 4505
C: ArrayList implementation in kernel mode

> You forgot about "administrative override". I did not - after all, this whole system can be thought of just as of an indicator that shows with a certain degree of accuracy how much our hosts are annoyed by any particular poster's most recent posting history. > Perhaps instead of worrying about how to game the system, This is not about "gaming the system" - this is more about getting an indication of the "red line"... > .... just don't try so hard to be a jerk. You know, sometimes it is really hard to refrain from speaking ironically to some posters.... For example, let's look at this particular case objectively. The OP seems to be a kind of a "programmer" who is capable of making 5 mistakes (not just some accidental typo-produced bugs but the mistakes that immediately reveal his profound lack of knowledge of C language basics) in 2 lines of code. To make it even "better", he does not seem to be progressing any faster than VinayKP either. There are quite a few things that have to be pointed out to him under these circumstances, don't you think. However, Mr.Burn does not really care about all the above - his primary concern is just the OP's use of a couple of undocumented functions, and the way he tends to express his thought about everything unsupported/undocumented does not really seem to be totally adequate - in fact, it is reminiscent of his requests concerning company name/ shouting in capitals. To make it even funnier, he did all that elsewhere, and then proudly posted a link to NDTEV. Do you really think that speaking ironically to him under these circumstances is indicative of being a jerk/troll???? Anton Bassov
  Message 11 of 11  
17 Apr 18 10:41
Peter Viscarola
xxxxxx@osr.com
Join Date:
Posts To This List: 6237
List Moderator
C: ArrayList implementation in kernel mode

<quote> Do you really think that speaking ironically to him under these circumstances is indicative of being a jerk/troll???? </quote> Again, your use of "ironic" is incorrect here. But, in any case, the answer is "Yes" -- I think you're being BOTH a jerk AND a troll. We may port your account in "Troll Mode"... Peter OSR @OSRDrivers
Posting Rules  
You may not post new threads
You may not post replies
You may not post attachments
You must login to OSR Online AND be a member of the ntdev list to be able to post.

All times are GMT -5. The time now is 17:03.


Copyright ©2015, OSR Open Systems Resources, Inc.
Based on vBulletin Copyright ©2000 - 2005, Jelsoft Enterprises Ltd.
Modified under license