1 /**
2 * Win32 EntropySource
3 * 
4 * Copyright:
5 * (C) 1999-2009 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.entropy.es_win32;
12 
13 version(Windows):
14 import botan.constants;
15 static if (BOTAN_HAS_ENTROPY_SRC_WIN32):
16 
17 import botan.entropy.entropy_src;
18 
19 import core.sys.windows.windows;
20 
21 /**
22 * Win32 Entropy Source
23 */
24 final class Win32EntropySource : EntropySource
25 {
26 public:
27     @property string name() const { return "Win32 Statistics"; }
28     
29     /**
30     * Win32 poll using stats functions including Tooltip32
31     */
32     void poll(ref EntropyAccumulator accum)
33     {
34         /*
35         First query a bunch of basic statistical stuff, though
36         don't count it for much in terms of contributed entropy.
37         */
38         accum.add(GetTickCount(), 0);
39         accum.add(GetMessagePos(), 0);
40         accum.add(GetMessageTime(), 0);
41         accum.add(GetInputState(), 0);
42         accum.add(GetCurrentProcessId(), 0);
43         accum.add(GetCurrentThreadId(), 0);
44         
45         SYSTEM_INFO sys_info;
46         GetSystemInfo(&sys_info);
47         accum.add(sys_info, 1);
48         
49         MEMORYSTATUS mem_info;
50         GlobalMemoryStatus(&mem_info);
51         accum.add(mem_info, 1);
52         
53         POINT point;
54         GetCursorPos(&point);
55         accum.add(point, 1);
56         
57         GetCaretPos(&point);
58         accum.add(point, 1);
59         
60         LARGE_INTEGER perf_counter;
61         QueryPerformanceCounter(&perf_counter);
62         accum.add(perf_counter, 0);
63         
64         /*
65         Now use the Tooltip library to iterate throug various objects on
66         the system, including processes, threads, and heap objects.
67         */
68         
69         HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
70         
71         
72         TOOLHELP32_ITER!(MODULEENTRY32, Module32First, Module32Next, snapshot)(accum);
73         TOOLHELP32_ITER!(PROCESSENTRY32, Process32First, Process32Next, snapshot)(accum);
74         TOOLHELP32_ITER!(THREADENTRY32, Thread32First, Thread32Next, snapshot)(accum);
75         
76         
77         if (!accum.pollingGoalAchieved())
78         {
79             size_t heap_lists_found = 0;
80             HEAPLIST32 heap_list;
81             heap_list.dwSize = (HEAPLIST32).sizeof;
82             
83             __gshared immutable size_t HEAP_LISTS_MAX = 32;
84             __gshared immutable size_t HEAP_OBJS_PER_LIST = 128;
85             
86             if (Heap32ListFirst(snapshot, &heap_list))
87             {
88                 do
89                 {
90                     accum.add(heap_list, 1);
91                     
92                     if (++heap_lists_found > HEAP_LISTS_MAX)
93                         break;
94                     
95                     size_t heap_objs_found = 0;
96                     HEAPENTRY32 heap_entry;
97                     heap_entry.dwSize = (HEAPENTRY32).sizeof;
98                     if (Heap32First(&heap_entry, heap_list.th32ProcessID,
99                                     heap_list.th32HeapID))
100                     {
101                         do
102                         {
103                             if (heap_objs_found++ > HEAP_OBJS_PER_LIST)
104                                 break;
105                             accum.add(heap_entry, 1);
106                         } while(Heap32Next(&heap_entry));
107                     }
108                     
109                     if (accum.pollingGoalAchieved())
110                         break;
111                     
112                 } while(Heap32ListNext(snapshot, &heap_list));
113             }
114         }
115         
116         CloseHandle(snapshot);
117     }
118 }
119 
120 
121 
122 void TOOLHELP32_ITER(alias DATA_TYPE, alias FUNC_FIRST, alias FUNC_NEXT, alias SNAPSHOT)(ref EntropyAccumulator accum) {
123     if (!accum.pollingGoalAchieved())
124     {
125         DATA_TYPE info;
126         info.dwSize = (DATA_TYPE).sizeof;
127         if (FUNC_FIRST(SNAPSHOT, &info))
128         {
129             do
130             {
131                 accum.add(info, 1);
132             } while(FUNC_NEXT(SNAPSHOT, &info));
133         }
134     }
135 }
136 
137 import core.sys.windows.windows;
138 
139 extern(Windows) private nothrow @nogc:
140 
141 DWORD GetMessagePos();
142 LONG GetMessageTime();
143 BOOL GetInputState();
144 enum : uint {
145     HF32_DEFAULT = 1,
146     HF32_SHARED
147 }
148 
149 alias LARGE_INTEGER = long;
150 enum : uint {
151     LF32_FIXED    = 0x1,
152     LF32_FREE     = 0x2,
153     LF32_MOVEABLE = 0x4
154 }
155 
156 const MAX_MODULE_NAME32 = 255;
157 
158 enum : uint {
159     TH32CS_SNAPHEAPLIST = 0x1,
160     TH32CS_SNAPPROCESS  = 0x2,
161     TH32CS_SNAPTHREAD   = 0x4,
162     TH32CS_SNAPMODULE   = 0x8,
163     TH32CS_SNAPALL      = (TH32CS_SNAPHEAPLIST|TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD|TH32CS_SNAPMODULE),
164     TH32CS_INHERIT      = 0x80000000
165 }
166 
167 struct HEAPLIST32 {
168     DWORD dwSize;
169     DWORD th32ProcessID;
170     DWORD th32HeapID;
171     DWORD dwFlags;
172 } 
173 alias HEAPLIST32* PHEAPLIST32;
174 alias HEAPLIST32* LPHEAPLIST32;
175 
176 struct HEAPENTRY32 {
177     DWORD dwSize;
178     HANDLE hHandle;
179     DWORD dwAddress;
180     DWORD dwBlockSize;
181     DWORD dwFlags;
182     DWORD dwLockCount;
183     DWORD dwResvd;
184     DWORD th32ProcessID;
185     DWORD th32HeapID;
186 }
187 alias HEAPENTRY32* PHEAPENTRY32;
188 alias HEAPENTRY32* LPHEAPENTRY32;
189 
190 struct PROCESSENTRY32W {
191     DWORD dwSize;
192     DWORD cntUsage;
193     DWORD th32ProcessID;
194     DWORD th32DefaultHeapID;
195     DWORD th32ModuleID;
196     DWORD cntThreads;
197     DWORD th32ParentProcessID;
198     LONG pcPriClassBase;
199     DWORD dwFlags;
200     WCHAR[MAX_PATH] szExeFile;
201 }
202 alias PROCESSENTRY32W* PPROCESSENTRY32W;
203 alias PROCESSENTRY32W* LPPROCESSENTRY32W;
204 
205 struct THREADENTRY32 {
206     DWORD dwSize;
207     DWORD cntUsage;
208     DWORD th32ThreadID;
209     DWORD th32OwnerProcessID;
210     LONG tpBasePri;
211     LONG tpDeltaPri;
212     DWORD dwFlags;
213 }
214 alias THREADENTRY32* PTHREADENTRY32;
215 alias THREADENTRY32* LPTHREADENTRY32;
216 
217 struct MODULEENTRY32W {
218     DWORD dwSize;
219     DWORD th32ModuleID;
220     DWORD th32ProcessID;
221     DWORD GlblcntUsage;
222     DWORD ProccntUsage;
223     BYTE *modBaseAddr;
224     DWORD modBaseSize;
225     HMODULE hModule; 
226     WCHAR[MAX_MODULE_NAME32 + 1] szModule;
227     WCHAR[MAX_PATH] szExePath;
228 }
229 alias MODULEENTRY32W* PMODULEENTRY32W;
230 alias MODULEENTRY32W* LPMODULEENTRY32W;
231 
232 struct PROCESSENTRY32 {
233     DWORD dwSize;
234     DWORD cntUsage;
235     DWORD th32ProcessID;
236     DWORD th32DefaultHeapID;
237     DWORD th32ModuleID;
238     DWORD cntThreads;
239     DWORD th32ParentProcessID;
240     LONG pcPriClassBase;
241     DWORD dwFlags;
242     CHAR[MAX_PATH]  szExeFile;
243 }
244 alias PROCESSENTRY32* PPROCESSENTRY32;
245 alias PROCESSENTRY32* LPPROCESSENTRY32;
246 
247 struct MODULEENTRY32 {
248     DWORD dwSize;
249     DWORD th32ModuleID;
250     DWORD th32ProcessID;
251     DWORD GlblcntUsage;
252     DWORD ProccntUsage;
253     BYTE *modBaseAddr;
254     DWORD modBaseSize;
255     HMODULE hModule;
256     char[MAX_MODULE_NAME32 + 1] szModule;
257     char[MAX_PATH] szExePath;
258 }
259 alias MODULEENTRY32* PMODULEENTRY32;
260 alias MODULEENTRY32* LPMODULEENTRY32;
261 
262 BOOL Heap32First(LPHEAPENTRY32,DWORD,DWORD);
263 BOOL Heap32ListFirst(HANDLE,LPHEAPLIST32);
264 BOOL Heap32ListNext(HANDLE,LPHEAPLIST32);
265 BOOL Heap32Next(LPHEAPENTRY32);
266 BOOL Thread32First(HANDLE,LPTHREADENTRY32);
267 BOOL Thread32Next(HANDLE,LPTHREADENTRY32);
268 BOOL Toolhelp32ReadProcessMemory(DWORD,LPCVOID,LPVOID,DWORD,LPDWORD);
269 HANDLE CreateToolhelp32Snapshot(DWORD,DWORD);
270 BOOL Module32FirstW(HANDLE,LPMODULEENTRY32W);
271 BOOL Module32NextW(HANDLE,LPMODULEENTRY32W);
272 BOOL Process32FirstW(HANDLE,LPPROCESSENTRY32W);
273 BOOL Process32NextW(HANDLE,LPPROCESSENTRY32W);
274 
275 BOOL Module32First(HANDLE,LPMODULEENTRY32);
276 BOOL Module32Next(HANDLE,LPMODULEENTRY32);
277 BOOL Process32First(HANDLE,LPPROCESSENTRY32);
278 BOOL Process32Next(HANDLE,LPPROCESSENTRY32);