procedure OpenShareData;
begin
MapHandle:=CreateFileMapping($FFFFFFFF,
nil,
PAGE_READWRITE,
0,
$ffff,
'MyMap');
if MapHandle<>0 then
begin
DLLData:=MapViewOfFile(MapHandle,FILE_MAP_ALL_ACCESS,0,0,0);
if DLLData=nil then
CloseHandle(MapHandle);
end
else if GetLastError = ERROR_ALREADY_EXISTS then
begin
MapHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'MyMap');
if MapHandle = 0 then
Exit;
end
else
Exit;
end;pankun版主,这是你的“Delphi拦截其他程序的网络数据包”中的代码,为什么我把接收MapViewOfFile返回值的那个DLLData指针换成我自己定义的指针就导致非法访问内存?我看了MapViewOfFile的声明,返回PVoid,所以换个指针变量应该没问题的吧?
begin
MapHandle:=CreateFileMapping($FFFFFFFF,
nil,
PAGE_READWRITE,
0,
$ffff,
'MyMap');
if MapHandle<>0 then
begin
DLLData:=MapViewOfFile(MapHandle,FILE_MAP_ALL_ACCESS,0,0,0);
if DLLData=nil then
CloseHandle(MapHandle);
end
else if GetLastError = ERROR_ALREADY_EXISTS then
begin
MapHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'MyMap');
if MapHandle = 0 then
Exit;
end
else
Exit;
end;pankun版主,这是你的“Delphi拦截其他程序的网络数据包”中的代码,为什么我把接收MapViewOfFile返回值的那个DLLData指针换成我自己定义的指针就导致非法访问内存?我看了MapViewOfFile的声明,返回PVoid,所以换个指针变量应该没问题的吧?
type
PData = ^TData;
TData = record
Hook: THandle;
Hooked: Boolean;
end;var
DLLData:PData;我自己声明了一个pTmp:PChar;
pTmp:=MapViewOfFile(MapHandle,FILE_MAP_ALL_ACCESS,0,0,0);就肯定出问题。
想不通……………………
>>法访问内存?同一地址, 在不同進程, 可能對應不同的物理內存位置,
如果你 "那个DLLData指针换成我自己定义的指针"
傳到另外一個進程中, 指向內存其實是變了, 當然會:
>>导致非法访问内存?
那要看你具體轉在什麼地方, 如何操作了
还有就是入口这里,变个变量名和类型而已吧?那我都帖来。library Hook;uses
SysUtils,windows,Messages,APIHook in 'ApiHook.pas';type
PData = ^TData;
TData = record
Hook: THandle;
Hooked: Boolean;
end;
var
DLLData: PData;
MapHandle:THandle;
pTemp:PChar;
const
MapFileName = 'PCG';
{------------------------------------}
{过程名:钩子进程
过程功能:执行钩子进程
过程参数:钩子类型、消息附加参数}
{------------------------------------}
procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;
begin
if not DLLData^.Hooked then
begin
HookAPI;
DLLData^.Hooked := True;
end;
//调用下一个Hook
CallNextHookEx(DLLData^.Hook, nCode, wParam, lParam);
end;
{------------------------------------}
{函数名:安装钩子
函数功能:取得窗体线程ID,安装钩子。
函数参数:窗体句柄}
{------------------------------------}
function InstallHook(SWindow: LongWORD):Boolean;stdcall;
var
ThreadID: LongWORD;
begin
Result := False;
DLLData^.Hook := 0;
ThreadID := GetWindowThreadProcessId(sWindow, nil);
//给指定窗口挂上钩子
DLLData^.Hook := SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, ThreadID);
if DLLData^.Hook > 0 then
Result := True//是否成功HOOK
else
Exit;
end;
{------------------------------------}
{过程名:UnHook
过程功能:取消钩子
过程参数:无}
{------------------------------------}
procedure UnHook;stdcall;
begin
if DLLData.Hooked = true then
begin
UnHookAPI;
UnhookWindowsHookEx(DLLData^.Hook);
end
else
MessageBox(GetCurrentProcess,'还没有成功挂接','Error',MB_OK);
Exit;
end;
{------------------------------------}
{函数名:取得共享数据
函数功能:取得共享数据
函数参数:无}
{------------------------------------}
function GetData:PChar;StdCall;
begin
Result := Buffer;
end;
{------------------------------------}
{过程名:打开数据共享
过程功能:建立映象文件
过程参数:无}
{------------------------------------}
procedure OpenShareData;
begin
MapHandle:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,$ffff,'MyMap');
if MapHandle<>0 then
begin
DLLData:=MapViewOfFile(MapHandle,FILE_MAP_ALL_ACCESS,0,0,0);
if DLLData=nil then
CloseHandle(MapHandle);
end
else if GetLastError = ERROR_ALREADY_EXISTS then
begin
MapHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'MyMap');
if MapHandle = 0 then
Exit;
end
else
Exit;
end;
{------------------------------------}
{过程名:关闭数据共享
过程功能:释放映象文件
过程参数:无}
{------------------------------------}
procedure CloseShareData;
begin
UnmapViewOfFile(Pointer(MapHandle));
end;{------------------------------------}
{过程名:DLL入口函数
过程功能:进行DLL初始化,释放等
过程参数:DLL状态}
{------------------------------------}
procedure DLLEntryPoint(Reason:integer);
begin
case Reason of
DLL_PROCESS_ATTACH:OpenShareData;
DLL_PROCESS_DETACH:CloseShareData ;
end;
end;
{$R *.res}
exports
InstallHook, UnHook,GetData;
begin
DLLProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
DLLData^.Hooked := False;
end.
unit APIHook;
interfaceuses
SysUtils,Windows,WinSock;Const
TCPFlag_URG = 0;
TCPFlag_ACK = 2;
TCPFlag_PSH = 4;
TCPFlag_RST = 8;
TCPFlag_SYN = 16;
TCPFlag_FYN = 32; IPPROTO_IP = 0; //dummy for IP
IPPROTO_ICMP = 1; // control message protocol
IPPROTO_IGMP = 2; //internet group management protocol
IPPROTO_GGP = 3; // gateway^2 (deprecated)
IPPROTO_TCP = 6; // tcp
IPPROTO_PUP = 12; // pup
IPPROTO_UDP = 17; // user datagram protocol
IPPROTO_IDP = 22; // xns idp
IPPROTO_ND = 77; // UNOFFICIAL net disk proto IPPROTO_RAW = 255; // raw IP packet
IPPROTO_MAX = 256;
Type TIPPROTO = Record
itype: word;
name: String;
End; PIP_Header = ^TIP_Header;
TIP_Header = Packed Record
ip_verlen: Byte; //4 位版本 4 位首部长度
ip_tos: Byte; //服务类型(TOS)
ip_totallength: Word; //总长度
ip_id: Word; //标记
ip_offset: Word; //
ip_ttl: Byte; //8 位生存时间
ip_protocol: Byte; //8 位协议
ip_checksum: Word; //首部校验和
ip_srcaddr: LongWord; //源ip
ip_destaddr: LongWord; //目的ip
End;
PUDP_Header = ^TUDP_Header;
TUDP_Header = Packed Record
src_portno: Word; //源端口号
dst_portno: Word; //目的端口号
udp_length: Word; //UDP 首部和UDP 数据的字节长度
udp_checksum: Word; //UDP首部和数据的校验和
End;
PTCP_Hearder = ^TTCP_Hearder;
TTCP_Hearder = Packed Record
src_portno: Word; //源端口号
dst_portno: Word; //目的端口号
Sequenceno: LongWord; //序号
Acknowledgeno: LongWord; //确认序号
DataOffset: Byte; //
flag: byte;
Windows: WORD; //窗口大小
checksum: WORD; //校验和
UrgentPointer: WORD; //紧急指针
End;Const
IPPROTO: Array[0..8] Of TIPPROTO = (
(iType: IPPROTO_IP; name: 'IP'),
(iType: IPPROTO_ICMP; name: 'ICMP'),
(iType: IPPROTO_IGMP; name: 'IGMP'),
(iType: IPPROTO_GGP; name: 'GGP'),
(iType: IPPROTO_TCP; name: 'TCP'),
(iType: IPPROTO_PUP; name: 'PUP'),
(iType: IPPROTO_UDP; name: 'UDP'),
(iType: IPPROTO_IDP; name: 'IDP'),
(iType: IPPROTO_ND; name: 'ND'));
type
TCo = function (s: TSocket;
var Buf;
len,flags:Integer):Integer; stdcall; TCl = function (s: TSocket;
var Buf;
len, flags: Integer;
var Addr: TSockAddr;
Length: Integer): Integer; stdcall; PJmpCode = ^TJmpCode;
TJmpCode = packed record
JmpCode: BYTE;
Address: TCl;
MovEAX: Array [0..2] of BYTE;
end;
procedure HookAPI;
procedure UnHookAPI;var
OldSend, OldRecv: TCo;
OldSendTo,OldRecvFrom: TCl;
JmpCode: TJmpCode;
OldProc: array [0..3] of TJmpCode;
pSend, pRecv,pSendto,pRecvFrom: pointer;
ProcessHandle:THandle;implementationfunction MySendTo(s:TSocket;
var Buf;
Len,Flags:integer;
var AddrTo:TSockAddr;
ToLen:Integer):integer;StdCall;
var
dwSize:cardinal;begin
MessageBeep(1000); WriteProcessMemory(ProcessHandle,pSendTo,@OldProc[0],8,dwSize);
Result:=OldSendTo(s,Buf,Len,Flags,AddrTo,ToLen);
JmpCode.Address:=@MySendTo;
WriteProcessMemory(ProcessHandle,pSendTo,@JmpCode,8,dwSize);
end;function MyRecvFrom(s:TSocket;
var Buf;
Len,Flags:integer;
var from: TSockAddr;
fromlen: Integer):integer;StdCall;
var
dwSize:cardinal;
begin
MessageBeep(1000); WriteProcessMemory(processHandle,pRecvFrom,@OldProc[1],8,dwSize);
Result:=OldRecvFrom(S,Buf,Len,Flags,From,FromLen);
JmpCode.Address :=@MyRecvFrom;
WriteProcessMemory(ProcessHandle,pRecvFrom,@JmpCode,8,dwSize);
end;function MySend(s: TSocket;
var Buf;
len, flags:Integer): Integer; stdcall;
var
dwSize: cardinal;
begin
MessageBeep(1000); WriteProcessMemory(ProcessHandle, pSend, @OldProc[2], 8, dwSize);
Result := OldSend(S,Buf,len,flags);
JmpCode.Address := @MySend;
WriteProcessMemory(ProcessHandle, pSend, @JmpCode, 8, dwSize);
end;function MyRecv(s:TSocket;
var Buf;
len,flags:Integer): Integer;stdcall;
var
dwSize: cardinal;
begin
MessageBeep(1000); WriteProcessMemory(ProcessHandle, pRecv, @OldProc[3], 8,dwSize);
Result := OldRecv(S, Buf, len, flags);
JmpCode.Address := @MyRecv;
WriteProcessMemory(ProcessHandle, pRecv, @JmpCode, 8, dwSize);
end;procedure HookAPI;
var
DLLModule: THandle;
dwSize: cardinal;
begin
ProcessHandle := GetCurrentProcess;
DLLModule := LoadLibrary('ws2_32.dll');
pSend := GetProcAddress(DLLModule, 'send'); //取得API地址
pRecv := GetProcAddress(DLLModule, 'recv');
pSendTo:=GetProcAddress(DLLModule,'sendto');
pRecvFrom:=GetProcAddress(DLLModule,'recvfrom'); JmpCode.JmpCode := $B8;
JmpCode.MovEAX[0] := $FF;
JmpCode.MovEAX[1] := $E0;
JmpCode.MovEAX[2] := 0; ReadProcessMemory(ProcessHandle,pSendTo,@OldProc[0],8,dwSize);
JmpCode.Address:=@MySendTo;
WriteProcessMemory(ProcessHandle,pSendTo,@JmpCode,8,dwSize); ReadProcessMemory(ProcessHandle,pRecvFrom,@OldProc[1],8,dwSize);
JmpCode.Address:=@MyRecvFrom;
WriteProcessMemory(ProcessHandle,pRecvFrom,@JmpCode,8,dwSize); ReadProcessMemory(ProcessHandle, pSend, @OldProc[2], 8, dwSize);
JmpCode.Address := @MySend;
WriteProcessMemory(ProcessHandle, pSend, @JmpCode, 8, dwSize); ReadProcessMemory(ProcessHandle, pRecv, @OldProc[3], 8, dwSize);
JmpCode.Address := @MyRecv;
WriteProcessMemory(ProcessHandle, pRecv, @JmpCode, 8, dwSize); OldSend := pSend;
OldRecv := pRecv;
OldSendTo:=pSendTo;
OldRecvFrom:=pRecvFrom;
end;procedure UnHookAPI;
var
dwSize: Cardinal;
begin WriteProcessMemory(ProcessHandle, pSendto, @OldProc[0], 8,dwSize);
WriteProcessMemory(ProcessHandle, pRecvFrom, @OldProc[1], 8,dwSize);
WriteProcessMemory(ProcessHandle, pSend, @OldProc[2], 8,dwSize);
WriteProcessMemory(ProcessHandle, pRecv, @OldProc[3], 8,dwSize);
end;
end.这里边我自己加了点报头结构的定义,那也不可能是这个的问题呀。
DLLData:=MapViewOfFile(MapHandle,FILE_MAP_ALL_ACCESS,0,0,0);
这个DLLData换成pTemp就出问题。
TData = record
Hook: THandle;
Hooked: Boolean;
end;在DLL开始执行的时候
{$R *.res}
exports
InstallHook, UnHook,GetData;
begin
DLLProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
DLLData^.Hooked := False;
end.DLLData^.Hooked := False;是这句导致了非法访问内存吗?