Coverage Report

Created: 2023-09-25 07:15

/src/yara/libyara/modules/lnk/lnk.c
Line
Count
Source (jump to first uncovered line)
1
#include <wchar.h>
2
#include <yara/endian.h>
3
#include <yara/lnk.h>
4
#include <yara/lnk_utils.h>
5
#include <yara/mem.h>
6
#include <yara/modules.h>
7
8
#define MODULE_NAME lnk
9
10
0
begin_declarations
11
0
  declare_integer("HAS_LINK_TARGET_ID_LIST");
12
0
  declare_integer("HAS_LINK_INFO");
13
0
  declare_integer("HAS_NAME");
14
0
  declare_integer("HAS_RELATIVE_PATH");
15
0
  declare_integer("HAS_WORKING_DIR");
16
0
  declare_integer("HAS_ARGUMENTS");
17
0
  declare_integer("HAS_ICON_LOCATION");
18
0
  declare_integer("IS_UNICODE");
19
0
  declare_integer("FORCE_NO_LINK_INFO");
20
0
  declare_integer("HAS_EXP_STRING");
21
0
  declare_integer("RUN_IN_SEPARATE_PROCESS");
22
0
  declare_integer("UNUSED_1");
23
0
  declare_integer("HAS_DARWIN_ID");
24
0
  declare_integer("RUN_AS_USER");
25
0
  declare_integer("HAS_EXP_ICON");
26
0
  declare_integer("NO_PIDL_ALIAS");
27
0
  declare_integer("UNUSED_2");
28
0
  declare_integer("RUN_WITH_SHIM_LAYER");
29
0
  declare_integer("FORCE_NO_LINK_TRACK");
30
0
  declare_integer("ENABLE_TARGET_METADATA");
31
0
  declare_integer("DISABLE_LINK_PATH_TRACKING");
32
0
  declare_integer("DISABLE_KNOWN_FOLDER_TRACKING");
33
0
  declare_integer("DISABLE_KNOWN_FOLDER_ALIAS");
34
0
  declare_integer("ALLOW_LINK_TO_LINK");
35
0
  declare_integer("UNALIAS_ON_SAVE");
36
0
  declare_integer("PREFER_ENVIRONMENT_PATH");
37
0
  declare_integer("KEEP_LOCAL_ID_LIST_FOR_UNC_TARGET");
38
39
0
  declare_integer("FILE_ATTRIBUTE_READONLY");
40
0
  declare_integer("FILE_ATTRIBUTE_HIDDEN");
41
0
  declare_integer("FILE_ATTRIBUTE_SYSTEM");
42
0
  declare_integer("RESERVED_1");
43
0
  declare_integer("FILE_ATTRIBUTE_DIRECTORY");
44
0
  declare_integer("FILE_ATTRIBUTE_ARCHIVE");
45
0
  declare_integer("RESERVED_2");
46
0
  declare_integer("FILE_ATTRIBUTE_NORMAL");
47
0
  declare_integer("FILE_ATTRIBUTE_TEMPORARY");
48
0
  declare_integer("FILE_ATTRIBUTE_SPARSE_FILE");
49
0
  declare_integer("FILE_ATTRIBUTE_REPARSE_POINT");
50
0
  declare_integer("FILE_ATTRIBUTE_COMPRESSED");
51
0
  declare_integer("FILE_ATTRIBUTE_OFFLINE");
52
0
  declare_integer("FILE_ATTRIBUTE_NOT_CONTENT_INDEXED");
53
0
  declare_integer("FILE_ATTRIBUTE_ENCRYPTED");
54
55
0
  declare_integer("SW_SHOWNORMAL");
56
0
  declare_integer("SW_SHOWMAXIMIZED");
57
0
  declare_integer("SW_SHOWMINNOACTIVE");
58
59
0
  declare_integer("HOTKEYF_SHIFT");
60
0
  declare_integer("HOTKEYF_CONTROL");
61
0
  declare_integer("HOTKEYF_ALT");
62
63
0
  declare_integer("VOLUME_ID_AND_LOCAL_BASE_PATH");
64
0
  declare_integer("COMMON_NETWORK_RELATIVE_LINK_AND_PATH_SUFFIX");
65
66
0
  declare_integer("DRIVE_UNKNOWN");
67
0
  declare_integer("DRIVE_NO_ROOT_DIR");
68
0
  declare_integer("DRIVE_REMOVABLE");
69
0
  declare_integer("DRIVE_FIXED");
70
0
  declare_integer("DRIVE_REMOTE");
71
0
  declare_integer("DRIVE_CDROM");
72
0
  declare_integer("DRIVE_RAMDISK");
73
74
0
  declare_integer("VALID_DEVICE");
75
0
  declare_integer("VALID_NET_TYPE");
76
77
0
  declare_integer("WNNC_NET_AVID");
78
0
  declare_integer("WNNC_NET_DOCUSPACE");
79
0
  declare_integer("WNNC_NET_MANGOSOFT");
80
0
  declare_integer("WNNC_NET_SERNET");
81
0
  declare_integer("WNNC_NET_RIVERFRONT1");
82
0
  declare_integer("WNNC_NET_RIVERFRONT2");
83
0
  declare_integer("WNNC_NET_DECORB");
84
0
  declare_integer("WNNC_NET_PROTSTOR");
85
0
  declare_integer("WNNC_NET_FJ_REDIR");
86
0
  declare_integer("WNNC_NET_DISTINCT");
87
0
  declare_integer("WNNC_NET_TWINS");
88
0
  declare_integer("WNNC_NET_RDR2SAMPLE");
89
0
  declare_integer("WNNC_NET_CSC");
90
0
  declare_integer("WNNC_NET_3IN1");
91
0
  declare_integer("WNNC_NET_EXTENDNET");
92
0
  declare_integer("WNNC_NET_STAC");
93
0
  declare_integer("WNNC_NET_FOXBAT");
94
0
  declare_integer("WNNC_NET_YAHOO");
95
0
  declare_integer("WNNC_NET_EXIFS");
96
0
  declare_integer("WNNC_NET_DAV");
97
0
  declare_integer("WNNC_NET_KNOWARE");
98
0
  declare_integer("WNNC_NET_OBJECT_DIRE");
99
0
  declare_integer("WNNC_NET_MASFAX");
100
0
  declare_integer("WNNC_NET_HOB_NFS");
101
0
  declare_integer("WNNC_NET_SHIVA");
102
0
  declare_integer("WNNC_NET_IBMAL");
103
0
  declare_integer("WNNC_NET_LOCK");
104
0
  declare_integer("WNNC_NET_TERMSRV");
105
0
  declare_integer("WNNC_NET_SRT");
106
0
  declare_integer("WNNC_NET_QUINCY");
107
0
  declare_integer("WNNC_NET_OPENAFS");
108
0
  declare_integer("WNNC_NET_AVID1");
109
0
  declare_integer("WNNC_NET_DFS");
110
0
  declare_integer("WNNC_NET_KWNP");
111
0
  declare_integer("WNNC_NET_ZENWORKS");
112
0
  declare_integer("WNNC_NET_DRIVEONWEB");
113
0
  declare_integer("WNNC_NET_VMWARE");
114
0
  declare_integer("WNNC_NET_RSFX");
115
0
  declare_integer("WNNC_NET_MFILES");
116
0
  declare_integer("WNNC_NET_MS_NFS");
117
0
  declare_integer("WNNC_NET_GOOGLE");
118
119
0
  declare_integer("FOREGROUND_BLUE");
120
0
  declare_integer("FOREGROUND_GREEN");
121
0
  declare_integer("FOREGROUND_RED");
122
0
  declare_integer("FOREGROUND_INTENSITY");
123
0
  declare_integer("BACKGROUND_BLUE");
124
0
  declare_integer("BACKGROUND_GREEN");
125
0
  declare_integer("BACKGROUND_RED");
126
0
  declare_integer("BACKGROUND_INTENSITY");
127
128
0
  declare_integer("FF_DONTCARE");
129
0
  declare_integer("FF_ROMAN");
130
0
  declare_integer("FF_SWISS");
131
0
  declare_integer("FF_MODERN");
132
0
  declare_integer("FF_SCRIPT");
133
0
  declare_integer("FF_DECORATIVE");
134
135
0
  declare_integer("TMPF_NONE");
136
0
  declare_integer("TMPF_FIXED_PITCH");
137
0
  declare_integer("TMPF_VECTOR");
138
0
  declare_integer("TMPF_TRUETYPE");
139
0
  declare_integer("TMPF_DEVICE");
140
141
0
  declare_integer("is_lnk");
142
0
  declare_integer("creation_time");
143
0
  declare_integer("access_time");
144
0
  declare_integer("write_time");
145
0
  declare_integer("file_size");
146
0
  declare_integer("link_flags");
147
0
  declare_integer("file_attributes_flags");
148
0
  declare_integer("icon_index");
149
0
  declare_integer("show_command");
150
0
  declare_integer("hotkey_flags");
151
152
0
  declare_string("hotkey");
153
0
  declare_integer("hotkey_modifier_flags");
154
0
  declare_integer("has_hotkey");
155
156
0
  begin_struct("link_target_id_list");
157
0
    begin_struct_array("item_id_list");
158
0
      declare_integer("size");
159
0
      declare_string("data");
160
0
    end_struct_array("item_id_list");
161
162
0
    declare_integer("number_of_item_ids");
163
0
    declare_integer("item_id_list_size");
164
0
  end_struct("link_target_id_list");
165
166
0
  begin_struct("link_info");
167
0
    declare_integer("size");
168
0
    declare_integer("header_size");
169
0
    declare_integer("flags");
170
0
    declare_integer("volume_id_offset");
171
0
    declare_integer("local_base_path_offset");
172
0
    declare_integer("common_network_relative_link_offset");
173
0
    declare_integer("common_path_suffix_offset");
174
0
    declare_integer("local_base_path_offset_unicode");
175
0
    declare_integer("common_path_suffix_offset_unicode");
176
177
0
    declare_integer("has_volume_id");
178
179
0
    begin_struct("volume_id");
180
0
      declare_integer("size");
181
0
      declare_integer("drive_type");
182
0
      declare_integer("drive_serial_number");
183
0
      declare_integer("volume_label_offset");
184
0
      declare_integer("volume_label_offset_unicode");
185
0
      declare_string("data");
186
0
    end_struct("volume_id");
187
188
0
    declare_string("local_base_path");
189
190
0
    declare_integer("has_common_network_relative_link");
191
192
0
    begin_struct("common_network_relative_link");
193
0
      declare_integer("size");
194
0
      declare_integer("flags");
195
0
      declare_integer("net_name_offset");
196
0
      declare_integer("device_name_offset");
197
0
      declare_integer("network_provider_type");
198
0
      declare_integer("net_name_offset_unicode");
199
0
      declare_integer("device_name_offset_unicode");
200
0
      declare_string("net_name");
201
0
      declare_string("device_name");
202
0
      declare_string("net_name_unicode");
203
0
      declare_string("device_name_unicode");
204
0
    end_struct("common_network_relative_link");
205
206
0
    declare_string("common_path_suffix");
207
0
    declare_string("local_base_path_unicode");
208
0
    declare_string("common_path_suffix_unicode");
209
0
  end_struct("link_info");
210
211
0
  declare_string("name_string");
212
0
  declare_string("relative_path");
213
0
  declare_string("working_dir");
214
0
  declare_string("command_line_arguments");
215
0
  declare_string("icon_location");
216
217
0
  declare_integer("has_console_data");
218
219
0
  begin_struct("console_data");
220
0
    declare_integer("block_size");
221
0
    declare_integer("block_signature");
222
0
    declare_integer("fill_attributes");
223
0
    declare_integer("popup_fill_attributes");
224
0
    declare_integer("screen_buffer_size_x");
225
0
    declare_integer("screen_buffer_size_y");
226
0
    declare_integer("window_size_x");
227
0
    declare_integer("window_size_y");
228
0
    declare_integer("window_origin_x");
229
0
    declare_integer("window_origin_y");
230
0
    declare_integer("font_size");
231
0
    declare_integer("font_family");
232
0
    declare_integer("font_weight");
233
0
    declare_string("face_name");
234
0
    declare_integer("cursor_size");
235
0
    declare_integer("full_screen");
236
0
    declare_integer("quick_edit");
237
0
    declare_integer("insert_mode");
238
0
    declare_integer("auto_position");
239
0
    declare_integer("history_buffer_size");
240
0
    declare_integer("number_of_history_buffers");
241
0
    declare_integer("history_no_dup");
242
0
    declare_integer_array("color_table");
243
0
  end_struct("console_data");
244
245
0
  declare_integer("has_console_fe_data");
246
247
0
  begin_struct("console_fe_data");
248
0
    declare_integer("block_size");
249
0
    declare_integer("block_signature");
250
0
    declare_integer("code_page");
251
0
  end_struct("console_fe_data");
252
253
0
  declare_integer("has_darwin_data");
254
255
0
  begin_struct("darwin_data");
256
0
    declare_integer("block_size");
257
0
    declare_integer("block_signature");
258
0
    declare_string("darwin_data_ansi");
259
0
    declare_string("darwin_data_unicode");
260
0
  end_struct("darwin_data");
261
262
0
  declare_integer("has_environment_variable_data");
263
264
0
  begin_struct("environment_variable_data");
265
0
    declare_integer("block_size");
266
0
    declare_integer("block_signature");
267
0
    declare_string("target_ansi");
268
0
    declare_string("target_unicode");
269
0
  end_struct("environment_variable_data");
270
271
0
  declare_integer("has_icon_environment_data");
272
273
0
  begin_struct("icon_environment_data");
274
0
    declare_integer("block_size");
275
0
    declare_integer("block_signature");
276
0
    declare_string("target_ansi");
277
0
    declare_string("target_unicode");
278
0
  end_struct("icon_environment_data");
279
280
0
  declare_integer("has_known_folder_data");
281
282
0
  begin_struct("known_folder_data");
283
0
    declare_integer("block_size");
284
0
    declare_integer("block_signature");
285
0
    declare_integer("offset");
286
0
    declare_integer_array("known_folder_id");
287
0
  end_struct("known_folder_data");
288
289
0
  declare_integer("has_property_store_data");
290
291
0
  begin_struct("property_store_data");
292
0
    declare_integer("block_size");
293
0
    declare_integer("block_signature");
294
0
  end_struct("property_store_data");
295
296
0
  declare_integer("has_shim_data");
297
298
0
  begin_struct("shim_data");
299
0
    declare_integer("block_size");
300
0
    declare_integer("block_signature");
301
0
    declare_string("layer_name");
302
0
  end_struct("shim_data");
303
304
0
  declare_integer("has_special_folder_data");
305
306
0
  begin_struct("special_folder_data");
307
0
    declare_integer("block_size");
308
0
    declare_integer("block_signature");
309
0
    declare_integer("special_folder_id");
310
0
    declare_integer("offset");
311
0
  end_struct("special_folder_data");
312
313
0
  declare_integer("has_tracker_data");
314
315
0
  begin_struct("tracker_data");
316
0
    declare_integer("block_size");
317
0
    declare_integer("block_signature");
318
0
    declare_string("machine_id");
319
0
    declare_string("droid_volume_identifier");
320
0
    declare_string("droid_file_identifier");
321
0
    declare_string("droid_birth_volume_identifier");
322
0
    declare_string("droid_birth_file_identifier");
323
0
  end_struct("tracker_data");
324
325
0
  declare_integer("has_vista_and_above_id_list_data");
326
327
0
  begin_struct("vista_and_above_id_list_data");
328
0
    declare_integer("block_size");
329
0
    declare_integer("block_signature");
330
0
    declare_integer("number_of_item_ids");
331
332
0
    begin_struct_array("item_id_list");
333
0
      declare_integer("size");
334
0
      declare_string("data");
335
0
    end_struct_array("item_id_list");
336
0
  end_struct("vista_and_above_id_list_data");
337
338
0
  declare_integer("has_overlay");
339
0
  declare_integer("overlay_offset");
340
341
0
  declare_integer("is_malformed");
342
0
end_declarations
343
344
uint32_t parse_id_list(
345
    const uint8_t* id_list_ptr,
346
    YR_OBJECT* module_object,
347
    uint32_t block_data_size_remaining,
348
    bool extra_data)
349
0
{
350
0
  uint16_t item_id_size;
351
0
  uint32_t num_item_ids = 0;
352
0
  const uint8_t* item_id_data_ptr;
353
354
  // Get the first ItemIDSize
355
0
  if (block_data_size_remaining < sizeof(item_id_size))
356
0
  {
357
0
    return 0;
358
0
  }
359
0
  memcpy(&item_id_size, id_list_ptr, sizeof(item_id_size));
360
0
  block_data_size_remaining -= sizeof(item_id_size);
361
362
0
  while (yr_le16toh(item_id_size) != 0)
363
0
  {
364
    // Subtract 2 to not include it
365
0
    if (extra_data)
366
0
    {
367
0
      yr_set_integer(
368
0
          yr_le16toh(item_id_size) - 2,
369
0
          module_object,
370
0
          "vista_and_above_id_list_data.item_id_list[%i].size",
371
0
          num_item_ids);
372
0
    }
373
0
    else
374
0
    {
375
0
      yr_set_integer(
376
0
          yr_le16toh(item_id_size) - 2,
377
0
          module_object,
378
0
          "link_target_id_list.item_id_list[%i].size",
379
0
          num_item_ids);
380
0
    }
381
382
    // Get pointer to the ItemID Data
383
0
    item_id_data_ptr = id_list_ptr + sizeof(item_id_size);
384
385
0
    if (block_data_size_remaining < yr_le16toh(item_id_size) - sizeof(item_id_size))
386
0
    {
387
0
      return 0;
388
0
    }
389
390
0
    if (extra_data)
391
0
    {
392
0
      yr_set_sized_string(
393
0
          (const char*) item_id_data_ptr,
394
0
          yr_le16toh(item_id_size) - sizeof(item_id_size),
395
0
          module_object,
396
0
          "vista_and_above_id_list_data.item_id_list[%i].data",
397
0
          num_item_ids);
398
0
    }
399
0
    else
400
0
    {
401
0
      yr_set_sized_string(
402
0
          (const char*) item_id_data_ptr,
403
0
          yr_le16toh(item_id_size) - sizeof(item_id_size),
404
0
          module_object,
405
0
          "link_target_id_list.item_id_list[%i].data",
406
0
          num_item_ids);
407
0
    }
408
0
    block_data_size_remaining -= yr_le16toh(item_id_size) - sizeof(item_id_size);
409
410
0
    num_item_ids += 1;
411
0
    id_list_ptr += yr_le16toh(item_id_size);
412
413
    // Get the next ItemIDSize (or 0x0000 if we've reached TerminalID)
414
0
    if (block_data_size_remaining < sizeof(item_id_size))
415
0
    {
416
0
      return 0;
417
0
    }
418
0
    memcpy(&item_id_size, id_list_ptr, sizeof(item_id_size));
419
0
    block_data_size_remaining -= sizeof(item_id_size);
420
0
  }
421
422
0
  if (extra_data)
423
0
  {
424
0
    yr_set_integer(
425
0
        num_item_ids,
426
0
        module_object,
427
0
        "vista_and_above_id_list_data.number_of_item_ids");
428
0
  }
429
0
  else
430
0
  {
431
0
    yr_set_integer(
432
0
        num_item_ids, module_object, "link_target_id_list.number_of_item_ids");
433
0
  }
434
435
0
  return 1;
436
0
}
437
438
uint32_t parse_link_target_id_list(
439
    const uint8_t* link_target_id_list_ptr,
440
    YR_OBJECT* module_object,
441
    uint32_t block_data_size_remaining)
442
0
{
443
0
  uint16_t id_list_size;
444
445
  // First, get the IDListSize
446
0
  if (block_data_size_remaining < sizeof(id_list_size))
447
0
  {
448
0
    return 0;
449
0
  }
450
0
  memcpy(&id_list_size, link_target_id_list_ptr, sizeof(id_list_size));
451
0
  block_data_size_remaining -= sizeof(id_list_size);
452
453
0
  yr_set_integer(
454
0
      yr_le16toh(id_list_size), module_object, "link_target_id_list.item_id_list_size");
455
456
  // Get pointer to start of IDList
457
0
  link_target_id_list_ptr += sizeof(id_list_size);
458
459
0
  if (!parse_id_list(
460
0
          link_target_id_list_ptr,
461
0
          module_object,
462
0
          block_data_size_remaining,
463
0
          false))
464
0
  {
465
0
    return 0;
466
0
  }
467
468
  // Return the size of the whole section to compute where the next one starts
469
0
  return yr_le16toh(id_list_size) + 2;
470
0
}
471
472
uint32_t parse_volume_id(
473
    const uint8_t* volume_id_ptr,
474
    YR_OBJECT* module_object,
475
    uint32_t block_data_size_remaining)
476
0
{
477
0
  volume_id_t volume_id;
478
0
  uint32_t size_of_data;
479
0
  uint32_t volume_label_offset_unicode;
480
0
  char* volume_id_data=NULL;
481
0
  uint32_t total_data_read = 0;
482
483
0
  if (block_data_size_remaining < sizeof(volume_id_t))
484
0
  {
485
0
    return 0;
486
0
  }
487
488
0
  memcpy(&volume_id, (volume_id_t*) volume_id_ptr, sizeof(volume_id_t));
489
490
0
  yr_set_integer(
491
0
      yr_le32toh(volume_id.volume_id_size), module_object, "link_info.volume_id.size");
492
0
  yr_set_integer(
493
0
      yr_le32toh(volume_id.drive_type), module_object, "link_info.volume_id.drive_type");
494
0
  yr_set_integer(
495
0
      yr_le32toh(volume_id.drive_serial_number),
496
0
      module_object,
497
0
      "link_info.volume_id.drive_serial_number");
498
0
  yr_set_integer(
499
0
      yr_le32toh(volume_id.volume_label_offset),
500
0
      module_object,
501
0
      "link_info.volume_id.volume_label_offset");
502
503
  // To work out the size of the data, we need to subtract the size of
504
  // the whole structure from the VolumeIDSize. However, this structure
505
  // size is variable based on if the unicode offset is present.
506
0
  size_of_data = yr_le32toh(volume_id.volume_id_size) - yr_le32toh(volume_id.volume_label_offset);
507
508
0
  volume_id_ptr += sizeof(volume_id_t);
509
0
  block_data_size_remaining -= sizeof(volume_id_t);
510
0
  total_data_read += sizeof(volume_id_t);
511
512
0
  if (yr_le32toh(volume_id.volume_label_offset) == 0x14)
513
0
  {
514
0
    if (block_data_size_remaining < sizeof(volume_label_offset_unicode))
515
0
    {
516
0
      return 0;
517
0
    }
518
519
0
    memcpy(
520
0
        &volume_label_offset_unicode,
521
0
        volume_id_ptr,
522
0
        sizeof(volume_label_offset_unicode));
523
0
    yr_set_integer(
524
0
        yr_le32toh(volume_label_offset_unicode),
525
0
        module_object,
526
0
        "link_info.volume_id.volume_label_offset_unicode");
527
0
    volume_id_ptr += sizeof(volume_label_offset_unicode);
528
0
    block_data_size_remaining -= sizeof(volume_label_offset_unicode);
529
0
    total_data_read += sizeof(volume_label_offset_unicode);
530
531
    // Compensate for extra entry in the structure
532
    // Todo: Extra checks if this size makes sense?
533
0
    size_of_data = yr_le32toh(volume_id.volume_id_size) - yr_le32toh(volume_label_offset_unicode);
534
0
  }
535
536
0
  if (block_data_size_remaining < size_of_data)
537
0
  {
538
0
    return 0;
539
0
  }
540
541
0
  if (size_of_data > 256) {
542
0
    return 0;
543
0
  }
544
545
0
  volume_id_data = yr_malloc(size_of_data);
546
547
0
  memcpy(volume_id_data, volume_id_ptr, size_of_data);
548
0
  yr_set_sized_string(
549
0
      volume_id_data, size_of_data, module_object, "link_info.volume_id.data");
550
551
0
  volume_id_ptr += size_of_data;
552
0
  block_data_size_remaining -= size_of_data;
553
0
  total_data_read += size_of_data;
554
555
0
  if (volume_id_data) {
556
0
    yr_free(volume_id_data);
557
0
  }
558
559
0
  return total_data_read;
560
0
}
561
562
uint32_t parse_common_network_relative_link(
563
    const uint8_t* common_network_relative_link_ptr,
564
    YR_OBJECT* module_object,
565
    uint32_t block_data_size_remaining)
566
0
{
567
0
  common_network_relative_link_t common_network_relative_link;
568
0
  uint32_t net_name_offset_unicode = 0;
569
0
  uint32_t device_name_offset_unicode = 0;
570
0
  char* net_name=NULL;
571
0
  char* device_name=NULL;
572
0
  wchar_t* net_name_unicode=NULL;
573
0
  wchar_t* device_name_unicode=NULL;
574
0
  uint32_t net_name_len;
575
0
  uint32_t device_name_len;
576
0
  uint32_t net_name_unicode_len;
577
0
  uint32_t device_name_unicode_len;
578
579
0
  if (block_data_size_remaining < sizeof(common_network_relative_link_t))
580
0
  {
581
0
    return 0;
582
0
  }
583
584
0
  memcpy(
585
0
      &common_network_relative_link,
586
0
      (common_network_relative_link_t*) common_network_relative_link_ptr,
587
0
      sizeof(common_network_relative_link_t));
588
589
0
  yr_set_integer(
590
0
      yr_le32toh(common_network_relative_link.common_network_relative_link_size),
591
0
      module_object,
592
0
      "link_info.common_network_relative_link.size");
593
0
  yr_set_integer(
594
0
      yr_le32toh(common_network_relative_link.common_network_relative_link_flags),
595
0
      module_object,
596
0
      "link_info.common_network_relative_link.flags");
597
0
  yr_set_integer(
598
0
      yr_le32toh(common_network_relative_link.net_name_offset),
599
0
      module_object,
600
0
      "link_info.common_network_relative_link.net_name_offset");
601
0
  yr_set_integer(
602
0
      yr_le32toh(common_network_relative_link.device_name_offset),
603
0
      module_object,
604
0
      "link_info.common_network_relative_link.device_name_offset");
605
0
  yr_set_integer(
606
0
      yr_le32toh(common_network_relative_link.network_provider_type),
607
0
      module_object,
608
0
      "link_info.common_network_relative_link.network_provider_type");
609
610
0
  common_network_relative_link_ptr += sizeof(common_network_relative_link_t);
611
0
  block_data_size_remaining -= sizeof(common_network_relative_link_t);
612
613
0
  if (yr_le32toh(common_network_relative_link.net_name_offset) > 0x14)
614
0
  {
615
0
    if (block_data_size_remaining < sizeof(net_name_offset_unicode))
616
0
    {
617
0
      return 0;
618
0
    }
619
620
0
    memcpy(
621
0
        &net_name_offset_unicode,
622
0
        common_network_relative_link_ptr,
623
0
        sizeof(net_name_offset_unicode));
624
0
    yr_set_integer(
625
0
        yr_le32toh(net_name_offset_unicode),
626
0
        module_object,
627
0
        "link_info.common_network_relative_link.net_name_offset_unicode");
628
0
    common_network_relative_link_ptr += sizeof(net_name_offset_unicode);
629
0
    block_data_size_remaining -= sizeof(net_name_offset_unicode);
630
631
0
    if (block_data_size_remaining < sizeof(device_name_offset_unicode))
632
0
    {
633
0
      return 0;
634
0
    }
635
636
0
    memcpy(
637
0
        &device_name_offset_unicode,
638
0
        common_network_relative_link_ptr,
639
0
        sizeof(device_name_offset_unicode));
640
0
    yr_set_integer(
641
0
        yr_le32toh(device_name_offset_unicode),
642
0
        module_object,
643
0
        "link_info.common_network_relative_link.device_name_offset_unicode");
644
0
    common_network_relative_link_ptr += sizeof(device_name_offset_unicode);
645
0
    block_data_size_remaining -= sizeof(device_name_offset_unicode);
646
647
    // Parse unicode strings
648
0
    net_name_unicode_len = wcslen(
649
0
        (const wchar_t*) common_network_relative_link_ptr);
650
651
0
    if (block_data_size_remaining < net_name_unicode_len * 2)
652
0
    {
653
0
      return 0;
654
0
    }
655
656
0
    if (net_name_unicode_len > 260) {
657
0
      return 0;
658
0
    }
659
660
0
    net_name_unicode = yr_malloc(net_name_unicode_len * 2);
661
662
0
    memcpy(
663
0
        net_name_unicode,
664
0
        common_network_relative_link_ptr,
665
0
        net_name_unicode_len * 2);
666
667
0
    yr_set_sized_string(
668
0
        (char*) net_name_unicode,
669
0
        net_name_unicode_len,
670
0
        module_object,
671
0
        "link_info.common_network_relative_link.net_name_unicode");
672
673
    // Add 1 to deal with null terminator
674
0
    common_network_relative_link_ptr += (net_name_unicode_len * 2) + 1;
675
0
    block_data_size_remaining -= (net_name_unicode_len * 2) + 1;
676
677
0
    device_name_unicode_len = wcslen(
678
0
        (const wchar_t*) common_network_relative_link_ptr);
679
680
0
    if (block_data_size_remaining < device_name_unicode_len * 2)
681
0
    {
682
0
      return 0;
683
0
    }
684
685
0
    if (device_name_unicode_len > 260) {
686
0
      return 0;
687
0
    }
688
689
0
    device_name_unicode = yr_malloc(device_name_unicode_len * 2);
690
691
0
    memcpy(
692
0
        device_name_unicode,
693
0
        common_network_relative_link_ptr,
694
0
        device_name_unicode_len * 2);
695
696
0
    yr_set_sized_string(
697
0
        (char*) device_name_unicode,
698
0
        device_name_unicode_len,
699
0
        module_object,
700
0
        "link_info.common_network_relative_link.device_name_unicode");
701
702
    // Add 1 to deal with null terminator
703
0
    common_network_relative_link_ptr += (device_name_unicode_len * 2) + 1;
704
0
    block_data_size_remaining -= (device_name_unicode_len * 2) + 1;
705
0
  }
706
707
  // Otherwise parse ASCII strings
708
0
  else
709
0
  {
710
0
    net_name_len = strlen((const char*) common_network_relative_link_ptr);
711
712
0
    if (block_data_size_remaining < net_name_len)
713
0
    {
714
0
      return 0;
715
0
    }
716
717
0
    if (net_name_len > 260) {
718
0
      return 0;
719
0
    }
720
721
0
    net_name = yr_malloc(net_name_len);
722
723
0
    memcpy(net_name, common_network_relative_link_ptr, net_name_len);
724
725
0
    yr_set_sized_string(
726
0
        net_name,
727
0
        net_name_len,
728
0
        module_object,
729
0
        "link_info.common_network_relative_link.net_name");
730
731
    // Add 1 to deal with null terminator
732
0
    common_network_relative_link_ptr += net_name_len + 1;
733
0
    block_data_size_remaining -= net_name_len + 1;
734
735
0
    device_name_len = strlen((const char*) common_network_relative_link_ptr);
736
737
0
    if (block_data_size_remaining < device_name_len)
738
0
    {
739
0
      return 0;
740
0
    }
741
742
0
    if (device_name_len > 260) {
743
0
      return 0;
744
0
    }
745
746
0
    device_name = yr_malloc(device_name_len);
747
748
0
    memcpy(device_name, common_network_relative_link_ptr, device_name_len);
749
750
0
    yr_set_sized_string(
751
0
        device_name,
752
0
        device_name_len,
753
0
        module_object,
754
0
        "link_info.common_network_relative_link.device_name");
755
756
    // Add 1 to deal with null terminator
757
0
    common_network_relative_link_ptr += device_name_len + 1;
758
0
    block_data_size_remaining -= device_name_len + 1;
759
0
  }
760
761
0
  if (net_name) {
762
0
    yr_free(net_name);
763
0
  }
764
765
0
  if (device_name) {
766
0
    yr_free(device_name);
767
0
  }
768
769
0
  if (net_name_unicode) {
770
0
    yr_free(net_name_unicode);
771
0
  }
772
773
0
  if (device_name_unicode) {
774
0
    yr_free(device_name_unicode);
775
0
  }
776
777
0
  return yr_le32toh(common_network_relative_link.common_network_relative_link_size);
778
0
}
779
780
uint32_t parse_link_info(
781
    const uint8_t* link_info_ptr,
782
    YR_OBJECT* module_object,
783
    uint32_t block_data_size_remaining)
784
0
{
785
0
  link_info_fixed_header_t* link_info_fixed_header;
786
0
  uint32_t local_base_path_offset_unicode = 0;
787
0
  uint32_t common_path_suffix_offset_unicode = 0;
788
0
  char* local_base_path=NULL;
789
0
  char* common_path_suffix=NULL;
790
0
  wchar_t* local_base_path_unicode=NULL;
791
0
  wchar_t* common_path_suffix_unicode=NULL;
792
0
  uint32_t local_base_path_len;
793
0
  uint32_t common_path_suffix_len;
794
0
  uint32_t local_base_path_unicode_len;
795
0
  uint32_t common_path_suffix_unicode_len;
796
0
  uint32_t volume_id_size;
797
0
  uint32_t common_network_relative_link_size;
798
799
0
  if (block_data_size_remaining < sizeof(link_info_fixed_header_t))
800
0
  {
801
0
    return 0;
802
0
  }
803
0
  link_info_fixed_header = (link_info_fixed_header_t*) link_info_ptr;
804
805
0
  yr_set_integer(
806
0
      yr_le32toh(link_info_fixed_header->link_info_size), module_object, "link_info.size");
807
0
  yr_set_integer(
808
0
      yr_le32toh(link_info_fixed_header->link_info_header_size),
809
0
      module_object,
810
0
      "link_info.header_size");
811
0
  yr_set_integer(
812
0
      yr_le32toh(link_info_fixed_header->link_info_flags),
813
0
      module_object,
814
0
      "link_info.flags");
815
0
  yr_set_integer(
816
0
      yr_le32toh(link_info_fixed_header->volume_id_offset),
817
0
      module_object,
818
0
      "link_info.volume_id_offset");
819
0
  yr_set_integer(
820
0
      yr_le32toh(link_info_fixed_header->local_base_path_offset),
821
0
      module_object,
822
0
      "link_info.local_base_path_offset");
823
0
  yr_set_integer(
824
0
      yr_le32toh(link_info_fixed_header->common_network_relative_link_offset),
825
0
      module_object,
826
0
      "link_info.common_network_relative_link_offset");
827
0
  yr_set_integer(
828
0
      yr_le32toh(link_info_fixed_header->common_path_suffix_offset),
829
0
      module_object,
830
0
      "link_info.common_path_suffix_offset");
831
832
0
  link_info_ptr += sizeof(link_info_fixed_header_t);
833
0
  block_data_size_remaining -= sizeof(link_info_fixed_header_t);
834
835
  // if VOLUME_ID_AND_LOCAL_BASE_PATH flag:
836
  //   VolumeID and LocalBasePath present
837
  //   VolumeIDOffset and LocalBasePathOffset specify offsets
838
  //   if LinkInfoHeaderSize > 0x24:
839
  //     LocalBasePathUnicode present (specified by offset value)
840
  // else
841
  //   VolumeID, LocalBasePath, and LocalBasePathUnicode fields are not present
842
  //   VolumeIDOffset and LocalBasePathOffset are 0
843
  //   if LinkInfoHeaderSize > 0x24:
844
  //     LocalBasePathOffsetUnicode is 0
845
846
0
  if (yr_le32toh(link_info_fixed_header->link_info_flags) & VOLUME_ID_AND_LOCAL_BASE_PATH)
847
0
  {
848
0
    if (yr_le32toh(link_info_fixed_header->link_info_header_size) >= 0x24)
849
0
    {
850
0
      if (block_data_size_remaining < sizeof(local_base_path_offset_unicode))
851
0
      {
852
0
        return 0;
853
0
      }
854
855
0
      memcpy(
856
0
          &local_base_path_offset_unicode,
857
0
          link_info_ptr,
858
0
          sizeof(local_base_path_offset_unicode));
859
0
      yr_set_integer(
860
0
          yr_le32toh(local_base_path_offset_unicode),
861
0
          module_object,
862
0
          "link_info.local_base_path_offset_unicode");
863
0
      link_info_ptr += sizeof(local_base_path_offset_unicode);
864
0
      block_data_size_remaining -= sizeof(local_base_path_offset_unicode);
865
0
    }
866
867
0
    if (yr_le32toh(link_info_fixed_header->volume_id_offset))
868
0
    {
869
0
      yr_set_integer(1, module_object, "link_info.has_volume_id");
870
871
0
      volume_id_size = parse_volume_id(
872
0
          link_info_ptr, module_object, block_data_size_remaining);
873
874
0
      if (volume_id_size == 0)
875
0
      {
876
0
        return 0;
877
0
      }
878
879
0
      if (block_data_size_remaining < volume_id_size)
880
0
      {
881
0
        return 0;
882
0
      }
883
884
0
      link_info_ptr += volume_id_size;
885
0
      block_data_size_remaining -= volume_id_size;
886
0
    }
887
888
0
    else
889
0
    {
890
0
      yr_set_integer(0, module_object, "link_info.has_volume_id");
891
0
    }
892
893
    // Handle LocalBasePath
894
0
    if (yr_le32toh(link_info_fixed_header->local_base_path_offset))
895
0
    {
896
0
      local_base_path_len = strlen((const char*) link_info_ptr);
897
898
0
      if (local_base_path_len > 256) {
899
0
        return 0;
900
0
      }
901
902
0
      if (block_data_size_remaining < local_base_path_len)
903
0
      {
904
0
        return 0;
905
0
      }
906
907
0
      local_base_path = (char*)yr_malloc(local_base_path_len);
908
909
0
      memcpy(local_base_path, link_info_ptr, local_base_path_len);
910
0
      yr_set_sized_string(
911
0
          local_base_path,
912
0
          local_base_path_len,
913
0
          module_object,
914
0
          "link_info.local_base_path");
915
916
      // Add 1 to deal with null terminator
917
0
      link_info_ptr += local_base_path_len + 1;
918
0
      block_data_size_remaining -= local_base_path_len + 1;
919
0
    }
920
0
  }
921
922
0
  if (yr_le32toh(link_info_fixed_header->link_info_header_size) >= 0x24)
923
0
  {
924
0
    if (block_data_size_remaining < sizeof(common_path_suffix_offset_unicode))
925
0
    {
926
0
      return 0;
927
0
    }
928
929
0
    memcpy(
930
0
        &common_path_suffix_offset_unicode,
931
0
        link_info_ptr,
932
0
        sizeof(common_path_suffix_offset_unicode));
933
0
    yr_set_integer(
934
0
        yr_le32toh(common_path_suffix_offset_unicode),
935
0
        module_object,
936
0
        "link_info.common_path_suffix_offset_unicode");
937
0
    link_info_ptr += sizeof(common_path_suffix_offset_unicode);
938
0
    block_data_size_remaining -= sizeof(common_path_suffix_offset_unicode);
939
0
  }
940
941
0
  if (yr_le32toh(link_info_fixed_header->link_info_flags) &
942
0
      COMMON_NETWORK_RELATIVE_LINK_AND_PATH_SUFFIX)
943
0
  {
944
0
    if (yr_le32toh(link_info_fixed_header->common_network_relative_link_offset))
945
0
    {
946
0
      common_network_relative_link_size = parse_common_network_relative_link(
947
0
          link_info_ptr, module_object, block_data_size_remaining);
948
949
0
      if (common_network_relative_link_size == 0)
950
0
      {
951
0
        return 0;
952
0
      }
953
954
0
      if (block_data_size_remaining < common_network_relative_link_size)
955
0
      {
956
0
        return 0;
957
0
      }
958
959
0
      link_info_ptr += common_network_relative_link_size;
960
0
      block_data_size_remaining -= common_network_relative_link_size;
961
0
    }
962
0
  }
963
964
  // Handle CommonPathSuffix
965
0
  if (yr_le32toh(link_info_fixed_header->common_path_suffix_offset))
966
0
  {
967
0
    if (block_data_size_remaining < 1)
968
0
    {
969
0
      return 0;
970
0
    }
971
972
    // Have to deal with this possibly being an empty string
973
0
    if (memcmp(link_info_ptr, "\x00", 1) == 0)
974
0
    {
975
0
      yr_set_sized_string(
976
0
          "\x00", 1, module_object, "link_info.common_path_suffix");
977
0
      link_info_ptr += 1;
978
0
      block_data_size_remaining -= 1;
979
0
    }
980
981
0
    else
982
0
    {
983
0
      common_path_suffix_len = strlen((const char*) link_info_ptr);
984
985
0
      if (block_data_size_remaining < common_path_suffix_len)
986
0
      {
987
0
        return 0;
988
0
      }
989
990
0
      if (common_path_suffix_len > 256) {
991
0
        return 0;
992
0
      }
993
994
0
      common_path_suffix = yr_malloc(common_path_suffix_len);
995
996
0
      memcpy(common_path_suffix, link_info_ptr, common_path_suffix_len);
997
998
0
      yr_set_sized_string(
999
0
          common_path_suffix,
1000
0
          common_path_suffix_len,
1001
0
          module_object,
1002
0
          "link_info.common_path_suffix");
1003
1004
      // Add 1 to deal with null terminator
1005
0
      link_info_ptr += common_path_suffix_len + 1;
1006
0
      block_data_size_remaining -= common_path_suffix_len + 1;
1007
0
    }
1008
0
  }
1009
1010
  // TODO: These unicode functions will need some careful testing
1011
  // Need some samples to test against
1012
0
  if (local_base_path_offset_unicode)
1013
0
  {
1014
0
    local_base_path_unicode_len = wcslen((const wchar_t*) link_info_ptr);
1015
1016
0
    if (block_data_size_remaining < local_base_path_unicode_len * 2)
1017
0
    {
1018
0
      return 0;
1019
0
    }
1020
1021
0
    if (local_base_path_unicode_len > 256) {
1022
0
      return 0;
1023
0
    }
1024
1025
0
    local_base_path_unicode = yr_malloc(local_base_path_unicode_len * 2);
1026
1027
0
    memcpy(
1028
0
        local_base_path_unicode,
1029
0
        link_info_ptr,
1030
0
        local_base_path_unicode_len * 2);
1031
1032
0
    yr_set_sized_string(
1033
0
        (char*) local_base_path_unicode,
1034
0
        local_base_path_unicode_len,
1035
0
        module_object,
1036
0
        "link_info.local_base_path_unicode");
1037
1038
    // Add 1 to deal with null terminator
1039
0
    link_info_ptr += (local_base_path_unicode_len * 2) + 1;
1040
0
    block_data_size_remaining -= (local_base_path_unicode_len * 2) + 1;
1041
0
  }
1042
1043
0
  if (common_path_suffix_offset_unicode)
1044
0
  {
1045
0
    if (block_data_size_remaining < 1)
1046
0
    {
1047
0
      return 0;
1048
0
    }
1049
1050
    // Have to deal with this possibly being an empty string
1051
0
    if (memcmp(link_info_ptr, "\x00", 1) == 0)
1052
0
    {
1053
0
      yr_set_sized_string(
1054
0
          "\x00", 1, module_object, "link_info.common_path_suffix_unicode");
1055
0
      link_info_ptr += 1;
1056
0
      block_data_size_remaining -= 1;
1057
0
    }
1058
1059
0
    else
1060
0
    {
1061
0
      common_path_suffix_unicode_len = wcslen((const wchar_t*) link_info_ptr);
1062
1063
0
      if (block_data_size_remaining < common_path_suffix_unicode_len * 2)
1064
0
      {
1065
0
        return 0;
1066
0
      }
1067
1068
0
      if (common_path_suffix_unicode_len > 256) {
1069
0
        return 0;
1070
0
      }
1071
1072
0
      common_path_suffix_unicode = yr_malloc(common_path_suffix_unicode_len * 2);
1073
1074
0
      memcpy(
1075
0
          common_path_suffix_unicode,
1076
0
          link_info_ptr,
1077
0
          common_path_suffix_unicode_len * 2);
1078
1079
0
      yr_set_sized_string(
1080
0
          (char*) common_path_suffix_unicode,
1081
0
          common_path_suffix_unicode_len,
1082
0
          module_object,
1083
0
          "link_info.common_path_suffix_unicode");
1084
1085
      // Add 1 to deal with null terminator
1086
0
      link_info_ptr += (common_path_suffix_unicode_len * 2) + 1;
1087
0
      block_data_size_remaining -= (common_path_suffix_unicode_len * 2) + 1;
1088
0
    }
1089
0
  }
1090
1091
0
  if (local_base_path){
1092
0
    yr_free(local_base_path);
1093
0
  }
1094
1095
0
  if (common_path_suffix){
1096
0
    yr_free(common_path_suffix);
1097
0
  }
1098
1099
0
  if (local_base_path_unicode) {
1100
0
    yr_free(local_base_path_unicode);
1101
0
  }
1102
1103
0
  if (common_path_suffix_unicode) {
1104
0
    yr_free(common_path_suffix_unicode);
1105
0
  }
1106
1107
0
  return (int) yr_le32toh(link_info_fixed_header->link_info_size);
1108
0
}
1109
1110
uint32_t parse_string_data(
1111
    const uint8_t* string_data_ptr,
1112
    YR_OBJECT* module_object,
1113
    uint32_t block_data_size_remaining,
1114
    const char* name,
1115
    bool is_unicode)
1116
0
{
1117
0
  uint16_t count_characters;
1118
0
  uint32_t string_size;
1119
1120
  // CountCharacters only returns the number of characters in the string, but
1121
  // not information on whether the string is unicode vs. another type of
1122
  // string. The IS_UNICODE flag will tell us if the StringData values are
1123
  // unicode, and if it is not set, we'll assume it is ascii (although it can be
1124
  // whatever is the default codepage from where the LNK is generated)
1125
1126
0
  if (block_data_size_remaining < sizeof(count_characters))
1127
0
  {
1128
0
    return 0;
1129
0
  }
1130
1131
0
  memcpy(&count_characters, string_data_ptr, sizeof(count_characters));
1132
0
  string_data_ptr += sizeof(count_characters);
1133
0
  block_data_size_remaining -= sizeof(count_characters);
1134
1135
0
  if (is_unicode)
1136
0
  {
1137
0
    if (block_data_size_remaining < yr_le16toh(count_characters) * 2)
1138
0
    {
1139
0
      return 0;
1140
0
    }
1141
1142
0
    string_size = yr_le16toh(count_characters) * 2;
1143
0
  }
1144
1145
0
  else
1146
0
  {
1147
0
    string_size = yr_le16toh(count_characters);
1148
0
  }
1149
1150
  // Do these extra comparisons due to "format not a string literal and no
1151
  // format arguments" error on compilation
1152
0
  if (strcmp(name, "name_string") == 0)
1153
0
  {
1154
0
    yr_set_sized_string(
1155
0
        (char*) string_data_ptr, string_size, module_object, "name_string");
1156
0
  }
1157
1158
0
  else if (strcmp(name, "relative_path") == 0)
1159
0
  {
1160
0
    yr_set_sized_string(
1161
0
        (char*) string_data_ptr, string_size, module_object, "relative_path");
1162
0
  }
1163
1164
0
  else if (strcmp(name, "working_dir") == 0)
1165
0
  {
1166
0
    yr_set_sized_string(
1167
0
        (char*) string_data_ptr, string_size, module_object, "working_dir");
1168
0
  }
1169
1170
0
  else if (strcmp(name, "command_line_arguments") == 0)
1171
0
  {
1172
0
    yr_set_sized_string(
1173
0
        (char*) string_data_ptr,
1174
0
        string_size,
1175
0
        module_object,
1176
0
        "command_line_arguments");
1177
0
  }
1178
1179
0
  else if (strcmp(name, "icon_location") == 0)
1180
0
  {
1181
0
    yr_set_sized_string(
1182
0
        (char*) string_data_ptr, string_size, module_object, "icon_location");
1183
0
  }
1184
1185
0
  else
1186
0
  {
1187
0
    return 0;
1188
0
  }
1189
1190
0
  return string_size + sizeof(count_characters);
1191
0
}
1192
1193
uint32_t parse_console_data_block(
1194
    const uint8_t* extra_block_ptr,
1195
    YR_OBJECT* module_object,
1196
    uint32_t block_data_size_remaining,
1197
    uint32_t extra_data_block_size,
1198
    uint32_t extra_data_block_signature)
1199
0
{
1200
0
  console_data_block_t console_data_block;
1201
0
  int i;
1202
1203
0
  if (block_data_size_remaining < sizeof(console_data_block_t))
1204
0
  {
1205
0
    return 0;
1206
0
  }
1207
1208
0
  memcpy(
1209
0
      &console_data_block,
1210
0
      (console_data_block_t*) extra_block_ptr,
1211
0
      sizeof(console_data_block_t));
1212
1213
0
  yr_set_integer(extra_data_block_size, module_object, "console_data.block_size");
1214
0
  yr_set_integer(
1215
0
      extra_data_block_signature,
1216
0
      module_object,
1217
0
      "console_data.block_signature");
1218
0
  yr_set_integer(
1219
0
      yr_le16toh(console_data_block.fill_attributes),
1220
0
      module_object,
1221
0
      "console_data.fill_attributes");
1222
0
  yr_set_integer(
1223
0
      yr_le16toh(console_data_block.popup_fill_attributes),
1224
0
      module_object,
1225
0
      "console_data.popup_fill_attributes");
1226
0
  yr_set_integer(
1227
0
      yr_le16toh(console_data_block.screen_buffer_size_x),
1228
0
      module_object,
1229
0
      "console_data.screen_buffer_size_x");
1230
0
  yr_set_integer(
1231
0
      yr_le16toh(console_data_block.screen_buffer_size_y),
1232
0
      module_object,
1233
0
      "console_data.screen_buffer_size_y");
1234
0
  yr_set_integer(
1235
0
      yr_le16toh(console_data_block.window_size_x),
1236
0
      module_object,
1237
0
      "console_data.window_size_x");
1238
0
  yr_set_integer(
1239
0
      yr_le16toh(console_data_block.window_size_y),
1240
0
      module_object,
1241
0
      "console_data.window_size_y");
1242
0
  yr_set_integer(
1243
0
      yr_le16toh(console_data_block.window_origin_x),
1244
0
      module_object,
1245
0
      "console_data.window_origin_x");
1246
0
  yr_set_integer(
1247
0
      yr_le16toh(console_data_block.window_origin_y),
1248
0
      module_object,
1249
0
      "console_data.window_origin_y");
1250
0
  yr_set_integer(
1251
0
      yr_le32toh(console_data_block.font_size), module_object, "console_data.font_size");
1252
0
  yr_set_integer(
1253
0
      yr_le32toh(console_data_block.font_family),
1254
0
      module_object,
1255
0
      "console_data.font_family");
1256
0
  yr_set_integer(
1257
0
      yr_le32toh(console_data_block.font_weight),
1258
0
      module_object,
1259
0
      "console_data.font_weight");
1260
0
  yr_set_sized_string(
1261
0
      (char*) console_data_block.face_name,
1262
0
      wcslen((wchar_t*) console_data_block.face_name),
1263
0
      module_object,
1264
0
      "console_data.face_name");
1265
0
  yr_set_integer(
1266
0
      yr_le32toh(console_data_block.cursor_size),
1267
0
      module_object,
1268
0
      "console_data.cursor_size");
1269
0
  yr_set_integer(
1270
0
      yr_le32toh(console_data_block.full_screen),
1271
0
      module_object,
1272
0
      "console_data.full_screen");
1273
0
  yr_set_integer(
1274
0
      yr_le32toh(console_data_block.quick_edit), module_object, "console_data.quick_edit");
1275
0
  yr_set_integer(
1276
0
      yr_le32toh(console_data_block.insert_mode),
1277
0
      module_object,
1278
0
      "console_data.insert_mode");
1279
0
  yr_set_integer(
1280
0
      yr_le32toh(console_data_block.auto_position),
1281
0
      module_object,
1282
0
      "console_data.auto_position");
1283
0
  yr_set_integer(
1284
0
      yr_le32toh(console_data_block.history_buffer_size),
1285
0
      module_object,
1286
0
      "console_data.history_buffer_size");
1287
0
  yr_set_integer(
1288
0
      yr_le32toh(console_data_block.number_of_history_buffers),
1289
0
      module_object,
1290
0
      "console_data.number_of_history_buffers");
1291
0
  yr_set_integer(
1292
0
      yr_le32toh(console_data_block.history_no_dup),
1293
0
      module_object,
1294
0
      "console_data.history_no_dup");
1295
1296
0
  for (i = 0; i < 16; i++)
1297
0
  {
1298
0
    yr_set_integer(
1299
0
        yr_le32toh(console_data_block.color_table[i]),
1300
0
        module_object,
1301
0
        "console_data.color_table[%i]",
1302
0
        i);
1303
0
  }
1304
1305
0
  return 1;
1306
0
}
1307
1308
uint32_t parse_console_fe_data_block(
1309
    const uint8_t* extra_block_ptr,
1310
    YR_OBJECT* module_object,
1311
    uint32_t block_data_size_remaining,
1312
    uint32_t extra_data_block_size,
1313
    uint32_t extra_data_block_signature)
1314
0
{
1315
0
  console_fe_data_block_t console_fe_data;
1316
1317
0
  if (block_data_size_remaining < sizeof(console_fe_data_block_t))
1318
0
  {
1319
0
    return 0;
1320
0
  }
1321
1322
0
  memcpy(
1323
0
      &console_fe_data,
1324
0
      (console_fe_data_block_t*) extra_block_ptr,
1325
0
      sizeof(console_fe_data_block_t));
1326
1327
0
  yr_set_integer(
1328
0
      extra_data_block_size, module_object, "console_fe_data.block_size");
1329
0
  yr_set_integer(
1330
0
      extra_data_block_signature,
1331
0
      module_object,
1332
0
      "console_fe_data.block_signature");
1333
0
  yr_set_integer(
1334
0
      yr_le32toh(console_fe_data.code_page), module_object, "console_fe_data.code_page");
1335
1336
0
  return 1;
1337
0
}
1338
1339
uint32_t parse_darwin_data_block(
1340
    const uint8_t* extra_block_ptr,
1341
    YR_OBJECT* module_object,
1342
    uint32_t block_data_size_remaining,
1343
    uint32_t extra_data_block_size,
1344
    uint32_t extra_data_block_signature)
1345
0
{
1346
0
  darwin_data_block_t darwin_data;
1347
1348
0
  if (block_data_size_remaining < sizeof(darwin_data_block_t))
1349
0
  {
1350
0
    return 0;
1351
0
  }
1352
1353
0
  memcpy(
1354
0
      &darwin_data,
1355
0
      (darwin_data_block_t*) extra_block_ptr,
1356
0
      sizeof(darwin_data_block_t));
1357
1358
0
  yr_set_integer(extra_data_block_size, module_object, "darwin_data.block_size");
1359
0
  yr_set_integer(
1360
0
      extra_data_block_signature, module_object, "darwin_data.block_signature");
1361
0
  yr_set_string(
1362
0
      darwin_data.darwin_data_ansi,
1363
0
      module_object,
1364
0
      "darwin_data.darwin_data_ansi");
1365
0
  yr_set_sized_string(
1366
0
      (char*) darwin_data.darwin_data_unicode,
1367
0
      wcslen((wchar_t*) darwin_data.darwin_data_unicode) * 2,
1368
0
      module_object,
1369
0
      "darwin_data.darwin_data_unicode");
1370
1371
0
  return 1;
1372
0
}
1373
1374
uint32_t parse_environment_variable_data_block(
1375
    const uint8_t* extra_block_ptr,
1376
    YR_OBJECT* module_object,
1377
    uint32_t block_data_size_remaining,
1378
    uint32_t extra_data_block_size,
1379
    uint32_t extra_data_block_signature)
1380
0
{
1381
0
  environment_variable_data_block_t environment_variable_data;
1382
1383
0
  if (block_data_size_remaining < sizeof(environment_variable_data_block_t))
1384
0
  {
1385
0
    return 0;
1386
0
  }
1387
1388
0
  memcpy(
1389
0
      &environment_variable_data,
1390
0
      (environment_variable_data_block_t*) extra_block_ptr,
1391
0
      sizeof(environment_variable_data_block_t));
1392
1393
0
  yr_set_integer(
1394
0
      extra_data_block_size,
1395
0
      module_object,
1396
0
      "environment_variable_data.block_size");
1397
0
  yr_set_integer(
1398
0
      extra_data_block_signature,
1399
0
      module_object,
1400
0
      "environment_variable_data.block_signature");
1401
0
  yr_set_string(
1402
0
      environment_variable_data.target_ansi,
1403
0
      module_object,
1404
0
      "environment_variable_data.target_ansi");
1405
0
  yr_set_sized_string(
1406
0
      (char*) environment_variable_data.target_unicode,
1407
0
      wcslen((wchar_t*) environment_variable_data.target_unicode) * 2,
1408
0
      module_object,
1409
0
      "environment_variable_data.target_unicode");
1410
1411
0
  return 1;
1412
0
}
1413
1414
uint32_t parse_icon_environment_data_block(
1415
    const uint8_t* extra_block_ptr,
1416
    YR_OBJECT* module_object,
1417
    uint32_t block_data_size_remaining,
1418
    uint32_t extra_data_block_size,
1419
    uint32_t extra_data_block_signature)
1420
0
{
1421
0
  icon_environment_data_block_t icon_environment_data;
1422
1423
0
  if (block_data_size_remaining < sizeof(icon_environment_data_block_t))
1424
0
  {
1425
0
    return 0;
1426
0
  }
1427
1428
0
  memcpy(
1429
0
      &icon_environment_data,
1430
0
      (icon_environment_data_block_t*) extra_block_ptr,
1431
0
      sizeof(icon_environment_data_block_t));
1432
1433
0
  yr_set_integer(
1434
0
      extra_data_block_size, module_object, "icon_environment_data.block_size");
1435
0
  yr_set_integer(
1436
0
      extra_data_block_signature,
1437
0
      module_object,
1438
0
      "icon_environment_data.block_signature");
1439
0
  yr_set_string(
1440
0
      icon_environment_data.target_ansi,
1441
0
      module_object,
1442
0
      "icon_environment_data.target_ansi");
1443
0
  yr_set_sized_string(
1444
0
      (char*) icon_environment_data.target_unicode,
1445
0
      wcslen((wchar_t*) icon_environment_data.target_unicode) * 2,
1446
0
      module_object,
1447
0
      "icon_environment_data.target_unicode");
1448
1449
0
  return 1;
1450
0
}
1451
1452
uint32_t parse_known_folder_data_block(
1453
    const uint8_t* extra_block_ptr,
1454
    YR_OBJECT* module_object,
1455
    uint32_t block_data_size_remaining,
1456
    uint32_t extra_data_block_size,
1457
    uint32_t extra_data_block_signature)
1458
0
{
1459
0
  known_folder_data_block_t known_folder_data;
1460
0
  int i;
1461
1462
0
  if (block_data_size_remaining < sizeof(known_folder_data_block_t))
1463
0
  {
1464
0
    return 0;
1465
0
  }
1466
1467
0
  memcpy(
1468
0
      &known_folder_data,
1469
0
      (known_folder_data_block_t*) extra_block_ptr,
1470
0
      sizeof(known_folder_data_block_t));
1471
1472
0
  yr_set_integer(
1473
0
      extra_data_block_size, module_object, "known_folder_data.block_size");
1474
0
  yr_set_integer(
1475
0
      extra_data_block_signature,
1476
0
      module_object,
1477
0
      "known_folder_data.block_signature");
1478
0
  yr_set_integer(
1479
0
      yr_le32toh(known_folder_data.offset), module_object, "known_folder_data.offset");
1480
1481
0
  for (i = 0; i < 16; i++)
1482
0
  {
1483
0
    yr_set_integer(
1484
0
        known_folder_data.known_folder_id[i],
1485
0
        module_object,
1486
0
        "known_folder_data.known_folder_id[%i]",
1487
0
        i);
1488
0
  }
1489
1490
0
  return 1;
1491
0
}
1492
1493
uint32_t parse_property_store_data_block(
1494
    const uint8_t* extra_block_ptr,
1495
    YR_OBJECT* module_object,
1496
    uint32_t block_data_size_remaining,
1497
    uint32_t extra_data_block_size,
1498
    uint32_t extra_data_block_signature)
1499
0
{
1500
0
  yr_set_integer(
1501
0
      extra_data_block_size, module_object, "property_store_data.block_size");
1502
0
  yr_set_integer(
1503
0
      extra_data_block_signature,
1504
0
      module_object,
1505
0
      "property_store_data.block_signature");
1506
1507
  // TODO: implement parsing the rest of the structure
1508
  // https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-PROPSTORE/%5bMS-PROPSTORE%5d.pdf
1509
1510
0
  return 1;
1511
0
}
1512
1513
uint32_t parse_shim_data_block(
1514
    const uint8_t* extra_block_ptr,
1515
    YR_OBJECT* module_object,
1516
    uint32_t block_data_size_remaining,
1517
    uint32_t extra_data_block_size,
1518
    uint32_t extra_data_block_signature)
1519
0
{
1520
0
  wchar_t* layer_name;
1521
1522
0
  if (block_data_size_remaining < extra_data_block_size -
1523
0
                                      sizeof(extra_data_block_size) -
1524
0
                                      sizeof(extra_data_block_signature))
1525
0
  {
1526
0
    return 0;
1527
0
  }
1528
1529
0
  layer_name = (wchar_t*) extra_block_ptr;
1530
1531
0
  yr_set_integer(extra_data_block_size, module_object, "shim_data.block_size");
1532
0
  yr_set_integer(
1533
0
      extra_data_block_signature, module_object, "shim_data.block_signature");
1534
0
  yr_set_sized_string(
1535
0
      (char*) layer_name,
1536
0
      extra_data_block_size - sizeof(extra_data_block_size) -
1537
0
          sizeof(extra_data_block_signature),
1538
0
      module_object,
1539
0
      "shim_data.layer_name");
1540
1541
0
  return 1;
1542
0
}
1543
1544
uint32_t parse_special_folder_data_block(
1545
    const uint8_t* extra_block_ptr,
1546
    YR_OBJECT* module_object,
1547
    uint32_t block_data_size_remaining,
1548
    uint32_t extra_data_block_size,
1549
    uint32_t extra_data_block_signature)
1550
0
{
1551
0
  special_folder_data_block_t special_folder_data;
1552
1553
0
  if (block_data_size_remaining < sizeof(special_folder_data_block_t))
1554
0
  {
1555
0
    return 0;
1556
0
  }
1557
1558
0
  memcpy(
1559
0
      &special_folder_data,
1560
0
      (special_folder_data_block_t*) extra_block_ptr,
1561
0
      sizeof(special_folder_data_block_t));
1562
1563
0
  yr_set_integer(
1564
0
      extra_data_block_size, module_object, "special_folder_data.block_size");
1565
0
  yr_set_integer(
1566
0
      extra_data_block_signature,
1567
0
      module_object,
1568
0
      "special_folder_data.block_signature");
1569
0
  yr_set_integer(
1570
0
      yr_le32toh(special_folder_data.special_folder_id),
1571
0
      module_object,
1572
0
      "special_folder_data.special_folder_id");
1573
0
  yr_set_integer(
1574
0
      yr_le32toh(special_folder_data.offset), module_object, "special_folder_data.offset");
1575
1576
0
  return 1;
1577
0
}
1578
1579
uint32_t parse_tracker_data_block(
1580
    const uint8_t* extra_block_ptr,
1581
    YR_OBJECT* module_object,
1582
    uint32_t block_data_size_remaining,
1583
    uint32_t extra_data_block_size,
1584
    uint32_t extra_data_block_signature)
1585
0
{
1586
0
  tracker_data_block_t tracker_data_block;
1587
1588
0
  if (block_data_size_remaining < sizeof(tracker_data_block_t))
1589
0
  {
1590
0
    return 0;
1591
0
  }
1592
1593
0
  memcpy(
1594
0
      &tracker_data_block,
1595
0
      (tracker_data_block_t*) extra_block_ptr,
1596
0
      sizeof(tracker_data_block_t));
1597
1598
0
  yr_set_integer(extra_data_block_size, module_object, "tracker_data.block_size");
1599
0
  yr_set_integer(
1600
0
      extra_data_block_signature,
1601
0
      module_object,
1602
0
      "tracker_data.block_signature");
1603
0
  yr_set_string(
1604
0
      tracker_data_block.machine_id, module_object, "tracker_data.machine_id");
1605
0
  yr_set_sized_string(
1606
0
      (char*) tracker_data_block.droid_volume_identifier,
1607
0
      sizeof(tracker_data_block.droid_volume_identifier),
1608
0
      module_object,
1609
0
      "tracker_data.droid_volume_identifier");
1610
0
  yr_set_sized_string(
1611
0
      (char*) tracker_data_block.droid_file_identifier,
1612
0
      sizeof(tracker_data_block.droid_file_identifier),
1613
0
      module_object,
1614
0
      "tracker_data.droid_file_identifier");
1615
0
  yr_set_sized_string(
1616
0
      (char*) tracker_data_block.droid_birth_volume_identifier,
1617
0
      sizeof(tracker_data_block.droid_birth_volume_identifier),
1618
0
      module_object,
1619
0
      "tracker_data.droid_birth_volume_identifier");
1620
0
  yr_set_sized_string(
1621
0
      (char*) tracker_data_block.droid_birth_file_identifier,
1622
0
      sizeof(tracker_data_block.droid_birth_file_identifier),
1623
0
      module_object,
1624
0
      "tracker_data.droid_birth_file_identifier");
1625
1626
0
  return 1;
1627
0
}
1628
1629
uint32_t parse_vista_and_above_id_list_data_block(
1630
    const uint8_t* extra_block_ptr,
1631
    YR_OBJECT* module_object,
1632
    uint32_t block_data_size_remaining,
1633
    uint32_t extra_data_block_size,
1634
    uint32_t extra_data_block_signature)
1635
0
{
1636
0
  if (block_data_size_remaining < extra_data_block_size -
1637
0
                                      sizeof(extra_data_block_size) -
1638
0
                                      sizeof(extra_data_block_signature))
1639
0
  {
1640
0
    return 0;
1641
0
  }
1642
1643
0
  yr_set_integer(
1644
0
      extra_data_block_size,
1645
0
      module_object,
1646
0
      "vista_and_above_id_list_data.block_size");
1647
0
  yr_set_integer(
1648
0
      extra_data_block_signature,
1649
0
      module_object,
1650
0
      "vista_and_above_id_list_data.block_signature");
1651
0
  if (!parse_id_list(
1652
0
          extra_block_ptr, module_object, block_data_size_remaining, true))
1653
0
  {
1654
0
    return 0;
1655
0
  }
1656
1657
0
  return 1;
1658
0
}
1659
1660
uint32_t parse_extra_block(
1661
    const uint8_t* extra_block_ptr,
1662
    YR_OBJECT* module_object,
1663
    uint32_t block_data_size_remaining,
1664
    uint32_t extra_data_block_size,
1665
    uint32_t extra_data_block_signature)
1666
0
{
1667
1668
0
  switch (extra_data_block_signature)
1669
0
  {
1670
0
  case CONSOLE_DATA_BLOCK_SIGNATURE:
1671
1672
0
    yr_set_integer(1, module_object, "has_console_data");
1673
1674
0
    if (extra_data_block_size == CONSOLE_DATA_BLOCK_SIZE &&
1675
0
        parse_console_data_block(
1676
0
            extra_block_ptr,
1677
0
            module_object,
1678
0
            block_data_size_remaining,
1679
0
            extra_data_block_size,
1680
0
            extra_data_block_signature))
1681
0
    {
1682
0
      return 1;
1683
0
    }
1684
0
    break;
1685
1686
0
  case CONSOLE_FE_DATA_BLOCK_SIGNATURE:
1687
1688
0
    yr_set_integer(1, module_object, "has_console_fe_data");
1689
1690
0
    if (extra_data_block_size == CONSOLE_FE_DATA_BLOCK_SIZE &&
1691
0
        parse_console_fe_data_block(
1692
0
            extra_block_ptr,
1693
0
            module_object,
1694
0
            block_data_size_remaining,
1695
0
            extra_data_block_size,
1696
0
            extra_data_block_signature))
1697
0
    {
1698
0
      return 1;
1699
0
    }
1700
0
    break;
1701
1702
0
  case DARWIN_DATA_BLOCK_SIGNATURE:
1703
1704
0
    yr_set_integer(1, module_object, "has_darwin_data");
1705
1706
0
    if (extra_data_block_size == DARWIN_DATA_BLOCK_SIZE &&
1707
0
        parse_darwin_data_block(
1708
0
            extra_block_ptr,
1709
0
            module_object,
1710
0
            block_data_size_remaining,
1711
0
            extra_data_block_size,
1712
0
            extra_data_block_signature))
1713
0
    {
1714
0
      return 1;
1715
0
    }
1716
0
    break;
1717
1718
0
  case ENVIRONMENT_VARIABLE_DATA_BLOCK_SIGNATURE:
1719
1720
0
    yr_set_integer(1, module_object, "has_environment_variable_data");
1721
1722
0
    if (extra_data_block_size == ENVIRONMENT_VARIABLE_DATA_BLOCK_SIZE &&
1723
0
        parse_environment_variable_data_block(
1724
0
            extra_block_ptr,
1725
0
            module_object,
1726
0
            block_data_size_remaining,
1727
0
            extra_data_block_size,
1728
0
            extra_data_block_signature))
1729
0
    {
1730
0
      return 1;
1731
0
    }
1732
0
    break;
1733
1734
0
  case ICON_ENVIRONMENT_DATA_BLOCK_SIGNATURE:
1735
1736
0
    yr_set_integer(1, module_object, "has_icon_environment_data");
1737
1738
0
    if (extra_data_block_size == ICON_ENVIRONMENT_DATA_BLOCK_SIZE &&
1739
0
        parse_icon_environment_data_block(
1740
0
            extra_block_ptr,
1741
0
            module_object,
1742
0
            block_data_size_remaining,
1743
0
            extra_data_block_size,
1744
0
            extra_data_block_signature))
1745
0
    {
1746
0
      return 1;
1747
0
    }
1748
0
    break;
1749
1750
0
  case KNOWN_FOLDER_DATA_BLOCK_SIGNATURE:
1751
1752
0
    yr_set_integer(1, module_object, "has_known_folder_data");
1753
1754
0
    if (extra_data_block_size == KNOWN_FOLDER_DATA_BLOCK_SIZE &&
1755
0
        parse_known_folder_data_block(
1756
0
            extra_block_ptr,
1757
0
            module_object,
1758
0
            block_data_size_remaining,
1759
0
            extra_data_block_size,
1760
0
            extra_data_block_signature))
1761
0
    {
1762
0
      return 1;
1763
0
    }
1764
0
    break;
1765
1766
0
  case PROPERTY_STORE_DATA_BLOCK_SIGNATURE:
1767
1768
0
    yr_set_integer(1, module_object, "has_property_store_data");
1769
1770
0
    if (extra_data_block_size >= PROPERTY_STORE_DATA_BLOCK_MIN_SIZE &&
1771
0
        parse_property_store_data_block(
1772
0
            extra_block_ptr,
1773
0
            module_object,
1774
0
            block_data_size_remaining,
1775
0
            extra_data_block_size,
1776
0
            extra_data_block_signature))
1777
0
    {
1778
0
      return 1;
1779
0
    }
1780
0
    break;
1781
1782
0
  case SHIM_DATA_BLOCK_SIGNATURE:
1783
1784
0
    yr_set_integer(1, module_object, "has_shim_data");
1785
1786
0
    if (extra_data_block_size >= SHIM_DATA_BLOCK_MIN_SIZE &&
1787
0
        parse_shim_data_block(
1788
0
            extra_block_ptr,
1789
0
            module_object,
1790
0
            block_data_size_remaining,
1791
0
            extra_data_block_size,
1792
0
            extra_data_block_signature))
1793
0
    {
1794
0
      return 1;
1795
0
    }
1796
0
    break;
1797
1798
0
  case SPECIAL_FOLDER_DATA_BLOCK_SIGNATURE:
1799
1800
0
    yr_set_integer(1, module_object, "has_special_folder_data");
1801
1802
0
    if (extra_data_block_size == SPECIAL_FOLDER_DATA_BLOCK_SIZE &&
1803
0
        parse_special_folder_data_block(
1804
0
            extra_block_ptr,
1805
0
            module_object,
1806
0
            block_data_size_remaining,
1807
0
            extra_data_block_size,
1808
0
            extra_data_block_signature))
1809
0
    {
1810
0
      return 1;
1811
0
    }
1812
0
    break;
1813
1814
0
  case TRACKER_DATA_BLOCK_SIGNATURE:
1815
1816
0
    yr_set_integer(1, module_object, "has_tracker_data");
1817
1818
0
    if (extra_data_block_size == TRACKER_DATA_BLOCK_SIZE &&
1819
0
        parse_tracker_data_block(
1820
0
            extra_block_ptr,
1821
0
            module_object,
1822
0
            block_data_size_remaining,
1823
0
            extra_data_block_size,
1824
0
            extra_data_block_signature))
1825
0
    {
1826
0
      return 1;
1827
0
    }
1828
0
    break;
1829
1830
0
  case VISTA_AND_ABOVE_ID_LIST_DATA_BLOCK_SIGNATURE:
1831
1832
0
    yr_set_integer(1, module_object, "has_vista_and_above_id_list_data");
1833
1834
0
    if (extra_data_block_size >= VISTA_AND_ABOVE_ID_LIST_DATA_BLOCK_MIN_SIZE &&
1835
0
        parse_vista_and_above_id_list_data_block(
1836
0
            extra_block_ptr,
1837
0
            module_object,
1838
0
            block_data_size_remaining,
1839
0
            extra_data_block_size,
1840
0
            extra_data_block_signature))
1841
0
    {
1842
0
      return 1;
1843
0
    }
1844
0
    break;
1845
1846
0
  default:
1847
0
    return 0;
1848
0
  }
1849
1850
0
  return 0;
1851
0
}
1852
1853
int module_initialize(YR_MODULE* module)
1854
2
{
1855
2
  return ERROR_SUCCESS;
1856
2
}
1857
1858
int module_finalize(YR_MODULE* module)
1859
0
{
1860
0
  return ERROR_SUCCESS;
1861
0
}
1862
1863
int module_load(
1864
    YR_SCAN_CONTEXT* context,
1865
    YR_OBJECT* module_object,
1866
    void* module_data,
1867
    size_t module_data_size)
1868
0
{
1869
0
  YR_MEMORY_BLOCK* block;
1870
0
  shell_link_header_t* lnk_header;
1871
0
  yr_set_integer(0, module_object, "is_lnk");
1872
1873
0
  yr_set_integer(HAS_LINK_TARGET_ID_LIST, module_object, "HAS_LINK_TARGET_ID_LIST");
1874
0
  yr_set_integer(HAS_LINK_INFO, module_object, "HAS_LINK_INFO");
1875
0
  yr_set_integer(HAS_NAME, module_object, "HAS_NAME");
1876
0
  yr_set_integer(HAS_RELATIVE_PATH, module_object, "HAS_RELATIVE_PATH");
1877
0
  yr_set_integer(HAS_WORKING_DIR, module_object, "HAS_WORKING_DIR");
1878
0
  yr_set_integer(HAS_ARGUMENTS, module_object, "HAS_ARGUMENTS");
1879
0
  yr_set_integer(HAS_ICON_LOCATION, module_object, "HAS_ICON_LOCATION");
1880
0
  yr_set_integer(IS_UNICODE, module_object, "IS_UNICODE");
1881
0
  yr_set_integer(FORCE_NO_LINK_INFO, module_object, "FORCE_NO_LINK_INFO");
1882
0
  yr_set_integer(HAS_EXP_STRING, module_object, "HAS_EXP_STRING");
1883
0
  yr_set_integer(RUN_IN_SEPARATE_PROCESS, module_object, "RUN_IN_SEPARATE_PROCESS");
1884
0
  yr_set_integer(UNUSED_1, module_object, "UNUSED_1");
1885
0
  yr_set_integer(HAS_DARWIN_ID, module_object, "HAS_DARWIN_ID");
1886
0
  yr_set_integer(RUN_AS_USER, module_object, "RUN_AS_USER");
1887
0
  yr_set_integer(HAS_EXP_ICON, module_object, "HAS_EXP_ICON");
1888
0
  yr_set_integer(NO_PIDL_ALIAS, module_object, "NO_PIDL_ALIAS");
1889
0
  yr_set_integer(UNUSED_2, module_object, "UNUSED_2");
1890
0
  yr_set_integer(RUN_WITH_SHIM_LAYER, module_object, "RUN_WITH_SHIM_LAYER");
1891
0
  yr_set_integer(FORCE_NO_LINK_TRACK, module_object, "FORCE_NO_LINK_TRACK");
1892
0
  yr_set_integer(ENABLE_TARGET_METADATA, module_object, "ENABLE_TARGET_METADATA");
1893
0
  yr_set_integer(
1894
0
      DISABLE_LINK_PATH_TRACKING, module_object, "DISABLE_LINK_PATH_TRACKING");
1895
0
  yr_set_integer(
1896
0
      DISABLE_KNOWN_FOLDER_TRACKING, module_object, "DISABLE_KNOWN_FOLDER_TRACKING");
1897
0
  yr_set_integer(
1898
0
      DISABLE_KNOWN_FOLDER_ALIAS, module_object, "DISABLE_KNOWN_FOLDER_ALIAS");
1899
0
  yr_set_integer(ALLOW_LINK_TO_LINK, module_object, "ALLOW_LINK_TO_LINK");
1900
0
  yr_set_integer(UNALIAS_ON_SAVE, module_object, "UNALIAS_ON_SAVE");
1901
0
  yr_set_integer(PREFER_ENVIRONMENT_PATH, module_object, "PREFER_ENVIRONMENT_PATH");
1902
0
  yr_set_integer(
1903
0
      KEEP_LOCAL_ID_LIST_FOR_UNC_TARGET,
1904
0
      module_object,
1905
0
      "KEEP_LOCAL_ID_LIST_FOR_UNC_TARGET");
1906
1907
0
  yr_set_integer(
1908
0
      FILE_ATTRIBUTE_READONLY, module_object, "FILE_ATTRIBUTE_READONLY");
1909
0
  yr_set_integer(FILE_ATTRIBUTE_HIDDEN, module_object, "FILE_ATTRIBUTE_HIDDEN");
1910
0
  yr_set_integer(FILE_ATTRIBUTE_SYSTEM, module_object, "FILE_ATTRIBUTE_SYSTEM");
1911
0
  yr_set_integer(RESERVED_1, module_object, "RESERVED_1");
1912
0
  yr_set_integer(
1913
0
      FILE_ATTRIBUTE_DIRECTORY, module_object, "FILE_ATTRIBUTE_DIRECTORY");
1914
0
  yr_set_integer(FILE_ATTRIBUTE_ARCHIVE, module_object, "FILE_ATTRIBUTE_ARCHIVE");
1915
0
  yr_set_integer(RESERVED_2, module_object, "RESERVED_2");
1916
0
  yr_set_integer(FILE_ATTRIBUTE_NORMAL, module_object, "FILE_ATTRIBUTE_NORMAL");
1917
0
  yr_set_integer(
1918
0
      FILE_ATTRIBUTE_TEMPORARY, module_object, "FILE_ATTRIBUTE_TEMPORARY");
1919
0
  yr_set_integer(
1920
0
      FILE_ATTRIBUTE_SPARSE_FILE, module_object, "FILE_ATTRIBUTE_SPARSE_FILE");
1921
0
  yr_set_integer(
1922
0
      FILE_ATTRIBUTE_REPARSE_POINT,
1923
0
      module_object,
1924
0
      "FILE_ATTRIBUTE_REPARSE_POINT");
1925
0
  yr_set_integer(
1926
0
      FILE_ATTRIBUTE_COMPRESSED, module_object, "FILE_ATTRIBUTE_COMPRESSED");
1927
0
  yr_set_integer(FILE_ATTRIBUTE_OFFLINE, module_object, "FILE_ATTRIBUTE_OFFLINE");
1928
0
  yr_set_integer(
1929
0
      FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,
1930
0
      module_object,
1931
0
      "FILE_ATTRIBUTE_NOT_CONTENT_INDEXED");
1932
0
  yr_set_integer(
1933
0
      FILE_ATTRIBUTE_ENCRYPTED, module_object, "FILE_ATTRIBUTE_ENCRYPTED");
1934
1935
0
  yr_set_integer(SW_SHOWNORMAL, module_object, "SW_SHOWNORMAL");
1936
0
  yr_set_integer(SW_SHOWMAXIMIZED, module_object, "SW_SHOWMAXIMIZED");
1937
0
  yr_set_integer(SW_SHOWMINNOACTIVE, module_object, "SW_SHOWMINNOACTIVE");
1938
1939
0
  yr_set_integer(HOTKEYF_SHIFT, module_object, "HOTKEYF_SHIFT");
1940
0
  yr_set_integer(HOTKEYF_CONTROL, module_object, "HOTKEYF_CONTROL");
1941
0
  yr_set_integer(HOTKEYF_ALT, module_object, "HOTKEYF_ALT");
1942
1943
0
  yr_set_integer(
1944
0
      VOLUME_ID_AND_LOCAL_BASE_PATH, module_object, "VOLUME_ID_AND_LOCAL_BASE_PATH");
1945
0
  yr_set_integer(
1946
0
      COMMON_NETWORK_RELATIVE_LINK_AND_PATH_SUFFIX,
1947
0
      module_object,
1948
0
      "COMMON_NETWORK_RELATIVE_LINK_AND_PATH_SUFFIX");
1949
1950
0
  yr_set_integer(DRIVE_UNKNOWN, module_object, "DRIVE_UNKNOWN");
1951
0
  yr_set_integer(DRIVE_NO_ROOT_DIR, module_object, "DRIVE_NO_ROOT_DIR");
1952
0
  yr_set_integer(DRIVE_REMOVABLE, module_object, "DRIVE_REMOVABLE");
1953
0
  yr_set_integer(DRIVE_FIXED, module_object, "DRIVE_FIXED");
1954
0
  yr_set_integer(DRIVE_REMOTE, module_object, "DRIVE_REMOTE");
1955
0
  yr_set_integer(DRIVE_CDROM, module_object, "DRIVE_CDROM");
1956
0
  yr_set_integer(DRIVE_RAMDISK, module_object, "DRIVE_RAMDISK");
1957
1958
0
  yr_set_integer(VALID_DEVICE, module_object, "VALID_DEVICE");
1959
0
  yr_set_integer(VALID_NET_TYPE, module_object, "VALID_NET_TYPE");
1960
1961
0
  yr_set_integer(WNNC_NET_AVID, module_object, "WNNC_NET_AVID");
1962
0
  yr_set_integer(WNNC_NET_DOCUSPACE, module_object, "WNNC_NET_DOCUSPACE");
1963
0
  yr_set_integer(WNNC_NET_MANGOSOFT, module_object, "WNNC_NET_MANGOSOFT");
1964
0
  yr_set_integer(WNNC_NET_SERNET, module_object, "WNNC_NET_SERNET");
1965
0
  yr_set_integer(WNNC_NET_RIVERFRONT1, module_object, "WNNC_NET_RIVERFRONT1");
1966
0
  yr_set_integer(WNNC_NET_RIVERFRONT2, module_object, "WNNC_NET_RIVERFRONT2");
1967
0
  yr_set_integer(WNNC_NET_DECORB, module_object, "WNNC_NET_DECORB");
1968
0
  yr_set_integer(WNNC_NET_PROTSTOR, module_object, "WNNC_NET_PROTSTOR");
1969
0
  yr_set_integer(WNNC_NET_FJ_REDIR, module_object, "WNNC_NET_FJ_REDIR");
1970
0
  yr_set_integer(WNNC_NET_DISTINCT, module_object, "WNNC_NET_DISTINCT");
1971
0
  yr_set_integer(WNNC_NET_TWINS, module_object, "WNNC_NET_TWINS");
1972
0
  yr_set_integer(WNNC_NET_RDR2SAMPLE, module_object, "WNNC_NET_RDR2SAMPLE");
1973
0
  yr_set_integer(WNNC_NET_CSC, module_object, "WNNC_NET_CSC");
1974
0
  yr_set_integer(WNNC_NET_3IN1, module_object, "WNNC_NET_3IN1");
1975
0
  yr_set_integer(WNNC_NET_EXTENDNET, module_object, "WNNC_NET_EXTENDNET");
1976
0
  yr_set_integer(WNNC_NET_STAC, module_object, "WNNC_NET_STAC");
1977
0
  yr_set_integer(WNNC_NET_FOXBAT, module_object, "WNNC_NET_FOXBAT");
1978
0
  yr_set_integer(WNNC_NET_YAHOO, module_object, "WNNC_NET_YAHOO");
1979
0
  yr_set_integer(WNNC_NET_EXIFS, module_object, "WNNC_NET_EXIFS");
1980
0
  yr_set_integer(WNNC_NET_DAV, module_object, "WNNC_NET_DAV");
1981
0
  yr_set_integer(WNNC_NET_KNOWARE, module_object, "WNNC_NET_KNOWARE");
1982
0
  yr_set_integer(WNNC_NET_OBJECT_DIRE, module_object, "WNNC_NET_OBJECT_DIRE");
1983
0
  yr_set_integer(WNNC_NET_MASFAX, module_object, "WNNC_NET_MASFAX");
1984
0
  yr_set_integer(WNNC_NET_HOB_NFS, module_object, "WNNC_NET_HOB_NFS");
1985
0
  yr_set_integer(WNNC_NET_SHIVA, module_object, "WNNC_NET_SHIVA");
1986
0
  yr_set_integer(WNNC_NET_IBMAL, module_object, "WNNC_NET_IBMAL");
1987
0
  yr_set_integer(WNNC_NET_LOCK, module_object, "WNNC_NET_LOCK");
1988
0
  yr_set_integer(WNNC_NET_TERMSRV, module_object, "WNNC_NET_TERMSRV");
1989
0
  yr_set_integer(WNNC_NET_SRT, module_object, "WNNC_NET_SRT");
1990
0
  yr_set_integer(WNNC_NET_QUINCY, module_object, "WNNC_NET_QUINCY");
1991
0
  yr_set_integer(WNNC_NET_OPENAFS, module_object, "WNNC_NET_OPENAFS");
1992
0
  yr_set_integer(WNNC_NET_AVID1, module_object, "WNNC_NET_AVID1");
1993
0
  yr_set_integer(WNNC_NET_DFS, module_object, "WNNC_NET_DFS");
1994
0
  yr_set_integer(WNNC_NET_KWNP, module_object, "WNNC_NET_KWNP");
1995
0
  yr_set_integer(WNNC_NET_ZENWORKS, module_object, "WNNC_NET_ZENWORKS");
1996
0
  yr_set_integer(WNNC_NET_DRIVEONWEB, module_object, "WNNC_NET_DRIVEONWEB");
1997
0
  yr_set_integer(WNNC_NET_VMWARE, module_object, "WNNC_NET_VMWARE");
1998
0
  yr_set_integer(WNNC_NET_RSFX, module_object, "WNNC_NET_RSFX");
1999
0
  yr_set_integer(WNNC_NET_MFILES, module_object, "WNNC_NET_MFILES");
2000
0
  yr_set_integer(WNNC_NET_MS_NFS, module_object, "WNNC_NET_MS_NFS");
2001
0
  yr_set_integer(WNNC_NET_GOOGLE, module_object, "WNNC_NET_GOOGLE");
2002
2003
0
  yr_set_integer(FOREGROUND_BLUE, module_object, "FOREGROUND_BLUE");
2004
0
  yr_set_integer(FOREGROUND_GREEN, module_object, "FOREGROUND_GREEN");
2005
0
  yr_set_integer(FOREGROUND_RED, module_object, "FOREGROUND_RED");
2006
0
  yr_set_integer(FOREGROUND_INTENSITY, module_object, "FOREGROUND_INTENSITY");
2007
0
  yr_set_integer(BACKGROUND_BLUE, module_object, "BACKGROUND_BLUE");
2008
0
  yr_set_integer(BACKGROUND_GREEN, module_object, "BACKGROUND_GREEN");
2009
0
  yr_set_integer(BACKGROUND_RED, module_object, "BACKGROUND_RED");
2010
0
  yr_set_integer(BACKGROUND_INTENSITY, module_object, "BACKGROUND_INTENSITY");
2011
2012
0
  yr_set_integer(FF_DONTCARE, module_object, "FF_DONTCARE");
2013
0
  yr_set_integer(FF_ROMAN, module_object, "FF_ROMAN");
2014
0
  yr_set_integer(FF_SWISS, module_object, "FF_SWISS");
2015
0
  yr_set_integer(FF_MODERN, module_object, "FF_MODERN");
2016
0
  yr_set_integer(FF_SCRIPT, module_object, "FF_SCRIPT");
2017
0
  yr_set_integer(FF_DECORATIVE, module_object, "FF_DECORATIVE");
2018
2019
0
  yr_set_integer(TMPF_NONE, module_object, "TMPF_NONE");
2020
0
  yr_set_integer(TMPF_FIXED_PITCH, module_object, "TMPF_FIXED_PITCH");
2021
0
  yr_set_integer(TMPF_VECTOR, module_object, "TMPF_VECTOR");
2022
0
  yr_set_integer(TMPF_TRUETYPE, module_object, "TMPF_TRUETYPE");
2023
0
  yr_set_integer(TMPF_DEVICE, module_object, "TMPF_DEVICE");
2024
2025
0
  const uint8_t* block_data;
2026
0
  uint32_t block_data_size_remaining;
2027
0
  char* hotkey_str;
2028
0
  const uint8_t* current_location;
2029
0
  uint32_t id_list_size;
2030
0
  uint32_t link_info_size;
2031
0
  uint32_t string_data_size;
2032
0
  uint32_t extra_data_block_size;
2033
0
  uint32_t extra_data_block_signature;
2034
2035
0
  block = first_memory_block(context);
2036
0
  block_data = block->fetch_data(block);
2037
2038
  // Keep track the amount of space in the current block we have left
2039
  // to prevent any issues when dereferencing pointers
2040
0
  block_data_size_remaining = (int) block->size;
2041
2042
  // Don't try to parse a file unless it is the minimum size an LNK can be
2043
  // based on fixed length headers it has (described in shell_link_header_t)
2044
0
  if (block_data != NULL &&
2045
0
      block_data_size_remaining >= sizeof(shell_link_header_t))
2046
0
  {
2047
    // Validate LNK header
2048
0
    lnk_header = (shell_link_header_t*) block_data;
2049
0
    if (yr_le32toh(lnk_header->header_size) == HEADER_SIZE &&
2050
0
        yr_le32toh(lnk_header->clsid[0]) == LINK_CLSID_0 &&
2051
0
        yr_le32toh(lnk_header->clsid[1]) == LINK_CLSID_1 &&
2052
0
        yr_le32toh(lnk_header->clsid[2]) == LINK_CLSID_2 &&
2053
0
        yr_le32toh(lnk_header->clsid[3]) == LINK_CLSID_3)
2054
0
    {
2055
0
      yr_set_integer(1, module_object, "is_lnk");
2056
2057
      // Convert timestamps from Windows TIMESTAMP to Unix timestamp
2058
0
      yr_set_integer(
2059
0
          convertWindowsTimeToUnixTime(yr_le64toh(lnk_header->creation_time)),
2060
0
          module_object,
2061
0
          "creation_time");
2062
2063
0
      yr_set_integer(
2064
0
          convertWindowsTimeToUnixTime(yr_le64toh(lnk_header->access_time)),
2065
0
          module_object,
2066
0
          "access_time");
2067
2068
0
      yr_set_integer(
2069
0
          convertWindowsTimeToUnixTime(yr_le64toh(lnk_header->write_time)),
2070
0
          module_object,
2071
0
          "write_time");
2072
2073
0
      yr_set_integer(yr_le32toh(lnk_header->file_size), module_object, "file_size");
2074
0
      yr_set_integer(yr_le32toh(lnk_header->link_flags), module_object, "link_flags");
2075
0
      yr_set_integer(
2076
0
          yr_le32toh(lnk_header->file_attributes_flags),
2077
0
          module_object,
2078
0
          "file_attributes_flags");
2079
0
      yr_set_integer(yr_le32toh(lnk_header->icon_index), module_object, "icon_index");
2080
0
      yr_set_integer(yr_le32toh(lnk_header->show_command), module_object, "show_command");
2081
0
      yr_set_integer(yr_le16toh(lnk_header->hotkey_flags), module_object, "hotkey_flags");
2082
2083
      // Hotkey handling code
2084
0
      if (yr_le16toh(lnk_header->hotkey_flags) & 0xFF)
2085
0
      {
2086
0
        hotkey_str = get_hotkey_char(yr_le16toh(lnk_header->hotkey_flags) & 0xFF);
2087
2088
0
        if (hotkey_str)
2089
0
        {
2090
0
          yr_set_string(hotkey_str, module_object, "hotkey");
2091
0
        }
2092
2093
0
        yr_set_integer(1, module_object, "has_hotkey");
2094
0
      }
2095
2096
0
      else
2097
0
      {
2098
0
        yr_set_integer(0, module_object, "has_hotkey");
2099
0
      }
2100
2101
0
      yr_set_integer(
2102
0
          (yr_le16toh(lnk_header->hotkey_flags) >> 8),
2103
0
          module_object,
2104
0
          "hotkey_modifier_flags");
2105
2106
      // Set pointer of current location to be after the LNK fixed header
2107
0
      current_location = block_data + sizeof(shell_link_header_t);
2108
0
      block_data_size_remaining -= sizeof(shell_link_header_t);
2109
2110
      // Optional parsing of LinkTargetIDList
2111
0
      if (yr_le32toh(lnk_header->link_flags) & HAS_LINK_TARGET_ID_LIST)
2112
0
      {
2113
0
        id_list_size = parse_link_target_id_list(
2114
0
            current_location, module_object, block_data_size_remaining);
2115
2116
0
        if (id_list_size == 0)
2117
0
        {
2118
0
          yr_set_integer(1, module_object, "is_malformed");
2119
0
          return ERROR_SUCCESS;
2120
0
        }
2121
2122
0
        if (block_data_size_remaining < id_list_size)
2123
0
        {
2124
0
          yr_set_integer(1, module_object, "is_malformed");
2125
0
          return ERROR_SUCCESS;
2126
0
        }
2127
2128
0
        current_location += id_list_size;
2129
0
        block_data_size_remaining -= id_list_size;
2130
0
      }
2131
2132
0
      if (yr_le32toh(lnk_header->link_flags) & HAS_LINK_INFO)
2133
0
      {
2134
0
        link_info_size = parse_link_info(
2135
0
            current_location, module_object, block_data_size_remaining);
2136
2137
0
        if (link_info_size == 0)
2138
0
        {
2139
0
          yr_set_integer(1, module_object, "is_malformed");
2140
0
          return ERROR_SUCCESS;
2141
0
        }
2142
2143
0
        if (block_data_size_remaining < link_info_size)
2144
0
        {
2145
0
          yr_set_integer(1, module_object, "is_malformed");
2146
0
          return ERROR_SUCCESS;
2147
0
        }
2148
2149
0
        current_location += link_info_size;
2150
0
        block_data_size_remaining -= link_info_size;
2151
0
      }
2152
2153
      // NAME_STRING
2154
0
      if (yr_le32toh(lnk_header->link_flags) & HAS_NAME)
2155
0
      {
2156
0
        string_data_size = parse_string_data(
2157
0
            current_location,
2158
0
            module_object,
2159
0
            block_data_size_remaining,
2160
0
            "name_string",
2161
0
            yr_le32toh(lnk_header->link_flags) & IS_UNICODE);
2162
2163
0
        if (string_data_size == 0)
2164
0
        {
2165
0
          yr_set_integer(1, module_object, "is_malformed");
2166
0
          return ERROR_SUCCESS;
2167
0
        }
2168
2169
0
        if (block_data_size_remaining < string_data_size)
2170
0
        {
2171
0
          yr_set_integer(1, module_object, "is_malformed");
2172
0
          return ERROR_SUCCESS;
2173
0
        }
2174
2175
0
        current_location += string_data_size;
2176
0
        block_data_size_remaining -= string_data_size;
2177
0
      }
2178
2179
      // RELATIVE_PATH
2180
0
      if (yr_le32toh(lnk_header->link_flags) & HAS_RELATIVE_PATH)
2181
0
      {
2182
0
        string_data_size = parse_string_data(
2183
0
            current_location,
2184
0
            module_object,
2185
0
            block_data_size_remaining,
2186
0
            "relative_path",
2187
0
            yr_le32toh(lnk_header->link_flags) & IS_UNICODE);
2188
2189
0
        if (string_data_size == 0)
2190
0
        {
2191
0
          yr_set_integer(1, module_object, "is_malformed");
2192
0
          return ERROR_SUCCESS;
2193
0
        }
2194
2195
0
        if (block_data_size_remaining < string_data_size)
2196
0
        {
2197
0
          yr_set_integer(1, module_object, "is_malformed");
2198
0
          return ERROR_SUCCESS;
2199
0
        }
2200
2201
0
        current_location += string_data_size;
2202
0
        block_data_size_remaining -= string_data_size;
2203
0
      }
2204
2205
      // WORKING_DIR
2206
0
      if (yr_le32toh(lnk_header->link_flags) & HAS_WORKING_DIR)
2207
0
      {
2208
0
        string_data_size = parse_string_data(
2209
0
            current_location,
2210
0
            module_object,
2211
0
            block_data_size_remaining,
2212
0
            "working_dir",
2213
0
            yr_le32toh(lnk_header->link_flags) & IS_UNICODE);
2214
2215
0
        if (string_data_size == 0)
2216
0
        {
2217
0
          yr_set_integer(1, module_object, "is_malformed");
2218
0
          return ERROR_SUCCESS;
2219
0
        }
2220
2221
0
        if (block_data_size_remaining < string_data_size)
2222
0
        {
2223
0
          yr_set_integer(1, module_object, "is_malformed");
2224
0
          return ERROR_SUCCESS;
2225
0
        }
2226
2227
0
        current_location += string_data_size;
2228
0
        block_data_size_remaining -= string_data_size;
2229
0
      }
2230
2231
      // COMMAND_LINK_ARGUMENTS
2232
0
      if (yr_le32toh(lnk_header->link_flags) & HAS_ARGUMENTS)
2233
0
      {
2234
0
        string_data_size = parse_string_data(
2235
0
            current_location,
2236
0
            module_object,
2237
0
            block_data_size_remaining,
2238
0
            "command_line_arguments",
2239
0
            yr_le32toh(lnk_header->link_flags) & IS_UNICODE);
2240
2241
0
        if (string_data_size == 0)
2242
0
        {
2243
0
          yr_set_integer(1, module_object, "is_malformed");
2244
0
          return ERROR_SUCCESS;
2245
0
        }
2246
2247
0
        if (block_data_size_remaining < string_data_size)
2248
0
        {
2249
0
          yr_set_integer(1, module_object, "is_malformed");
2250
0
          return ERROR_SUCCESS;
2251
0
        }
2252
2253
0
        current_location += string_data_size;
2254
0
        block_data_size_remaining -= string_data_size;
2255
0
      }
2256
2257
      // ICON_LOCATION
2258
0
      if (yr_le32toh(lnk_header->link_flags) & HAS_ICON_LOCATION)
2259
0
      {
2260
0
        string_data_size = parse_string_data(
2261
0
            current_location,
2262
0
            module_object,
2263
0
            block_data_size_remaining,
2264
0
            "icon_location",
2265
0
            yr_le32toh(lnk_header->link_flags) & IS_UNICODE);
2266
2267
0
        if (string_data_size == 0)
2268
0
        {
2269
0
          yr_set_integer(1, module_object, "is_malformed");
2270
0
          return ERROR_SUCCESS;
2271
0
        }
2272
2273
0
        if (block_data_size_remaining < string_data_size)
2274
0
        {
2275
0
          yr_set_integer(1, module_object, "is_malformed");
2276
0
          return ERROR_SUCCESS;
2277
0
        }
2278
2279
0
        current_location += string_data_size;
2280
0
        block_data_size_remaining -= string_data_size;
2281
0
      }
2282
2283
0
      yr_set_integer(0, module_object, "has_console_data");
2284
0
      yr_set_integer(0, module_object, "has_console_fe_data");
2285
0
      yr_set_integer(0, module_object, "has_darwin_data");
2286
0
      yr_set_integer(0, module_object, "has_environment_variable_data");
2287
0
      yr_set_integer(0, module_object, "has_icon_environment_data");
2288
0
      yr_set_integer(0, module_object, "has_known_folder_data");
2289
0
      yr_set_integer(0, module_object, "has_property_store_data");
2290
0
      yr_set_integer(0, module_object, "has_shim_data");
2291
0
      yr_set_integer(0, module_object, "has_special_folder_data");
2292
0
      yr_set_integer(0, module_object, "has_tracker_data");
2293
0
      yr_set_integer(0, module_object, "has_vista_and_above_id_list_data");
2294
2295
      // Parse ExtraData
2296
0
      if (block_data_size_remaining > 0)
2297
0
      {
2298
0
        if (block_data_size_remaining < sizeof(extra_data_block_size))
2299
0
        {
2300
0
          yr_set_integer(1, module_object, "is_malformed");
2301
0
          return ERROR_SUCCESS;
2302
0
        }
2303
2304
0
        memcpy(
2305
0
            &extra_data_block_size,
2306
0
            current_location,
2307
0
            sizeof(extra_data_block_size));
2308
0
        current_location += sizeof(extra_data_block_size);
2309
2310
        // The TerminalBlock must be less than 0x04, so iterate until we find it
2311
        // (or run out of space)
2312
0
        while (yr_le32toh(extra_data_block_size) >= 0x04)
2313
0
        {
2314
          // Only do this in the loop so we don't overshoot the end of the block
2315
0
          block_data_size_remaining -= sizeof(extra_data_block_size);
2316
2317
0
          if (block_data_size_remaining < sizeof(extra_data_block_signature))
2318
0
          {
2319
0
            yr_set_integer(1, module_object, "is_malformed");
2320
0
            return ERROR_SUCCESS;
2321
0
          }
2322
2323
0
          memcpy(
2324
0
              &extra_data_block_signature,
2325
0
              current_location,
2326
0
              sizeof(extra_data_block_signature));
2327
0
          current_location += sizeof(extra_data_block_signature);
2328
0
          block_data_size_remaining -= sizeof(extra_data_block_signature);
2329
2330
0
          if (!parse_extra_block(
2331
0
                  current_location,
2332
0
                  module_object,
2333
0
                  block_data_size_remaining,
2334
0
                  yr_le32toh(extra_data_block_size),
2335
0
                  yr_le32toh(extra_data_block_signature)))
2336
0
          {
2337
0
            break;
2338
0
          }
2339
2340
          // Don't add/take away the block size + signature, as those have
2341
          // already been dealt with
2342
0
          current_location += yr_le32toh(extra_data_block_size) -
2343
0
                              sizeof(extra_data_block_size) -
2344
0
                              sizeof(extra_data_block_signature);
2345
0
          block_data_size_remaining -= yr_le32toh(extra_data_block_size) -
2346
0
                                       sizeof(extra_data_block_size) -
2347
0
                                       sizeof(extra_data_block_signature);
2348
2349
0
          if (block_data_size_remaining < sizeof(extra_data_block_size))
2350
0
          {
2351
0
            yr_set_integer(1, module_object, "is_malformed");
2352
0
            return ERROR_SUCCESS;
2353
0
          }
2354
2355
0
          memcpy(
2356
0
              &extra_data_block_size,
2357
0
              current_location,
2358
0
              sizeof(extra_data_block_size));
2359
0
          current_location += sizeof(extra_data_block_size);
2360
0
        }
2361
2362
        // Finally, take away size of the TerminalBlock
2363
0
        block_data_size_remaining -= 4;
2364
0
      }
2365
2366
0
      if (block_data_size_remaining > 0)
2367
0
      {
2368
0
        yr_set_integer(1, module_object, "has_overlay");
2369
0
        yr_set_integer(
2370
0
            block->size - block_data_size_remaining,
2371
0
            module_object,
2372
0
            "overlay_offset");
2373
0
      }
2374
2375
0
      else
2376
0
      {
2377
0
        yr_set_integer(0, module_object, "has_overlay");
2378
0
      }
2379
2380
      // If all parsing successful, say that the LNK isn't malformed
2381
0
      yr_set_integer(0, module_object, "is_malformed");
2382
0
    }
2383
0
  }
2384
2385
0
  return ERROR_SUCCESS;
2386
0
}
2387
2388
int module_unload(YR_OBJECT* module_object)
2389
0
{
2390
0
  return ERROR_SUCCESS;
2391
0
}