HollowsHunter
Scans all running processes. Recognizes and dumps a variety of potentially malicious implants (replaced/implanted PEs, shellcodes, hooks, in-memory patches).
Loading...
Searching...
No Matches
time_util.cpp
Go to the documentation of this file.
1#include "time_util.h"
2#include <codecvt>
3#include <locale>
4#include <string>
5#include <sstream>
6
7#include <iostream>
8#include <iomanip>
9#include <ctime>
10#include <cmath>
11
12#include "ntddk.h"
13#include "custom_buffer.h"
14
15std::wstring util::strtime(const time_t t)
16{
17 struct tm time_info;
18 if (localtime_s(&time_info, &t) == 0) {
19 std::wstringstream str;
20 str << std::put_time(&time_info, L"%c");
21 std::wstring result = str.str();
22 return result;
23 }
24 return L"";
25}
26
27// snippet from: https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
28LONGLONG util::LargeTime_to_POSIX(LARGE_INTEGER date)
29{
30 // takes the last modified date
31 LARGE_INTEGER adjust;
32
33 // 100-nanoseconds = milliseconds * 10000
34 adjust.QuadPart = 11644473600000 * 10000;
35
36 // removes the diff between 1970 and 1601
37 date.QuadPart -= adjust.QuadPart;
38
39 // converts back from 100-nanoseconds to seconds
40 return date.QuadPart / 10000000;
41}
42
43
44LONGLONG util::FileTime_to_POSIX(FILETIME ft)
45{
46 // takes the last modified date
47 LARGE_INTEGER date;
48 date.HighPart = ft.dwHighDateTime;
49 date.LowPart = ft.dwLowDateTime;
50 return LargeTime_to_POSIX(date);
51}
52
53
54//---
55
56LONGLONG util::process_start_time(IN DWORD pid)
57{
58 static auto mod = GetModuleHandleA("ntdll.dll");
59 if (!mod) return INVALID_TIME;
60
61 static auto pNtQuerySystemInformation = reinterpret_cast<decltype(&NtQuerySystemInformation)>(GetProcAddress(mod, "NtQuerySystemInformation"));
62 if (!pNtQuerySystemInformation) return false;
63
65
66 NTSTATUS status = STATUS_UNSUCCESSFUL;
67 while (status != STATUS_SUCCESS) {
68 ULONG ret_len = 0;
69 status = pNtQuerySystemInformation(SystemProcessInformation, bBuf.buf, bBuf.buf_size, &ret_len);
70 if (status == STATUS_INFO_LENGTH_MISMATCH) {
71 if (!bBuf.alloc(ret_len)) {
72 return INVALID_TIME;
73 }
74 continue; // try again
75 }
76 break; //other error, or success
77 };
78
79 if (status != STATUS_SUCCESS) {
80 return INVALID_TIME;
81 }
82
83 bool found = false;
84 SYSTEM_PROCESS_INFORMATION* info = (SYSTEM_PROCESS_INFORMATION*)bBuf.buf;
85 while (info) {
86 if (info->UniqueProcessId == pid) {
87 found = true;
88 break;
89 }
90 if (!info->NextEntryOffset) {
91 break;
92 }
93 size_t record_size = info->NextEntryOffset;
94 if (record_size < sizeof(SYSTEM_PROCESS_INFORMATION)) {
95 // Record size smaller than expected, probably it is an old system that doesn not support the new version of this API
96#ifdef _DEBUG
97 std::cout << "The new version of SYSTEM_PROCESS_INFORMATION is not supported!\n";
98#endif
99 break;
100 }
101 info = (SYSTEM_PROCESS_INFORMATION*)((ULONG_PTR)info + info->NextEntryOffset);
102 if (!info) {
103 break;
104 }
105 }
106
107 if (!found) {
108 return INVALID_TIME;
109 }
110
111 LARGE_INTEGER createTime = info->CreateTime;
112 return util::LargeTime_to_POSIX(createTime);
113}
114
LONGLONG process_start_time(IN DWORD processID)
Definition time_util.cpp:56
LONGLONG FileTime_to_POSIX(FILETIME ft)
Definition time_util.cpp:44
std::wstring strtime(const time_t t)
Definition time_util.cpp:15
LONGLONG LargeTime_to_POSIX(LARGE_INTEGER date)
Definition time_util.cpp:28
BYTE * alloc(size_t _buf_size)
#define INVALID_TIME
Definition time_util.h:7