Detecting running applications, port activity

Is there a way in C++ to detect which exe files are running (like the task manager does) then to exit them out. I'm trying to figure out how to list all running exe files then only permitting trusted programs to even run. Its not an antivirus. I just realize how easy it is for people to install applications on someones computer then run them without the user knowing. I want to have my program running and to prompt me when any application tries to run that i have not specifically allowed to run.

So in the event that i do get some kind of unnoticed application i will be prompted by my own software when it begins running then i can determine myself its authenticy.

When it comes to monitoring ports i think this is more of an advanced topic that would be better left to an actual antivirus. But i'm also interested in how to monitor ports for traffic that way i can determine which applications are trying to access the web or when i am getting requests from outside IP's ect. And winsock doesn't really allow for any of these outside of the custom program that i know of.
Last edited on
Monitoring running processes and terminate them is very easy, using CreateToolhelp32Snapshot:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <tlhelp32.h>
PROCESSENTRY32 procEntry;

	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnap == INVALID_HANDLE_VALUE)
	{
		return 1 ;
	}

	procEntry.dwSize = sizeof(PROCESSENTRY32);

	if (!Process32First(hSnap, &procEntry))
	{
		CloseHandle(hSnap);
		return 1 ;
	}

	do
	{
		if (_tcsicmp(procEntry.szExeFile, TEXT("winlogon.exe")) == 0)
		{
			// We found a winlogon.exe process...make sure it's running in the console session
			DWORD winlogonSessId = 0;
			if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId)
			{
				winlogonPid = procEntry.th32ProcessID;
				break;
			}
		}

	} while (Process32Next(hSnap, &procEntry));
	
	CloseHandle(hSnap);




The code is from a working project, adapt it to suit your needs ...



As for intercepting new process creation, this requires a kernel-mode driver which patches the kernel. Only works in x86 windows versions. To compile you need Windows DDK installed:

SOURCES:

1
2
3
4
5
6
TARGETNAME=protector
TARGETPATH=obj
TARGETTYPE=DRIVER


SOURCES=protector.c


protector.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#include "ntddk.h"

struct SYS_SERVICE_TABLE { 
	void **ServiceTable; 
	unsigned long CounterTable; 
	unsigned long ServiceLimit; 
	void **ArgumentsTable; 
}; 



const WCHAR devicename[]=L"\\Device\\Protector";
const WCHAR devicelink[]=L"\\DosDevices\\PROTECTOR";


KEVENT event; 



ULONG Index,RealCallee;
char*output;
extern struct SYS_SERVICE_TABLE *KeServiceDescriptorTable; 


//this function decides whether we should allow NtCreateSection() call to be successfull
ULONG __stdcall check(PULONG arg)
{

	HANDLE hand=0;
	PFILE_OBJECT file=0;
	POBJECT_HANDLE_INFORMATION info = {0};
	ULONG a;char*buff;
	ANSI_STRING str;
	LARGE_INTEGER li;
	li.QuadPart=-10000;

//check the flags. If PAGE_EXECUTE access to the section is not requested,
//it does not make sense to be bothered about it	
if((arg[4]&0xf0)==0)return 1;
if((arg[5]&0x01000000)==0)return 1;


//get the file name via the file handle
hand=(HANDLE)arg[6];
ObReferenceObjectByHandle(hand,0,0,KernelMode,&file,/*&info*/NULL);
if(!file)return 1;
RtlUnicodeStringToAnsiString(&str,&file->FileName,1);

a=str.Length;buff=str.Buffer;
while(1)
{
	if(buff[a]=='.'){a++;break;}
	a--;
}
ObDereferenceObject(file);

//if it is not executable, it does not make sense to be bothered about it
//return 1
if(_stricmp(&buff[a],"exe")){RtlFreeAnsiString(&str);return 1;}

//now we are going to ask user's opinion. Write file name to the buffer, and wait until
//the user indicates the response (1 as a first DWORD means we can proceed)

//synchronize access to the buffer
KeWaitForSingleObject(&event,Executive,KernelMode,0,0);


// set first 2 DWORD of a buffer to zero, copy the string into the buffer, and loop
//until the user sets first DWORD to 1. The value of the second DWORD indicates user's 
//response
strcpy(&output[8],buff);
RtlFreeAnsiString(&str);



a=1;
memmove(&output[0],&a,4);
while(1)
{
KeDelayExecutionThread(KernelMode,0,&li);
memmove(&a,&output[0],4);
if(!a)break;
}
memmove(&a,&output[4],4);
KeSetEvent(&event,0,0);

return a;
}


//just saves execution contect and calls check() 
_declspec(naked) Proxy()
{

_asm{

//save execution contect and calls check() -the rest depends upon the value check() returns
// if it is 1, proceed to the actual callee. Otherwise,return STATUS_ACCESS_DENIED
pushfd
pushad
mov ebx,esp
add ebx,40
push ebx
call check
cmp eax,1
jne block

//proceed to the actual callee
popad
popfd
jmp RealCallee

//return STATUS_ACCESS_DENIED
block:popad
mov ebx, dword ptr[esp+8]
mov dword ptr[ebx],0
mov eax,0xC0000022L
popfd
ret 32

}
}


NTSTATUS DrvDispatch(IN PDEVICE_OBJECT device,IN PIRP Irp)

{
	UCHAR*buff=0; ULONG a,base;



PIO_STACK_LOCATION loc=IoGetCurrentIrpStackLocation(Irp);

if(loc->Parameters.DeviceIoControl.IoControlCode==1000)
{
buff=(UCHAR*)Irp->AssociatedIrp.SystemBuffer;


// hook service dispatch table
memmove(&Index,buff,4);
a=4*Index+(ULONG)KeServiceDescriptorTable->ServiceTable;
base=(ULONG)MmMapIoSpace(MmGetPhysicalAddress((void*)a),4,0);
a=(ULONG)&Proxy;

_asm
{
mov eax,base
mov ebx,dword ptr[eax]
mov RealCallee,ebx
mov ebx,a
mov dword ptr[eax],ebx
}

MmUnmapIoSpace((void*)base, (size_t)4);

memmove(&a,&buff[4],4);
output=(char*)MmMapIoSpace(MmGetPhysicalAddress((void*)a),256,0);
}



Irp->IoStatus.Status=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return 0;


}



// nothing special
NTSTATUS DrvCreateClose(IN PDEVICE_OBJECT device,IN PIRP Irp)

{
	
Irp->IoStatus.Information=0;
Irp->IoStatus.Status=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return 0;

}



// nothing special -just a cleanup
void DrvUnload(IN PDRIVER_OBJECT driver)
{
UNICODE_STRING devlink;
ULONG a,base;

//unhook dispatch table
a=4*Index+(ULONG)KeServiceDescriptorTable->ServiceTable;
base=(ULONG)MmMapIoSpace(MmGetPhysicalAddress((void*)a),4,0);

_asm
{
mov eax,base
mov ebx,RealCallee
mov dword ptr[eax],ebx
}

MmUnmapIoSpace((void*)base,4);
MmUnmapIoSpace(output,256);

RtlInitUnicodeString(&devlink,devicelink);
IoDeleteSymbolicLink(&devlink);
IoDeleteDevice(driver->DeviceObject);
}


//DriverEntry just creates our device - nothing special here
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver,IN PUNICODE_STRING path)
{

PDEVICE_OBJECT devobject=0;

UNICODE_STRING devlink,devname;

ULONG a,b;



RtlInitUnicodeString(&devname,devicename);
RtlInitUnicodeString(&devlink,devicelink);

IoCreateDevice(driver,256,&devname,FILE_DEVICE_UNKNOWN,0,TRUE,&devobject);
IoCreateSymbolicLink(&devlink,&devname);



driver->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DrvDispatch;
driver->MajorFunction[IRP_MJ_CREATE]=DrvCreateClose;
driver->MajorFunction[IRP_MJ_CLOSE]=DrvCreateClose;
driver->DriverUnload=DrvUnload;
KeInitializeEvent(&event,SynchronizationEvent,1);


return 0;
}


makefile:
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of Windows NT
#
!INCLUDE $(NTMAKEENV)\makefile.def


All 3 files must be in same directory. To build, use nmake from WinDDK command prompt.






And a GUI application to use the driver (must be run elevated in Vista/Windows 7:
http://wapftp.mobi/stuff/protector.zip
@ modoran: That's an interesting looking driver, it would almost be a good reference but I do have a problem I'd like to address if you wouldn't take offence to it. I'm refering to the assembly code. Why? What you have written here doesn't need to be micro managed byte by byte so why are you copping out? Is there some security layer that would prevent this from executing? Here are some things that I noticed:

Lines 92 - 122: The "check()" function can be modified to except a function pointer as an argument eliminating the need for this assembly crap. It could then either allow the "RealCallee" to execute or deny access based on the logic you already have written.

Line 139: Is the OP trying to hide this driver from himself? Why are we hooking the Service Dispatch Table at all?

Line 142: Second argument to "MmGetPhysicalAddress(...)" should be sizeof(ULONG*), not hard coded to 4 bytes. Also what's wrong with returning a reference to 'a' as the first argument to MmMapIoSpace(...)?

Line 145: More assembly code, why? You're better then this.


Topic archived. No new replies allowed.