本人有一个利用sys驱动Hook进程、注册表和内核的VC源码,运行后可以通过exe程序和sys之间通信来决定是否Hook。
现在本人把整个exe的VC源码全部改写为Delphi源码,完成后可以实现服务安装、启动和停止等,也可以实现拦截,但是最大的问题是无法实现sys向exe的信息输出,现在把代码如数列出,完整代码可点击这里下载。
目前的问题如下:
第一个问题:接收不到驱动程序返回的文件字符串信息 ;
第二个问题:进程监控开启关闭一次后,再开启不出现提示对话框,强行关闭后造成蓝屏死机。exe的VC代码如下:#include <windows.h>
#include <stdio.h>#include "resource.h"
HWND hDialog;
HANDLE device;
char outputbuff[256];
char * strings[256];
DWORD stringcount;
DWORD controlbuff[64];DWORD dw;
NOTIFYICONDATA nid;
HWND hwnd;
BOOL bdrv;
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
void steup();
void CloseSrv();
void Begin();
void thread();
#define WM_PRM_NOTIFY WM_USER+1int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HACCEL hAccel; hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); //调入指定的加速键表
hDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);
hwnd = hDialog;
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hDialog;
nid.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
nid.uCallbackMessage = WM_PRM_NOTIFY;
nid.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
nid.uID = 100001; Shell_NotifyIcon(NIM_ADD, &nid ); //用于托盘的Shell API RECT rect;
int ScreenWidth= GetSystemMetrics(SM_CXSCREEN);
int ScreenHeight= GetSystemMetrics(SM_CYSCREEN);
GetWindowRect(hDialog,&rect);
int width = rect.right-rect.left;
int height = rect.bottom-rect.top;
MoveWindow(hDialog,ScreenWidth/2-width/2,ScreenHeight/2-height/2,width,height,TRUE);
ShowWindow(hDialog, nCmdShow);
UpdateWindow(hDialog);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(hDialog, hAccel, &msg)) //设置加速键表
{
if(!IsDialogMessage(hDialog, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return msg.wParam;
}
//该函数为一个应用程序定义可与DialogBOX函数一起使用的回调函数。
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) //回调函数
{
switch (message) //判断获得的消息,由此做出响应
{
case WM_SHOWWINDOW: //显示窗口?
if (bdrv)
{
SetWindowText(GetDlgItem(hwnd,IDC_SA),"内核模块加载成功!"); //强迫一开始就打开进程监控(相当于按下“开启”按钮)
DeviceIoControl(device,1000,controlbuff,256,controlbuff,256,&dw,0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMON),FALSE); //禁用“开启”按钮
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMOFF),TRUE); //启用“关闭”按钮
}
else
{
//SetWindowText(GetDlgItem(hwnd,IDC_SA),"内核模块加载失败!");
CloseSrv(); //内核模块加载失败就自杀(活着也没什么意思)
DestroyWindow(hwndDlg);
PostQuitMessage(0); }
return TRUE;
case WM_INITDIALOG: //收到窗口初始化消息
Begin(); //安装监控服务,打开虚拟设备
return (TRUE);
case WM_PRM_NOTIFY:
if (lParam == WM_LBUTTONDOWN )
{
ShowWindow(hwndDlg,SW_RESTORE);
SetForegroundWindow(hwndDlg);
}
else if (lParam == WM_RBUTTONDOWN)
{ }
return TRUE ;
case WM_SIZE :
if (wParam == SIZE_MINIMIZED)
{
ShowWindow(hwndDlg,SW_HIDE);
}
else
{
return TRUE;
}
return TRUE;
case WM_COMMAND: //收到命令消息 switch (LOWORD(wParam)) //接收按钮消息
{
case IDC_BTN_PMON: //当进程监控按钮“开启”按下时
DeviceIoControl(device,
1000,
controlbuff,
256,
controlbuff,
256,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMON),FALSE); //禁用“开启”按钮
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMOFF),TRUE); //启用“关闭”按钮
return TRUE;
case IDC_BTN_PMOFF: //当进程监控按钮“关闭”按下时
DeviceIoControl(device,
1001,
NULL,
NULL,
NULL,
NULL,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMON),TRUE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMOFF),FALSE);
return TRUE;
case IDC_BTN_RMON: //注册表监控开启
DeviceIoControl(device,
1002,
controlbuff,
256,
controlbuff,
256,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_RMON),FALSE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_RMOFF),TRUE);
return TRUE;
case IDC_BTN_RMOFF: //注册表监控关闭
DeviceIoControl(device,
1003,
NULL,
NULL,
NULL,
NULL,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_RMON),TRUE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_RMOFF),FALSE);
return TRUE;
case IDC_BTN_MMON: //内核监控开启
DeviceIoControl(device,
1004,
controlbuff,
256,
controlbuff,
256,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_MMON),FALSE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_MMOFF),TRUE);
return TRUE;
case IDC_BTN_MMOFF: //内核监控关闭
DeviceIoControl(device,
1005,
NULL,
NULL,
NULL,
NULL,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_MMON),TRUE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_MMOFF),FALSE);
return TRUE;
default:
break;
}
return (FALSE);
case WM_CLOSE:
CloseSrv();
DestroyWindow(hwndDlg);
PostQuitMessage(0);
break;
case WM_DESTROY:
Shell_NotifyIcon(NIM_DELETE,&nid);
EndDialog (hwndDlg, 0);
return (TRUE);
}
return (FALSE);
}void steup() //安装监控服务
{
int i;
char namebuff[256];
SC_HANDLE sch,scm; GetModuleFileName(NULL,namebuff,256); //该函数返回该应用程序全路径
i = strlen(namebuff);
while (namebuff[i] != '\\')
{
i--;
}
i++; strcpy(&namebuff[i],"PRMonitor.sys"); sch = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); //打开服务管理器
scm = CreateService(sch,
"PRMonitor",
"PRMonitor",
SERVICE_START|SERVICE_STOP,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
namebuff,
0,
0,
0,
0,
0); StartService(scm,NULL,NULL); //启动服务 CloseServiceHandle(scm);
}void CloseSrv() //关闭服务
{
CloseHandle(device); SC_HANDLE sch ;
SERVICE_STATUS ss;
sch = OpenSCManager(NULL,0,0);
SC_HANDLE scm ;
scm = OpenService(sch,"PRMonitor",SERVICE_ALL_ACCESS);
ControlService(scm,SERVICE_CONTROL_STOP,&ss);
DeleteService(scm);
}void Begin() //安装虚拟设备
{
steup(); //安装监控服务
Sleep(100); //以毫秒为单位,让函数滞留
//create processing thread
CreateThread(0,0,(LPTHREAD_START_ROUTINE)thread,0,0,&dw); //在主线程的基础上创建一个新线程
//open device
device=CreateFile("\\\\.\\PRMONITOR", //创建File这个内核对象
GENERIC_READ|GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM,
0); if (device == INVALID_HANDLE_VALUE)
{
bdrv = FALSE; //device打开失败
}
else
{
bdrv = TRUE; //device打开成功
} DWORD * addr=(DWORD *)(1+(DWORD)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtCreateProcess"));
ZeroMemory(outputbuff,256); //用0来填充一块内存区域
controlbuff[0]=addr[0];
controlbuff[1]=(DWORD)&outputbuff[0];
MessageBox(0, (LPCTSTR)controlbuff[1],"WARNING",MB_YESNO|MB_ICONQUESTION|0x00200000L);
//CloseHandle(device);}void thread()
{
DWORD a,x; char msgbuff[512];
char *pdest;
int result;
while(1) //反复循环以下代码
{
//由src所指内存区域复制count个字节到dest所指内存区域。
memmove(&a,&outputbuff[0],4);
if(!a){Sleep(10);continue;} //如果a为0,暂停10ms,返回进行下一轮循环
char*name=(char*)&outputbuff[8]; for(x=0;x<stringcount;x++)
{ //好像是:如果发现有以前已经同意执行的进程,则不询问直接执行
if(!stricmp(name,strings[x])){a=1;goto skip;} //stricmp比较字符串s1和s2
}
pdest = strstr(name,"##"); //返回"##"第一次在name中出现的位置
if (pdest != NULL)
{
result = pdest-name; //outputbuff[8]中:(准备创建进程的程序名)##(将被创建进程的完整路径)
strcpy(msgbuff, "是否允许“");
strncat(msgbuff,&outputbuff[8],result); //准备创建进程的程序名
strcat(msgbuff,"”运行:");
strcat(msgbuff,&outputbuff[result+10]); //将被创建进程的完整路径
strcat(msgbuff," ?");
}
else if((pdest=strstr(name,"$$")) != NULL)
{
result = pdest-name;
strcpy(msgbuff, "是否允许");
strncat(msgbuff,&outputbuff[8],result);
strcat(msgbuff,"设置注册表");
strcat(msgbuff,&outputbuff[result+10]);
}
else
{
pdest = strstr(name,"&&");
result = pdest-name;
strcpy(msgbuff,"是否允许");
strncat(msgbuff,&outputbuff[8],result);
strcat(msgbuff,"加载驱动");
strcat(msgbuff,&outputbuff[result]+10);
}
if(IDYES==MessageBox(0, msgbuff,"WARNING",MB_YESNO|MB_ICONQUESTION|0x00200000L))
{
a=1; //如果回答“是”
strings[stringcount]=_strdup(name);
stringcount++;
}
else a=0;
skip:memmove(&outputbuff[4],&a,4);
a=0;
memmove(&outputbuff[0],&a,4);
}
}
现在本人把整个exe的VC源码全部改写为Delphi源码,完成后可以实现服务安装、启动和停止等,也可以实现拦截,但是最大的问题是无法实现sys向exe的信息输出,现在把代码如数列出,完整代码可点击这里下载。
目前的问题如下:
第一个问题:接收不到驱动程序返回的文件字符串信息 ;
第二个问题:进程监控开启关闭一次后,再开启不出现提示对话框,强行关闭后造成蓝屏死机。exe的VC代码如下:#include <windows.h>
#include <stdio.h>#include "resource.h"
HWND hDialog;
HANDLE device;
char outputbuff[256];
char * strings[256];
DWORD stringcount;
DWORD controlbuff[64];DWORD dw;
NOTIFYICONDATA nid;
HWND hwnd;
BOOL bdrv;
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
void steup();
void CloseSrv();
void Begin();
void thread();
#define WM_PRM_NOTIFY WM_USER+1int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HACCEL hAccel; hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); //调入指定的加速键表
hDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);
hwnd = hDialog;
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hDialog;
nid.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
nid.uCallbackMessage = WM_PRM_NOTIFY;
nid.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
nid.uID = 100001; Shell_NotifyIcon(NIM_ADD, &nid ); //用于托盘的Shell API RECT rect;
int ScreenWidth= GetSystemMetrics(SM_CXSCREEN);
int ScreenHeight= GetSystemMetrics(SM_CYSCREEN);
GetWindowRect(hDialog,&rect);
int width = rect.right-rect.left;
int height = rect.bottom-rect.top;
MoveWindow(hDialog,ScreenWidth/2-width/2,ScreenHeight/2-height/2,width,height,TRUE);
ShowWindow(hDialog, nCmdShow);
UpdateWindow(hDialog);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(hDialog, hAccel, &msg)) //设置加速键表
{
if(!IsDialogMessage(hDialog, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return msg.wParam;
}
//该函数为一个应用程序定义可与DialogBOX函数一起使用的回调函数。
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) //回调函数
{
switch (message) //判断获得的消息,由此做出响应
{
case WM_SHOWWINDOW: //显示窗口?
if (bdrv)
{
SetWindowText(GetDlgItem(hwnd,IDC_SA),"内核模块加载成功!"); //强迫一开始就打开进程监控(相当于按下“开启”按钮)
DeviceIoControl(device,1000,controlbuff,256,controlbuff,256,&dw,0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMON),FALSE); //禁用“开启”按钮
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMOFF),TRUE); //启用“关闭”按钮
}
else
{
//SetWindowText(GetDlgItem(hwnd,IDC_SA),"内核模块加载失败!");
CloseSrv(); //内核模块加载失败就自杀(活着也没什么意思)
DestroyWindow(hwndDlg);
PostQuitMessage(0); }
return TRUE;
case WM_INITDIALOG: //收到窗口初始化消息
Begin(); //安装监控服务,打开虚拟设备
return (TRUE);
case WM_PRM_NOTIFY:
if (lParam == WM_LBUTTONDOWN )
{
ShowWindow(hwndDlg,SW_RESTORE);
SetForegroundWindow(hwndDlg);
}
else if (lParam == WM_RBUTTONDOWN)
{ }
return TRUE ;
case WM_SIZE :
if (wParam == SIZE_MINIMIZED)
{
ShowWindow(hwndDlg,SW_HIDE);
}
else
{
return TRUE;
}
return TRUE;
case WM_COMMAND: //收到命令消息 switch (LOWORD(wParam)) //接收按钮消息
{
case IDC_BTN_PMON: //当进程监控按钮“开启”按下时
DeviceIoControl(device,
1000,
controlbuff,
256,
controlbuff,
256,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMON),FALSE); //禁用“开启”按钮
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMOFF),TRUE); //启用“关闭”按钮
return TRUE;
case IDC_BTN_PMOFF: //当进程监控按钮“关闭”按下时
DeviceIoControl(device,
1001,
NULL,
NULL,
NULL,
NULL,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMON),TRUE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_PMOFF),FALSE);
return TRUE;
case IDC_BTN_RMON: //注册表监控开启
DeviceIoControl(device,
1002,
controlbuff,
256,
controlbuff,
256,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_RMON),FALSE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_RMOFF),TRUE);
return TRUE;
case IDC_BTN_RMOFF: //注册表监控关闭
DeviceIoControl(device,
1003,
NULL,
NULL,
NULL,
NULL,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_RMON),TRUE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_RMOFF),FALSE);
return TRUE;
case IDC_BTN_MMON: //内核监控开启
DeviceIoControl(device,
1004,
controlbuff,
256,
controlbuff,
256,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_MMON),FALSE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_MMOFF),TRUE);
return TRUE;
case IDC_BTN_MMOFF: //内核监控关闭
DeviceIoControl(device,
1005,
NULL,
NULL,
NULL,
NULL,
&dw,
0);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_MMON),TRUE);
EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_MMOFF),FALSE);
return TRUE;
default:
break;
}
return (FALSE);
case WM_CLOSE:
CloseSrv();
DestroyWindow(hwndDlg);
PostQuitMessage(0);
break;
case WM_DESTROY:
Shell_NotifyIcon(NIM_DELETE,&nid);
EndDialog (hwndDlg, 0);
return (TRUE);
}
return (FALSE);
}void steup() //安装监控服务
{
int i;
char namebuff[256];
SC_HANDLE sch,scm; GetModuleFileName(NULL,namebuff,256); //该函数返回该应用程序全路径
i = strlen(namebuff);
while (namebuff[i] != '\\')
{
i--;
}
i++; strcpy(&namebuff[i],"PRMonitor.sys"); sch = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); //打开服务管理器
scm = CreateService(sch,
"PRMonitor",
"PRMonitor",
SERVICE_START|SERVICE_STOP,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
namebuff,
0,
0,
0,
0,
0); StartService(scm,NULL,NULL); //启动服务 CloseServiceHandle(scm);
}void CloseSrv() //关闭服务
{
CloseHandle(device); SC_HANDLE sch ;
SERVICE_STATUS ss;
sch = OpenSCManager(NULL,0,0);
SC_HANDLE scm ;
scm = OpenService(sch,"PRMonitor",SERVICE_ALL_ACCESS);
ControlService(scm,SERVICE_CONTROL_STOP,&ss);
DeleteService(scm);
}void Begin() //安装虚拟设备
{
steup(); //安装监控服务
Sleep(100); //以毫秒为单位,让函数滞留
//create processing thread
CreateThread(0,0,(LPTHREAD_START_ROUTINE)thread,0,0,&dw); //在主线程的基础上创建一个新线程
//open device
device=CreateFile("\\\\.\\PRMONITOR", //创建File这个内核对象
GENERIC_READ|GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM,
0); if (device == INVALID_HANDLE_VALUE)
{
bdrv = FALSE; //device打开失败
}
else
{
bdrv = TRUE; //device打开成功
} DWORD * addr=(DWORD *)(1+(DWORD)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtCreateProcess"));
ZeroMemory(outputbuff,256); //用0来填充一块内存区域
controlbuff[0]=addr[0];
controlbuff[1]=(DWORD)&outputbuff[0];
MessageBox(0, (LPCTSTR)controlbuff[1],"WARNING",MB_YESNO|MB_ICONQUESTION|0x00200000L);
//CloseHandle(device);}void thread()
{
DWORD a,x; char msgbuff[512];
char *pdest;
int result;
while(1) //反复循环以下代码
{
//由src所指内存区域复制count个字节到dest所指内存区域。
memmove(&a,&outputbuff[0],4);
if(!a){Sleep(10);continue;} //如果a为0,暂停10ms,返回进行下一轮循环
char*name=(char*)&outputbuff[8]; for(x=0;x<stringcount;x++)
{ //好像是:如果发现有以前已经同意执行的进程,则不询问直接执行
if(!stricmp(name,strings[x])){a=1;goto skip;} //stricmp比较字符串s1和s2
}
pdest = strstr(name,"##"); //返回"##"第一次在name中出现的位置
if (pdest != NULL)
{
result = pdest-name; //outputbuff[8]中:(准备创建进程的程序名)##(将被创建进程的完整路径)
strcpy(msgbuff, "是否允许“");
strncat(msgbuff,&outputbuff[8],result); //准备创建进程的程序名
strcat(msgbuff,"”运行:");
strcat(msgbuff,&outputbuff[result+10]); //将被创建进程的完整路径
strcat(msgbuff," ?");
}
else if((pdest=strstr(name,"$$")) != NULL)
{
result = pdest-name;
strcpy(msgbuff, "是否允许");
strncat(msgbuff,&outputbuff[8],result);
strcat(msgbuff,"设置注册表");
strcat(msgbuff,&outputbuff[result+10]);
}
else
{
pdest = strstr(name,"&&");
result = pdest-name;
strcpy(msgbuff,"是否允许");
strncat(msgbuff,&outputbuff[8],result);
strcat(msgbuff,"加载驱动");
strcat(msgbuff,&outputbuff[result]+10);
}
if(IDYES==MessageBox(0, msgbuff,"WARNING",MB_YESNO|MB_ICONQUESTION|0x00200000L))
{
a=1; //如果回答“是”
strings[stringcount]=_strdup(name);
stringcount++;
}
else a=0;
skip:memmove(&outputbuff[4],&a,4);
a=0;
memmove(&outputbuff[0],&a,4);
}
}
本人改写的Delphi代码如下:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, WinSvc, StrUtils, ShellAPI;// SvcMgr;type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
Button1: TButton;
Button2: TButton;
GroupBox2: TGroupBox;
Button3: TButton;
Button4: TButton;
GroupBox3: TGroupBox;
Button5: TButton;
Button6: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
hDialog:HWND;
device:THandle; //HANDLE device;
outputbuff:array[0..255] of Char; //char outputbuff[256];
controlbuff:array[0..63] of DWORD; //DWORD controlbuff[64];
dw:DWORD; //DWORD dw;
hhwnd:HWND; //HWND hwnd;
bdrv:Boolean; //BOOL bdrv;implementation{$R *.dfm}
//-------------------------------------------------------
procedure steup;
var
//i:Integer;
namebuff: ShortString;
sch,scm:SC_HANDLE;
lpServiceArgVectors:PAnsiChar;
begin
//int i;
//char namebuff[256];
//SC_HANDLE sch,scm;
//GetModuleFileName(NIL,namebuff,255);
namebuff:=Application.ExeName;
namebuff:=AnsiReplaceText(namebuff,'.exe','.sys') ; //strcpy(&namebuff[i],"PRMonitor.sys");
sch:= OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); //连接服务数据库
scm:= CreateService(sch,
'PRMonitor',
'PRMonitor',
SERVICE_START or SERVICE_STOP,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
PAnsiChar(AnsiString(namebuff)),
nil,
nil,
nil,
nil,
nil);
lpServiceArgVectors := nil;
StartService(scm,0,lpServiceArgVectors); //启动服务 CloseServiceHandle(scm);
end;
//----------------------------------------------------
procedure thread;
var
a:DWORD; msgbuff:String;
pdest:Integer;
//result:Integer;
name:ShortString;
begin
//DWORD a,x; char msgbuff[512];
//char *pdest;
//int result; while 1=1 do //反复循环以下代码
begin
//由src所指内存区域复制count个字节到dest所指内存区域。
Move(outputbuff[0],a,4); //outputbuff[0]中值为1表示拦截到监控内容,为0表示已经询问完用户 if (a=0) then
begin
Sleep(10);
continue; //如果a为0,暂停10ms,返回进行下一轮循环
end;
name:=MidStr(outputbuff,9,SIZEOF(outputbuff)-8);
//问题主要就在这里:outputbuff中总是为空,得不到返回的字符串信息 pdest := AnsiPos('##',name); //该函数返回"##"第一次在name中出现的位置
if (pdest>0) then
begin
//outputbuff[8]中保存的是:(准备创建进程的程序名)##(将被创建进程的完整路径)
msgbuff:=msgbuff+'是否允许“';
msgbuff:=msgbuff+ MidStr(outputbuff,9,pdest-1); //准备创建进程的程序名
msgbuff:=msgbuff+'”运行:';
msgbuff:=msgbuff+ outputbuff[pdest+10]+'?'; //将被创建进程的完整路径
//strcat(msgbuff,@outputbuff[result+10]);
//strcat(msgbuff,' ?');
end
else if(AnsiPos('$$',name) >0) then
begin
pdest:=AnsiPos('$$',name);
//resultt := pdest-name;
//strcpy(msgbuff, '是否允许');
//strncat(msgbuff,&outputbuff[8],result);
msgbuff:='设置注册表';
//strcat(msgbuff,&outputbuff[result+10]);
end
else
begin
pdest := AnsiPos('&&',name);
//result := pdest-name;
//strcpy(msgbuff,'是否允许');
//strncat(msgbuff,&outputbuff[8],result);
msgbuff:='加载驱动';
//strcat(msgbuff,&outputbuff[result]+10);
end;
msgbuff:=msgbuff +'name='+ name+';pdest='+inttostr(pdest); // 询问用户是否允许执行
if MessageDlg(msgbuff, mtConfirmation, [mbYes, mbNo], 0) = mrYes then
a:=1 //如果回答“是”
else
a:=0; Move(a,outputbuff[4],4); //outputbuff[4]中值为1表示用户同意操作,为0表示不同意 a:=0;
Move(a,outputbuff[0],4); //outputbuff[0]中值为1表示拦截到监控内容,为0表示已经询问完用户
end;end;//----------------------------------------------------
procedure Beginn;
var
addr:PDWORD;
begin
steup(); //安装监控服务
Sleep(100); //以毫秒为单位,让函数滞留
//create processing thread
CreateThread(nil,0,@thread,nil,0,Dw); //在主线程的基础上创建一个新线程
//open device
device:=CreateFile('\\.\PRMONITOR', //创建File这个内核对象
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_SYSTEM,
0); if (device = INVALID_HANDLE_VALUE) then
bdrv := FALSE //device打开失败
else
bdrv := TRUE; //device打开成功
addr:= Pdword(1+DWORD(GetProcAddress(GetModuleHandle('ntdll.dll'),'NtCreateProcess')));
ZeroMemory(@outputbuff,256); //用0来填充一块内存区域,填充的内存区域的大小,按字节来计算。
controlbuff[0]:=addr^;//DWORD();
controlbuff[1]:=DWORD(@outputbuff);
end;//----------------------------------------------------------
procedure CloseSrv; //关闭服务
var
sch,scm:SC_HANDLE;
ss:_SERVICE_STATUS; // SERVICE_STATUS ss;
begin
CloseHandle(device); sch := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS); scm := OpenService(sch,'PRMonitor',SERVICE_ALL_ACCESS);
ControlService(scm,SERVICE_CONTROL_STOP,ss);
DeleteService(scm);
end;procedure TForm1.FormCreate(Sender: TObject);
begin
beginn();
end;procedure TForm1.FormShow(Sender: TObject);
begin
if (bdrv) Then
Label1.Caption:='内核模块加载成功!'
else
Label1.Caption:='内核模块加载失败!';
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSrv;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
DeviceIoControl(device,1000,@controlbuff,256,@controlbuff,256,dw,NIL);
Button1.Enabled:=False;
Button2.Enabled:=True;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
DeviceIoControl(device,1001,NIL,0,NIL,0,dw,NIL);
Button2.Enabled:=False;
Button1.Enabled:=True;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
DeviceIoControl(device,1002,@controlbuff,256,@controlbuff,256,dw,nil);
Button3.Enabled:=False;
Button4.Enabled:=True;
end;procedure TForm1.Button4Click(Sender: TObject);
begin
DeviceIoControl(device,1003,NIL,0,NIL,0,dw,NIL);
Button4.Enabled:=False;
Button3.Enabled:=True;
end;end.//第一个问题:接收不到驱动程序返回的文件字符串信息 ;
//第二个问题:进程监控开启关闭一次后,再开启不出现提示对话框,强行关闭后造成蓝屏死机。
敬请高手不吝赐教,万分感谢!!完整代码可点击这里下载。
此处不欢迎毫无意义的回复,此类人员请绕道。
的原因可能是outputbuff里面有 0 字符,所以,你要用其他函数来截取,至于第二个问题,你要自己调试了,光看,我还没有看出来.
第一个问题:
Move(a,outputbuff[4],4); outputbuff前8个字节中还要保存a的值,一开始a的值是可以带过来和传过去的,只是字符串过不来。
第二个问题可能还是因为后来的a值没带过来造成的,所以问题都还是出在outputbuff上。关键它是exe和驱动共享的内存区域,想换也不可能。