📄 tdifw_svc.c
字号:
return inet_addr(addr);
}
// GetLongPathName is in Windows 2000 only so make it for NT4
void my_GetLongPathName(LPCSTR lpszShortPath, LPSTR lpszLongPath, DWORD cchBuffer)
{
LPSTR p_l;
LPCSTR p_s;
lpszLongPath[0] = lpszShortPath[0];
lpszLongPath[1] = lpszShortPath[1];
lpszLongPath[2] = lpszShortPath[2];
lpszLongPath[3] = '\0';
p_l = &lpszLongPath[3];
p_s = &lpszShortPath[3];
for (;;){
LPSTR p_s2;
HANDLE search;
WIN32_FIND_DATA ffd;
size_t len;
BOOL overflow;
p_s2 = strchr(p_s, '\\');
if (p_s2 != NULL)
len = p_s2 - p_s;
else
len = strlen(p_s);
// check the buffer
if (len + (p_l - lpszLongPath) >= cchBuffer)
{
// buffer overflow: copy and exit
len = cchBuffer - (p_l - lpszLongPath) - 1;
overflow = TRUE;
}
else
overflow = FALSE;
memcpy(p_l, p_s, len);
p_l[len] = '\0';
if (overflow)
break;
search = FindFirstFile(lpszLongPath, &ffd);
if (search != INVALID_HANDLE_VALUE)
{
len = strlen(ffd.cFileName);
if (p_s2 != NULL)
len++;
// check the buffer
if (len + (p_l - lpszLongPath) >= cchBuffer)
{
// buffer overflow: copy and exit
len = cchBuffer - (p_l - lpszLongPath) - 1;
p_s2 = NULL;
}
memcpy(p_l, ffd.cFileName, len);
if (p_s2 != NULL)
{
p_l[len - 1] = '\\';
p_l[len] = '\0';
}
else
p_l[len] = '\0';
FindClose(search);
}
if (p_s2 == NULL)
break;
p_l += strlen(p_l);
p_s = p_s2 + 1;
}
// ignore status
}
// dynamically try to link with psapi.lib
void link_psapi(void)
{
g_psapi = LoadLibrary("psapi.dll");
if (g_psapi == NULL)
{
// no psapi.dll - log it!
error("INIT\tCan't load psapi.dll!");
return;
}
pEnumProcesses = (EnumProcesses_t *)GetProcAddress(g_psapi, "EnumProcesses");
pEnumProcessModules = (EnumProcessModules_t *)GetProcAddress(g_psapi, "EnumProcessModules");
#ifdef UNICODE
pGetModuleFileNameEx = (GetModuleFileNameEx_t *)GetProcAddress(g_psapi, "GetModuleFileNameExW");
#else
pGetModuleFileNameEx = (GetModuleFileNameEx_t *)GetProcAddress(g_psapi, "GetModuleFileNameExA");
#endif
if (pEnumProcesses == NULL || pEnumProcessModules == NULL || pGetModuleFileNameEx == NULL)
{
// invalid psapi.dll?
error("INIT\tInvalid psapi.dll!");
FreeLibrary(g_psapi);
g_psapi = NULL;
}
}
#define PRINT_IP_ADDR(addr) \
((UCHAR *)&(addr))[0], ((UCHAR *)&(addr))[1], ((UCHAR *)&(addr))[2], ((UCHAR *)&(addr))[3]
// enum listening objects
void enum_listen(void)
{
ULONG size;
struct listen_nfo *ln = NULL;
int i, n;
// try to dynamically link psapi.dll
link_psapi();
/* connect with driver */
g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (g_device == INVALID_HANDLE_VALUE)
{
winerr(g_nfo_device_name);
goto done;
}
/* get list of listening objects */
size = sizeof(*ln) * 0x10000 * 3; // this size is good enough :-)
ln = (struct listen_nfo *)malloc(size);
if (ln == NULL)
{
perror("malloc");
goto done;
}
if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_LISTEN, NULL, 0,
ln, size, &size, NULL))
{
winerr("DeviceIoControl");
goto done;
}
n = size / sizeof(*ln);
// sort this list!
qsort(ln, n, sizeof(*ln), compare_ln);
printf("IPProto\tAddress:Port\tProcess (pid)\n");
printf("-------\t------------\t---------------------------------------------\n");
for (i = 0; i < n ; i++)
{
char *proto, pname[MAX_PATH];
if (ln[i].ipproto == IPPROTO_TCP)
proto = "TCP";
else if (ln[i].ipproto == IPPROTO_UDP)
proto = "UDP";
else if (ln[i].ipproto == IPPROTO_IP)
proto = "RawIP";
else
proto = "?";
// resolve pid!
if (!get_pname_by_pid(ln[i].pid, pname, sizeof(pname)))
pname[0] = '\0';
printf("%s\t%d.%d.%d.%d:%d\t%s (%d)\n",
proto, PRINT_IP_ADDR(ln[i].addr), ntohs(ln[i].port), pname, ln[i].pid);
}
done:
free(ln);
if (g_device != INVALID_HANDLE_VALUE)
CloseHandle(g_device);
}
int compare_ln(const void *arg1, const void *arg2)
{
const struct listen_nfo *l1 = (const struct listen_nfo *)arg1;
const struct listen_nfo *l2 = (const struct listen_nfo *)arg2;
int result;
result = l1->ipproto - l2->ipproto;
if (result == 0)
{
result = ntohl(l2->addr) - ntohl(l1->addr);
if (result == 0)
result = ntohs(l1->port) - ntohs(l2->port);
}
return result;
}
// enum connections
void enum_connect(void)
{
ULONG size;
struct tcp_conn_nfo *tn = NULL;
int i, n;
unsigned __int64 traffic[TRAFFIC_MAX];
// try to dynamically link psapi.dll
link_psapi();
/* connect with driver */
g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (g_device == INVALID_HANDLE_VALUE)
{
winerr(g_nfo_device_name);
goto done;
}
/* get list of listening objects */
size = sizeof(*tn) * 0x10000 * 3; // this size is good enough :-)
tn = (struct tcp_conn_nfo *)malloc(size);
if (tn == NULL)
{
perror("malloc");
goto done;
}
if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_TCP_CONN, NULL, 0,
tn, size, &size, NULL))
{
winerr("DeviceIoControl");
goto done;
}
n = size / sizeof(*tn);
// sort this list!
qsort(tn, n, sizeof(*tn), compare_tn);
for (i = 0; i < n ; i++)
{
char pname[MAX_PATH];
if (tn[i].state >= TCP_STATE_MAX)
tn[i].state = 0;
// resolve pid!
if (!get_pname_by_pid(tn[i].pid, pname, sizeof(pname)))
pname[0] = '\0';
printf("%s\t%d.%d.%d.%d:%d\t%d.%d.%d.%d:%d\t%s (%d)\t%u/%u\n",
g_tcp_states[tn[i].state],
PRINT_IP_ADDR(tn[i].laddr), ntohs(tn[i].lport),
PRINT_IP_ADDR(tn[i].raddr), ntohs(tn[i].rport),
pname, tn[i].pid,
tn[i].bytes_out, tn[i].bytes_in);
}
// output traffic counters
get_traffic_stats(traffic);
printf(
"\n"
"Traffic counters (out/in):\n"
" Total: %I64u/%I64u\n"
" Counted: %I64u/%I64u\n",
traffic[TRAFFIC_TOTAL_OUT], traffic[TRAFFIC_TOTAL_IN],
traffic[TRAFFIC_COUNTED_OUT], traffic[TRAFFIC_COUNTED_IN]);
done:
free(tn);
if (g_device != INVALID_HANDLE_VALUE)
CloseHandle(g_device);
}
int compare_tn(const void *arg1, const void *arg2)
{
const struct tcp_conn_nfo *t1 = (const struct tcp_conn_nfo *)arg1;
const struct tcp_conn_nfo *t2 = (const struct tcp_conn_nfo *)arg2;
int result;
result = t1->state - t2->state;
if (result == 0)
{
result = ntohl(t1->laddr) - ntohl(t2->laddr);
if (result == 0)
{
result = ntohs(t1->lport) - ntohs(t2->lport);
if (result == 0)
{
result = ntohl(t1->raddr) - ntohl(t2->raddr);
if (result == 0)
result = ntohs(t1->rport) - ntohs(t2->rport);
}
}
}
return result;
}
/*
* Routing functions help us to get local IP address of outgoing datagrams or connections
* Warning! This functions are slow!
* TODO: make it faster!
*/
ULONG get_if_ip(ULONG remote_ip)
{
ULONG if_index;
// get interface index by routing table
if_index = route_ip(remote_ip);
if (if_index == (ULONG)-1)
return 0;
return get_if_index_ip(if_index);
}
ULONG route_ip(ULONG remote_ip)
{
ULONG size, i, bestmetric, result;
MIB_IPFORWARDTABLE *buf;
// get route table
size = 0;
if (GetIpForwardTable(NULL, &size, FALSE) != ERROR_INSUFFICIENT_BUFFER)
return (ULONG)-1;
buf = (MIB_IPFORWARDTABLE *)malloc(size);
if (buf == NULL)
return (ULONG)-1;
if (GetIpForwardTable(buf, &size, FALSE) != NO_ERROR)
{
free(buf);
return (ULONG)-1;
}
// find optimal route
bestmetric = (ULONG)-1;
result = (ULONG)-1;
for (i = 0; i < buf->dwNumEntries; i++)
{
if ((remote_ip & buf->table[i].dwForwardMask) ==
(buf->table[i].dwForwardDest & buf->table[i].dwForwardMask))
{
if (bestmetric == (ULONG)-1 || buf->table[i].dwForwardMetric1 > bestmetric)
{
bestmetric = buf->table[i].dwForwardMetric1;
result = buf->table[i].dwForwardIfIndex;
}
}
}
free(buf);
return result;
}
ULONG get_if_index_ip(ULONG if_index)
{
ULONG size, i;
MIB_IPADDRTABLE *buf;
ULONG result;
size = 0;
if (GetIpAddrTable(NULL, &size, FALSE) != ERROR_INSUFFICIENT_BUFFER)
return (ULONG)-1;
buf = (MIB_IPADDRTABLE *)malloc(size);
if (buf == NULL)
return (ULONG)-1;
if (GetIpAddrTable(buf, &size, FALSE) != NO_ERROR)
{
free(buf);
return (ULONG)-1;
}
result = 0;
for (i = 0; i < buf->dwNumEntries; i++)
if (buf->table[i].dwIndex == if_index)
{
result = buf->table[i].dwAddr;
break;
}
free(buf);
return result;
}
BOOL load_users(const char *config)
{
BOOL result = FALSE;
char *section, *p, *all_sids = NULL;
int line, sid_id;
ULONG all_sids_len = 0, all_sids_size = 0, n;
section = (char *)malloc(MAX_SECTION_SIZE);
if (section == NULL)
{
liberr("malloc");
return FALSE;
}
GetPrivateProfileSection("_users_", section, MAX_SECTION_SIZE, config);
// get lines
sid_id = 0;
for (p = section, line = 1; *p != '\0'; p += strlen(p) + 1, line++)
{
char *p2, *p3, *authority, *principal, domain[100];
char *sid_buf;
DWORD sid_size, domain_size;
SID_NAME_USE use;
if (*p == ';')
continue; // comment
p2 = strchr(p, '=');
if (p2 == NULL)
{
error("%s:[_users_]:%d: invalid line format (no '=' character)", config, line);
continue;
}
*p2 = '\0'; // temporary kill '='
if (sid_id != 0)
{
// not _default_
p3 = strchr(p, '\\');
if (p3 != NULL)
{
*p3 = '\0';
authority = p;
if (strcmp(authority, "NT AUTHORITY") == 0)
authority = NULL;
principal = p3 + 1;
}
else {
authority = NULL;
principal = p;
}
// try to get SID size
sid_size = 0;
domain_size = 0;
LookupAccountName(authority, principal, NULL, &sid_size, NULL, &domain_size, &use);
}
else
sid_size = 0; // empty SID for default
if (all_sids_len + sid_size + sizeof(ULONG) >= all_sids_size)
{
all_sids_size += sid_size + sizeof(ULONG) + 4096;
all_sids = (char *)realloc(all_sids, all_sids_size);
if (all_sids == NULL)
{
liberr("malloc");
goto done;
}
}
sid_buf = all_sids + all_sids_len;
all_sids_len += sid_size + sizeof(ULONG);
*(ULONG *)sid_buf = sid_size;
if (sid_id != 0)
{
domain_size = sizeof(domain);
if (!LookupAccountName(authority, principal,
(PSID)(sid_buf + sizeof(ULONG)), &sid_size, domain, &domain_size, &use))
{
winerr("LookupAccountName");
error("%s:[_users_]:%d: Error getting SID for %s\\%s", config, line,
(authority != NULL ? authority : "."), principal);
goto done;
}
if (use != SidTypeUser && use != SidTypeWellKnownGroup)
{
error("%s:[_users_]:%d: Invalid SID type (%d) for %s\\%s", config, line, use,
(authority != NULL ? authority : "."), principal);
goto done;
}
if (p3 != NULL)
*p3 = '\\';
}
*p2 = '='; // recover '=' to make strlen(p) works right
sid_id++;
}
// send all_sids buffer to filter driver!
result = DeviceIoControl(g_device, IOCTL_CMD_SET_SIDS, all_sids, all_sids_len,
NULL, 0, &n, NULL);
if (!result)
winerr("DeviceIoControl");
done:
free(all_sids);
free(section);
return result;
}
void get_sid_mask(const char *config, const char *name, UCHAR *sid_mask)
{
BOOL result = FALSE;
char *section, *p;
int line, sid_id;
memset(sid_mask, 0, MAX_SIDS_COUNT / 8);
section = (char *)malloc(MAX_SECTION_SIZE);
if (section == NULL)
{
liberr("malloc");
return;
}
GetPrivateProfileSection("_users_", section, MAX_SECTION_SIZE, config);
// get lines
sid_id = 0;
for (p = section, line = 1; *p != '\0'; p += strlen(p) + 1, line++)
{
char *p2;
if (*p == ';')
continue; // comment
p2 = strchr(p, '=');
if (p2 == NULL)
{
error("%s:[_users_]:%d: invalid line format (no '=' character)", config, line);
continue;
}
*p2 = '\0'; // temporary kill '='
if (check_for_name(config, "_users_", p, name))
sid_mask[sid_id / 8] |= 1 << (sid_id % 8); // set bit in mask
*p2 = '='; // recover '=' to make strlen(p) works right
sid_id++;
}
free(section);
}
BOOL check_for_name(const char *config, const char *section, const char *value, const char *name)
{
char buf[1024], *p, *p2;
GetPrivateProfileString(section, value, "", buf, sizeof(buf), config);
p = buf;
if (strcmp(p, "*") == 0)
return TRUE; // *
while (p != NULL)
{
p2 = strchr(p, ' ');
if (p2 != NULL)
{
while (*p2 == ' ')
*(p2++) = '\0';
}
if (*p != '\0' && strcmp(p, name) == 0)
return TRUE;
p = p2;
}
return FALSE;
}
void get_traffic_stats(unsigned __int64 *stats)
{
DWORD n;
memset(stats, 0, sizeof(unsigned __int64) * TRAFFIC_MAX);
DeviceIoControl(g_device, IOCTL_CMD_GET_COUNTERS, NULL, 0, stats, sizeof(unsigned __int64) * TRAFFIC_MAX, &n, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -