编程实现管理员远程登录报警器

作者在 2010-01-25 13:04:03 发布以下内容
收集的哦!
使用delphi编写的远程桌面报警器!具体实现的代码以及附件---
unit main;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, WinSock, jpeg;

type
  TMainForm = class(TForm)
    Eip: TEdit;
    lbl1: TLabel;
    lbl2: TLabel;
    EPort: TEdit;
    timer1: TTimer;
    StartButton: TButton;
    StopButton: TButton;
    image1: TImage;
    procedure StartButtonClick(Sender: TObject);
    procedure StopButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure timer1Timer(Sender: TObject);
    procedure EipKeyPress(Sender: TObject; var Key: Char);
    procedure EPortKeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TAsnOctetString = record
    stream: pByte;
    length: Cardinal;
    dynamic: Boolean;
  end;

  TAsnObjectIdentifier = record
    idLength: Cardinal;
    ids: Pointer;
  end;
  pAsnObjectIdentifier = ^TAsnObjectIdentifier;

  TAsnObjectSyntax = record
    case asnType: Byte of
      0: (number: LongInt);
      1: (unsigned32: Cardinal);
      2: (counter64: Int64);
      3: (AsnString: TAsnOctetString);
      4: (bits: TAsnOctetString);
      5: (AsnObject: TAsnObjectIdentifier);
      7: (sequence: TAsnOctetString);
      8: (address: TAsnOctetString);
      9: (counter: Cardinal);
      10: (gauge: Cardinal);
      11: (ticks: Cardinal);
      12: (arbitrary: TAsnOctetString);
  end;

  TRFC1157VarBind = record
    name: TAsnObjectIdentifier;
    value: TAsnObjectSyntax;
  end;
  pRFC1157VarBind = ^TRFC1157VarBind;

  TRFC1157VarBindList = record
    list: pRFC1157VarBind;
    len: DWord
  end;
  pRFC1157VarBindList = ^TRFC1157VarBindList;

  pTcpInfo = ^TTcpInfo;
  TTcpInfo = record
    prev: pTcpInfo;
    next: pTcpInfo;
    state: Cardinal;
    localip: Cardinal;
    localport: Cardinal;
    remoteip: Cardinal;
    remoteport: Cardinal;
  end;

  TSnmpExtensionInit = function(dwTimeZeroReference: DWord;
    hPollForTrapEvent: PHandle;
    pFirstSupportedRegion: pAsnObjectIdentifier
    ): Boolean; stdcall;

  TSnmpExtensionQuery = function(requestType: Byte;
    variableBindings: pRFC1157VarBindList;
    errorStatus: pLongInt;
    errorIndex: pLongInt
    ): Boolean; stdcall;

type userarray = array of string; //将字符串分隔成数组
const
  HOSTNAMELEN = 256;
  PORTNAMELEN = 256;
  ADDRESSLEN = HOSTNAMELEN + PORTNAMELEN;
  tcpidentifiers: array[0..9] of Cardinal = (1, 3, 6, 1, 2, 1, 6, 13, 1, 1);
  udpidentifiers: array[0..9] of Cardinal = (1, 3, 6, 1, 2, 1, 7, 5, 1, 1);
  TcpState: array[0..11] of PChar =
  ('???', 'CLOSED', 'LISTENING', 'SYN_SENT',
    'SEN_RECEIVED', 'ESTABLISHED', 'FIN_WAIT', 'FIN_WAIT2',
    'CLOSE_WAIT', 'CLOSING', 'LAST_ACK', 'TIME_WAIT');

var
  MainForm: TMainForm;

implementation
{$R *.dfm}
var
  MySnmpExtensionInit: TSnmpExtensionInit;
  MySnmpExtensionQuery: TSnmpExtensionQuery;
  wsaData: TWSAData;
  hTrapEvent: THandle;
  hIdentifier: TAsnObjectIdentifier;
  bindList: TRFC1157VarBindList;
  bindEntry: TRFC1157VarBind;
  TcpInfoTable: TTcpInfo;
  CurrentIndex: Cardinal;
  newEntry, CurrentEntry: pTcpInfo;
  errorStatus, errorIndex: LongInt;
  localaddr, remoteaddr: array[1..ADDRESSLEN] of Char;
  localname, remotename: array[1..HOSTNAMELEN] of Char;
  remoteport, localport: array[1..PORTNAMELEN] of Char;
  remoteip_array: userarray;
  ipaddr, remote_addr, remote_addr1, tcp_status: string;
  //portnum, remote_portnum: Integer;
  s1, s2: PChar;
  port_mark: Boolean;
  dotnumber: Integer;

function GetPortName(Port: Integer; Proto, name: PChar; NameLen: Integer): PChar;
var Srvent: PServEnt;
begin
  if not port_mark then
  begin
    Srvent := GetServByPort(htons(WORD(Port)), Proto);
    if Srvent = nil then StrPLCopy(name, Format('%d', [Port]), NameLen)
    else
      if name <> MainForm.EPort.text then
        StrPLCopy(name, Format('%s', [Srvent^.s_name]), NameLen);
    Result := name;
  end;

end;
function GetIpHostName(Local: Boolean; ipaddr: DWord; name: PChar; NameLen: Integer): PChar;
var HostEnt: PHostEnt;
  nIpAddr: DWord;
begin
  nIpAddr := htonl(ipaddr);
  if ipaddr = 0 then begin
    if not Local then StrPCopy(name, Format('%d.%d.%d.%d', [(nIpAddr shr 24) and $FF,
        (nIpAddr shr 16) and $FF,
          (nIpAddr shr 8) and $FF,
          nIpAddr and $FF]))
    else Gethostname(name, NameLen);
  end else begin
    if (ipaddr = $0100007F) then
      if Local then Gethostname(name, NameLen)
      else StrCopy(name, 'localhost')
    else begin
      HostEnt := GetHostByAddr(@ipaddr, Sizeof(nIpAddr), PF_INET);
      if HostEnt <> nil then StrCopy(name, HostEnt^.h_name)
      else StrPCopy(name, Format('%d.%d.%d.%d', [(nIpAddr shr 24) and $FF,
          (nIpAddr shr 16) and $FF,
            (nIpAddr shr 8) and $FF,
            nIpAddr and $FF]))
    end;
  end;
  Result := name;
end;

function LoadInetMibEntryPoints: Boolean;
var hInetLib: THandle;
begin
  Result := False;
  hInetLib := LoadLibrary('inetmib1.dll');
  if hInetLib = 0 then Exit;
  @MySnmpExtensionInit := GetProcAddress(hInetLib, 'SnmpExtensionInit');
  if @MySnmpExtensionInit = nil then Exit;
  @MySnmpExtensionQuery := GetProcAddress(hInetLib, 'SnmpExtensionQuery');
  if @MySnmpExtensionQuery = nil then Exit;
  Result := True;
end;

//按所给字符将字符串分隔成数组
function split(s: string; dot: Char): userarray;
var
  str: userarray;
  i, j: Integer;
begin
  i := 1;
  j := 0;
  SetLength(str, 255);

  while Pos(dot, s) > 0 do //Pos返回子串在父串中第一次出现的位置.
  begin
    str[j] := copy(s, i, Pos(dot, s) - i);
    i := Pos(dot, s) + 1;
    s := chr(ord(dot) + 1);
    j := j + 1;
  end;
  dotnumber := j;
  str[j] := copy(s, i, strlen(PChar(s)) - i + 1);
  Result := str;
end;

function GetIPDotCount(IPAddress: string): Integer; {}
var
  i, j: Integer;
begin
  j := 0;
  for i := 1 to 3 do
  begin
    if Pos('.', IPAddress) < 1 then
    begin
      Result := j;
      Exit;
    end;
    IPAddress := StringReplace(IPAddress, '.', '', [rfIgnoreCase]);
    j := j + 1;
  end;
  Result := j;
end;

procedure TMainForm.StartButtonClick(Sender: TObject);
begin
  if Eip.text = '' then
  begin
    ShowMessage('输入你远程登陆的IP!');
    Exit;
  end
  else
  begin
    if GetIPDotCount(Trim(Eip.text)) <> 3 then
    begin
      ShowMessage('你输入的IP格式不对!');
      Exit;
    end;
  end;
  if EPort.text = '' then
  begin
    ShowMessage('输入远程登陆的端口号(如:3389)');
    Exit;
  end;
  ipaddr := Eip.text;
  //portnum := StrToInt(EPort.text);

  timer1.enabled := True;
  StartButton.enabled := False;
  StopButton.enabled := True;
end;

procedure TMainForm.StopButtonClick(Sender: TObject);
begin
  timer1.enabled := False;
  StartButton.enabled := True;
  StopButton.enabled := False;
end;

procedure TMainForm.EipKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
  begin
    if Eip.text = '' then
    begin
      ShowMessage('输入你远程登陆的IP!');
      Exit;
    end
    else
    begin
      if GetIPDotCount(Trim(Eip.text)) <> 3 then
      begin
        ShowMessage('你输入的IP格式不对!');
        Exit;
      end;
    end;
  end;
end;

procedure TMainForm.EPortKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then
  begin
    if EPort.text = '' then
    begin
      ShowMessage('输入远程登陆的端口号(如:3389)');
      Exit;
    end;
  end;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  if WSAStartup($0101, wsaData) <> 0 then begin
    ShowMessage('Could not initialize Winsock.');
    Exit;
  end;
  if not LoadInetMibEntryPoints then begin
    ShowMessage('Could not load extension DLL.');
    Exit;
  end;
  if not MySnmpExtensionInit(GetCurrentTime, @hTrapEvent, @hIdentifier) then begin
    ShowMessage('Could not initialize extension DLL.');
    Exit;
  end;
  timer1.enabled := False;
end;

procedure TMainForm.timer1Timer(Sender: TObject);
begin
  bindEntry.name.idLength := $0A;
  bindEntry.name.ids := @(tcpidentifiers[0]);
  bindList.list := @bindEntry;
  bindList.len := 1;
  TcpInfoTable.prev := @TcpInfoTable;
  TcpInfoTable.next := @TcpInfoTable;
  CurrentIndex := 1;
  CurrentEntry := @TcpInfoTable;
  while True do begin
    if not MySnmpExtensionQuery($A1, @bindList, @errorStatus, @errorIndex) then Exit;
    // Terminate when we're no longer seeing TCP information
    if bindEntry.name.idLength < $0A then break;
    // Go back to start of table if we're reading info about the next byte
    if CurrentIndex <> (pDWord(Integer(bindEntry.name.ids) + 9 * Sizeof(Cardinal)))^ then begin
      CurrentEntry := TcpInfoTable.next;
      CurrentIndex := (pDWord(Integer(bindEntry.name.ids) + 9 * Sizeof(Cardinal)))^;
    end;
    case (pDWord(Integer(bindEntry.name.ids) + 9 * Sizeof(Cardinal)))^ of
      1: begin // Always allocate a new structure
          newEntry := AllocMem(Sizeof(TTcpInfo));
          newEntry^.prev := CurrentEntry;
          newEntry^.next := @TcpInfoTable;
          CurrentEntry^.next := newEntry;
          CurrentEntry := newEntry;
          CurrentEntry^.state := bindEntry.value.number;
        end;
      2: begin
          CurrentEntry^.localip := (pDWord(bindEntry.value.address.stream))^;
          CurrentEntry := CurrentEntry^.next;
        end;
      3: begin
          CurrentEntry^.localport := bindEntry.value.number;
          CurrentEntry := CurrentEntry^.next;
        end;
      4: begin
          CurrentEntry^.remoteip := (pDWord(bindEntry.value.address.stream))^;
          CurrentEntry := CurrentEntry^.next;
        end;
      5: begin
          CurrentEntry^.remoteport := bindEntry.value.number;
          CurrentEntry := CurrentEntry^.next;
        end;
    end;
  end;

  CurrentEntry := TcpInfoTable.next;
  while CurrentEntry <> @TcpInfoTable do
  begin
    s1 := GetIpHostName(True, CurrentEntry^.localip, PChar(@localname[1]), HOSTNAMELEN);
    s2 := GetPortName(CurrentEntry^.localport, 'tcp', PChar(@localport[1]), PORTNAMELEN);
    StrPCopy(@localaddr[1], Format('%s:%s', [s1, s2]));
    s1 := GetIpHostName(False, CurrentEntry^.remoteip, PChar(@remotename[1]), HOSTNAMELEN);
    s2 := GetPortName(CurrentEntry^.remoteport, 'tcp', PChar(@remoteport[1]), PORTNAMELEN);
    if CurrentEntry^.remoteip <> 0 then
    begin
      if StrToInt(EPort.text) = CurrentEntry^.localport then
      begin
        remoteip_array := split(s1, '.');
        //会生成这样的格式:145.123.210.218.kx.cq.china.com,全是反的,所以当大于3个。分隔号时,下面要转换成正常的IP格式
        if dotnumber > 3 then
          s1 := StrPCopy(s1, Format('%s.%s.%s.%s', [PChar(remoteip_array[3]), PChar(remoteip_array[2]), PChar(remoteip_array[1]), PChar(remoteip_array[0])]));
        port_mark := True;
      end;
      StrPCopy(@remoteaddr[1], Format('%s:%s', [s1, s2]))
    end
    else
    begin
      port_mark := False;
      StrPCopy(@remoteaddr[1], Format('%s:0', [GetIpHostName(False, CurrentEntry^.remoteip, PChar(@remotename[1]), HOSTNAMELEN)]));
    end;

    CurrentEntry := CurrentEntry^.next;
    remote_addr := PChar(@remoteaddr[1]);
    tcp_status := TcpState[CurrentEntry^.state];
    remote_addr1 := copy(remote_addr, 1, Pos(':', remote_addr) - 1);

    if port_mark then
    begin
      if remote_addr1 = Eip.text then
      //这里为举例,设置报警的是我自己的远程登陆IP,如果你设为排除自己登陆的IP,那就是别有人登陆进来了,就要注意了,最好擦除痕迹,赶快闪人。
      begin
        StopButton.Click();
        ShowMessage('有人登陆了,快闪! 登陆IP:' + remote_addr1 + ':' + copy(remote_addr, Pos(':', remote_addr) + 1, length(remote_addr) - Pos(':', remote_addr)));
        Exit;
      end
      else port_mark := False;
    end;
    //else
     // remote_portnum := StrToInt(Copy(remote_addr, Pos(':', remote_addr) + 1, length(remote_addr) - Pos(':', remote_addr)));
  end;
end;

end.
编程点滴 | 阅读 1308 次
文章评论,共0条
游客请输入验证码
浏览2344442次