cstringwindowsdriverwdm

How to copy a UCHAR string in WCHAR string in C Windows Kernel Driver


I'm having troubles in this piece of code, i'm trying to save the retrieved list of loaded system modules in a struct array defined as:

typedef struct _DRIVER_INFO {  
    PVOID MappedBase;     
    PVOID ImageBase;     
    ULONG ImageSize;     
    WCHAR ModuleName[MAXIMUM_FILENAME_LENGTH];     
    WCHAR FullPathName[MAXIMUM_FILENAME_LENGTH]; 
} DRIVER_INFO;

and the source of data is a struct defined as:

typedef struct _SYSTEM_MODULE_INFORMATION {
    HANDLE Section;     
    PVOID MappedBase;     
    PVOID ImageBase;     
    ULONG ImageSize;     
    ULONG Flags;     
    USHORT LoadOrderIndex;     
    USHORT InitOrderIndex;     
    USHORT LoadCount;     
    USHORT OffsetToFileName;     
    UCHAR FullPathName[MAXIMUM_FILENAME_LENGTH]; 
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;

This is the code i can't complete, I've tried different functions to copy a string defined in wdm.h. I have to copy a UCHAR string in WCHAR (even UNICODE_STRING would be fine)

for (ULONG i = 0; i < moduleList->NumberOfModules; i++)
{
    PRTL_PROCESS_MODULE_INFORMATION module = (PRTL_PROCESS_MODULE_INFORMATION)&moduleList->Modules[i];
    DRIVER_INFO driverInfo;
    driverInfo.MappedBase = module->MappedBase;
    driverInfo.ImageBase = module->ImageBase;
    driverInfo.ImageSize = module->ImageSize;
    
    //Here i have to copy module.FullPathName in driverInfo.FullPathName
    //and module.FullPathName + module.OffsetToFileName in driverInfo.ModuleName
    
    systemDrivers[i] = driverInfo;
    DebugMessage("Driver Path: %s\n", driverInfo.FullPathName);
}

EDIT 1:

With just the first RtlAnsiStringToUnicodeString it works, but if I add the second one it dies and reports "attempted write to read only location", what am I missing?

for (ULONG i = 0; i < moduleList->NumberOfModules; i++)
{
    PRTL_PROCESS_MODULE_INFORMATION module = (PRTL_PROCESS_MODULE_INFORMATION)&moduleList->Modules[i];
    DRIVER_INFO driverInfo;
    PCSTR moduleName = (PCSTR)(module->FullPathName + module->OffsetToFileName);
    PCSTR fullPathName = (PCSTR)(module->FullPathName);
    DebugMessage("Driver Name: %s, Driver Path: %s\n", moduleName, fullPathName);
    //driverInfo.MappedBase = module->MappedBase;
    //driverInfo.ImageBase = module->ImageBase;
    //driverInfo.ImageSize = module->ImageSize;

    RtlAnsiStringToUnicodeString(&driverInfo.ModuleName, (PCANSI_STRING)&moduleName, TRUE);
    RtlAnsiStringToUnicodeString(&driverInfo.FullPathName, (PCANSI_STRING)&fullPathName, TRUE);
}

Solution

  • Solved it in this way, thank you all.

    for (ULONG i = 0; i < moduleList->NumberOfModules; i++)
    {
        PRTL_PROCESS_MODULE_INFORMATION module = (PRTL_PROCESS_MODULE_INFORMATION)&moduleList->Modules[i];
        PCSTR moduleName = (PCSTR)(module->FullPathName + module->OffsetToFileName);
        ANSI_STRING ansiModuleName;
        RtlInitAnsiString(&ansiModuleName, moduleName);
        PCSTR fullPathName = (PCSTR)(module->FullPathName);
        ANSI_STRING ansiFullPathName;
        RtlInitAnsiString(&ansiFullPathName, fullPathName);
        systemDrivers[i].MappedBase = module->MappedBase;
        systemDrivers[i].ImageBase = module->ImageBase;
        systemDrivers[i].ImageSize = module->ImageSize;
        RtlAnsiStringToUnicodeString(&systemDrivers[i].ModuleName, &ansiModuleName, TRUE);
        RtlAnsiStringToUnicodeString(&systemDrivers[i].FullPathName, &ansiFullPathName, TRUE);
    }