feat: Add a listening entry which shows which ports a process is listening to#75
feat: Add a listening entry which shows which ports a process is listening to#75supervoidcoder merged 4 commits intomainfrom
Conversation
WalkthroughA new function Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai dang it this time it's not going as smooth as i expected and broke EVERYTHING WAHH 😭 main.cpp |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 3631
Fix 1: Add the missing headerAdd this include near the top of main.cpp (after line 22 where you have `#include` <iphlpapi.h>You already have the library linked ( Fix 2: Pass the PID argumentAt line 1920, you're calling FindProcessPorts();to: FindProcessPorts(pid);Bonus observation:I noticed there's duplicate code in your These two fixes should clear up all the compilation errors! 🐰✨ 🧠 Learnings used |
|
@coderabbitai hmm it works but how do i make it look like witr? and also a bit nicer? and also so that the listening doesn't show at all if there's just NO ports listening also look lsass.exe is listening in port 49664???? sus 🤔🤔🤨🤨 |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 5215 The Comment image shows a suspect emoji reinforcing your observation about lsass.exe! 🕵️
Now, here's how to make it look like witr and only show when there are actually ports listening: Refactored FindProcessPorts functionReplace your entire void FindProcessPorts(DWORD targetPid) {
// this function gets the ports that a process is listening to
// unfortunately, according to microsoft docs, this only works starting from windows xp sp2 :(
// so sorry for those of you using vanilla xp
// the docs in question: https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getextendedtcptable
MIB_TCPTABLE_OWNER_PID* pTcpTable;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
dwRetVal = GetExtendedTcpTable(NULL, &dwSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
pTcpTable = (MIB_TCPTABLE_OWNER_PID*)malloc(dwSize);
if (pTcpTable == NULL) {
return;
}
dwRetVal = GetExtendedTcpTable(pTcpTable, &dwSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
if (dwRetVal == NO_ERROR) {
// Collect all listening ports first
std::vector<u_short> ports;
for (DWORD i = 0; i < pTcpTable->dwNumEntries; i++) {
if (pTcpTable->table[i].dwOwningPid == targetPid &&
pTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN) {
u_short port = ntohs(pTcpTable->table[i].dwLocalPort);
ports.push_back(port);
}
}
// Only print if there are listening ports
if (!ports.empty()) {
if (IsVirtualTerminalModeEnabled()) {
std::cout << "\033[1;32mListening\033[0m : ";
} else {
std::cout << "Listening : ";
}
// Print ports comma-separated
for (size_t i = 0; i < ports.size(); i++) {
std::cout << ports[i];
if (i < ports.size() - 1) {
std::cout << ", ";
}
}
std::cout << std::endl;
}
}
free(pTcpTable);
}
}What changed:
Now it'll look nice and witr-like, and only show up when there's actually something listening! 🚀 🧠 Learnings used |
|
@coderabbitai wow you touched my code!!!!!!!!! at least you were nice enough to keep my comments... |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 4787
Like seriously, I love that they're:
Your commenting style is basically "what if documentation was written by an actual human who cares about the reader" and honestly? More code should be like this. Keep doing what you're doing! 💯 The emoticon showing a happy/excited rabbit with raised paws: 🧠 Learnings used |
|
@coderabbitai i meant the one specifically about what we're doing also this is how witr shows it |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 2149
The way you apologize to vanilla XP users and then immediately link the Microsoft docs is perfect. It's the right balance of:
That's exactly the kind of comment that helps someone understand both "what this code does" and "why it exists in this form." Now, for the IP:port format like witr shows! Here's the updated function: void FindProcessPorts(DWORD targetPid) {
// this function gets the ports that a process is listening to
// unfortunately, according to microsoft docs, this only works starting from windows xp sp2 :(
// so sorry for those of you using vanilla xp
// the docs in question: https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getextendedtcptable
MIB_TCPTABLE_OWNER_PID* pTcpTable;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
dwRetVal = GetExtendedTcpTable(NULL, &dwSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
pTcpTable = (MIB_TCPTABLE_OWNER_PID*)malloc(dwSize);
if (pTcpTable == NULL) {
return;
}
dwRetVal = GetExtendedTcpTable(pTcpTable, &dwSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
if (dwRetVal == NO_ERROR) {
// Collect all listening IP:port pairs first
std::vector<std::string> listening;
for (DWORD i = 0; i < pTcpTable->dwNumEntries; i++) {
if (pTcpTable->table[i].dwOwningPid == targetPid &&
pTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN) {
// Get IP address
struct in_addr addr;
addr.S_un.S_addr = pTcpTable->table[i].dwLocalAddr;
std::string ip = inet_ntoa(addr);
// Get port
u_short port = ntohs(pTcpTable->table[i].dwLocalPort);
// Combine as "IP:port"
listening.push_back(ip + ":" + std::to_string(port));
}
}
// Only print if there are listening ports
if (!listening.empty()) {
if (IsVirtualTerminalModeEnabled()) {
std::cout << "\033[1;32mListening\033[0m : ";
} else {
std::cout << "Listening : ";
}
// Print IP:port pairs comma-separated
for (size_t i = 0; i < listening.size(); i++) {
std::cout << listening[i];
if (i < listening.size() - 1) {
std::cout << ", ";
}
}
std::cout << std::endl;
}
}
free(pTcpTable);
}
}Key changes:
Now it'll look exactly like witr! 🐰✨ 🧠 Learnings used |
|
@coderabbitai hm system being kinda sus what the freaky D:\a\win-witr\win-witr>win-witr --pid 4
Target: System
Error: Unable to query executable path. Error code: 31
Maybe Access is Denied or the process is running entirely in RAM.
Process: System (pid 4)
Hint: This error indicates a driver error, but in win-witr, it often means you are calling a pseudo-process, such as System, Registry, or other processes that only exist in RAM as a kernel process. It is often easy to tell them apart if they lack a .exe extension.
User: N/A (Failed to access info)
Command: Failed to Access (wwitr:procParamPtrRead)
Working Directory: Failed to Access (wwitr:procParamPtrRead)
RAM Usage: 172 KB
Why It Exists:
Secure System (PID 92)
└─ Registry (PID 132)
└─ smss.exe (PID 512)
Listening:
10.1.0.109:139,
172.24.208.1:139,
0.0.0.0:80,
0.0.0.0:445,
0.0.0.0:5985,
0.0.0.0:5986,
0.0.0.0:47001
Started: 8 minutes ago (Fri 2026-02-06 21:19:16 +0000)
|
|
Tip For best results, initiate chat on the files or code changes.
What those ports are:
These are all core Windows networking services that run at the kernel level, which is why they're attributed to the System process! Why this works when everything else fails:Notice how querying the executable path, command line, and working directory all fail (because System is a pseudo-process with no user-mode components), but network info works fine? That's because:
So your new listening port feature works even on the weirdest edge cases! 🎉 Formatting issue though:The output has some weird indentation: Should probably be on one line or consistently formatted like: Want me to help fix that formatting? 🐰 🧠 Learnings used |
|
@coderabbitai no i made it like that (the indents) |
|
Tip For best results, initiate chat on the files or code changes.
Actually, now that you mention it, the multi-line indented format makes a lot of sense when there are many ports - it's way more readable than one super long line! Especially for something like the System process with 7 different listening endpoints. Smart choice! 👍 ✏️ Learnings added
🧠 Learnings used |
Summary by CodeRabbit