Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
"netsh trace start caputre=yes traceFile=D:\packet.etl"の再現
/*
Copyright © 2016 Egtra
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define UNICODE
#define _UNICODE
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdint>
#include <ctime>
#include <windows.h>
#include <lmcons.h>
#include <winevt.h>
#include <netcfgx.h>
#include <evntrace.h>
#include <comdef.h>
#include <atlbase.h>
#include <atlutil.h>
#pragma comment(lib, "rpcrt4.lib")
using namespace std::literals;
HRESULT OutputErrorMessgae(_In_ PCWSTR functionName, HRESULT hr)
{
std::wclog << functionName << '\n';
std::wclog << std::showbase << std::hex << hr << '\n';
std::wclog << ATL::AtlGetErrorDescription(hr).GetString() << std::endl;
return hr;
}
HRESULT OutputLastError(_In_ PCWSTR functionName)
{
auto hr = ATL::AtlHresultFromLastError();
return OutputErrorMessgae(functionName, hr);
}
void ExitIfErrorHResult(_In_ PCWSTR functionName, HRESULT hr)
{
if (FAILED(hr))
{
std::quick_exit(OutputErrorMessgae(functionName, hr));
}
}
void ExitIfErrorWin32(_In_ PCWSTR functionName, DWORD e)
{
ExitIfErrorHResult(functionName, HRESULT_FROM_WIN32(e));
}
_COM_SMARTPTR_TYPEDEF(INetCfg, __uuidof(INetCfg));
_COM_SMARTPTR_TYPEDEF(INetCfgLock, __uuidof(INetCfgLock));
_COM_SMARTPTR_TYPEDEF(INetCfgComponent, __uuidof(INetCfgComponent));
_COM_SMARTPTR_TYPEDEF(INetCfgComponentBindings, __uuidof(INetCfgComponentBindings));
_COM_SMARTPTR_TYPEDEF(IEnumNetCfgBindingPath, __uuidof(IEnumNetCfgBindingPath));
_COM_SMARTPTR_TYPEDEF(INetCfgBindingPath, __uuidof(INetCfgBindingPath));
int wmain()
{
std::locale l(std::locale::classic(), "", std::locale::ctype);
std::wcout.imbue(l);
std::wclog.imbue(l);
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
ExitIfErrorHResult(L"CoInitializeEx", hr);
DWORD result;
HKEY hkSession;
HKEY hkParameters;
result = RegCreateKeyEx(
HKEY_CURRENT_USER,
LR"(System\CurrentControlSet\Control\NetTrace\Session)",
0,
nullptr,
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
nullptr,
&hkSession,
nullptr);
ExitIfErrorWin32(L"RegOpenKeyEx (Session)", result);
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, LR"(System\CurrentControlSet\Services\NdisCap\Parameters)", 0, KEY_WRITE, &hkParameters);
ExitIfErrorWin32(L"RegOpenKeyEx (Parameters)", result);
auto hscm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT);
auto hsc = OpenService(hscm, L"ndiscap", SERVICE_START | SERVICE_CHANGE_CONFIG);
result = StartService(hsc, 0, nullptr);
//result = ChangeServiceConfig(hsc, SERVICE_KERNEL_DRIVER, SERVICE_SYSTEM_START, SERVICE_NO_CHANGE, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
DWORD refCount = 1;
result = RegSetValueEx(hkParameters, L"RefCount", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&refCount), sizeof refCount);
ExitIfErrorWin32(L"RegSetValueEx(RefCount)", result);
DWORD captureMode = 0;
result = RegSetValueEx(hkParameters, L"CaptureMode", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&captureMode), sizeof captureMode);
ExitIfErrorWin32(L"RegSetValueEx(CaptureMode)", result);
INetCfgPtr nc(CLSID_CNetCfg, nullptr, CLSCTX_SERVER);
INetCfgLockPtr lock = nc;
hr = lock->AcquireWriteLock(5000, L"Sample app (ndiscap-netsh)", nullptr);
ExitIfErrorHResult(L"INetCfgLock::AcquireWriteLock", hr);
if (hr != S_OK)
{
std::wclog << "Locked" << std::endl;
std::quick_exit(1);
}
hr = nc->Initialize(nullptr);
ExitIfErrorHResult(L"INetCfg::Initialize", hr);
INetCfgComponentPtr ndisCap;
hr = nc->FindComponent(L"ms_ndiscap", &ndisCap);
ExitIfErrorHResult(L"INetCfg::FindComponent", hr);
INetCfgComponentBindingsPtr b = ndisCap;
IEnumNetCfgBindingPathPtr enumBindingPath;
hr = b->EnumBindingPaths(EBP_BELOW, &enumBindingPath);
ExitIfErrorHResult(L"INetCfgComponentBindings::EnumBindingPaths", hr);
INetCfgBindingPathPtr bindingPath;
ULONG fetched;
while (enumBindingPath->Next(1, &bindingPath, &fetched) == S_OK)
{
// netshでは、先にIsEnabledを確認している
hr = bindingPath->Enable(TRUE);
ExitIfErrorHResult(L"INetCfgBindingPath::Enable", hr);
}
hr = nc->Apply();
ExitIfErrorHResult(L"INetCfg::Apply", hr);
DWORD value = 1;
result = RegSetValueEx(hkSession, L"CaptureEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value);
ExitIfErrorWin32(L"RegSetValueEx(CaptureEnabled)", result);
hr = lock->ReleaseWriteLock();
WCHAR computerName[16]{};
DWORD computerNameSize = ARRAYSIZE(computerName);
GetComputerName(computerName, &computerNameSize);
WCHAR userName[UNLEN + 1]{};
DWORD userNameSize = ARRAYSIZE(userName);
GetUserName(userName, &userNameSize);
std::wstring sessionName = L"NetTrace-"s + computerName + L'-' + userName;
std::wcout << sessionName << std::endl;
auto logFileName = LR"(D:\packet.etl)";
TRACEHANDLE th;
union
{
char buffer[1024];
EVENT_TRACE_PROPERTIES etp;
};
memset(buffer, 0, sizeof buffer);
etp.Wnode.BufferSize = sizeof etp + sizeof(WCHAR) * (sessionName.size() + 1 + wcslen(logFileName) + 1);
etp.Wnode.ClientContext = 2; // Query perfomance counter
etp.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
etp.BufferSize = 128;
etp.MaximumBuffers = 128;
etp.MaximumFileSize = 250;
etp.LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR | EVENT_TRACE_FLAG_DEBUG_EVENTS | EVENT_TRACE_REAL_TIME_MODE;
etp.LogFileNameOffset = sizeof etp + sizeof(WCHAR) * (sessionName.size() + 1);
etp.LoggerNameOffset = sizeof etp; // 120
wmemcpy((PWSTR)(buffer + etp.LogFileNameOffset), logFileName, wcslen(logFileName) + 1);
wmemcpy((PWSTR)(buffer + etp.LoggerNameOffset), sessionName.c_str(), sessionName.size() + 1);
result = StartTrace(&th, sessionName.c_str(), &etp);
ExitIfErrorWin32(L"StartTrace", HRESULT_FROM_WIN32(result));
struct __declspec(uuid("{83ed54f0-4d48-4e45-b16e-726ffd1fa4af}")) Microsoft_Windows_Networking_Correlation;
struct __declspec(uuid("{2ed6006e-4729-4609-b423-3ee7bcd678ef}")) Microsoft_Windows_NDIS_PacketCapture;
ENABLE_TRACE_PARAMETERS params{};
params.Version = ENABLE_TRACE_PARAMETERS_VERSION;
result = EnableTraceEx2(th, &__uuidof(Microsoft_Windows_Networking_Correlation), EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_NONE, 7, 0, 0, &params);
ExitIfErrorWin32(L"EnableTraceEx2(Microsoft-Windows-Networking-Correlation)", result);
params.Version = ENABLE_TRACE_PARAMETERS_VERSION;
result = EnableTraceEx2(th, &__uuidof(Microsoft_Windows_NDIS_PacketCapture), EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_INFORMATION, 0, 0, 0, &params);
ExitIfErrorWin32(L"EnableTraceEx2(Microsoft-Windows-NDIS-PacketCapture)", result);
value = 0;
result = RegSetValueEx(hkSession, L"ReportEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value);
ExitIfErrorWin32(L"RegSetValueEx(ReportEnabled)", result);
value = 1;
result = RegSetValueEx(hkSession, L"MiniReportEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value);
ExitIfErrorWin32(L"RegSetValueEx(MiniReportEnabled)", result);
result = RegSetValueEx(hkSession, L"CorrelateEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value);
ExitIfErrorWin32(L"RegSetValueEx(CorrelateEnabled)", result);
result = RegSetValueEx(hkSession, L"PerfMergeEnabled", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof value);
ExitIfErrorWin32(L"RegSetValueEx(PerfMergeEnabled)", result);
GUID sessionId{};
UuidCreateSequential(&sessionId);
WCHAR sessionIdString[39]{};
StringFromGUID2(sessionId, sessionIdString, ARRAYSIZE(sessionIdString));
result = RegSetValueEx(hkSession, L"SessionId", 0, REG_SZ, reinterpret_cast<const BYTE*>(&sessionIdString), sizeof sessionIdString);
ExitIfErrorWin32(L"RegSetValueEx(SessionId)", result);
auto startTime = static_cast<std::uint64_t>(std::time(nullptr));
result = RegSetValueEx(hkSession, L"StartTime", 0, REG_QWORD, reinterpret_cast<const BYTE*>(&startTime), sizeof startTime);
ExitIfErrorWin32(L"RegSetValueEx(StartTime)", result);
hr = nc->Uninitialize();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.