/* * SfuQueryResourceData * * Purpose: * * Load resource by given id (win32 FindResource, SizeofResource, LockResource). * */ PBYTE SfuQueryResourceData( _In_ ULONG_PTR ResourceId, _In_ PVOID DllHandle, _In_ PULONG DataSize ) { NTSTATUS status; ULONG_PTR IdPath[3]; IMAGE_RESOURCE_DATA_ENTRY *DataEntry; PBYTE Data = NULL; ULONG SizeOfData = 0; if (DllHandle != NULL) { IdPath[0] = (ULONG_PTR)RT_RCDATA; //type IdPath[1] = ResourceId; //id IdPath[2] = 0; //lang status = LdrFindResource_U(DllHandle, (ULONG_PTR*)&IdPath, 3, &DataEntry); if (NT_SUCCESS(status)) { status = LdrAccessResource(DllHandle, DataEntry, &Data, &SizeOfData); if (NT_SUCCESS(status)) { if (DataSize) { *DataSize = SizeOfData; } } } } return Data; }
NTSTATUS NtGetVersionResource( IN PVOID BaseAddress, OUT PVOID* Resource, OUT PULONG ResourceSize OPTIONAL) { // #define RT_VERSION MAKEINTRESOURCE(16) // See winuser.h #define VS_VERSION_INFO 1 // See psdk/verrsrc.h #define VS_FILE_INFO RT_VERSION NTSTATUS Status; LDR_RESOURCE_INFO ResourceInfo; PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; PVOID Data = NULL; ULONG Size = 0; /* Try to find the resource */ ResourceInfo.Type = 16; // RT_VERSION; ResourceInfo.Name = VS_VERSION_INFO; // MAKEINTRESOURCEW(VS_VERSION_INFO); ResourceInfo.Language = 0; // Don't care about the language Status = LdrFindResource_U(BaseAddress, &ResourceInfo, RESOURCE_DATA_LEVEL, &ResourceDataEntry); if (!NT_SUCCESS(Status)) { DPRINT1("NtGetVersionResource: Version resource not found, Status 0x%08lx\n", Status); return Status; } /* Access the resource */ Status = LdrAccessResource(BaseAddress, ResourceDataEntry, &Data, &Size); if (!NT_SUCCESS(Status)) { DPRINT1("NtGetVersionResource: Cannot access Version resource, Status 0x%08lx\n", Status); return Status; } *Resource = Data; if (ResourceSize) *ResourceSize = Size; return STATUS_SUCCESS; }
PWCHAR config_LoadStringTable(HMODULE hModule,DWORD dwStringID) { PWCHAR lpStringTable; PIMAGE_RESOURCE_DATA_ENTRY piResDataEntry; LDR_RESOURCE_INFO ldrResInfo; ldrResInfo.Name=(ULONG)MAKEINTRESOURCEW((dwStringID/16)+1); // stringtable ldrResInfo.Type=(ULONG)MAKEINTRESOURCEW(6); // stringtable ldrResInfo.Language=(ULONG)MAKEINTRESOURCEW(0); // 0 // find stringtable if (!NT_SUCCESS(LdrFindResource_U(hModule,&ldrResInfo,3,&piResDataEntry))) return NULL; // load stringtable in memory if (!NT_SUCCESS(LdrAccessResource(hModule,piResDataEntry,&lpStringTable,NULL))) return NULL; return lpStringTable; }
VOID INIT_FUNCTION NTAPI KiInitializeBugCheck(VOID) { PMESSAGE_RESOURCE_DATA BugCheckData; LDR_RESOURCE_INFO ResourceInfo; PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; NTSTATUS Status; PLDR_DATA_TABLE_ENTRY LdrEntry; /* Get the kernel entry */ LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); /* Cache the Bugcheck Message Strings. Prepare the Lookup Data */ ResourceInfo.Type = 11; ResourceInfo.Name = 1; ResourceInfo.Language = 9; /* Do the lookup. */ Status = LdrFindResource_U(LdrEntry->DllBase, &ResourceInfo, RESOURCE_DATA_LEVEL, &ResourceDataEntry); /* Make sure it worked */ if (NT_SUCCESS(Status)) { /* Now actually get a pointer to it */ Status = LdrAccessResource(LdrEntry->DllBase, ResourceDataEntry, (PVOID*)&BugCheckData, NULL); if (NT_SUCCESS(Status)) KiBugCodeMessages = BugCheckData; } }
/********************************************************************** * RtlFindMessage (NTDLL.@) */ NTSTATUS WINAPI RtlFindMessage( HMODULE hmod, ULONG type, ULONG lang, ULONG msg_id, const MESSAGE_RESOURCE_ENTRY **ret ) { const MESSAGE_RESOURCE_DATA *data; const MESSAGE_RESOURCE_BLOCK *block; const IMAGE_RESOURCE_DATA_ENTRY *rsrc; LDR_RESOURCE_INFO info; NTSTATUS status; void *ptr; unsigned int i; info.Type = type; info.Name = 1; info.Language = lang; if ((status = LdrFindResource_U( hmod, &info, 3, &rsrc )) != STATUS_SUCCESS) return status; if ((status = LdrAccessResource( hmod, rsrc, &ptr, NULL )) != STATUS_SUCCESS) return status; data = ptr; block = data->Blocks; for (i = 0; i < data->NumberOfBlocks; i++, block++) { if (msg_id >= block->LowId && msg_id <= block->HighId) { const MESSAGE_RESOURCE_ENTRY *entry; entry = (const MESSAGE_RESOURCE_ENTRY *)((const char *)data + block->OffsetToEntries); for (i = msg_id - block->LowId; i > 0; i--) entry = (const MESSAGE_RESOURCE_ENTRY *)((const char *)entry + entry->Length); *ret = entry; return STATUS_SUCCESS; } } return STATUS_MESSAGE_NOT_FOUND; }
PVOID NTAPI INIT_FUNCTION FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN ULONG ResourceId) { UNICODE_STRING UpString = RTL_CONSTANT_STRING(L"ntoskrnl.exe"); UNICODE_STRING MpString = RTL_CONSTANT_STRING(L"ntkrnlmp.exe"); PLIST_ENTRY NextEntry, ListHead; PLDR_DATA_TABLE_ENTRY LdrEntry; PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; LDR_RESOURCE_INFO ResourceInfo; NTSTATUS Status; PVOID Data = NULL; /* Loop the driver list */ ListHead = &LoaderBlock->LoadOrderListHead; NextEntry = ListHead->Flink; while (NextEntry != ListHead) { /* Get the entry */ LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); /* Check for a match */ if ((RtlEqualUnicodeString(&LdrEntry->BaseDllName, &UpString, TRUE)) || (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &MpString, TRUE))) { /* Break out */ break; } } /* Check if we found it */ if (NextEntry != ListHead) { /* Try to find the resource */ ResourceInfo.Type = 2; //RT_BITMAP; ResourceInfo.Name = ResourceId; ResourceInfo.Language = 0; Status = LdrFindResource_U(LdrEntry->DllBase, &ResourceInfo, RESOURCE_DATA_LEVEL, &ResourceDataEntry); if (NT_SUCCESS(Status)) { /* Access the resource */ ULONG Size = 0; Status = LdrAccessResource(LdrEntry->DllBase, ResourceDataEntry, &Data, &Size); if ((Data) && (ResourceId < 3)) { KiBugCheckData[4] ^= RtlComputeCrc32(0, Data, Size); } if (!NT_SUCCESS(Status)) Data = NULL; } } /* Return the pointer */ return Data; }
/* * @implemented */ NTSTATUS NTAPI RtlFindMessage( IN PVOID BaseAddress, IN ULONG Type, IN ULONG Language, IN ULONG MessageId, OUT PMESSAGE_RESOURCE_ENTRY* MessageResourceEntry) { LDR_RESOURCE_INFO ResourceInfo; PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; PMESSAGE_RESOURCE_DATA MessageTable; NTSTATUS Status; ULONG EntryOffset = 0, IdOffset = 0; PMESSAGE_RESOURCE_ENTRY MessageEntry; ULONG i; DPRINT("RtlFindMessage()\n"); ResourceInfo.Type = Type; ResourceInfo.Name = 1; ResourceInfo.Language = Language; Status = LdrFindResource_U(BaseAddress, &ResourceInfo, RESOURCE_DATA_LEVEL, &ResourceDataEntry); if (!NT_SUCCESS(Status)) { return Status; } DPRINT("ResourceDataEntry: %p\n", ResourceDataEntry); Status = LdrAccessResource(BaseAddress, ResourceDataEntry, (PVOID*)&MessageTable, NULL); if (!NT_SUCCESS(Status)) { return Status; } DPRINT("MessageTable: %p\n", MessageTable); DPRINT("NumberOfBlocks %lu\n", MessageTable->NumberOfBlocks); for (i = 0; i < MessageTable->NumberOfBlocks; i++) { DPRINT("LoId 0x%08lx HiId 0x%08lx Offset 0x%08lx\n", MessageTable->Blocks[i].LowId, MessageTable->Blocks[i].HighId, MessageTable->Blocks[i].OffsetToEntries); } for (i = 0; i < MessageTable->NumberOfBlocks; i++) { if ((MessageId >= MessageTable->Blocks[i].LowId) && (MessageId <= MessageTable->Blocks[i].HighId)) { EntryOffset = MessageTable->Blocks[i].OffsetToEntries; IdOffset = MessageId - MessageTable->Blocks[i].LowId; break; } if (MessageId < MessageTable->Blocks[i].LowId) { return STATUS_MESSAGE_NOT_FOUND; } } if (MessageTable->NumberOfBlocks <= i) { return STATUS_MESSAGE_NOT_FOUND; } MessageEntry = (PMESSAGE_RESOURCE_ENTRY) ((PUCHAR)MessageTable + MessageTable->Blocks[i].OffsetToEntries); DPRINT("EntryOffset 0x%08lx\n", EntryOffset); DPRINT("IdOffset 0x%08lx\n", IdOffset); DPRINT("MessageEntry: %p\n", MessageEntry); for (i = 0; i < IdOffset; i++) { MessageEntry = (PMESSAGE_RESOURCE_ENTRY) ((PUCHAR)MessageEntry + (ULONG)MessageEntry->Length); } if (MessageEntry->Flags == 0) { DPRINT("AnsiText: %s\n", MessageEntry->Text); } else { DPRINT("UnicodeText: %S\n", (PWSTR)MessageEntry->Text); } if (MessageResourceEntry != NULL) { *MessageResourceEntry = MessageEntry; } return STATUS_SUCCESS; }