forked from WerWolv/ImHex-Patterns
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththumbcache.hexpat
More file actions
149 lines (134 loc) · 4.23 KB
/
thumbcache.hexpat
File metadata and controls
149 lines (134 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma author MrMcX
#pragma description Windows thumbcache files
/*
Thanks to Joachim Metz for his work that helped improve the pattern:
https://github.com/libyal/libwtcdb/blob/main/documentation/Windows%20Explorer%20Thumbnail%20Cache%20database%20format.asciidoc
*/
#pragma magic [0x43 0x4D 0x4D 0x4D] @ 0x00
#pragma endian little
import std.mem;
import type.magic;
import hex.core;
import std.string;
enum WinVer : u32 {
WIN_VISTA = 20,
WIN_7 = 21,
WIN_8 = 30,
WIN_8_1 = 31,
WIN_10 = 32
};
enum Win7Vista_Type : u32 {
THUMBCACHE_32_DB = 0x0,
THUMBCACHE_96_DB = 0x1,
THUMBCACHE_256_DB = 0x2,
THUMBCACHE_1024_DB = 0x3,
THUMBCACHE_SR_DB = 0x4
};
enum Win8_Type: u32 {
THUMBCACHE_16_DB = 0x0,
THUMBCACHE_32_DB = 0x1,
THUMBCACHE_48_DB = 0x2,
THUMBCACHE_96_DB = 0x3,
THUMBCACHE_256_DB = 0x4,
THUMBCACHE_1024_DB = 0x5,
THUMBCACHE_SR_DB = 0x6,
THUMBCACHE_WIDE_DB = 0x7,
THUMBCACHE_EXIF_DB = 0x8
};
enum Win81_Type: u32 {
THUMBCACHE_16_DB = 0x0,
THUMBCACHE_32_DB = 0x1,
THUMBCACHE_48_DB = 0x2,
THUMBCACHE_96_DB = 0x3,
THUMBCACHE_256_DB = 0x4,
THUMBCACHE_1024_DB = 0x5,
THUMBCACHE_1600_DB = 0x6,
THUMBCACHE_SR_DB = 0x7,
THUMBCACHE_WIDE_DB = 0x8,
THUMBCACHE_EXIF_DB = 0x9,
THUMBCACHE_WIDE_ALTERNATE_DB = 0xA
};
enum Win10_Type: u32 {
THUMBCACHE_16_DB = 0x0,
THUMBCACHE_32_DB = 0x1,
THUMBCACHE_48_DB = 0x2,
THUMBCACHE_96_DB = 0x3,
THUMBCACHE_256_DB = 0x4,
THUMBCACHE_768_DB = 0x5,
THUMBCACHE_1280_DB = 0x6,
THUMBCACHE_1920_DB = 0x7,
THUMBCACHE_2560_DB = 0x8,
THUMBCACHE_WIDE_DB = 0x9,
THUMBCACHE_SR_DB = 0xA,
THUMBCACHE_EXIF_DB = 0xB,
THUMBCACHE_WIDE_ALTERNATE_DB = 0xC,
THUMBCACHE_CUSTOM_STREAM_DB = 0xD,
};
struct ThumbCacheHeader {
type::Magic<"CMMM"> signature;
WinVer version;
if(version == WinVer::WIN_10) {
Win10_Type type;
} else if(version == WinVer::WIN_8_1) {
Win81_Type type;
} else if(version == WinVer::WIN_8) {
Win8_Type type;
} else if(version <= WinVer::WIN_7) {
Win7Vista_Type type;
} else {
u32 type;
std::print("Unknown cache type: {}", type);
}
if(version >= WinVer::WIN_8) {
u32;
}
u32 header_size;
u32 offset_to_first_empty;
if(version <= WinVer::WIN_7) {
u32 count;
}
};
struct CacheRecord {
char signature[4];
if (signature != "CMMM") {
std::warning(std::format("Invalid cache entry at 0x{:08x}, skipping: {} ", $, type::escape_bytes(signature)));
padding[while(std::mem::read_string($, 4) != "CMMM")];
continue;
}
u32 size;
u64 entry_hash;
if(header.version == WinVer::WIN_VISTA) {
char16 extension[4];
}
u32 name_size;
u32 padding_size;
u32 data_size;
if(header.version == WinVer::WIN_10) {
u32 width;
u32 height;
}
u32;
u64 data_checksum;
u64 header_checksum;
char16 name[(name_size / 2)];
if(padding_size > 0) {
padding[padding_size];
}
if(data_size > 0) {
u8 data[data_size];
if(data[0] == 0x42 && data[1] == 0x4D) {
str suffix = ".bmp";
} else if(data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF && data[3] == 0xE0) {
str suffix = ".jpg";
} else if(data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47) {
str suffix = ".png";
} else {
str suffix = "";
std::warning("Thumbnail file type unknown, no suffix added");
}
hex::core::add_virtual_file(std::string::to_string(name) + suffix, data);
}
padding[while(std::mem::read_unsigned($, 1) == 0x00)];
};
ThumbCacheHeader header @ 0x00;
CacheRecord records[while(!std::mem::reached(header.offset_to_first_empty))] @ header.header_size;