1// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <windows.h>
6#include <Tlhelp32.h>
7#include "sandbox/win/sandbox_poc/pocdll/exports.h"
8#include "sandbox/win/sandbox_poc/pocdll/utils.h"
9
10// This file contains the tests used to verify the security of threads and
11// processes.
12
13void POCDLL_API TestProcesses(HANDLE log) {
14  HandleToFile handle2file;
15  FILE *output = handle2file.Translate(log, "w");
16
17  HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
18  if (INVALID_HANDLE_VALUE == snapshot) {
19    fprintf(output, "[BLOCKED] Cannot list all processes on the system. "
20                    "Error %ld\r\n", ::GetLastError());
21    return;
22  }
23
24  PROCESSENTRY32 process_entry = {0};
25  process_entry.dwSize = sizeof(PROCESSENTRY32);
26
27  BOOL result = ::Process32First(snapshot, &process_entry);
28
29  while (result) {
30    HANDLE process = ::OpenProcess(PROCESS_VM_READ,
31                                   FALSE,  // Do not inherit handle.
32                                   process_entry.th32ProcessID);
33    if (NULL == process) {
34      fprintf(output, "[BLOCKED] Found process %S:%ld but cannot open it. "
35                      "Error %ld\r\n",
36                      process_entry.szExeFile,
37                      process_entry.th32ProcessID,
38                      ::GetLastError());
39    } else {
40      fprintf(output, "[GRANTED] Found process %S:%ld and open succeeded.\r\n",
41                      process_entry.szExeFile, process_entry.th32ProcessID);
42      ::CloseHandle(process);
43    }
44
45    result = ::Process32Next(snapshot, &process_entry);
46  }
47
48  DWORD err_code = ::GetLastError();
49  if (ERROR_NO_MORE_FILES != err_code) {
50    fprintf(output, "[ERROR] Error %ld while looking at the processes on "
51                    "the system\r\n", err_code);
52  }
53
54  ::CloseHandle(snapshot);
55}
56
57void POCDLL_API TestThreads(HANDLE log) {
58  HandleToFile handle2file;
59  FILE *output = handle2file.Translate(log, "w");
60
61  HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);
62  if (INVALID_HANDLE_VALUE == snapshot) {
63    fprintf(output, "[BLOCKED] Cannot list all threads on the system. "
64                    "Error %ld\r\n", ::GetLastError());
65    return;
66  }
67
68  THREADENTRY32 thread_entry = {0};
69  thread_entry.dwSize = sizeof(THREADENTRY32);
70
71  BOOL result = ::Thread32First(snapshot, &thread_entry);
72  int nb_success = 0;
73  int nb_failure = 0;
74
75  while (result) {
76    HANDLE thread = ::OpenThread(THREAD_QUERY_INFORMATION,
77                                 FALSE,  // Do not inherit handles.
78                                 thread_entry.th32ThreadID);
79    if (NULL == thread) {
80      nb_failure++;
81    } else {
82      nb_success++;
83      fprintf(output, "[GRANTED] Found thread %ld:%ld and able to open it.\r\n",
84                      thread_entry.th32OwnerProcessID,
85                      thread_entry.th32ThreadID);
86      ::CloseHandle(thread);
87    }
88
89    result = Thread32Next(snapshot, &thread_entry);
90  }
91
92  DWORD err_code = ::GetLastError();
93  if (ERROR_NO_MORE_FILES != err_code) {
94    fprintf(output, "[ERROR] Error %ld while looking at the processes on "
95                    "the system\r\n", err_code);
96  }
97
98  fprintf(output, "[INFO] Found %d threads. Able to open %d of them\r\n",
99          nb_success + nb_failure, nb_success);
100
101  ::CloseHandle(snapshot);
102}
103