diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9a6ca41 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.gitignore b/.gitignore index 259148f..0a3407a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,32 +1,5 @@ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app +/x64/ +/.vs/ +/Debug/ +/Release/ +/*.user diff --git a/TcpConnectionKiller.sln b/TcpConnectionKiller.sln new file mode 100644 index 0000000..29a268c --- /dev/null +++ b/TcpConnectionKiller.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2035 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TcpConnectionKiller", "TcpConnectionKiller\TcpConnectionKiller.vcxproj", "{DA8A02AC-9048-491A-A701-AF8674BB606F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DA8A02AC-9048-491A-A701-AF8674BB606F}.Debug|x64.ActiveCfg = Debug|x64 + {DA8A02AC-9048-491A-A701-AF8674BB606F}.Debug|x64.Build.0 = Debug|x64 + {DA8A02AC-9048-491A-A701-AF8674BB606F}.Debug|x86.ActiveCfg = Debug|Win32 + {DA8A02AC-9048-491A-A701-AF8674BB606F}.Debug|x86.Build.0 = Debug|Win32 + {DA8A02AC-9048-491A-A701-AF8674BB606F}.Release|x64.ActiveCfg = Release|x64 + {DA8A02AC-9048-491A-A701-AF8674BB606F}.Release|x64.Build.0 = Release|x64 + {DA8A02AC-9048-491A-A701-AF8674BB606F}.Release|x86.ActiveCfg = Release|Win32 + {DA8A02AC-9048-491A-A701-AF8674BB606F}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C0237241-8D4D-4D81-9AB8-DFF9C619F32A} + EndGlobalSection +EndGlobal diff --git a/TcpConnectionKiller/.gitignore b/TcpConnectionKiller/.gitignore new file mode 100644 index 0000000..3318fc8 --- /dev/null +++ b/TcpConnectionKiller/.gitignore @@ -0,0 +1,3 @@ +/Debug/ +/Release/ +/x64/ diff --git a/TcpConnectionKiller/TcpConnectionKiller.cpp b/TcpConnectionKiller/TcpConnectionKiller.cpp new file mode 100644 index 0000000..ff23a1f --- /dev/null +++ b/TcpConnectionKiller/TcpConnectionKiller.cpp @@ -0,0 +1,86 @@ +#include "stdafx.h" +#include + +using namespace std; + +string FormatAddress(DWORD ip) +{ + struct in_addr paddr; + paddr.S_un.S_addr = ip; + + return inet_ntoa(paddr); +} + +uint16_t FixPortNumber(DWORD port) +{ + return ntohs(port & 0xffff); +} + +void KillAll(vector const& toKill) +{ + for (auto con : toKill) { + + MIB_TCPROW row; + row.dwLocalAddr = con.dwLocalAddr; + row.dwLocalPort = FixPortNumber(con.dwLocalPort); + row.dwRemoteAddr = con.dwRemoteAddr; + row.dwRemotePort = FixPortNumber(con.dwRemotePort); + row.dwState = MIB_TCP_STATE_DELETE_TCB; + + cout << "Killing " << FormatAddress(row.dwLocalAddr) << ":" << row.dwLocalPort << " -> " << FormatAddress(row.dwRemoteAddr) << ":" << row.dwRemotePort << endl; + + DWORD result; + if ((result = SetTcpEntry(&row)) == 0) + { + cout << "Killed." << endl; + } + else + { + cout << "Windows reported that it failed to kill this connection, but may be lying. The result was " << result << "." << endl; + } + } +} + +vector GetConnectionsFromProcess(int processIdToKill) +{ + auto tableMemory = vector(1000000); + const auto table = reinterpret_cast(&tableMemory[0]); + ULONG size = tableMemory.size(); + if (GetTcpTable2(table, &size, TRUE) != 0) + { + throw exception("Failed to get TCP table"); + } + + vector rows; + copy_if(&table->table[0], &table->table[table->dwNumEntries], back_inserter(rows), [processIdToKill](const MIB_TCPROW2 row) { return row.dwOwningPid == processIdToKill; }); + + return rows; +} + +int main(const int argc, char const* argv[]) +{ + try { + if (argc != 2) + { + throw exception("Process ID is required."); + } + + auto const processIdToKill = stoi(argv[1]); + auto const rows = GetConnectionsFromProcess(processIdToKill); + KillAll(rows); + cout << "Ensuring all connections were killed..." << endl; + auto const remainingRows = GetConnectionsFromProcess(processIdToKill); + if(remainingRows.size() != 0) + { + throw exception("Not all connections were killed."); + } + cout << "Done." << endl; + return 0; + } + catch(exception& ex) + { + cout << "Failed: " << ex.what() << endl; + return 1; + } +} + diff --git a/TcpConnectionKiller/TcpConnectionKiller.vcxproj b/TcpConnectionKiller/TcpConnectionKiller.vcxproj new file mode 100644 index 0000000..50c6f2b --- /dev/null +++ b/TcpConnectionKiller/TcpConnectionKiller.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {DA8A02AC-9048-491A-A701-AF8674BB606F} + Win32Proj + ConsoleApplication2 + 10.0.17134.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + Iphlpapi.lib;Ws2_32.lib;%(AdditionalDependencies) + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + Create + Create + Create + Create + + + + + + + \ No newline at end of file diff --git a/TcpConnectionKiller/stdafx.cpp b/TcpConnectionKiller/stdafx.cpp new file mode 100644 index 0000000..a27b824 --- /dev/null +++ b/TcpConnectionKiller/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/TcpConnectionKiller/stdafx.h b/TcpConnectionKiller/stdafx.h new file mode 100644 index 0000000..ae05ce0 --- /dev/null +++ b/TcpConnectionKiller/stdafx.h @@ -0,0 +1,11 @@ +#pragma once + +#include "targetver.h" + +#include +#include +#include +#include +#include +#include +#include diff --git a/TcpConnectionKiller/targetver.h b/TcpConnectionKiller/targetver.h new file mode 100644 index 0000000..90e767b --- /dev/null +++ b/TcpConnectionKiller/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include