Files
fastfetch/src/common/impl/binary_windows.c
T

72 lines
2.8 KiB
C
Raw Normal View History

2026-01-06 09:48:38 +08:00
#include "common/binary.h"
#include "common/io.h"
2026-05-28 15:58:08 +08:00
#include "common/strutil.h"
2026-02-27 22:59:46 +08:00
#include "common/windows/nt.h"
2024-08-22 16:41:06 +08:00
#include <windows.h>
#include <stdlib.h>
#include <string.h>
2025-04-02 10:27:25 +08:00
/**
* Extracts string literals from a PE (Windows) executable
*
* This function maps the PE file into memory, locates the .rdata section
* (which typically contains string literals), and scans it for valid strings.
* Each string found is passed to the callback function for processing.
*/
2026-03-29 09:28:49 +08:00
const char* ffBinaryExtractStrings(const char* peFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength) {
FF_AUTO_CLOSE_FD HANDLE hFile = CreateFileA(peFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
2026-02-27 22:59:46 +08:00
return "CreateFileA() failed";
2026-03-29 09:28:49 +08:00
}
2024-08-22 16:41:06 +08:00
2026-03-23 09:54:04 +08:00
FF_AUTO_CLOSE_FD HANDLE hSection = NULL;
2026-03-29 09:28:49 +08:00
if (!NT_SUCCESS(NtCreateSection(&hSection, SECTION_MAP_READ, NULL, NULL, PAGE_READONLY, SEC_COMMIT, hFile))) {
2026-03-23 09:54:04 +08:00
return "NtCreateSection() failed";
2026-03-29 09:28:49 +08:00
}
2026-02-27 22:59:46 +08:00
2026-03-23 09:54:04 +08:00
PVOID base = NULL;
SIZE_T viewSize = 0;
2026-03-29 09:28:49 +08:00
if (!NT_SUCCESS(NtMapViewOfSection(hSection, NtCurrentProcess(), &base, 0, 0, NULL, &viewSize, ViewUnmap, 0, PAGE_READONLY))) {
2026-03-23 09:54:04 +08:00
return "NtMapViewOfSection() failed";
2026-03-29 09:28:49 +08:00
}
2026-02-27 22:59:46 +08:00
PIMAGE_NT_HEADERS ntHeaders = RtlImageNtHeader(base);
2026-03-29 09:28:49 +08:00
if (!ntHeaders) {
2026-03-23 18:11:14 +08:00
NtUnmapViewOfSection(NtCurrentProcess(), base);
2026-02-27 22:59:46 +08:00
return "RtlImageNtHeader() failed";
}
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);
2026-03-29 09:28:49 +08:00
for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i, ++section) {
2025-04-02 10:27:25 +08:00
// Look for initialized data sections with the name ".rdata" which typically contains string literals
2026-03-29 09:28:49 +08:00
if ((section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) && ffStrEquals((const char*) section->Name, ".rdata")) {
uint8_t* data = (uint8_t*) base + section->PointerToRawData;
2024-08-22 16:41:06 +08:00
2025-04-02 10:27:25 +08:00
// Scan the section for string literals
2026-03-29 09:28:49 +08:00
for (size_t off = 0; off < section->SizeOfRawData; ++off) {
2024-08-22 16:41:06 +08:00
const char* p = (const char*) data + off;
2026-03-29 09:28:49 +08:00
if (*p == '\0') {
continue;
}
uint32_t len = (uint32_t) strnlen(p, section->SizeOfRawData - off);
2026-03-29 09:28:49 +08:00
if (len < minLength) {
off += len;
2026-03-29 09:28:49 +08:00
continue;
}
2025-04-02 10:27:25 +08:00
// Only process printable ASCII characters
2024-08-22 16:41:06 +08:00
if (*p >= ' ' && *p <= '~') // Ignore control characters
{
2026-03-29 09:28:49 +08:00
if (!cb(p, len, userdata)) {
break;
}
2024-08-22 16:41:06 +08:00
}
off += len;
}
}
}
2026-03-23 09:54:04 +08:00
NtUnmapViewOfSection(NtCurrentProcess(), base);
2024-08-22 16:41:06 +08:00
return NULL;
}