Delphi下如何使用 Winsock SPI 函数拦截网络数据?(300分)

  • 主题发起人 主题发起人 x.45
  • 开始时间 开始时间
to duducat
你看过此书?哪里有售?
 
SPI方面VC的资料也不多
 
http://www.bookschina.com/book_find/default.asp?Str_Search=bookname&book=Delphi
 
注意:ISBN 为 7115069085 的书是《Delphi 5 API 函数开发实例》

书 名: Delphi 5 API 函数开发实例
出版社: 人民邮电出版社
出版日期:2001年1月1日
作 者: 同志工作室编著
ISBN号: 7115069085
开 本:26cm
定 价: 人民币:29.00
[内 容 摘 要]
本书从API 编程基础开始,以示例的形式全面介绍了Delphi 5 支持的API 函数以及API 函数的应用,涵
盖了文本、图形、高级绘图、图像处理、窗口、菜单、系统信息控制、消息控制等各个方同,揭去了API 函数
的神秘面纱,带领读者进入Windows 程序开发的内部。
 
注意:ISBN 为 7115069085 的书是《Delphi 5 API 函数开发实例》

书 名: Delphi 5 API 函数开发实例
出版社: 人民邮电出版社
出版日期:2001年1月1日
作 者: 同志工作室编著
ISBN号: 7115069085
开 本:26cm
定 价: 人民币:29.00
[内 容 摘 要]
本书从API 编程基础开始,以示例的形式全面介绍了Delphi 5 支持的API 函数以及API 函数的应用,涵
盖了文本、图形、高级绘图、图像处理、窗口、菜单、系统信息控制、消息控制等各个方同,揭去了API 函数
的神秘面纱,带领读者进入Windows 程序开发的内部。
 
我也是刚刚插足这个方面。洗耳恭听ing。。
 
sundayboys
你的东西我怎么复制不下来啊
 
哈哈,简单,贴个我改自费尔出的那本书的代码吧,本来想写文章的,没有时间,算了,
对了,要去JEDI那里下载那个WINAPI的文件。要安装的,安装程序可以用费尔那本书,
带的那个也可,我这个改的是用来截传奇的包并解码的,另外调用了一个DLL用来解码,
自己看看代码来改吧,直接编译肯定用不了。想很清楚,就买费尔出的那本书,挺简单的。

library spi;

uses
Windows,
Sysutils,
SyncObjs,
JwaWS2spi,
JwaWinType,
JwaWinSock2,
overlapped in 'overlapped.pas';

var
sprocessname:string;
NextProcTable:WSPPROC_TABLE;
glCS:TCriticalSection;
cOverlapped: TOverlapped;

procedure debug(msg:string;_type:byte{1:string,2:hex,3:decoder1,4:decoder2});
begin
OutputDebugString(pchar(msg));
end;

{function bytetohex(src: byte): string;
begin
result:=inttohex(src,2);
exit;
setlength(result, 2);
asm
mov edi, [result]
mov edi, [edi]
mov al, src
mov ah, al // save to ah
shr al, 4 // output high 4 bits
add al, '0'
cmp al, '9'
jbe @@outcharlo
add al, 'a'-'9'-1
@@outcharlo:
and ah, $f
add ah, '0'
cmp ah, '9'
jbe @@outchar
add ah, 'a'-'9'-1
@@outchar:
stosw
end;
end;

function DATA2HEX(lpBuffers: LPWSABUF):string;
var
i,len:integer;
x:char;
tmp,rtmp:string;
begin
result:='';
//if not assigned(lpBuffers) then
// exit;
len:=lpBuffers.len;
debug('len: '+inttostr(len));
tmp:=strpas(lpBuffers.buf);
debug('tmp: '+tmp);
if tmp='' then
exit;
for i:=1 to len do
begin
x:=tmp;

rtmp:=rtmp+' '+bytetohex(byte(x));
end;
result:= rtmp;
end; }


function WSPSocket(af, type_, protocol: Integer; lpProtocolInfo: LPWSAPROTOCOL_INFOW;
g: GROUP; dwFlags: DWORD; var lpErrno: Integer): TSocket; stdcall;
begin
debug('WSPSocket...',1);

result:=NextProcTable.lpWSPSocket(af,type_,protocol,lpProtocolInfo,g,dwFlags,lpErrno);
end;

function WSPCloseSocket(s: TSocket; var lpErrno: Integer): Integer; stdcall;
begin
debug('WSPCloseSocket...',1);

result:=NextProcTable.lpWSPCloseSocket(s,lpErrno);
end;

function WSPConnect(s: TSocket; name: PSockAddr; namelen: Integer; lpCallerData: LPWSABUF;
lpCalleeData: LPWSABUF; lpSQOS: LPQOS; lpGQOS: LPQOS; var lpErrno: Integer): Integer; stdcall;
begin
debug('WSPConnect...',1);

result:=NextProcTable.lpWSPConnect(s,name,namelen,lpCallerData,lpCalleeData,
lpSQOS,lpGQOS,lpErrno);
end;

function WSPAccept(s: TSocket; addr: PSockAddr; addrlen: PINT;
lpfnCondition: LPCONDITIONPROC; dwCallbackData: DWORD; var Errno: Integer): TSocket; stdcall;
begin
debug('WSPAccept...',1);

result:=NextProcTable.lpWSPAccept(s,addr,addrlen,lpfnCondition,
dwCallbackData,Errno);
end;

function WSPSend(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD;
var lpNumberOfBytesSent: DWORD; dwFlags: DWORD; lpOverlapped: LPWSAOVERLAPPED;
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE;
lpThreadId: LPWSATHREADID; var lpErrno: Integer): Integer; stdcall;
begin
debug('WSPSend...',1);

result:=NextProcTable.lpWSPSend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent,
dwFlags,lpOverlapped,lpCompletionRoutine,lpThreadId,lpErrno);

debug(' Return code: '+inttostr(result)+' Error code: '+inttostr(lpErrno),1);
debug(' SOCKET: '+inttostr(S)+' WSPSend: '+inttostr(lpnumberofbytessent)+'Bytes',1);
end;

function WSPSendTo(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD;
var lpNumberOfBytesSent: DWORD; dwFlags: DWORD; lpTo: PSockAddr; iTolen: Integer;
lpOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE;
lpThreadId: LPWSATHREADID; var lpErrno: Integer): Integer; stdcall;
begin
debug('WSPSendTo...',1);

result:=NextProcTable.lpWSPSendTo(s,lpBuffers,dwBufferCount,
lpNumberOfBytesSent,dwFlags,lpTo,iTolen,lpOverlapped,
lpCompletionRoutine,lpThreadId,lpErrno);

debug(' Return code: '+inttostr(result)+' Error code: '+inttostr(lpErrno),1);
debug(' SOCKET: '+inttostr(S)+' WSPSendTo: '+inttostr(lpnumberofbytessent)+'Bytes',1);
end;



procedure CompletionRoutine(dwError, cbTransferred: DWORD; lpOverlapped: LPWSAOVERLAPPED; dwFlags: DWORD); stdcall;
var
iIndex:integer;
cOR:Overlapped_Recorder;
begin
debug('CompletionRoutine...',1);

cOR:=cOverlapped.find_Overlapped(lpOverlapped,iIndex);
if iIndex<0 then
exit;
if cOR.FunctionType=1 then //WSPRecvFrom
begin
debug(' <==WSPRecvFrom WSA_IO_PENDING',1);
end
else
if cOR.FunctionType=0 then //WSPRecv
begin
debug(' <==WSPRecv WSA_IO_PENDING',1);
end
else
begin
debug(' ==>find error data',1);
cOverlapped.delete_Overlapped(iIndex);
exit;
end;
if assigned(cOR.lpCompletionRoutine) then
begin
cOR.lpCompletionRoutine(dwError,cbTransferred,lpOverlapped,dwFlags);
end;
cOverlapped.delete_Overlapped(iIndex);
end;

function WSPRecv(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD;
var lpNumberOfBytesRecvd, lpFlags: DWORD; lpOverlapped: LPWSAOVERLAPPED;
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE; lpThreadId: LPWSATHREADID;
var lpErrno: Integer): Integer; stdcall;
var
IsSetCompletionRoutine:boolean;
iRet:integer;
begin
debug('WSPRecv....',1);

IsSetCompletionRoutine:=false;
if (lpOverlapped<>nil)and(assigned(lpCompletionRoutine))and
(cOverlapped.add_Overlapped(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,
lpOverlapped,lpCompletionRoutine,nil,nil,0)) then
begin
debug(' ==>WSPRecv WSA_IO_PENDING',1);
lpCompletionRoutine:=CompletionRoutine;
IsSetCompletionRoutine:=true;
end;

iRet:=NextProcTable.lpWSPRecv(s,lpbuffers,dwbuffercount,lpnumberofbytesrecvd,
lpflags,lpoverlapped,lpCompletionRoutine,lpthreadid,
lperrno);
debug(' Return code: '+inttostr(iRet)+' Error code: '+inttostr(lpErrno),1);
if (iRet=SOCKET_ERROR)or(IsSetCompletionRoutine=true) then
begin
result:=iRet;
exit;
end;
debug(' SOCKET: '+inttostr(S)+' WSPRecv: '+inttostr(lpnumberofbytesrecvd)+'Bytes',1);
result:=iRet;
end;

function WSPRecvFrom(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD;
var lpNumberOfBytesRecvd, lpFlags: DWORD; lpFrom: PSockAddr; lpFromlen: PINT;
lpOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE;
lpThreadId: LPWSATHREADID; var lpErrno: Integer): Integer; stdcall;
var
IsSetCompletionRoutine:boolean;
iRet:integer;
begin
debug('WSPRecvFrom....',1);

IsSetCompletionRoutine:=false;
if (lpOverlapped<>nil)and(assigned(lpCompletionRoutine))and
(cOverlapped.add_Overlapped(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags,
lpOverlapped,lpCompletionRoutine,lpFrom,lpFromlen,0)) then
begin
debug(' ==>WSPRecvFrom WSA_IO_PENDING',1);
lpCompletionRoutine:=CompletionRoutine;
IsSetCompletionRoutine:=true;
end;

iRet:=NextProcTable.lpWSPRecvFrom(s,lpbuffers,dwbuffercount,lpnumberofbytesrecvd,
lpflags,lpfrom,lpfromlen,lpoverlapped,lpCompletionRoutine,
lpthreadid,lperrno);
debug(' Return code: '+inttostr(iRet)+' Error code: '+inttostr(lpErrno),1);
if (iRet=SOCKET_ERROR)or(IsSetCompletionRoutine=true) then
begin
result:=iRet;
exit;
end;
debug(' SOCKET: '+inttostr(S)+' WSPRecv: '+inttostr(lpnumberofbytesrecvd)+'Bytes',1);
result:=iRet;
end;

procedure xxShutDown(S:TSOCKET);
var
iError:integer;
begin
if NextProcTable.lpWSPShutdown(s,SD_BOTH,iError)<>0 then
WSASetLastError(iError);
end;

const
reg_key='SYSTEM/CurrentControlSet/Services/WinSock2/Xstudio_Packet_Capture';
MAX_PATH=1024;

function GetHookProvider(pProtocolInfo:LPWSAPROTOCOL_INFOW;var sPathName:string):boolean;
procedure GetRightEntryIdItem(pProtocolInfo:LPWSAPROTOCOL_INFOW;var sItem:string);
begin
if pProtocolInfo.ProtocolChain.ChainLen<=1 then
begin
sItem:=inttostr(pProtocolInfo.dwCatalogEntryId);
end
else
begin
sItem:=inttostr(pProtocolInfo.ProtocolChain.ChainEntries[pProtocolInfo.ProtocolChain.ChainLen-1]);
end;
end;
var
sItem:string;
sTemp,
sPathTmp:pchar;
hSubKey: hkey;
ulDateLenth: DWORD;
Datatype,i:integer;
begin
result:=true;
GetRightEntryIdItem(pProtocolInfo,sItem);
ulDateLenth:=MAX_PATH;
getmem(sTemp,MAX_PATH);
getmem(sPathTmp,MAX_PATH);
try
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar(reg_key),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
//debug('RegOpenKeyEx failed!');
result:=false;
exit;
end;
//debug('hSubKey: '+inttostr(hSubKey));
if RegQueryValueEx(hSubKey,pchar(sItem),nil,@Datatype,pbyte(sTemp),@ulDateLenth)=0 then
begin
//debug('sItem: '+sItem+#13#10+'sTemp: '+strpas(sTemp));
//debug('sPathName: '+sPathName+#13#10+'sTemp: '+strpas(sTemp));
i:=ExpandEnvironmentStrings(sTemp,sPathTmp,ulDateLenth);
//debug('sPathName: '+strpas(sPathTmp)+#13#10+'sTemp: '+strpas(sTemp));
if i<>0 then
begin
sPathName:=strpas(sPathTmp);
//debug(sPathName);
RegCloseKey(hSubKey);
end
else
begin
result:=false;
exit;
end;
end
else
begin
//debug('RegQueryValueEx failed!');
result:=false;
exit;
end;
finally
freemem(sTemp);
freemem(sPathTmp);
end;
end;

function WSPStartup(wVersionRequested: WORD; lpWSPData: LPWSPDATA;
lpProtocolInfo: LPWSAPROTOCOL_INFOW; UpcallTable: WSPUPCALLTABLE;
lpProcTable: LPWSPPROC_TABLE): Integer; stdcall;
var
WSPStartupFunc:LPWSPSTARTUP;
slibpath:string;
hlibhandle:hmodule;
begin
result:=0;
debug('WSPStartup...',1);
//slibpath:='f:/winnt/system32/msafd.dll';
if not GetHookProvider(lpProtocolInfo,slibPath) then
begin
//debug('PATH: '+slibpath);
//debug('Read registy failed!');
result:=WSAEPROVIDERFAILEDINIT;
exit;
end;
//debug('PATH: '+slibpath);
hlibhandle:=loadlibrary(pchar(slibpath));
if hlibhandle<>0 then
begin
WSPStartupFunc:= LPWSPSTARTUP(getprocaddress(hlibhandle,pchar('WSPStartup')));
if assigned(WSPStartupFunc) then
begin
//debug('Load library ok!');
result:=WSPStartupFunc(wVersionRequested,lpWSPData,lpProtocolInfo,UpcallTable,lpProcTable);
if result=0 then
begin
glCS.Enter;
NextProcTable:=lpProcTable^;
lpProcTable.lpWSPSocket:=WSPSocket;
lpProcTable.lpWSPCloseSocket:=WSPCloseSocket;
lpProcTable.lpWSPConnect:=WSPConnect;
lpProcTable.lpWSPAccept:=WSPAccept;
lpProcTable.lpWSPSend:=WSPSend;
lpProcTable.lpWSPSendTo:=WSPSendTo;
lpProcTable.lpWSPRecv:=WSPRecv;
lpProcTable.lpWSPRecvFrom:=WSPRecvFrom;
glCS.Leave;
//debug('Hook ok!');
exit;
end;
end
else
begin
result:=WSAEPROVIDERFAILEDINIT;
end;
end
else
begin
result:=WSAEPROVIDERFAILEDINIT;
end;
//debug('Fail!!!');
end;

procedure DllMain(dwReason : DWORD);
var
//h:DWORD;
tmp:pchar;
begin
case dwReason of
DLL_PROCESS_ATTACH :
begin
cOverlapped:=TOverlapped.create;
glCS:=TCriticalSection.Create;
getmem(tmp,1024);
//h:=getcurrentprocessid;
//if h>0 then
// debug('ProcessID:'+inttostr(h));
if getmodulefilenamea(0,tmp,1024)>0 then
begin
sprocessname:=strpas(tmp);
debug(sprocessname+' Loadind...',1);
end
else
begin
sprocessname:='';
debug('Loadind...',1);
end;
freemem(tmp);
end;
DLL_PROCESS_DETACH :
begin
cOverlapped.destroy;
glCS.Free;
end;
DLL_THREAD_ATTACH :
begin
end;
DLL_THREAD_DETACH :
begin
end;
end;
end;

exports
WSPStartup,
SetHostHandle,
AddProc,
DelProc,
AddTarget,
DelTarget,
AddFilter,
DelFilter,
AddPacket,
DelPacket,
ClearAll;

begin
DLLProc := @DLLMain;
DLLMain(DLL_PROCESS_ATTACH);
end.

 
关于OVERLAPPED这部分没有调试过,不知道改得是否对。


unit overlapped;

interface

uses
Windows,
//Messages,
Sysutils,
SyncObjs,
Classes,
JwaWS2spi,
JwaWinType,
JwaWinSock2;

type
Overlapped_Recorder = record
s: TSocket;
lpBuffers: LPWSABUF;
dwBufferCount: DWORD;
lpNumberOfBytesRecvd: DWORD;
lpFlags: DWORD;
lpOverlapped: LPWSAOVERLAPPED;
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE;
lpFrom: PSockAddr;
lpFromlen: PINT;
FunctionType: integer; //0:WSPRecv,1:WSPRecvFrom;
end;
pOverlapped_Recorder = ^ Overlapped_Recorder;

TOverlapped = class(Tobject)
private
Overlapped_list: TList;
sc: TCriticalSection;
public
constructor Create; overload;
destructor Destroy; override;
function add_Overlapped(s: TSocket;
lpBuffers: LPWSABUF;
dwBufferCount: DWORD;
var lpNumberOfBytesRecvd,
lpFlags: DWORD;
lpOverlapped: LPWSAOVERLAPPED;
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE;
lpFrom: PSockAddr;
lpFromlen: PINT;
FunctionType: integer):boolean;
function find_Overlapped(lpOverlapped: LPWSAOVERLAPPED;var index:integer):Overlapped_Recorder;
function delete_Overlapped(index:integer):boolean;
end;

implementation
procedure debug(msg:string);
begin
OutputDebugString(pchar(msg));
end;

constructor TOverlapped.Create;
begin
inherited Create;
Overlapped_list:=tlist.Create;
sc:=TCriticalSection.Create;
end;

destructor TOverlapped.Destroy;
var
i:integer;
aRecord:pOverlapped_Recorder;
begin
if Overlapped_list.Count>0 then
begin
sc.Enter;
for i:=0 to Overlapped_list.Count-1 do
begin
aRecord:=Overlapped_list.Items;
Dispose(aRecord);
end;
sc.Leave;
end;
Overlapped_list.Free;
sc.Free;
inherited Destroy;
end;

function TOverlapped.add_Overlapped(s: TSocket;
lpBuffers: LPWSABUF;
dwBufferCount: DWORD;
var lpNumberOfBytesRecvd,
lpFlags: DWORD;
lpOverlapped: LPWSAOVERLAPPED;
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE;
lpFrom: PSockAddr;
lpFromlen: PINT;
FunctionType: integer):boolean;
var
i:integer;
aRecord,
bRecord:pOverlapped_Recorder;
cRecord:Overlapped_Recorder;
begin
result:=false;
exit;
sc.Enter;

new(aRecord);
aRecord.s:=s;
aRecord.lpBuffers:=lpBuffers;
aRecord.dwBufferCount:=dwBufferCount;
aRecord.lpNumberOfBytesRecvd:=lpNumberOfBytesRecvd;
aRecord.lpFlags:=lpFlags;
aRecord.lpOverlapped:=lpOverlapped;
aRecord.lpCompletionRoutine:=lpCompletionRoutine;
aRecord.lpFrom:=lpFrom;
aRecord.lpFromlen:=lpFromlen;
aRecord.FunctionType:=FunctionType;

cRecord:=Find_Overlapped(lpOverlapped,i);
if i<0 then
begin
if Overlapped_list.Add(aRecord)<0 then
begin
result:=false;
debug('Add overlapped to list error!');
sc.Leave;
exit;
end;
end
else
begin
bRecord:=Overlapped_list.Items;
Overlapped_list.Items:=aRecord;
dispose(bRecord);
debug('Replace overlapped data ok!');
end;

sc.Leave;
result:=true;
end;

function TOverlapped.find_Overlapped(lpOverlapped: LPWSAOVERLAPPED;var index:integer):Overlapped_Recorder;
var
aRecord:pOverlapped_Recorder;
begin
end;

function TOverlapped.delete_Overlapped(index:integer):boolean;
var
aRecord:pOverlapped_Recorder;
begin
result:=true;
if Overlapped_list.Count=0 then
exit;
sc.Enter;
aRecord:=Overlapped_list.Items[index];
Overlapped_list.Delete(index);
Dispose(aRecord);
sc.Leave;
end;


end.
 
安装程序我也改了,不过很不好意思,很乱,自己看吧:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Buttons, ComCtrls, JwaWS2spi,JwaWinsock2;

type
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
Panel2: TPanel;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
Panel1: TPanel;
t1: TLabeledEdit;
p1: TLabeledEdit;
m1: TLabeledEdit;
Panel3: TPanel;
BitBtn3: TBitBtn;
BitBtn4: TBitBtn;
Panel4: TPanel;
spiname: TLabeledEdit;
BitBtn5: TBitBtn;
Image1: TImage;
Image2: TImage;
Image3: TImage;
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
procedure BitBtn4Click(Sender: TObject);
procedure BitBtn5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
m_sPathName:string;

const
REG_INSTALL_PATH_ITEM='PathName';
REG_INSTALL_KEY='SYSTEM/CurrentControlSet/Services/WinSock2/SockEyeS';
REG_PROTOCOL_CATALOG_KEY='SYSTEM/CurrentControlSet/Services/WinSock2/Parameters/Protocol_Catalog9/Catalog_Entries';
REG_PROTOCOL_CATALOG_ITEM='PackedCatalogItem';
myreg_key='SOFTWARE/SockEyeS';
MAX_PATH=260;
MAX_PROTOCOL_CATALOG_LENTH=sizeof(WSAPROTOCOL_INFOW) + MAX_PATH;

implementation

{$R *.dfm}

function readreg(sKey:string;var pBuffer:string;dwBufSize:dword;key:hkey;sSubKey:string;ulType:dword):boolean;
var
sTemp:pchar;
hSubKey: hkey;
Datatype:dword;
begin
result:=false;
if RegOpenKeyEx(key,pchar(sSubkey),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
exit;
end;
try
getmem(sTemp,dwBufSize);
if (RegQueryValueEx(hSubKey,pchar(sKey),nil,@Datatype,pbyte(sTemp),@dwBufSize)=0)and(DataType = ulType) then
begin
pBuffer:=sTemp;
result:=true;
end;
finally
RegCloseKey(hSubKey);
freemem(sTemp);
end;
end;

function savereg(sKey:string;pBuffer:string;dwBufSize:dword;key:hkey;sSubKey:string;ulType:dword):boolean;
var
hSubKey: hkey;
begin
result:=false;
if RegOpenKeyEx(key,pchar(sSubKey),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
if RegCreateKey(key,pchar(sSubKey),hSubKey)<>0 then
exit;
end;
try
if RegSetValueEx(hSubKey,pchar(sKey),0,ulType,pbyte(pchar(pBuffer)),dwBufSize)=0 then
begin
result:=true;
end;
finally
RegCloseKey(hSubKey);
end;
end;

function deletereg(key:hkey;sSubKey:string;sItem:string):boolean;
var
hSubKey:hkey;
begin
result:=false;
if (key=0)or(sSubKey='') then
exit;
if sItem='' then
begin
if RegDeleteKey(key,pchar(sSubKey))=0 then
begin
result:=true;
exit;
end
else
exit;
end;
if RegOpenKeyEx(key,pchar(sSubkey),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
exit;
end;
try
if RegDeleteValue(hSubKey, pchar(sItem))=0 then
result:=true;
finally
RegCloseKey(hSubKey);
end;
end;

function GetTarget(var Targets:string):boolean;
var
sTemp:pchar;
hSubKey: hkey;
Datatype:integer;
ulDateLenth: DWORD;
begin
result:=false;
targets:='';
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar(myreg_key),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
exit;
end;
ulDateLenth:=MAX_PATH;
getmem(sTemp,MAX_PATH);
try
if RegQueryValueEx(hSubKey,pchar('Target'),nil,@Datatype,pbyte(sTemp),@ulDateLenth)=0 then
begin
targets:=stemp;
result:=true;
end;
RegCloseKey(hSubKey);
finally
freemem(sTemp);
end;
end;

function SetTarget(Targets:string):boolean;
var
sTemp:pchar;
hSubKey: hkey;
Datatype:integer;
len: DWORD;
begin
result:=false;
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar(myreg_key),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
if RegCreateKey(HKEY_LOCAL_MACHINE,pchar(myreg_key),hSubKey)<>0 then
exit;
end;
len:=length(Targets)+1;
getmem(sTemp,len);
strcopy(stemp,pchar(targets));
Datatype:=REG_SZ;
try
if RegSetValueEx(hSubKey,pchar('Target'),0,Datatype,pbyte(sTemp),len)=0 then
begin
result:=true;
end;
RegCloseKey(hSubKey);
finally
freemem(sTemp);
end;
end;

function SetPlugin(Plugin:string):boolean;
var
sTemp:pchar;
hSubKey: hkey;
Datatype:integer;
len: DWORD;
begin
result:=false;
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar(myreg_key),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
if RegCreateKey(HKEY_LOCAL_MACHINE,pchar(myreg_key),hSubKey)<>0 then
exit;
end;
len:=length(plugin)+1;
getmem(sTemp,len);
strcopy(stemp,pchar(plugin));
Datatype:=REG_SZ;
try
if RegSetValueEx(hSubKey,pchar('Plugin'),0,Datatype,pbyte(sTemp),len)=0 then
begin
result:=true;
end;
RegCloseKey(hSubKey);
finally
freemem(sTemp);
end;
end;

function GetPlugin(var Plugin:string):boolean;
var
sTemp:pchar;
hSubKey: hkey;
Datatype:integer;
ulDateLenth: DWORD;
begin
result:=false;
plugin:='';
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar(myreg_key),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
exit;
end;
ulDateLenth:=MAX_PATH;
getmem(sTemp,MAX_PATH);
try
if RegQueryValueEx(hSubKey,pchar('Plugin'),nil,@Datatype,pbyte(sTemp),@ulDateLenth)=0 then
begin
Plugin:=stemp;
result:=true;
end;
RegCloseKey(hSubKey);
finally
freemem(sTemp);
end;
end;

function SetMir(Mir:string):boolean;
var
sTemp:pchar;
hSubKey: hkey;
Datatype:integer;
len: DWORD;
begin
result:=false;
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar(myreg_key),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
if RegCreateKey(HKEY_LOCAL_MACHINE,pchar(myreg_key),hSubKey)<>0 then
exit;
end;
len:=length(mir)+1;
getmem(sTemp,len);
strcopy(stemp,pchar(mir));
Datatype:=REG_SZ;
try
if RegSetValueEx(hSubKey,pchar('Mir'),0,Datatype,pbyte(sTemp),len)=0 then
begin
result:=true;
end;
RegCloseKey(hSubKey);
finally
freemem(sTemp);
end;
end;

function GetMir(var Mir:string):boolean;
var
sTemp:pchar;
hSubKey: hkey;
Datatype:integer;
ulDateLenth: DWORD;
begin
result:=false;
Mir:='';
if RegOpenKeyEx(HKEY_LOCAL_MACHINE,pchar(myreg_key),0,KEY_ALL_ACCESS,hSubKey)<>0 then
begin
exit;
end;
ulDateLenth:=MAX_PATH;
getmem(sTemp,MAX_PATH);
try
if RegQueryValueEx(hSubKey,pchar('Mir'),nil,@Datatype,pbyte(sTemp),@ulDateLenth)=0 then
begin
Mir:=stemp;
result:=true;
end;
RegCloseKey(hSubKey);
finally
freemem(sTemp);
end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
tmp:string;
begin
gettarget(tmp);
t1.Text:=tmp;
getplugin(tmp);
p1.Text:=tmp;
getmir(tmp);
m1.Text:=tmp;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
var
tmp:string;
begin
tmp:=t1.Text;
settarget(tmp);
tmp:=p1.Text;
setplugin(tmp);
tmp:=m1.Text;
setmir(tmp);
end;

function isinstalled(spiPathName:string):boolean;
var
tmp:string;
begin
result:=false;
try
if ReadReg( REG_INSTALL_PATH_ITEM,
Tmp,
MAX_PATH,
HKEY_LOCAL_MACHINE,
REG_INSTALL_KEY, REG_SZ
) then
begin
if tmp<>'' then
result:=true;
end;
finally
end;
end;

function SaveHookKey(key:hkey;sSubKey:pchar;IsRemove:boolean):boolean;
var
hSubKey:hkey;
ItemValue,
sItem,
sProvider:string;
ItemSize:integer;
Datatype:dword;
mProtocolInfo:PWsaProtocolInfoW;
begin
result:=false;
ItemSize:=MAX_PROTOCOL_CATALOG_LENTH;
if RegOpenKeyEx(key, sSubKey, 0, KEY_ALL_ACCESS, hSubKey)<>0 then
begin
exit;
end;
try
setlength(ItemValue,MAX_PROTOCOL_CATALOG_LENTH);
if(RegQueryValueEx(hSubKey, REG_PROTOCOL_CATALOG_ITEM
, nil,@Datatype, pbyte(pchar(ItemValue)), @ItemSize)<>0)or
(ItemSize <> MAX_PROTOCOL_CATALOG_LENTH) then
begin
exit;
end;
mProtocolInfo:=PWsaProtocolInfoW(pchar(ItemValue)+MAX_PATH);
if (mProtocolInfo.ProtocolChain.ChainLen = 1)and
(mProtocolInfo.iAddressFamily = AF_INET) then
begin
sItem:=inttostr(mProtocolInfo.dwCatalogEntryId);
if not isRemove then
begin
if not SaveReg(sItem, pchar(ItemValue), strlen(pchar(ItemValue)),
HKEY_LOCAL_MACHINE, REG_INSTALL_KEY, REG_SZ) then
begin
exit;
end;
strcopy(pchar(ItemValue), pchar(m_sPathName));
if RegSetValueEx(hSubKey, REG_PROTOCOL_CATALOG_ITEM
, 0, REG_BINARY, pchar(ItemValue), ItemSize)<>0 then
exit;
end
else
begin
if not ReadReg(sItem, sProvider, MAX_PATH,
HKEY_LOCAL_MACHINE, REG_INSTALL_KEY, REG_SZ) then
exit;
strcopy(pchar(ItemValue), pchar(sProvider));
if RegSetValueEx(hSubKey, REG_PROTOCOL_CATALOG_ITEM
, 0, REG_BINARY, pchar(ItemValue), ItemSize)<>0 then
exit;
end;
end;
finally
RegCloseKey(hSubKey);
end;
result:=true;
end;

function EnumHookKey(IsRemove:boolean):boolean;
var
skey:hkey;
ssubkey:pchar;
dwIndex:integer;
begin
result:=false;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE
, REG_PROTOCOL_CATALOG_KEY, 0, KEY_READ, skey) <>0) then
begin
exit;
end;
try
dwIndex:=0;
getmem(ssubkey,MAX_PATH);
while(RegEnumKey(skey, dwIndex, sSubKey, MAX_PATH) =0)do
begin
if not SaveHookKey(skey, sSubKey, IsRemove) then
begin
exit;
end;
inc(dwIndex);
end;
result:=true;
finally
freemem(sSubKey);
RegCloseKey(sKey);
end;
end;

function InstallProvider(spiPathName:string):integer;
begin
result:=123;
if isinstalled(spiPathName) then
begin
result:=1;
exit;
end;
m_sPathName:=spiPathName;
if not EnumHookKey(FALSE) then
begin
result:=2;
exit;
end;
if not SaveReg(REG_INSTALL_PATH_ITEM, spiPathName, length(spiPathName),
HKEY_LOCAL_MACHINE, REG_INSTALL_KEY, REG_SZ) then
begin
result:=3;
exit;
end;
result:=0;
end;

function RemoveProvider():integer;
begin
result:=123;
if not isInstalled('test') then
begin
result:=1;
exit;
end;
if not EnumHookKey(TRUE) then
begin
result:=2;
exit;
end;
if not deletereg(HKEY_LOCAL_MACHINE,REG_INSTALL_KEY,'') then
begin
result:=3;
exit;
end;
result:=0;
end;

procedure TForm1.BitBtn3Click(Sender: TObject);
var
err:integer;
begin
if spiname.Text<>'' then
err:=InstallProvider(spiname.Text);
case err of
0:
begin
showmessage('Install success!');
end;
1:
begin
showmessage('Already installed!');
end;
2:
begin
showmessage('Install error 2!');
end;
3:
begin
showmessage('Install error 3!');
end;
123:
begin
showmessage('Unknow error!');
end;
end;
end;

procedure TForm1.BitBtn4Click(Sender: TObject);
var
err:integer;
begin
err:=RemoveProvider();
case err of
0:
begin
showmessage('Uninstall success!');
end;
1:
begin
showmessage('Not install!');
end;
2:
begin
showmessage('UNinstall error 2!');
end;
3:
begin
showmessage('Uninstall error 3!');
end;
123:
begin
showmessage('Unknow error!');
end;
end;
end;

procedure TForm1.BitBtn5Click(Sender: TObject);
begin
if isInstalled('test') then
begin
showmessage('Already installed!');
end
else
begin
showmessage('Not install!');
end;
end;

end.
 
SPI的适用范围不大,用驱动级的吧

//
// 司马华鹏
//


#include "NdisHook.h"
#include "HookRule.h"

#pragma pack(push)
#pragma pack(1)
typedef struct _HOOK_CONTEXT_STRUCT
{
//runtime code
ubyte code1_0x58; //0x58 | pop eax | pop caller IP from stack to eax
ubyte code2_0x68; //0x68 | push IMM | push our hook context address
struct _HOOK_CONTEXT_STRUCT *m_pHookContext;//point this
ubyte code3_0x50; //0x50 | push eax | push caller IP from eax to stack
ubyte code4_0xE9; //0xE9 | jmp HookProc | jump our hook proc
udword m_pHookProcOffset;

//our context data

PVOID m_pOriginalProc;
PVOID m_pHookProc;
PVOID m_pBindAdaptHandle;
PVOID m_pProtocolContent;
PVOID *m_ppOriginPtr;

struct _HOOK_CONTEXT_STRUCT *m_pHookNext;

}HOOK_CONTEXT_STRUCT;
#pragma pack(pop)

HOOK_CONTEXT_STRUCT *m_pOurAllOfHookContext = NULL;

dword m_IsFilterEnabled = FALSE;
NDIS_HANDLE m_ourPacketPoolHandle = NULL;
NDIS_HANDLE m_ourBufferPoolHandle = NULL;
PNDIS_PACKET m_ourPacketHandle = NULL;
PNDIS_BUFFER m_ourBufferHandle = NULL;
PVOID m_ourBuffer = NULL;

void ReadPacket(PNDIS_PACKET Packet,PVOID pBuffer,udword dwBufSize);
uword wswap(uword value);

void HookUnload(void)
{
ReleaseHookFunc();

if( m_ourBufferHandle )
{
NdisFreeBuffer(m_ourBufferHandle);
m_ourBufferHandle = NULL;
}
if( m_ourBuffer )
{
NdisFreeMemory(m_ourBuffer,MAX_PACKET_SIZE,0);
m_ourBuffer = NULL;
}
if( m_ourPacketHandle )
{
NdisFreePacket(m_ourPacketHandle);
m_ourPacketHandle = NULL;
}
if( m_ourBufferPoolHandle )
{
NdisFreeBufferPool(m_ourBufferPoolHandle);
m_ourBufferPoolHandle = NULL;
}
if( m_ourPacketPoolHandle )
{
NdisFreePacketPool(m_ourPacketPoolHandle);
m_ourPacketPoolHandle = NULL;
}
return;
}
dword HookInit(void)
{
NTSTATUS status;

m_ourPacketPoolHandle = NULL;
NdisAllocatePacketPool(&status,&m_ourPacketPoolHandle,0xFFF,0x10);
if( status != NDIS_STATUS_SUCCESS )
return FALSE;

m_ourBufferPoolHandle = NULL;
NdisAllocateBufferPool(&status,&m_ourBufferPoolHandle,0x10);
if( status != NDIS_STATUS_SUCCESS )
return FALSE;

m_ourBuffer = NULL;
status = NdisAllocateMemoryWithTag(&m_ourBuffer,MAX_PACKET_SIZE,'NAMW');
if( status != NDIS_STATUS_SUCCESS )
return FALSE;

m_ourBufferHandle = NULL;
NdisAllocateBuffer(&status,&m_ourBufferHandle,m_ourBufferPoolHandle,m_ourBuffer,MAX_PACKET_SIZE);
if( status != NDIS_STATUS_SUCCESS )
return FALSE;

m_ourPacketHandle = NULL;
NdisAllocatePacket(&status,&m_ourPacketHandle,m_ourPacketPoolHandle);
if( status != NDIS_STATUS_SUCCESS )
return FALSE;

NdisChainBufferAtFront(m_ourPacketHandle,m_ourBufferHandle);
return TRUE;
}

typedef struct _NDIS41_PROTOCOL_CHARACTERISTICS
{
#ifdef __cplusplus
NDIS40_PROTOCOL_CHARACTERISTICS Ndis40Chars;
#else
NDIS40_PROTOCOL_CHARACTERISTICS;
#endif

//
// Start of NDIS 4.1 extensions.
//

CO_SEND_COMPLETE_HANDLER CoSendCompleteHandler;
CO_STATUS_HANDLER CoStatusHandler;
CO_RECEIVE_PACKET_HANDLER CoReceivePacketHandler;
CO_REQUEST_HANDLER CoRequestHandler;
CO_REQUEST_COMPLETE_HANDLER CoRequestCompleteHandler;

} NDIS41_PROTOCOL_CHARACTERISTICS;

dword HookProtocol(void)
{
//Default ndis version is 5.0
NDIS_PROTOCOL_CHARACTERISTICS ourNPC;
NDIS_STRING protoName = NDIS_STRING_CONST("HdFw_Slot");
NDIS_STATUS Status;
NDIS_HANDLE ourProtocolHandle = NULL;
byte *ProtocolChain;
dword offset;
dword len;

// NDIS_PROTOCOL_BLOCK *pNdisBlock = NULL;

// pNdisBlock = pNdisBlock->NextProtocol;
// pNdisBlock->NextProtocol = NULL;

memset(&ourNPC,0,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));


if( m_dwMajorVersion == 0x03 )
{
len = sizeof(NDIS30_PROTOCOL_CHARACTERISTICS);
//We must need at least ndis version 3.10
ourNPC.MajorNdisVersion = 0x03;
ourNPC.MinorNdisVersion = 0x0A;
}
else
if( m_dwMajorVersion == 0x04 )
{
len = sizeof(NDIS40_PROTOCOL_CHARACTERISTICS);

ourNPC.MajorNdisVersion = 0x04;
ourNPC.MinorNdisVersion = 0x00;
}
else
{ //treat as version 5.0
len = sizeof(NDIS50_PROTOCOL_CHARACTERISTICS);

ourNPC.MajorNdisVersion = 0x05;
ourNPC.MinorNdisVersion = 0x00;
}

ourNPC.Name = protoName;
ourNPC.OpenAdapterCompleteHandler = PtOpenAdapterComplete;
ourNPC.CloseAdapterCompleteHandler = PtCloseAdapterComplete;
ourNPC.SendCompleteHandler = PtSendComplete;
ourNPC.TransferDataCompleteHandler = PtTransferDataComplete;
ourNPC.ResetCompleteHandler = PtResetComplete;
ourNPC.RequestCompleteHandler = PtRequestComplete;
ourNPC.ReceiveHandler = PtReceive;
ourNPC.ReceiveCompleteHandler = PtReceiveComplete;
ourNPC.StatusHandler = PtStatus;
ourNPC.StatusCompleteHandler = PtStatusComplete;
ourNPC.BindAdapterHandler = PtBindAdapter;
ourNPC.UnbindAdapterHandler = PtUnbindAdapter;
ourNPC.UnloadHandler = PtUnload;
ourNPC.ReceivePacketHandler = PtReceivePacket;
ourNPC.PnPEventHandler = PtPNPHandler;

NdisRegisterProtocol(&Status,&ourProtocolHandle,&ourNPC,len);
if( !NT_SUCCESS(Status) || ourProtocolHandle == NULL )
return FALSE;

//NdisRegisterProtocol return hand reference of NDIS_PROTOCOL_BLOCK;
ProtocolChain = (byte *)ourProtocolHandle;
while(1)
{
DebugInfoCount++;

//Obtain pointer to next protocol link.
if( m_dwMajorVersion == 0x03 )
offset = 4;
else
if( m_dwMajorVersion == 0x04 )
{
if( m_dwMinorVersion == 0x01 )
offset = 0x8C;
else
offset = 0x60;
}
else
if( m_dwMajorVersion == 0x05 )
//NDIS_PROTOCOL_BLOCK->NextProtocol
offset = 0x10;
else
//Error
break;

ProtocolChain = ((byte **)(ProtocolChain + offset))[0];
if( ProtocolChain == NULL )
break;

HookFuncBlock(ProtocolChain);
}
if( m_dwMajorVersion != 4 )
NdisDeregisterProtocol(&Status,ourProtocolHandle);
else
{
// ((byte *)ourProtocolHandle)[0x0C] = 0x01;
// NdisDeregisterProtocol(&Status,ourProtocolHandle);
}
return TRUE;
}
// ProtocolContent
// Version NextChain offset NDIS_PROTOCOL_CHARACTERISTICS offset BindingAdaptHandle offset
// NDIS 3.XX 0x04 0x14 0x08
// NDIS 4.XX 0x60 0x14 0x00
// NDIS 4.01 0x8C 0x14 0x00
// NDIS 5.XX 0x10 0x14 0x00


//-----
VOID HookProtocolSendPackets(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE MiniportAdapterContext,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets
);

NDIS_STATUS HookProtocolWanSend(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE MacBindingHandle,
IN NDIS_HANDLE LinkHandle,
IN PVOID Packet
);
NDIS_STATUS HookProtocolSend(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE MacBindingHandle,
IN PNDIS_PACKET Packet
);

NDIS_STATUS HookProtocolReceive(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer,
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer,
IN UINT LookaheadBufferSize,
IN UINT PacketSize
);
NDIS_STATUS HookWanReceive(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE NdisLinkHandle,
IN PUCHAR Packet,
IN ULONG PacketSize
);
INT HookProtocolReceivePacket(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
);

VOID HookBindAdapterHandler(
IN HOOK_CONTEXT_STRUCT *pOurContext,
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING DeviceName,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2);

VOID HookSendComplete(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status
);


void ReleaseHookFunc(void)
{

HOOK_CONTEXT_STRUCT *pHookContext,*pNext;

pHookContext = m_pOurAllOfHookContext;
m_pOurAllOfHookContext = NULL;
while(pHookContext)
{
pNext = pHookContext->m_pHookNext;
pHookContext->m_ppOriginPtr[0] = pHookContext->m_pOriginalProc;
ExFreePool(pHookContext);
pHookContext = pNext;
}
return;
}

HOOK_CONTEXT_STRUCT *IsHookedNdisFunc(PVOID pAddr)
{

HOOK_CONTEXT_STRUCT *pHookContext;

pHookContext = m_pOurAllOfHookContext;
while(pHookContext)
{
if( pHookContext == pAddr )
break;
pHookContext = pHookContext->m_pHookNext;
}
return pHookContext;
}
HOOK_CONTEXT_STRUCT *IsHookedNdisFuncEx(PVOID *pAddr)
{

HOOK_CONTEXT_STRUCT *pHookContext;

pHookContext = m_pOurAllOfHookContext;
while(pHookContext)
{
if( pHookContext->m_ppOriginPtr == pAddr )
break;
pHookContext = pHookContext->m_pHookNext;
}
return pHookContext;
}

HOOK_CONTEXT_STRUCT *HookNdisFunc(PVOID pHookProc,PVOID *ppOrigProc,PVOID pBindAdaptHandle,PVOID pProtocolContent)
{

HOOK_CONTEXT_STRUCT *pHookContext;
PVOID OrgFunc;

pHookContext = IsHookedNdisFunc(ppOrigProc[0]);
if( pHookContext )
OrgFunc = pHookContext->m_pOriginalProc;
else
OrgFunc = ppOrigProc[0];
if( OrgFunc == NULL )
return NULL;

pHookContext = IsHookedNdisFuncEx(ppOrigProc);
if( pHookContext )
return pHookContext;
pHookContext = ExAllocatePoolWithTag(NonPagedPool,sizeof(HOOK_CONTEXT_STRUCT),'HCSP');
if( pHookContext == NULL )
return NULL;
memset(pHookContext,0,sizeof(HOOK_CONTEXT_STRUCT));

pHookContext->code1_0x58 = 0x58;
pHookContext->code2_0x68 = 0x68;
pHookContext->code3_0x50 = 0x50;
pHookContext->code4_0xE9 = 0xE9;

pHookContext->m_pHookContext = pHookContext;
pHookContext->m_pHookProcOffset = ((udword)pHookProc) - (((udword)&pHookContext->m_pHookProcOffset) + sizeof(udword));
pHookContext->m_pBindAdaptHandle = pBindAdaptHandle;
pHookContext->m_pProtocolContent = pProtocolContent;
pHookContext->m_pOriginalProc = OrgFunc;//ppOrigProc[0];
pHookContext->m_ppOriginPtr = ppOrigProc;
pHookContext->m_pHookProc = pHookProc;
pHookContext->m_pHookNext = m_pOurAllOfHookContext;
m_pOurAllOfHookContext = pHookContext;

ppOrigProc[0] = pHookContext;
return pHookContext;
}

typedef
struct _NDIS40_OPEN_BLOCK
{
PNDIS_MAC_BLOCK MacHandle; // pointer to our MAC
NDIS_HANDLE MacBindingHandle; // context when calling MacXX funcs
PNDIS_ADAPTER_BLOCK AdapterHandle; // pointer to our adapter
PNDIS_PROTOCOL_BLOCK ProtocolHandle; // pointer to our protocol
NDIS_HANDLE ProtocolBindingContext;// context when calling ProtXX funcs
PNDIS_OPEN_BLOCK AdapterNextOpen; // used by adapter's OpenQueue
PNDIS_OPEN_BLOCK ProtocolNextOpen; // used by protocol's OpenQueue
PFILE_OBJECT FileObject; // created by operating system
BOOLEAN Closing; // TRUE when removing this struct
BOOLEAN Unloading; // TRUE when processing unload
NDIS_HANDLE CloseRequestHandle; // 0 indicates an internal close
KSPIN_LOCK SpinLock; // guards Closing
PNDIS_OPEN_BLOCK NextGlobalOpen;

//
// These are optimizations for getting to MAC routines. They are not
// necessary, but are here to save a dereference through the MAC block.
//

SEND_HANDLER SendHandler;
TRANSFER_DATA_HANDLER TransferDataHandler;

//
// These are optimizations for getting to PROTOCOL routines. They are not
// necessary, but are here to save a dereference through the PROTOCOL block.
//

SEND_COMPLETE_HANDLER SendCompleteHandler;
TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;
RECEIVE_HANDLER ReceiveHandler;
RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler;

//
// Extentions to the OPEN_BLOCK since Product 1.
//
RECEIVE_HANDLER PostNt31ReceiveHandler;
RECEIVE_COMPLETE_HANDLER PostNt31ReceiveCompleteHandler;

//
// NDIS 4.0 extensions
//
RECEIVE_PACKET_HANDLER ReceivePacketHandler;
SEND_PACKETS_HANDLER SendPacketsHandler;

//
// Needed for PnP
//
UNICODE_STRING AdapterName; // Upcased name of the adapter we are bound to
}NDIS40_OPEN_BLOCK,*PNDIS40_OPEN_BLOCK;

void HookFuncBlock(byte *ProtocolContent)
{

PNDIS_PROTOCOL_CHARACTERISTICS pProChar;
dword IsWan;
NDIS_STRING WanString = NDIS_STRING_CONST("NDISWAN");
NDIS_STRING DeviceWanString = NDIS_STRING_CONST("//DEVICE//NDISWAN");

NDIS_STRING TcpipString = NDIS_STRING_CONST("Tcpip");
NDIS_STRING TcpArpString = NDIS_STRING_CONST("TCPIP_WANARP");
NDIS_STRING RasArpString = NDIS_STRING_CONST("RASARP");

if( ProtocolContent == NULL )
return;
//Get pointer to NDIS_PROTOCOL_CHARACTERISTICS from protocol content
pProChar = (PNDIS_PROTOCOL_CHARACTERISTICS)(ProtocolContent + 0x14);

if( KeGetCurrentIrql() == PASSIVE_LEVEL )
{
//Check protocol name whether is Wan Lan protocol so that we can correctly hook our function
if( !RtlCompareUnicodeString(&pProChar->Name,&WanString,TRUE) ||
!RtlCompareUnicodeString(&pProChar->Name,&DeviceWanString,TRUE) )
{
IsWan = 1;
}
else
IsWan = 0;

//We r only interest in following protocol
if( !(!RtlCompareUnicodeString(&pProChar->Name,&TcpipString,TRUE) ||
!RtlCompareUnicodeString(&pProChar->Name,&TcpArpString,TRUE) ||
!RtlCompareUnicodeString(&pProChar->Name,&RasArpString,TRUE)) )
{
return;
}
}
else
IsWan = 0;

//
if( !IsWan )
{
HookNdisFunc(HookProtocolReceive,(PVOID *)&pProChar->ReceiveHandler,NULL,ProtocolContent);

//{{added by gjp 6.24
// __asm int 3;
// HookNdisFunc(HookSendComplete,(PVOID *)&pProChar->SendCompleteHandler,NULL,ProtocolContent);
//}}
}
else
HookNdisFunc(HookWanReceive,(PVOID *)&pProChar->WanReceiveHandler,NULL,ProtocolContent);

if(pProChar->MajorNdisVersion > 0x03 )
{
HookNdisFunc(HookProtocolReceivePacket,(PVOID *)&pProChar->ReceivePacketHandler,NULL,ProtocolContent);
HookNdisFunc(HookBindAdapterHandler,(PVOID *)&pProChar->BindAdapterHandler,NULL,ProtocolContent);

}

//pProChar->Name;
//We should obtain and save BindAdaptHandle in order to pass it to NdisTransferData
//BindAdaptHandle is pNdisOpenBlock
if( m_dwMajorVersion == 0x05 )
{
PNDIS_OPEN_BLOCK pNdisOpenBlock;

pNdisOpenBlock = ((PNDIS_OPEN_BLOCK *)ProtocolContent)[0];
while(pNdisOpenBlock)
{
//__asm int 3;
if( !IsWan )
{
HookNdisFunc(HookProtocolSend,(PVOID *)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolReceive,(PVOID *)&pNdisOpenBlock->PostNt31ReceiveHandler,pNdisOpenBlock,ProtocolContent);
//{{added by gjp 6.24
// __asm int 3;
// HookNdisFunc(HookSendComplete,(PVOID *)&pNdisOpenBlock->SendCompleteHandler,pNdisOpenBlock,ProtocolContent);
//}}
}
else
{
HookNdisFunc(HookProtocolWanSend,(PVOID *)&pNdisOpenBlock->WanSendHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookWanReceive,(PVOID *)&pNdisOpenBlock->WanReceiveHandler,pNdisOpenBlock,ProtocolContent);
}
HookNdisFunc(HookProtocolReceive,(PVOID *)&pNdisOpenBlock->ReceiveHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolReceivePacket,(PVOID *)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolSendPackets,(PVOID *)&pNdisOpenBlock->SendPacketsHandler,pNdisOpenBlock,ProtocolContent);
pNdisOpenBlock = pNdisOpenBlock->ProtocolNextOpen;
}
}
else
if( m_dwMajorVersion == 0x04 )
{
PNDIS40_OPEN_BLOCK pNdisOpenBlock;
pNdisOpenBlock = ((PNDIS40_OPEN_BLOCK *)ProtocolContent)[0];

while(pNdisOpenBlock)
{
if( !IsWan )
{
HookNdisFunc(HookProtocolSend,(PVOID *)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolReceive,(PVOID *)&pNdisOpenBlock->PostNt31ReceiveHandler,pNdisOpenBlock,ProtocolContent);
}
else
{
HookNdisFunc(HookProtocolWanSend,(PVOID *)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookWanReceive,(PVOID *)&pNdisOpenBlock->PostNt31ReceiveHandler,pNdisOpenBlock,ProtocolContent);
}

HookNdisFunc(HookProtocolReceive,(PVOID *)&pNdisOpenBlock->ReceiveHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolReceivePacket,(PVOID *)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolSendPackets,(PVOID *)&pNdisOpenBlock->SendPacketsHandler,pNdisOpenBlock,ProtocolContent);
pNdisOpenBlock = (PNDIS40_OPEN_BLOCK)pNdisOpenBlock->ProtocolNextOpen;
}
// HookNdisFunc(HookProtocolReceivePacket,(PVOID *)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent);

}
else
if( m_dwMajorVersion == 0x03 )
{//Unknown information of ndis3.0 NDIS_OPEN_BLOCK struct

}
return;
}
void CheckSendHandle(HOOK_CONTEXT_STRUCT *pOurContext)
{
HOOK_CONTEXT_STRUCT *pHookContext;

if( pOurContext == NULL ||
pOurContext->m_pBindAdaptHandle == NULL )
return;

if( m_dwMajorVersion == 5 )
{
PNDIS_OPEN_BLOCK pNdisOpenBlock;

pNdisOpenBlock = (PNDIS_OPEN_BLOCK)pOurContext->m_pBindAdaptHandle;

pHookContext = (HOOK_CONTEXT_STRUCT *)pNdisOpenBlock->SendHandler;
if( pHookContext )
{
if( !(pHookContext->m_ppOriginPtr == (PVOID *)&pNdisOpenBlock->SendHandler
&& pHookContext->m_pHookProc == (PVOID)HookProtocolSend) )
{

pHookContext = IsHookedNdisFuncEx((PVOID *)&pNdisOpenBlock->SendHandler);
if( pHookContext )
{
if( pHookContext->m_pOriginalProc == (PVOID)pNdisOpenBlock->SendHandler)
{
pNdisOpenBlock->SendHandler = (SEND_HANDLER)pHookContext;
}
}
}
}

pHookContext = (HOOK_CONTEXT_STRUCT *)pNdisOpenBlock->SendPacketsHandler;
if( pHookContext )
{
if( !(pHookContext->m_ppOriginPtr == (PVOID *)&pNdisOpenBlock->SendPacketsHandler
&& pHookContext->m_pHookProc == (PVOID)HookProtocolSendPackets) )
{

pHookContext = IsHookedNdisFuncEx((PVOID *)&pNdisOpenBlock->SendPacketsHandler);
if( pHookContext )
{
if( pHookContext->m_pOriginalProc == (PVOID)pNdisOpenBlock->SendPacketsHandler)
{
pNdisOpenBlock->SendPacketsHandler = (SEND_PACKETS_HANDLER)pHookContext;
}
}
}
}
}
else
if( m_dwMajorVersion == 4 )
{
PNDIS40_OPEN_BLOCK pNdisOpenBlock;
pNdisOpenBlock = (PNDIS40_OPEN_BLOCK)pOurContext->m_pBindAdaptHandle;

pHookContext = (HOOK_CONTEXT_STRUCT *)pNdisOpenBlock->SendHandler;
if( pHookContext )
{
if( !(pHookContext->m_ppOriginPtr == (PVOID *)&pNdisOpenBlock->SendHandler
&& pHookContext->m_pHookProc == (PVOID)HookProtocolSend) )
{

pHookContext = IsHookedNdisFuncEx((PVOID *)&pNdisOpenBlock->SendHandler);
if( pHookContext )
{
if( pHookContext->m_pOriginalProc == (PVOID)pNdisOpenBlock->SendHandler)
{
pNdisOpenBlock->SendHandler = (SEND_HANDLER)pHookContext;
}
}
}
}

pHookContext = (HOOK_CONTEXT_STRUCT *)pNdisOpenBlock->SendPacketsHandler;
if( pHookContext )
{
if( !(pHookContext->m_ppOriginPtr == (PVOID *)&pNdisOpenBlock->SendPacketsHandler
&& pHookContext->m_pHookProc == (PVOID)HookProtocolSendPackets) )
{

pHookContext = IsHookedNdisFuncEx((PVOID *)&pNdisOpenBlock->SendPacketsHandler);
if( pHookContext )
{
if( pHookContext->m_pOriginalProc == (PVOID)pNdisOpenBlock->SendPacketsHandler)
{
pNdisOpenBlock->SendPacketsHandler = (SEND_PACKETS_HANDLER)pHookContext;
}
}
}
}
}
return;
}

dword HookFilterBuffer(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer,udword PacketSize,dword isOutgoing)
{
NTSTATUS status;
dword result = TRUE;

switch(wswap(((PETHHDR)pBuffer)->h_proto))
{
case ETH_P_IP:
{
if( isOutgoing )
TotalSendBytes += PacketSize;
else
TotalReceiveBytes += PacketSize;
TotalIPPackets++;
result = AnalyzeIP( (PIPHdr)(&((byte *)pBuffer)[sizeof(ETHHDR)]),PacketSize - sizeof(ETHHDR), isOutgoing);
break;
}
case ETH_P_ARP:
TotalARPPackets++;
break;
case ETH_P_RARP:
break;
default:
TotalOtherPackets++;
break;
}
return result;
}

dword HookFilterReceivePacket(HOOK_CONTEXT_STRUCT *pOurContext,udword TotalPacketSize,PVOID pHeadBuffer,udword dwHeadSize,PNDIS_PACKET pPacket,dword isOutgoing)
{
dword PacketSize;
PVOID pBuffer = NULL;
NTSTATUS status;
PNDIS_BUFFER firstBuffer,nextBuffer;
dword result = TRUE;
byte *pBuf;

NdisQueryPacket(pPacket,NULL,NULL,NULL,&PacketSize);
if( /*!PacketSize ||*/ PacketSize + dwHeadSize < sizeof(ETHHDR) )
return TRUE;


status = NdisAllocateMemoryWithTag(&pBuffer,PacketSize + dwHeadSize,'NAMW');
if( status != NDIS_STATUS_SUCCESS || pBuffer == NULL )
return TRUE;//FALSE;
//obtain content from the packet

pBuf = (byte *)pBuffer;
NdisMoveMemory(pBuf,pHeadBuffer,dwHeadSize);
ReadPacket(pPacket,&pBuf[dwHeadSize],PacketSize);

result = HookFilterBuffer(pOurContext,pBuffer,TotalPacketSize + dwHeadSize,isOutgoing);
NdisFreeMemory(pBuffer,PacketSize + dwHeadSize,0);
return result;
}

// Filter Packet
// return 0 = block this packet

dword HookFilterPacket(HOOK_CONTEXT_STRUCT *pOurContext,PNDIS_PACKET pPacket,dword isOutgoing)
{
dword PacketSize;
PVOID pBuffer = NULL;
NTSTATUS status;
PNDIS_BUFFER firstBuffer,nextBuffer;
dword result = TRUE;

NdisQueryPacket(pPacket,NULL,NULL,NULL,&PacketSize);
if( /*!PacketSize ||*/ PacketSize < sizeof(ETHHDR) )
return TRUE;


status = NdisAllocateMemoryWithTag(&pBuffer,PacketSize,'NAMW');
if( status != NDIS_STATUS_SUCCESS || pBuffer == NULL )
return TRUE;//FALSE;
//obtain content from the packet
ReadPacket(pPacket,pBuffer,PacketSize);

result = HookFilterBuffer(pOurContext,pBuffer,PacketSize,isOutgoing);
NdisFreeMemory(pBuffer,PacketSize,0);
return result;
}

__declspec( naked )
uword wswap(uword value)
{
__asm
{
movzx eax,byte ptr [esp + 5];
mov ah ,byte ptr [esp + 4];
ret 4
}
}

void ReadPacket(PNDIS_PACKET Packet,PVOID pBuffer,udword dwBufSize)
{
PVOID virtualAddress;
PNDIS_BUFFER firstBuffer, nextBuffer;
ULONG totalLength;
UINT len;
PVOID pBuf = NULL;
dword count = 0;

NdisQueryPacket(Packet, NULL, NULL, &firstBuffer, NULL);
while( firstBuffer != NULL)
{
//NdisQueryBufferSafe can't use in wdm1.0
// NdisQueryBufferSafe(firstBuffer, &virtualAddress,
// &len, 16 );
NdisQueryBuffer(firstBuffer, &virtualAddress,
&len);
if(!virtualAddress)
{
//
// System is running low on memory resources.
// So fail the read.
//
break;
}
if( count + len > dwBufSize )
break;
NdisMoveMemory(&((byte *)pBuffer)[count],virtualAddress,len);
count += len;
NdisGetNextBuffer(firstBuffer, &nextBuffer);
firstBuffer = nextBuffer;
}
return;
}

//----
VOID HookProtocolSendPackets(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE MiniportAdapterContext,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets
)
{
udword x;

PPNDIS_PACKET FilterPacketArray;
UINT NumberOfFilterPackets;

if( pOurContext )
{

if( NumberOfPackets == 0 )
{
((SEND_PACKETS_HANDLER)pOurContext->m_pOriginalProc)(
MiniportAdapterContext,
PacketArray,
NumberOfPackets);
return;
}

FilterPacketArray = ExAllocatePoolWithTag(NonPagedPool,sizeof(PNDIS_PACKET) * NumberOfPackets,'HFPA');
if( FilterPacketArray == NULL )
{
((SEND_PACKETS_HANDLER)pOurContext->m_pOriginalProc)(
MiniportAdapterContext,
PacketArray,
NumberOfPackets);
return;
}

for(NumberOfFilterPackets = 0,x = 0; x < NumberOfPackets; x++ )
{

if( HookFilterPacket(pOurContext,PacketArray[x],TRUE) )
{
FilterPacketArray[NumberOfFilterPackets++] = PacketArray[x];
}
}
if( NumberOfFilterPackets )
{
((SEND_PACKETS_HANDLER)pOurContext->m_pOriginalProc)(
MiniportAdapterContext,
FilterPacketArray,
NumberOfFilterPackets);
}
ExFreePool(FilterPacketArray);
}
return;
}

NDIS_STATUS HookProtocolWanSend(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE MacBindingHandle,
IN NDIS_HANDLE LinkHandle,
IN PVOID Packet
)
{
if( pOurContext )
{
return ((WAN_SEND_HANDLER)pOurContext->m_pOriginalProc)(
MacBindingHandle,
LinkHandle,
Packet);
}
return NDIS_STATUS_SUCCESS;
}

NDIS_STATUS HookProtocolSend(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE MacBindingHandle,
IN PNDIS_PACKET Packet
)
{
// udword PacketSize;
NTSTATUS status = NDIS_STATUS_SUCCESS;

if( pOurContext )
{
if( HookFilterPacket(pOurContext,Packet,TRUE) )
{
status = ((SEND_HANDLER)pOurContext->m_pOriginalProc)(
MacBindingHandle,
Packet);
}
else
status = NDIS_STATUS_NOT_ACCEPTED;
}
return status;
}

INT HookProtocolReceivePacket(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
)
{
NTSTATUS status = NDIS_STATUS_SUCCESS;

if( pOurContext )
{
CheckSendHandle(pOurContext);

if( HookFilterPacket(pOurContext,Packet,FALSE) )
{
status = ((RECEIVE_PACKET_HANDLER)pOurContext->m_pOriginalProc)(
ProtocolBindingContext,
Packet);
}
else
status = NDIS_STATUS_NOT_ACCEPTED;
}
return status;
}

NDIS_STATUS HookWanReceive(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE NdisLinkHandle,
IN PUCHAR Packet,
IN ULONG PacketSize
)
{

if( pOurContext )
{
return ((WAN_RECEIVE_HANDLER)pOurContext->m_pOriginalProc)(
NdisLinkHandle,
Packet,
PacketSize);
}
return NDIS_STATUS_SUCCESS;
}

NDIS_STATUS HookProtocolReceive(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer,
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer,
IN UINT LookAheadBufferSize,
IN UINT PacketSize
)
{
NTSTATUS status = NDIS_STATUS_SUCCESS;

if( pOurContext )
{

CheckSendHandle(pOurContext);
// TotalReceiveBytes += PacketSize;

if( pOurContext->m_pBindAdaptHandle )
{
udword len = 0;

if( PacketSize > LookAheadBufferSize )
{
NdisTransferData(&status,pOurContext->m_pBindAdaptHandle,MacReceiveContext,0,PacketSize,m_ourPacketHandle,&len);
}
else
{
NdisMoveMemory(m_ourBuffer,LookAheadBuffer,PacketSize);
}

if( status == NDIS_STATUS_SUCCESS )
{
TotalTransferPackets++;

if( !HookFilterReceivePacket(pOurContext,PacketSize,HeaderBuffer,HeaderBufferSize,m_ourPacketHandle,FALSE) )
//if( !HookFilterPacket(pOurContext,m_ourPacketHandle,FALSE) )
return NDIS_STATUS_NOT_ACCEPTED;
}
else
if( status == NDIS_STATUS_PENDING )
//Warning: Here An Error will be occured.
TotalTransferPendingPackets++;
else
TotalTransferErrorPackets++;

}
else
{
TotalUnbindTransferPackets++;
}
status = ((RECEIVE_HANDLER)pOurContext->m_pOriginalProc)(
ProtocolBindingContext,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
}
return status;
}
VOID HookBindAdapterHandler(
IN HOOK_CONTEXT_STRUCT *pOurContext,
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING DeviceName,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2)
{

if( pOurContext )
{
((BIND_HANDLER)pOurContext->m_pOriginalProc)(Status,BindContext,
DeviceName,
SystemSpecific1,
SystemSpecific2);

HookFuncBlock(pOurContext->m_pProtocolContent);
TotalTransferErrorPackets++;
}
return;
}

VOID HookSendComplete(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status
)
{

__asm int 3;
((SEND_COMPLETE_HANDLER)pOurContext->m_pOriginalProc)(
ProtocolBindingContext,
Packet,
Status
);
return;
}



 
驱动级的就不好转成DELPHI的了,对了,那个WINAPISPI可以到JEDI的网页上找,是某人写
的一个WINAPI头文件转DELPHI原马的包,里面就有
 
谢谢各位大哥,不过对我的应用而言,SPI 是很合适的了。
今天我就去买书,仔细看看大家的代码,这可是学习的好机会啊!
 
为什么非要转换成Delphi的?直接看vc的代码才“正宗”,驱动级的比SPI还要简单!
 
能不能详细点啊?我想学。
 
wingerk:是否能给小弟看看完整的代码,yalongsoft@163.com,谢谢!
 
还是先结束了吧!
 
spi里面,是否可以判断目标程序调用?
 
后退
顶部