只要你的DLL没问题,剩下的就好调试的多了,下面是接收窗体的主要代码,实际就是对MYWM_DataMessage和MYWM_TEST消息的处理,就不做太多说明了.程序太长,只能挑最主要的代码给大家看了。
unit fmCap;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ImgList, ExtCtrls, ToolWin, Menus,Base,WinSock2,Grids,Math, ShellAPI,
StdCtrls;
type TData=^TDataRec;
TDataRec=Record
Buf:array of byte;
Len:integer;
end;
type
TForm2 = class(TForm)
..............
private
procedure MessageCap(var Message:TMessage);message MyWM_DataMessage;
procedure MessageTest(var Message:TMessage);message MyWM_test;
..............
function TForm2.GetPackType(aDataIndex: Integer):string;
var istr:string;
begin
case TDataType(aDataIndex) of
dtSend1:istr:='WSock32.Send';
dtRecv1:istr:='WSock32.Recv';
dtSendTo1:istr:='WSock32.Sendto';
dtRecvFrom1:istr:='WSock32.RecvFrom';
dtSend2:istr:='WS2_32.Send';
dtRecv2:istr:='WS2_32.Recv';
dtSendTo2:istr:='WS2_32.SendTo';
dtRecvFrom2:istr:='WS2_32.RecvFrom';
dtWSASend:istr:='WS2_32.WSASend';
dtWSARecv:istr:='WS2_32.WSARecv';
dtWSASendto:istr:='WS2_32.WSASendTo';
dtWSARecvFrom:istr:='WS2_32.WSARecvFrom';
end;
result:=istr;
end;
procedure TForm2.MessageCap(var Message:TMessage);
var inode:TListItem;iData:TData;
begin
//if not ishooked then exit;
inode:=cdatalist.Items.Add;
inode.Caption:=GetPackType(message.LParam);
inode.SubItems.Add(inttostr(dlldata^.Socket));
inode.SubItems.Add(Format('%s:%d', [inet_ntoa(Tinaddr(dlldata^.FromAddr.sin_addr)), ntohs(dlldata^.FromAddr.sin_port)]));
inode.SubItems.Add(Format('%s:%d', [inet_ntoa(Tinaddr(dlldata^.ToAddr.sin_addr)), ntohs(dlldata^.ToAddr.sin_port)]));
inode.SubItems.Add(inttostr(dlldata^.Len));
inode.StateIndex:=listico;inode.ImageIndex:=listico;
new(idata);
setlength(idata.Buf,dlldata^.Len);
move(dlldata^.buf[0],idata.Buf[0],dlldata^.Len);
iNode.Data:=idata;
end;
procedure TForm2.MessageTest(var Message:TMessage);
begin
case message.LParam of
debug_hookon:begin
clog.Lines.Add('HookApi成功');
cbuthooknone.Enabled:=true;
cbutrehook.Enabled:=false;
cbutstop.Enabled:=false;
end;
debug_hookoff:begin
clog.Lines.Add('UnHookApi成功');
cbuthooknone.Enabled:=false;
cbutrehook.Enabled:=true;
cbutstop.Enabled:=true;
end;
debug_MapOk:cButRule.Enabled:=true;
debug_mapclose:if dllhandle<>0 then begin
clog.Lines.Add('内存映像文件已销毁');
unhook;
cButRule.Down:=false;
cButRule.Enabled:=false;
end;
debug_dlloff:begin
Freelibrary(DLLHandle);
clog.Lines.Add('解除注入');
clog.Lines.Add('=============');
//closehandle(dllhandle);
dllhandle:=0;
cButStop.Enabled:=false;
cbuthooknone.Enabled:=false;
cbutrehook.Enabled:=false;
end;
end;
end;
procedure TForm2.DLL_Init;
begin
if dllhandle<>0 then unhook;
DLLHandle := LoadLibrary('Hook.dll');
@InstallHook := GetProcAddress(DLLHandle, 'InstallHook');
@UnHook := GetProcAddress(DLLHandle, 'UnHook');
if createmap=true then clog.Lines.Add('建立内存映射成功!');
cButStop.Enabled:=InstallHook(MyInfo.hTarget, Self.Handle);
cButRehook.Enabled:=cbutstop.Enabled;
if cButStop.Enabled then begin
clog.Lines.Add('注入线程成功');
cButReHookClick(nil);
end else clog.Lines.Add('注入线程失败');
end;
procedure TForm2.cButStopClick(Sender: TObject);
begin
if dllhandle<>0 then unhook;
end;
该程序工作基本正常,不过还有点小问题
在SC中,用启动程序的方法注入DLL无法截获RECV函数,虽然已经挂接成功!对于非阻塞型的函数,似乎只有在这个函数正在执行的时候才能挂上。对SC来说,只有进入它发广播地图申请时再挂才能捕获函数。所以一起动就挂还不行,要取消挂接,当进入UDP广播时再挂上就可以了。
另,对SC,只要挂上RECV,当你取消挂接后,SC退出时依然会报错崩溃,目前还找不到原因。