-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvmmdll.h
2870 lines (2592 loc) · 114 KB
/
vmmdll.h
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// vmmdll.h : header file to include in projects that use vmm.dll / vmm.so
//
// Please also consult the guide at: https://github.com/ufrisk/MemProcFS/wiki
//
// U/W functions
// =============
// Windows may access both UTF-8 *U and Wide-Char *W versions of functions
// while Linux may only access UTF-8 versions. Some functionality may also
// be degraded or unavailable on Linux.
//
// (c) Ulf Frisk, 2018-2024
// Author: Ulf Frisk, pcileech@frizk.net
//
// Header Version: 5.9.8
//
#include "leechcore.h"
#ifndef __VMMDLL_H__
#define __VMMDLL_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef _WIN32
#include <Windows.h>
#undef EXPORTED_FUNCTION
#define EXPORTED_FUNCTION
typedef unsigned __int64 QWORD, *PQWORD;
#endif /* _WIN32 */
#ifdef LINUX
#include <inttypes.h>
#include <stdarg.h>
#include <stdlib.h>
#undef EXPORTED_FUNCTION
#define EXPORTED_FUNCTION __attribute__((visibility("default")))
typedef void VOID, *PVOID, *HANDLE, **PHANDLE, *HMODULE;
typedef long long unsigned int QWORD, *PQWORD, ULONG64, *PULONG64;
typedef size_t SIZE_T, *PSIZE_T;
typedef uint64_t FILETIME, *PFILETIME;
typedef uint32_t DWORD, *PDWORD, *LPDWORD, BOOL, *PBOOL, NTSTATUS;
typedef uint16_t WORD, *PWORD;
typedef uint8_t BYTE, *PBYTE, *LPBYTE, UCHAR;
typedef char CHAR, *PCHAR, *LPSTR;
typedef const char *LPCSTR;
typedef uint16_t WCHAR, *PWCHAR, *LPWSTR;
typedef const uint16_t *LPCWSTR;
#define MAX_PATH 260
#define _In_
#define _In_z_
#define _In_opt_
#define _In_reads_(x)
#define _In_reads_bytes_(x)
#define _In_reads_opt_(x)
#define _Inout_
#define _Inout_bytecount_(x)
#define _Inout_opt_
#define _Inout_updates_opt_(x)
#define _Out_
#define _Out_opt_
#define _Out_writes_(x)
#define _Out_writes_bytes_opt_(x)
#define _Out_writes_opt_(x)
#define _Out_writes_to_(x,y)
#define _When_(x,y)
#define _Frees_ptr_opt_
#define _Post_ptr_invalid_
#define _Check_return_opt_
#define _Printf_format_string_
#define _Success_(x)
#endif /* LINUX */
typedef struct tdVMM_HANDLE *VMM_HANDLE;
typedef struct tdVMMVM_HANDLE *VMMVM_HANDLE;
typedef BYTE OPAQUE_OB_HEADER[0x40];
//-----------------------------------------------------------------------------
// INITIALIZATION FUNCTIONALITY BELOW:
// Choose one way of initializing the VMM / MemProcFS.
//-----------------------------------------------------------------------------
/*
* Initialize VMM.DLL with command line parameters. For a more detailed info
* about the parameters please see github wiki for MemProcFS and LeechCore.
* NB! LeechCore initialization parameters are _also_ valid to this function.
* Important parameters are:
* -printf = show printf style outputs.
* -v -vv -vvv = extra verbosity levels.
* -device = device as on format for LeechCore - please see leechcore.h or
* Github documentation for additional information. Some values
* are: <file>, fpga, usb3380, hvsavedstate, totalmeltdown, pmem
* -remote = remote LeechCore instance - please see leechcore.h or Github
* documentation for additional information.
* -norefresh = disable background refreshes (even if backing memory is
* volatile memory).
* -memmap = specify a physical memory map given by file or specify 'auto'.
* example: -memmap c:\\temp\\my_custom_memory_map.txt
* example: -memmap auto
* -pagefile[0-9] = page file(s) to use in addition to physical memory.
* Normally pagefile.sys have index 0 and swapfile.sys index 1.
* Page files are in constant flux - do not use if time diff
* between memory dump and page files are more than few minutes.
* Example: 'pagefile0 swapfile.sys'
* -disable-python = prevent the python plugin sub-system from loading.
* -disable-symbolserver = disable symbol server until user change.
* This parameter will take precedence over registry settings.
* -disable-symbols = disable symbol lookups from .pdb files.
* -disable-infodb = disable the infodb and any symbol lookups via it.
* -waitinitialize = Wait for initialization to complete before returning.
* Normal use is that some initialization is done asynchronously
* and may not be completed when initialization call is completed.
* This includes virtual memory compression, registry and more.
* Example: '-waitinitialize'
* -userinteract = allow vmm.dll to, on the console, query the user for
* information such as, but not limited to, leechcore device options.
* Default: user interaction = disabled.
* -vm = virtual machine (VM) parsing.
* -vm-basic = virtual machine (VM) parsing (physical memory only).
* -vm-nested = virtual machine (VM) parsing (including nested VMs).
* -forensic-yara-rules = perfom a forensic yara scan with specified rules.
* Full path to source or compiled yara rules should be specified.
* Example: -forensic-yara-rules "C:\Temp\my_yara_rules.yar"
* -forensic = start a forensic scan of the physical memory immediately after
* startup if possible. Allowed parameter values range from 0-4.
* Note! forensic mode is not available for live memory.
* 1 = forensic mode with in-memory sqlite database.
* 2 = forensic mode with temp sqlite database deleted upon exit.
* 3 = forensic mode with temp sqlite database remaining upon exit.
* 4 = forensic mode with static named sqlite database (vmm.sqlite3).
* Example -forensic 4
*
* -- argc
* -- argv
* -- ppLcErrorInfo = optional pointer to receive a function allocated memory of
* struct LC_CONFIG_ERRORINFO with extended error information upon
* failure. Any memory received should be free'd by caller by
* calling LcMemFree().
* -- return = VMM_HANDLE on success for usage in subsequent API calls. NULL=fail.
*/
EXPORTED_FUNCTION _Success_(return != NULL)
VMM_HANDLE VMMDLL_Initialize(_In_ DWORD argc, _In_ LPCSTR argv[]);
EXPORTED_FUNCTION _Success_(return != NULL)
VMM_HANDLE VMMDLL_InitializeEx(_In_ DWORD argc, _In_ LPCSTR argv[], _Out_opt_ PPLC_CONFIG_ERRORINFO ppLcErrorInfo);
/*
* Close an instantiated version of VMM_HANDLE and free up any resources.
* -- hVMM
*/
EXPORTED_FUNCTION
VOID VMMDLL_Close(_In_opt_ _Post_ptr_invalid_ VMM_HANDLE hVMM);
/*
* Close all instantiated versions of VMM_HANDLE and free up all resources.
*/
EXPORTED_FUNCTION
VOID VMMDLL_CloseAll();
/*
* Query the size of memory allocated by the VMMDLL.
* -- pvMem
* -- return = number of bytes required to hold memory allocation.
*/
EXPORTED_FUNCTION _Success_(return != 0)
SIZE_T VMMDLL_MemSize(_In_ PVOID pvMem);
/*
* Free memory allocated by the VMMDLL.
* -- pvMem
*/
EXPORTED_FUNCTION
VOID VMMDLL_MemFree(_Frees_ptr_opt_ PVOID pvMem);
//-----------------------------------------------------------------------------
// CONFIGURATION SETTINGS BELOW:
// Configure MemProcFS or the underlying memory
// acquisition devices.
//-----------------------------------------------------------------------------
/*
* Options used together with the functions: VMMDLL_ConfigGet & VMMDLL_ConfigSet
* Options are defined with either: VMMDLL_OPT_* in this header file or as
* LC_OPT_* in leechcore.h
* For more detailed information check the sources for individual device types.
*/
#define VMMDLL_OPT_CORE_PRINTF_ENABLE 0x4000000100000000 // RW
#define VMMDLL_OPT_CORE_VERBOSE 0x4000000200000000 // RW
#define VMMDLL_OPT_CORE_VERBOSE_EXTRA 0x4000000300000000 // RW
#define VMMDLL_OPT_CORE_VERBOSE_EXTRA_TLP 0x4000000400000000 // RW
#define VMMDLL_OPT_CORE_MAX_NATIVE_ADDRESS 0x4000000800000000 // R
#define VMMDLL_OPT_CORE_LEECHCORE_HANDLE 0x4000001000000000 // R - underlying leechcore handle (do not close).
#define VMMDLL_OPT_CORE_VMM_ID 0x4000002000000000 // R - use with startup option '-create-from-vmmid' to create a thread-safe duplicate VMM instance.
#define VMMDLL_OPT_CORE_SYSTEM 0x2000000100000000 // R
#define VMMDLL_OPT_CORE_MEMORYMODEL 0x2000000200000000 // R
#define VMMDLL_OPT_CONFIG_IS_REFRESH_ENABLED 0x2000000300000000 // R - 1/0
#define VMMDLL_OPT_CONFIG_TICK_PERIOD 0x2000000400000000 // RW - base tick period in ms
#define VMMDLL_OPT_CONFIG_READCACHE_TICKS 0x2000000500000000 // RW - memory cache validity period (in ticks)
#define VMMDLL_OPT_CONFIG_TLBCACHE_TICKS 0x2000000600000000 // RW - page table (tlb) cache validity period (in ticks)
#define VMMDLL_OPT_CONFIG_PROCCACHE_TICKS_PARTIAL 0x2000000700000000 // RW - process refresh (partial) period (in ticks)
#define VMMDLL_OPT_CONFIG_PROCCACHE_TICKS_TOTAL 0x2000000800000000 // RW - process refresh (full) period (in ticks)
#define VMMDLL_OPT_CONFIG_VMM_VERSION_MAJOR 0x2000000900000000 // R
#define VMMDLL_OPT_CONFIG_VMM_VERSION_MINOR 0x2000000A00000000 // R
#define VMMDLL_OPT_CONFIG_VMM_VERSION_REVISION 0x2000000B00000000 // R
#define VMMDLL_OPT_CONFIG_STATISTICS_FUNCTIONCALL 0x2000000C00000000 // RW - enable function call statistics (.status/statistics_fncall file)
#define VMMDLL_OPT_CONFIG_IS_PAGING_ENABLED 0x2000000D00000000 // RW - 1/0
#define VMMDLL_OPT_CONFIG_DEBUG 0x2000000E00000000 // W
#define VMMDLL_OPT_CONFIG_YARA_RULES 0x2000000F00000000 // R
#define VMMDLL_OPT_WIN_VERSION_MAJOR 0x2000010100000000 // R
#define VMMDLL_OPT_WIN_VERSION_MINOR 0x2000010200000000 // R
#define VMMDLL_OPT_WIN_VERSION_BUILD 0x2000010300000000 // R
#define VMMDLL_OPT_WIN_SYSTEM_UNIQUE_ID 0x2000010400000000 // R
#define VMMDLL_OPT_FORENSIC_MODE 0x2000020100000000 // RW - enable/retrieve forensic mode type [0-4].
// REFRESH OPTIONS:
#define VMMDLL_OPT_REFRESH_ALL 0x2001ffff00000000 // W - refresh all caches
#define VMMDLL_OPT_REFRESH_FREQ_MEM 0x2001100000000000 // W - refresh memory cache (excl. TLB) [fully]
#define VMMDLL_OPT_REFRESH_FREQ_MEM_PARTIAL 0x2001000200000000 // W - refresh memory cache (excl. TLB) [partial 33%/call]
#define VMMDLL_OPT_REFRESH_FREQ_TLB 0x2001080000000000 // W - refresh page table (TLB) cache [fully]
#define VMMDLL_OPT_REFRESH_FREQ_TLB_PARTIAL 0x2001000400000000 // W - refresh page table (TLB) cache [partial 33%/call]
#define VMMDLL_OPT_REFRESH_FREQ_FAST 0x2001040000000000 // W - refresh fast frequency - incl. partial process refresh
#define VMMDLL_OPT_REFRESH_FREQ_MEDIUM 0x2001000100000000 // W - refresh medium frequency - incl. full process refresh
#define VMMDLL_OPT_REFRESH_FREQ_SLOW 0x2001001000000000 // W - refresh slow frequency.
// PROCESS OPTIONS: [LO-DWORD: Process PID]
#define VMMDLL_OPT_PROCESS_DTB 0x2002000100000000 // W - force set process directory table base.
#define VMMDLL_OPT_PROCESS_DTB_FAST_LOWINTEGRITY 0x2002000200000000 // W - force set process directory table base (fast, low integrity mode, with less checks) - use at own risk!.
static LPCSTR VMMDLL_MEMORYMODEL_TOSTRING[5] = { "N/A", "X86", "X86PAE", "X64", "ARM64" };
typedef enum tdVMMDLL_MEMORYMODEL_TP {
VMMDLL_MEMORYMODEL_NA = 0,
VMMDLL_MEMORYMODEL_X86 = 1,
VMMDLL_MEMORYMODEL_X86PAE = 2,
VMMDLL_MEMORYMODEL_X64 = 3,
VMMDLL_MEMORYMODEL_ARM64 = 4,
} VMMDLL_MEMORYMODEL_TP;
typedef enum tdVMMDLL_SYSTEM_TP {
VMMDLL_SYSTEM_UNKNOWN_PHYSICAL = 0,
VMMDLL_SYSTEM_UNKNOWN_64 = 1,
VMMDLL_SYSTEM_WINDOWS_64 = 2,
VMMDLL_SYSTEM_UNKNOWN_32 = 3,
VMMDLL_SYSTEM_WINDOWS_32 = 4,
VMMDLL_SYSTEM_UNKNOWN_X64 = 1, // deprecated - do not use!
VMMDLL_SYSTEM_WINDOWS_X64 = 2, // deprecated - do not use!
VMMDLL_SYSTEM_UNKNOWN_X86 = 3, // deprecated - do not use!
VMMDLL_SYSTEM_WINDOWS_X86 = 4 // deprecated - do not use!
} VMMDLL_SYSTEM_TP;
/*
* Get a device specific option value. Please see defines VMMDLL_OPT_* for infor-
* mation about valid option values. Please note that option values may overlap
* between different device types with different meanings.
* -- hVMM
* -- fOption
* -- pqwValue = pointer to ULONG64 to receive option value.
* -- return = success/fail.
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_ConfigGet(_In_ VMM_HANDLE hVMM, _In_ ULONG64 fOption, _Out_ PULONG64 pqwValue);
/*
* Set a device specific option value. Please see defines VMMDLL_OPT_* for infor-
* mation about valid option values. Please note that option values may overlap
* between different device types with different meanings.
* -- hVMM
* -- fOption
* -- qwValue
* -- return = success/fail.
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_ConfigSet(_In_ VMM_HANDLE hVMM, _In_ ULONG64 fOption, _In_ ULONG64 qwValue);
//-----------------------------------------------------------------------------
// FORWARD DECLARATIONS:
//-----------------------------------------------------------------------------
typedef struct tdVMMDLL_MAP_PFN *PVMMDLL_MAP_PFN;
//-----------------------------------------------------------------------------
// LINUX SPECIFIC DEFINES:
//-----------------------------------------------------------------------------
#ifdef LINUX
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
typedef struct _SERVICE_STATUS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
} SERVICE_STATUS, *LPSERVICE_STATUS;
#endif /* LINUX */
//-----------------------------------------------------------------------------
// VFS - VIRTUAL FILE SYSTEM FUNCTIONALITY BELOW:
// NB! VFS FUNCTIONALITY REQUIRES PLUGINS TO BE INITIALIZED
// WITH CALL TO VMMDLL_InitializePlugins().
// This is the core of MemProcFS. All implementation and analysis towards
// the virtual file system (vfs) is possible by using functionality below.
//-----------------------------------------------------------------------------
#define VMMDLL_STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define VMMDLL_STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#define VMMDLL_STATUS_END_OF_FILE ((NTSTATUS)0xC0000011L)
#define VMMDLL_STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L)
#define VMMDLL_STATUS_FILE_SYSTEM_LIMITATION ((NTSTATUS)0xC0000427L)
#define VMMDLL_VFS_FILELIST_EXINFO_VERSION 1
#define VMMDLL_VFS_FILELIST_VERSION 2
#define VMMDLL_VFS_FILELISTBLOB_VERSION 0xf88f0001
typedef struct tdVMMDLL_VFS_FILELIST_EXINFO {
DWORD dwVersion;
BOOL fCompressed; // set flag FILE_ATTRIBUTE_COMPRESSED - (no meaning but shows gui artifact in explorer.exe)
union {
FILETIME ftCreationTime; // 0 = default time
QWORD qwCreationTime;
};
union {
FILETIME ftLastAccessTime; // 0 = default time
QWORD qwLastAccessTime;
};
union {
FILETIME ftLastWriteTime; // 0 = default time
QWORD qwLastWriteTime;
};
} VMMDLL_VFS_FILELIST_EXINFO, *PVMMDLL_VFS_FILELIST_EXINFO;
typedef struct tdVMMDLL_VFS_FILELIST2 {
DWORD dwVersion;
VOID(*pfnAddFile) (_Inout_ HANDLE h, _In_ LPCSTR uszName, _In_ ULONG64 cb, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo);
VOID(*pfnAddDirectory)(_Inout_ HANDLE h, _In_ LPCSTR uszName, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo);
HANDLE h;
} VMMDLL_VFS_FILELIST2, *PVMMDLL_VFS_FILELIST2;
typedef struct tdVMMDLL_VFS_FILELISTBLOB_ENTRY {
ULONG64 ouszName; // byte offset to string from VMMDLL_VFS_FILELISTBLOB.uszMultiText
ULONG64 cbFileSize; // -1 == directory
VMMDLL_VFS_FILELIST_EXINFO ExInfo; // optional ExInfo
} VMMDLL_VFS_FILELISTBLOB_ENTRY, *PVMMDLL_VFS_FILELISTBLOB_ENTRY;
typedef struct tdVMMDLL_VFS_FILELISTBLOB {
DWORD dwVersion; // VMMDLL_VFS_FILELISTBLOB_VERSION
DWORD cbStruct;
DWORD cFileEntry;
DWORD cbMultiText;
union {
LPSTR uszMultiText;
QWORD _Reserved;
};
DWORD _FutureUse[8];
VMMDLL_VFS_FILELISTBLOB_ENTRY FileEntry[0];
} VMMDLL_VFS_FILELISTBLOB, *PVMMDLL_VFS_FILELISTBLOB;
/*
* Helper functions for callbacks into the VMM_VFS_FILELIST2 structure.
*/
EXPORTED_FUNCTION
VOID VMMDLL_VfsList_AddFile(_In_ HANDLE pFileList, _In_ LPCSTR uszName, _In_ ULONG64 cb, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo);
VOID VMMDLL_VfsList_AddFileW(_In_ HANDLE pFileList, _In_ LPCWSTR wszName, _In_ ULONG64 cb, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo);
EXPORTED_FUNCTION
VOID VMMDLL_VfsList_AddDirectory(_In_ HANDLE pFileList, _In_ LPCSTR uszName, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo);
VOID VMMDLL_VfsList_AddDirectoryW(_In_ HANDLE pFileList, _In_ LPCWSTR wszName, _In_opt_ PVMMDLL_VFS_FILELIST_EXINFO pExInfo);
EXPORTED_FUNCTION BOOL VMMDLL_VfsList_IsHandleValid(_In_ HANDLE pFileList);
/*
* List a directory of files in MemProcFS. Directories and files will be listed
* by callbacks into functions supplied in the pFileList parameter.
* If information of an individual file is needed it's neccessary to list all
* files in its directory.
* -- hVMM
* -- [uw]szPath
* -- pFileList
* -- return
*/
EXPORTED_FUNCTION
_Success_(return) BOOL VMMDLL_VfsListU(_In_ VMM_HANDLE hVMM, _In_ LPCSTR uszPath, _Inout_ PVMMDLL_VFS_FILELIST2 pFileList);
_Success_(return) BOOL VMMDLL_VfsListW(_In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszPath, _Inout_ PVMMDLL_VFS_FILELIST2 pFileList);
/*
* List a directory of files in MemProcFS and return a VMMDLL_VFS_FILELISTBLOB.
* CALLER FREE: VMMDLL_MemFree(return)
* -- hVMM
* -- uszPath
* -- return
*/
EXPORTED_FUNCTION
_Success_(return != NULL) PVMMDLL_VFS_FILELISTBLOB VMMDLL_VfsListBlobU(_In_ VMM_HANDLE hVMM, _In_ LPCSTR uszPath);
/*
* Read select parts of a file in MemProcFS.
* -- hVMM
* -- [uw]szFileName
* -- pb
* -- cb
* -- pcbRead
* -- cbOffset
* -- return
*
*/
EXPORTED_FUNCTION
NTSTATUS VMMDLL_VfsReadU(_In_ VMM_HANDLE hVMM, _In_ LPCSTR uszFileName, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset);
NTSTATUS VMMDLL_VfsReadW(_In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszFileName, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset);
/*
* Write select parts to a file in MemProcFS.
* -- hVMM
* -- [uw]szFileName
* -- pb
* -- cb
* -- pcbWrite
* -- cbOffset
* -- return
*/
EXPORTED_FUNCTION
NTSTATUS VMMDLL_VfsWriteU(_In_ VMM_HANDLE hVMM, _In_ LPCSTR uszFileName, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset);
NTSTATUS VMMDLL_VfsWriteW(_In_ VMM_HANDLE hVMM, _In_ LPCWSTR wszFileName, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset);
/*
* Utility functions for MemProcFS read/write towards different underlying data
* representations.
*/
EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsReadFile_FromPBYTE(_In_ PBYTE pbFile, _In_ ULONG64 cbFile, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset);
EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsReadFile_FromQWORD(_In_ ULONG64 qwValue, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset, _In_ BOOL fPrefix);
EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsReadFile_FromDWORD(_In_ DWORD dwValue, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset, _In_ BOOL fPrefix);
EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsReadFile_FromBOOL(_In_ BOOL fValue, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset);
EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsWriteFile_BOOL(_Inout_ PBOOL pfTarget, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset);
EXPORTED_FUNCTION NTSTATUS VMMDLL_UtilVfsWriteFile_DWORD(_Inout_ PDWORD pdwTarget, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset, _In_ DWORD dwMinAllow);
//-----------------------------------------------------------------------------
// PLUGIN MANAGER FUNCTIONALITY BELOW:
// Function and structures to initialize and use MemProcFS plugin functionality.
// The plugin manager is started by a call to function:
// VMM_VfsInitializePlugins. Each built-in plugin and external plugin of which
// the DLL name matches m_*.dll will receive a call to its InitializeVmmPlugin
// function. The plugin/module may decide to call pfnPluginManager_Register to
// register plugins in the form of different names one or more times.
// Example of registration function in a plugin DLL below:
// 'VOID InitializeVmmPlugin(_In_ VMM_HANDLE H, _In_ PVMM_PLUGIN_REGINFO pRegInfo)'
//-----------------------------------------------------------------------------
/*
* Initialize all potential plugins, both built-in and external, that maps into
* MemProcFS. Please note that plugins are not loaded by default - they have to
* be explicitly loaded by calling this function. They will be unloaded on a
* general close of the vmm dll.
* -- hVMM
* -- return
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_InitializePlugins(_In_ VMM_HANDLE hVMM);
#define VMMDLL_PLUGIN_CONTEXT_MAGIC 0xc0ffee663df9301c
#define VMMDLL_PLUGIN_CONTEXT_VERSION 5
#define VMMDLL_PLUGIN_REGINFO_MAGIC 0xc0ffee663df9301d
#define VMMDLL_PLUGIN_REGINFO_VERSION 18
#define VMMDLL_FORENSIC_JSONDATA_VERSION 0xc0ee0002
#define VMMDLL_FORENSIC_INGEST_VIRTMEM_VERSION 0xc0dd0001
#define VMMDLL_FORENSIC_INGEST_OBJECT_VERSION 0xc0de0001
#define VMMDLL_PLUGIN_NOTIFY_VERBOSITYCHANGE 0x01
#define VMMDLL_PLUGIN_NOTIFY_REFRESH_FAST 0x05 // refresh fast event - at partial process refresh.
#define VMMDLL_PLUGIN_NOTIFY_REFRESH_MEDIUM 0x02 // refresh medium event - at full process refresh.
#define VMMDLL_PLUGIN_NOTIFY_REFRESH_SLOW 0x04 // refresh slow event - at registry refresh.
#define VMMDLL_PLUGIN_NOTIFY_FORENSIC_INIT 0x01000100
#define VMMDLL_PLUGIN_NOTIFY_FORENSIC_INIT_COMPLETE 0x01000200
#define VMMDLL_PLUGIN_NOTIFY_VM_ATTACH_DETACH 0x01000400
typedef DWORD VMMDLL_MODULE_ID;
typedef HANDLE *PVMMDLL_PLUGIN_INTERNAL_CONTEXT;
typedef struct tdVMMDLL_CSV_HANDLE *VMMDLL_CSV_HANDLE;
#define VMMDLL_MID_MAIN ((VMMDLL_MODULE_ID)0x80000001)
#define VMMDLL_MID_PYTHON ((VMMDLL_MODULE_ID)0x80000002)
#define VMMDLL_MID_DEBUG ((VMMDLL_MODULE_ID)0x80000003)
#define VMMDLL_MID_RUST ((VMMDLL_MODULE_ID)0x80000004)
typedef struct tdVMMDLL_PLUGIN_CONTEXT {
ULONG64 magic;
WORD wVersion;
WORD wSize;
DWORD dwPID;
PVOID pProcess;
LPSTR uszModule;
LPSTR uszPath;
PVOID pvReserved1;
PVMMDLL_PLUGIN_INTERNAL_CONTEXT ctxM; // optional internal module context.
VMMDLL_MODULE_ID MID;
} VMMDLL_PLUGIN_CONTEXT, *PVMMDLL_PLUGIN_CONTEXT;
typedef struct tdVMMDLL_FORENSIC_JSONDATA {
DWORD dwVersion; // must equal VMMDLL_FORENSIC_JSONDATA_VERSION
DWORD _FutureUse;
LPSTR szjType; // log type/name (json encoded)
DWORD i;
DWORD dwPID;
QWORD vaObj;
BOOL fva[2]; // log va even if zero
QWORD va[2];
BOOL fNum[2]; // log num even if zero
QWORD qwNum[2];
BOOL fHex[2]; // log hex even if zero
QWORD qwHex[2];
// str: will be prioritized in order: szu > wsz.
LPCSTR usz[2]; // str: utf-8 encoded
LPCWSTR wsz[2]; // str: wide
BYTE _Reserved[0x4000+256];
} VMMDLL_FORENSIC_JSONDATA, *PVMMDLL_FORENSIC_JSONDATA;
typedef enum tdVMMDLL_FORENSIC_INGEST_OBJECT_TYPE {
VMMDLL_FORENSIC_INGEST_OBJECT_TYPE_FILE = 1,
} VMMDLL_FORENSIC_INGEST_OBJECT_TYPE;
typedef struct tdVMMDLL_FORENSIC_INGEST_OBJECT {
OPAQUE_OB_HEADER _Reserved;
DWORD dwVersion; // must equal VMMDLL_FORENSIC_INGEST_OBJECT_VERSION
VMMDLL_FORENSIC_INGEST_OBJECT_TYPE tp;
QWORD vaObject;
LPSTR uszText;
PBYTE pb;
DWORD cb;
DWORD cbReadActual; // actual bytes read (may be spread out in pb)
} VMMDLL_FORENSIC_INGEST_OBJECT, *PVMMDLL_FORENSIC_INGEST_OBJECT;
typedef struct tdVMMDLL_FORENSIC_INGEST_PHYSMEM {
BOOL fValid;
QWORD pa;
DWORD cb;
PBYTE pb;
DWORD cMEMs;
PPMEM_SCATTER ppMEMs;
PVMMDLL_MAP_PFN pPfnMap;
} VMMDLL_FORENSIC_INGEST_PHYSMEM, *PVMMDLL_FORENSIC_INGEST_PHYSMEM;
typedef struct tdVMMDLL_FORENSIC_INGEST_VIRTMEM {
OPAQUE_OB_HEADER _Reserved;
DWORD dwVersion; // must equal VMMDLL_FORENSIC_INGEST_VIRTMEM_VERSION
BOOL fPte;
BOOL fVad;
PVOID pvProcess;
DWORD dwPID;
QWORD va;
PBYTE pb;
DWORD cb;
DWORD cbReadActual; // actual bytes read (may be spread out in pb)
} VMMDLL_FORENSIC_INGEST_VIRTMEM, *PVMMDLL_FORENSIC_INGEST_VIRTMEM;
typedef struct tdVMMDLL_PLUGIN_REGINFO {
ULONG64 magic; // VMMDLL_PLUGIN_REGINFO_MAGIC
WORD wVersion; // VMMDLL_PLUGIN_REGINFO_VERSION
WORD wSize; // size of struct
VMMDLL_MEMORYMODEL_TP tpMemoryModel;
VMMDLL_SYSTEM_TP tpSystem;
HMODULE hDLL;
BOOL(*pfnPluginManager_Register)(_In_ VMM_HANDLE H, struct tdVMMDLL_PLUGIN_REGINFO *pPluginRegInfo);
LPSTR uszPathVmmDLL;
DWORD _Reserved[30];
// python plugin information - not for general use
struct {
BOOL fPythonStandalone;
DWORD _Reserved;
HMODULE hReservedDllPython3;
HMODULE hReservedDllPython3X;
} python;
// general plugin registration info to be filled out by the plugin below:
struct {
PVMMDLL_PLUGIN_INTERNAL_CONTEXT ctxM; // optional internal module context [must be cleaned by pfnClose() call].
CHAR uszPathName[128];
BOOL fRootModule;
BOOL fProcessModule;
BOOL fRootModuleHidden;
BOOL fProcessModuleHidden;
CHAR sTimelineNameShort[6];
CHAR _Reserved[2];
CHAR uszTimelineFile[32];
CHAR _Reserved2[32];
} reg_info;
// function plugin registration info to be filled out by the plugin below:
struct {
BOOL(*pfnList)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _Inout_ PHANDLE pFileList);
NTSTATUS(*pfnRead)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ ULONG64 cbOffset);
NTSTATUS(*pfnWrite)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_reads_(cb) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbWrite, _In_ ULONG64 cbOffset);
VOID(*pfnNotify)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_ DWORD fEvent, _In_opt_ PVOID pvEvent, _In_opt_ DWORD cbEvent);
VOID(*pfnClose)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP);
BOOL(*pfnVisibleModule)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP);
PVOID pvReserved[10];
} reg_fn;
// Optional forensic plugin functionality for forensic (more comprehensive)
// analysis of various data. Functions are optional.
// Functions are called in the below order and way.
// 1: pfnInitialize() - multi-threaded (between plugins).
// 2: (multiple types see below) - multi-threaded (between plugins).
// pfnLogCSV()
// pfnLogJSON()
// pfnFindEvil()
// pfnIngestPhysmem()
// pfnIngestVirtmem()
// 3. pfnIngestFinalize() - single-threaded. (pfnLogCSV/pfnLogJSON/pfnFindEvil may still be active).
// 4. pfnTimeline() - single-threaded. (pfnLogCSV/pfnLogJSON/pfnFindEvil may still be active).
// 5. pfnFinalize() - single-threaded.
struct {
PVOID(*pfnInitialize)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP);
VOID(*pfnFinalize)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc);
VOID(*pfnTimeline)(
_In_ VMM_HANDLE H,
_In_opt_ PVOID ctxfc,
_In_ HANDLE hTimeline,
_In_ VOID(*pfnAddEntry)(_In_ VMM_HANDLE H, _In_ HANDLE hTimeline, _In_ QWORD ft, _In_ DWORD dwAction, _In_ DWORD dwPID, _In_ DWORD dwData32, _In_ QWORD qwData64, _In_ LPCSTR uszText),
_In_ VOID(*pfnEntryAddBySql)(_In_ VMM_HANDLE H, _In_ HANDLE hTimeline, _In_ DWORD cEntrySql, _In_ LPCSTR *pszEntrySql));
VOID(*pfnIngestObject)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc, _In_ PVMMDLL_FORENSIC_INGEST_OBJECT pIngestObject);
VOID(*pfnIngestPhysmem)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc, _In_ PVMMDLL_FORENSIC_INGEST_PHYSMEM pIngestPhysmem);
VOID(*pfnIngestVirtmem)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc, _In_ PVMMDLL_FORENSIC_INGEST_VIRTMEM pIngestVirtmem);
VOID(*pfnIngestFinalize)(_In_ VMM_HANDLE H, _In_opt_ PVOID ctxfc);
VOID(*pfnFindEvil)(_In_ VMM_HANDLE H, _In_ VMMDLL_MODULE_ID MID, _In_opt_ PVOID ctxfc);
PVOID pvReserved[6];
VOID(*pfnLogCSV)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_ VMMDLL_CSV_HANDLE hCSV);
VOID(*pfnLogJSON)(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_ VOID(*pfnLogJSON)(_In_ VMM_HANDLE H, _In_ PVMMDLL_FORENSIC_JSONDATA pData));
} reg_fnfc;
// Additional system information - read/only by the plugins.
struct {
BOOL f32;
DWORD dwVersionMajor;
DWORD dwVersionMinor;
DWORD dwVersionBuild;
DWORD _Reserved[32];
} sysinfo;
} VMMDLL_PLUGIN_REGINFO, *PVMMDLL_PLUGIN_REGINFO;
//-----------------------------------------------------------------------------
// FORENSIC-MODE SPECIFIC FUNCTIONALITY BELOW:
//-----------------------------------------------------------------------------
/*
* Append text data to a memory-backed forensics file.
* All text should be UTF-8 encoded.
* -- H
* -- uszFileName
* -- uszFormat
* -- ..
* -- return = number of bytes appended (excluding terminating null).
*/
EXPORTED_FUNCTION _Success_(return != 0)
SIZE_T VMMDLL_ForensicFileAppend(
_In_ VMM_HANDLE H,
_In_ LPCSTR uszFileName,
_In_z_ _Printf_format_string_ LPCSTR uszFormat,
...
);
//-----------------------------------------------------------------------------
// VMM LOG FUNCTIONALITY BELOW:
// It's possible for external code (primarily external plugins) to make use of
// the MemProcFS logging system.
// ----------------------------------------------------------------------------
typedef enum tdVMMDLL_LOGLEVEL {
VMMDLL_LOGLEVEL_CRITICAL = 1, // critical stopping error
VMMDLL_LOGLEVEL_WARNING = 2, // severe warning error
VMMDLL_LOGLEVEL_INFO = 3, // normal/info message
VMMDLL_LOGLEVEL_VERBOSE = 4, // verbose message (visible with -v)
VMMDLL_LOGLEVEL_DEBUG = 5, // debug message (visible with -vv)
VMMDLL_LOGLEVEL_TRACE = 6, // trace message
VMMDLL_LOGLEVEL_NONE = 7, // do not use!
} VMMDLL_LOGLEVEL;
/*
* Log a message using the internal MemProcFS vmm logging system. Log messages
* will be displayed/suppressed depending on current logging configuration.
* -- hVMM
* -- MID = module id supplied by plugin context PVMMDLL_PLUGIN_CONTEXT or
* id given by VMMDLL_MID_*.
* -- dwLogLevel
* -- uszFormat
* -- ...
*/
EXPORTED_FUNCTION
VOID VMMDLL_Log(
_In_ VMM_HANDLE hVMM,
_In_opt_ VMMDLL_MODULE_ID MID,
_In_ VMMDLL_LOGLEVEL dwLogLevel,
_In_z_ _Printf_format_string_ LPCSTR uszFormat,
...
);
/*
* Log a message using the internal MemProcFS vmm logging system. Log messages
* will be displayed/suppressed depending on current logging configuration.
* -- hVMM
* -- MID = module id supplied by plugin context PVMMDLL_PLUGIN_CONTEXT or
* id given by VMMDLL_MID_*.
* -- dwLogLevel
* -- uszFormat
* -- arglist
*/
EXPORTED_FUNCTION
VOID VMMDLL_LogEx(
_In_ VMM_HANDLE hVMM,
_In_opt_ VMMDLL_MODULE_ID MID,
_In_ VMMDLL_LOGLEVEL dwLogLevel,
_In_z_ _Printf_format_string_ LPCSTR uszFormat,
va_list arglist
);
//-----------------------------------------------------------------------------
// VMM CORE FUNCTIONALITY BELOW:
// Vmm core functaionlity such as read (and write) to both virtual and physical
// memory. NB! writing will only work if the target is supported - i.e. not a
// memory dump file...
// To read physical memory specify dwPID as (DWORD)-1
//-----------------------------------------------------------------------------
#define VMMDLL_PID_PROCESS_WITH_KERNELMEMORY 0x80000000 // Combine with dwPID to enable process kernel memory (NB! use with extreme care).
// FLAG used to supress the default read cache in calls to VMM_MemReadEx()
// which will lead to the read being fetched from the target system always.
// Cached page tables (used for translating virtual2physical) are still used.
#define VMMDLL_FLAG_NOCACHE 0x0001 // do not use the data cache (force reading from memory acquisition device)
#define VMMDLL_FLAG_ZEROPAD_ON_FAIL 0x0002 // zero pad failed physical memory reads and report success if read within range of physical memory.
#define VMMDLL_FLAG_FORCECACHE_READ 0x0008 // force use of cache - fail non-cached pages - only valid for reads, invalid with VMM_FLAG_NOCACHE/VMM_FLAG_ZEROPAD_ON_FAIL.
#define VMMDLL_FLAG_NOPAGING 0x0010 // do not try to retrieve memory from paged out memory from pagefile/compressed (even if possible)
#define VMMDLL_FLAG_NOPAGING_IO 0x0020 // do not try to retrieve memory from paged out memory if read would incur additional I/O (even if possible).
#define VMMDLL_FLAG_NOCACHEPUT 0x0100 // do not write back to the data cache upon successful read from memory acquisition device.
#define VMMDLL_FLAG_CACHE_RECENT_ONLY 0x0200 // only fetch from the most recent active cache region when reading.
#define VMMDLL_FLAG_NO_PREDICTIVE_READ 0x0400 // do not perform additional predictive page reads (default on smaller requests).
#define VMMDLL_FLAG_FORCECACHE_READ_DISABLE 0x0800 // disable/override any use of VMM_FLAG_FORCECACHE_READ. only recommended for local files. improves forensic artifact order.
#define VMMDLL_FLAG_SCATTER_PREPAREEX_NOMEMZERO 0x1000 // do not zero out the memory buffer when preparing a scatter read.
/*
* Read memory in various non-contigious locations specified by the pointers to
* the items in the ppMEMs array. Result for each unit of work will be given
* individually. No upper limit of number of items to read, but no performance
* boost will be given if above hardware limit. Max size of each unit of work is
* one 4k page (4096 bytes). Reads must not cross 4k page boundaries. Reads must
* start at even DWORDs (4-bytes).
* -- hVMM
* -- dwPID - PID of target process, (DWORD)-1 to read physical memory.
* -- ppMEMs = array of scatter read headers.
* -- cpMEMs = count of ppMEMs.
* -- flags = optional flags as given by VMMDLL_FLAG_*
* -- return = the number of successfully read items.
*/
EXPORTED_FUNCTION
DWORD VMMDLL_MemReadScatter(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Inout_ PPMEM_SCATTER ppMEMs, _In_ DWORD cpMEMs, _In_ DWORD flags);
/*
* Write memory in various non-contigious locations specified by the pointers to
* the items in the ppMEMs array. Result for each unit of work will be given
* individually. No upper limit of number of items to write Max size of each
* unit of work is one 4k page (4096 bytes). Writes must not cross 4k page boundaries.
* -- hVMM
* -- dwPID - PID of target process, (DWORD)-1 to write physical memory.
* -- ppMEMs = array of scatter read headers.
* -- cpMEMs = count of ppMEMs.
* -- return = the number of hopefully successfully written items.
*/
EXPORTED_FUNCTION
DWORD VMMDLL_MemWriteScatter(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _Inout_ PPMEM_SCATTER ppMEMs, _In_ DWORD cpMEMs);
/*
* Read a single 4096-byte page of memory.
* -- hVMM
* -- dwPID - PID of target process, (DWORD)-1 to read physical memory.
* -- qwA
* -- pbPage
* -- return = success/fail (depending if all requested bytes are read or not).
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_MemReadPage(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwA, _Inout_bytecount_(4096) PBYTE pbPage);
/*
* Read a contigious arbitrary amount of memory.
* -- hVMM
* -- dwPID - PID of target process, (DWORD)-1 to read physical memory.
* -- qwA
* -- pb
* -- cb
* -- return = success/fail (depending if all requested bytes are read or not).
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_MemRead(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwA, _Out_writes_(cb) PBYTE pb, _In_ DWORD cb);
/*
* Read a contigious amount of memory and report the number of bytes read in pcbRead.
* -- hVMM
* -- dwPID - PID of target process, (DWORD)-1 to read physical memory.
* -- qwA
* -- pb
* -- cb
* -- pcbRead
* -- flags = flags as in VMMDLL_FLAG_*
* -- return = success/fail. NB! reads may report as success even if 0 bytes are
* read - it's recommended to verify pcbReadOpt parameter.
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_MemReadEx(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwA, _Out_writes_(cb) PBYTE pb, _In_ DWORD cb, _Out_opt_ PDWORD pcbReadOpt, _In_ ULONG64 flags);
/*
* Prefetch a number of addresses (specified in the pA array) into the memory
* cache. This function is to be used to batch larger known reads into local
* cache before making multiple smaller reads - which will then happen from
* the cache. Function exists for performance reasons.
* -- hVMM
* -- dwPID = PID of target process, (DWORD)-1 for physical memory.
* -- pPrefetchAddresses = array of addresses to read into cache.
* -- cPrefetchAddresses
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_MemPrefetchPages(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_reads_(cPrefetchAddresses) PULONG64 pPrefetchAddresses, _In_ DWORD cPrefetchAddresses);
/*
* Write a contigious arbitrary amount of memory. Please note some virtual memory
* such as pages of executables (such as DLLs) may be shared between different
* virtual memory over different processes. As an example a write to kernel32.dll
* in one process is likely to affect kernel32 in the whole system - in all
* processes. Heaps and Stacks and other memory are usually safe to write to.
* Please take care when writing to memory!
* -- hVMM
* -- dwPID = PID of target process, (DWORD)-1 to read physical memory.
* -- qwA
* -- pb
* -- cb
* -- return = TRUE on success, FALSE on partial or zero write.
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_MemWrite(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwA, _In_reads_(cb) PBYTE pb, _In_ DWORD cb);
/*
* Translate a virtual address to a physical address by walking the page tables
* of the specified process.
* -- hVMM
* -- dwPID
* -- qwVA
* -- pqwPA
* -- return = success/fail.
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_MemVirt2Phys(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ ULONG64 qwVA, _Out_ PULONG64 pqwPA);
//-----------------------------------------------------------------------------
// SIMPLIFIED EASIER TO USE READ SCATTER MEMORY FUNCTIONALITY BELOW:
// The flow is as following:
// 1. Call VMMDLL_Scatter_Initialize to initialize handle.
// 2. Populate memory ranges with multiple calls to VMMDLL_Scatter_Prepare
// and/or VMMDLL_Scatter_PrepareEx functions. The memory buffer given to
// VMMDLL_Scatter_PrepareEx will be populated with contents in step (3).
// 3. Retrieve the memory by calling VMMDLL_Scatter_Execute function.
// 4. If VMMDLL_Scatter_Prepare was used (i.e. not VMMDLL_Scatter_PrepareEx)
// then retrieve the memory read in (3).
// 5. Clear the handle for reuse by calling VMMDLL_Scatter_Clear alternatively
// Close the handle to free resources with VMMDLL_Scatter_CloseHandle.
// NB! buffers given to VMMDLL_Scatter_PrepareEx must not be free'd before
// handle is closed since it may be used internally.
// NB! VMMDLL_Scatter_ExecuteRead may be called at a later point in time to
// update (re-read) previously read data.
// NB! larger reads (up to 1 GB max) are supported but not recommended.
//-----------------------------------------------------------------------------
typedef HANDLE VMMDLL_SCATTER_HANDLE;
/*
* Initialize a scatter handle which is used to call VMMDLL_Scatter_* functions.
* CALLER CLOSE: VMMDLL_Scatter_CloseHandle(return)
* -- hVMM
* -- dwPID - PID of target process, (DWORD)-1 to read physical memory.
* -- flags = optional flags as given by VMMDLL_FLAG_*
* -- return = handle to be used in VMMDLL_Scatter_* functions.
*/
EXPORTED_FUNCTION _Success_(return != NULL)
VMMDLL_SCATTER_HANDLE VMMDLL_Scatter_Initialize(_In_ VMM_HANDLE hVMM, _In_ DWORD dwPID, _In_ DWORD flags);
/*
* Prepare (add) a memory range for reading. The memory may after a call to
* VMMDLL_Scatter_Execute*() be retrieved with VMMDLL_Scatter_Read().
* -- hS
* -- va = start address of the memory range to read.
* -- cb = size of memory range to read.
* -- return
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_Scatter_Prepare(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_ DWORD cb);
/*
* Prepare (add) a memory range for reading. The buffer pb and the read length
* *pcbRead will be populated when VMMDLL_Scatter_Execute*() is later called.
* NB! the buffer pb must not be deallocated before VMMDLL_Scatter_CloseHandle()
* has been called since it's used internally by the scatter functionality!
* -- hS
* -- va = start address of the memory range to read.
* -- cb = size of memory range to read.
* -- pb = buffer to populate with read memory when calling VMMDLL_Scatter_ExecuteRead()
* -- pcbRead = optional pointer to be populated with number of bytes successfully read.
* -- return
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_Scatter_PrepareEx(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_ DWORD cb, _Out_writes_opt_(cb) PBYTE pb, _Out_opt_ PDWORD pcbRead);
/*
* Prepare (add) a memory range for writing.
* The memory contents to write is processed when calling this function.
* Any changes to va/pb/cb after this call will not be reflected in the write.
* The memory is later written when calling VMMDLL_Scatter_Execute().
* Writing takes place before reading.
* -- hS
* -- va = start address of the memory range to write.
* -- pb = data to write.
* -- cb = size of memory range to write.
* -- return
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_Scatter_PrepareWrite(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_reads_(cb) PBYTE pb, _In_ DWORD cb);
/*
* Prepare (add) a memory range for writing.
* Memory contents to write is processed when calling VMMDLL_Scatter_Execute().
* The buffer pb must be valid when VMMDLL_Scatter_Execute() is called.
* The memory is later written when calling VMMDLL_Scatter_Execute().
* Writing takes place before reading.
* -- hS
* -- va = start address of the memory range to write.
* -- pb = data to write. Buffer must be valid when VMMDLL_Scatter_Execute() is called.
* -- cb = size of memory range to write.
* -- return
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_Scatter_PrepareWriteEx(_In_ VMMDLL_SCATTER_HANDLE hS, _In_ QWORD va, _In_reads_(cb) PBYTE pb, _In_ DWORD cb);
/*
* Retrieve and Write memory previously populated.
* Write any memory prepared with VMMDLL_Scatter_PrepareWrite function (1st).
* Retrieve the memory ranges previously populated with calls to the
* VMMDLL_Scatter_Prepare* functions (2nd).
* -- hS
* -- return
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_Scatter_Execute(_In_ VMMDLL_SCATTER_HANDLE hS);
/*
* Retrieve the memory ranges previously populated with calls to the
* VMMDLL_Scatter_Prepare* functions.
* -- hS
* -- return
*/
EXPORTED_FUNCTION _Success_(return)
BOOL VMMDLL_Scatter_ExecuteRead(_In_ VMMDLL_SCATTER_HANDLE hS);
/*