📄 tdi_fw_svc.c
字号:
if (tm == NULL) {
#ifdef _DEBUG
MessageBeep(0);
OutputDebugString("log_msg: localtime\n");
#endif
return;
}
if (g_logfile == NULL || tm->tm_mday != file_day) {
char fname[MAX_PATH];
if (g_logfile != NULL) {
// wow! we're working at midnight! change log file!
fprintf(g_logfile, "--- midnight ---\n");
fclose(g_logfile);
g_logfile = NULL;
}
file_day = tm->tm_mday;
// open logfile
if (_snprintf(fname, sizeof(fname),
"%s\\system32\\LogFiles\\tdi_fw\\%04d%02d%02d.log",
getenv("SystemRoot"),
tm->tm_year + 1900,
tm->tm_mon + 1,
tm->tm_mday) == -1) {
#ifdef _DEBUG
MessageBeep(0);
OutputDebugString("log_msg: _snprintf overflow!\n");
#endif
return;
}
g_logfile = fopen(fname, "a");
if (g_logfile == NULL) {
#ifdef _DEBUG
MessageBeep(0);
OutputDebugString("log_msg: fopen error!\n");
#endif
return;
}
fprintf(g_logfile, "--- begin ---\n");
}
if (_snprintf(tm_msg, sizeof(tm_msg),
"%010u %02d:%02d:%02d\t%s",
event_num++, tm->tm_hour, tm->tm_min, tm->tm_sec, msg) == -1)
tm_msg[sizeof(tm_msg) - 1] = '\0';
// write it to log file
fprintf(g_logfile, "%s\n", tm_msg);
fflush(g_logfile);
}
}
#define MAX_SECTION_SIZE (16 * 1024)
BOOL
load_config(const char *config)
{
char *section, *p;
DWORD n, pids[100];
BOOL result = FALSE;
int line, chain;
if (!read_config(config))
return FALSE;
// parse & add rules default and process-related
section = (char *)malloc(MAX_SECTION_SIZE);
if (section == NULL) {
liberr("malloc");
goto done;
}
GetPrivateProfileSection("_main_", section, MAX_SECTION_SIZE, config);
// get lines
chain = 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:[_main_]:%d: invalid line format (no '=' character)");
continue;
}
if (chain >= MAX_CHAINS_COUNT) {
error("%s:[_main_]:%d: too many rules lines!");
break;
}
*p2 = '\0'; // temporary kill '='
add_rules_name(p, config, chain);
*p2 = '='; // recover '=' to make strlen(p) works right
chain++;
}
// try to get names for existing processes
if (EnumProcesses(pids, sizeof(pids), &n)) {
DWORD i;
n /= sizeof(DWORD);
for (i = 0; i < n; i++) {
char pname[MAX_PATH];
if (get_pname_by_pid(pids[i], pname + sizeof(DWORD), sizeof(pname) - sizeof(DWORD))) {
// send information to driver about pid and pname
DWORD nn;
*(DWORD *)pname = pids[i];
if (!DeviceIoControl(g_device, IOCTL_CMD_SETPNAME, pname,
sizeof(DWORD) + strlen(pname + sizeof(DWORD)) + 1,
NULL, 0, &nn, NULL))
winerr("DeviceIoControl");
}
}
}
result = TRUE;
done:
free(section);
return result;
}
BOOL
read_config(const char *config)
{
static char config_name[] = "_config_";
static char signature_name[] = "_signature_";
static char signature_value[] = "$tdi_fw$";
char buf[100];
// first, check config file signature
GetPrivateProfileString(signature_name, signature_name, "", buf, sizeof(buf), config);
if (strcmp(buf, signature_value) != 0) {
error("\"%s\": invalid configuration file", config);
return FALSE;
}
// get g_eventlog_xxx values
g_eventlog_allow = GetPrivateProfileInt(config_name, "eventlog_allow", FALSE, config);
g_eventlog_deny = GetPrivateProfileInt(config_name, "eventlog_deny", FALSE, config);
g_eventlog_error = GetPrivateProfileInt(config_name, "eventlog_error", FALSE, config);
// get other values
g_rules_resolve_addr = GetPrivateProfileInt(config_name, "rules_resolve_addr", FALSE, config);
g_logs_resolve_addr = GetPrivateProfileInt(config_name, "logs_resolve_addr", FALSE, config);
return TRUE;
}
BOOL
add_rules_name(const char *main_name, const char *config, int chain)
{
char buf[1024], *p, *p2, *section = NULL;
BOOL result = FALSE;
DWORD n;
section = (char *)malloc(MAX_SECTION_SIZE);
if (section == NULL) {
liberr("malloc");
goto done;
}
/* 1. get ruleset string */
GetPrivateProfileString("_main_", main_name, "", buf, sizeof(buf), config);
if (*buf == '\0')
goto done; // no rules
// reset all rules for chain
if (!DeviceIoControl(g_device, IOCTL_CMD_CLEARCHAIN, &chain, sizeof(chain),
NULL, 0, &n, NULL)) {
winerr("DeviceIoControl");
goto done;
}
if (chain != 0) {
// set chain name
int len = sizeof(int) + strlen(main_name) + 1;
char *data = (char *)malloc(len);
if (data == NULL) {
liberr("malloc");
goto done;
}
*(int *)data = chain;
strcpy(data + sizeof(int), main_name);
if (!DeviceIoControl(g_device, IOCTL_CMD_SETCHAINPNAME, data, len,
NULL, 0, &n, NULL)) {
winerr("DeviceIoControl");
free(data);
goto done;
}
free(data);
}
/* 2. for each word in main_name string */
p = buf;
while (p != NULL) {
p2 = strchr(p, ' ');
if (p2 != NULL) {
while (*p2 == ' ')
*(p2++) = '\0';
}
if (*p != '\0') {
// get section by name in p
GetPrivateProfileSection(p, section, MAX_SECTION_SIZE, config);
if (*section == '\0')
error("\"%s\": unexistant or empty section %s", config, p);
else
add_rules(section, p, chain);
}
p = p2;
}
result = TRUE;
done:
free(section);
return result;
}
void
add_rules(char *buf, const char *name, int chain)
{
char *p, *p2;
int n_str;
for (p = buf, n_str = 1; *p != '\0'; p = p2, n_str++) {
struct flt_rule rule;
DWORD n;
p2 = p + strlen(p) + 1;
if (*buf == ';' || *buf == '\0')
continue; // empty line or comment
memset(&rule, 0, sizeof(rule));
if (!parse_rule(p, &rule)) {
error("Error in line #%d of section [%s]", n_str, name);
continue;
}
// set chain
rule.chain = chain;
// append rule
if (!DeviceIoControl(g_device, IOCTL_CMD_APPENDRULE, &rule, sizeof(rule),
NULL, 0, &n, NULL)) {
winerr("start: DeviceIoControl");
return;
}
}
}
BOOL
get_pname_by_pid(u_long pid, char *buf, int buf_size)
{
BOOL result;
HANDLE h_process;
HMODULE h_module;
DWORD n;
// try to resolve pid to pname
h_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (h_process != NULL)
EnumProcessModules(h_process, &h_module, sizeof(h_module), &n);
// on error write pid
if (h_module == NULL ||
GetModuleFileNameEx(h_process, h_module, buf, buf_size) == 0) {
// for "System" process last error value is:
// * ERROR_PARTIAL_COPY (on 2k)
// * ERROR_NOACCESS (on NT4)
// ??? on other (TODO: think about another way)
if (GetLastError() == ERROR_PARTIAL_COPY ||
GetLastError() == ERROR_NOACCESS) {
strncpy(buf, "System", buf_size);
buf[buf_size - 1] = '\0';
result = TRUE;
} else {
*buf = '\0';
result = FALSE;
}
} else {
if (strchr(buf, '~') != NULL) { // XXX is it a right way?
// try to convert long name to short name
char long_name[MAX_PATH];
my_GetLongPathName(buf, long_name, sizeof(long_name));
strncpy(buf, long_name, buf_size - 1);
buf[buf_size - 1] = '\0';
}
result = TRUE;
}
return result;
}
void
prepare_addr(char *buf, int size, u_long addr)
{
if (g_logs_resolve_addr) {
// TODO: doesn't work correctly (maybe remove it?)
struct hostent *he;
if (addr == INADDR_ANY) {
strcpy(buf, "ANY");
return;
}
// try to resolve addr
he = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
if (he != NULL) {
// set name in buffer (and reserve space for <ip>)
size_t len = size - sizeof("<XXX.XXX.XXX.XXX>");
strncpy(buf, he->h_name, len);
buf[len - 1] = '\0';
} else
buf[0] = '\0';
// add <ip>
strcat(buf, "[");
strcat(buf, inet_ntoa(*(struct in_addr *)&addr));
strcat(buf, "]");
} else
strcpy(buf, inet_ntoa(*(struct in_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
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -