分类 编程 下的文章

Delphi 获取系统版本{2K~10}

Function RtlGetVersion(Var lpOsInfo :TOSVersionInfoExW):DWORD; Stdcall; External 'ntdll.dll';
//GetVersionEx 在Win8以后的的版本会以兼容模式来获取结果导致获取到的NT内核版本都是6.2所以这里用RtlGetVersion
Function GetOs():Byte;
  Const
    SM_SERVERR2 = 89;
Var
  OSINFO: TOSVersionInfoExW;
begin
  Result := 255;
  OSINFO.dwOSVersionInfoSize := SizeOf(TOSVersionInfoExW);
  if RtlGetVersion(OSINFO) = 0 then
  begin
    if (OSINFO.dwMajorVersion = 5) and (OSINFO.dwMinorVersion = 0) then
      Result := 1//'Windows 2000'
    else if (OSINFO.dwMajorVersion = 5) and (OSINFO.dwMinorVersion = 1) then
      Result := 2//'Windows XP'
    else if (OSINFO.dwMajorVersion = 5) and (OSINFO.dwMinorVersion = 2) and (GetSystemMetrics(SM_SERVERR2) = 0) then
      Result := 3//'Windows Server 2003'
    else if (OSINFO.dwMajorVersion = 5) and (OSINFO.dwMinorVersion = 2) and (GetSystemMetrics(SM_SERVERR2) <> 0) then
      Result := 4//'Windows Server 2003 R2'
    else if (OSINFO.dwMajorVersion = 6) and (OSINFO.dwMinorVersion = 0) and (OSINFO.wProductType = VER_NT_WORKSTATION) then
      Result := 5//'Windows Vista'
    else if (OSINFO.dwMajorVersion = 6) and (OSINFO.dwMinorVersion = 0) and (OSINFO.wProductType <> VER_NT_WORKSTATION) then
      Result := 6//'Windows Server 2008'
    else if (OSINFO.dwMajorVersion = 6) and (OSINFO.dwMinorVersion = 1) and (OSINFO.wProductType <> VER_NT_WORKSTATION) then
      Result := 7//'Windows Server 2008 R2'
    else if (OSINFO.dwMajorVersion = 6) and (OSINFO.dwMinorVersion = 1) and (OSINFO.wProductType = VER_NT_WORKSTATION) then
      Result := 8//'Windows 7'
    else if (OSINFO.dwMajorVersion = 6) and (OSINFO.dwMinorVersion = 2) and (OSINFO.wProductType = VER_NT_WORKSTATION) then
      Result := 9//'Windows 8'
    else if (OSINFO.dwMajorVersion = 6) and (OSINFO.dwMinorVersion = 2) and (OSINFO.wProductType <> VER_NT_WORKSTATION) then
      Result := 10//'Windows Server 2012'
    else if (OSINFO.dwMajorVersion = 6) and (OSINFO.dwMinorVersion = 3) and (OSINFO.wProductType = VER_NT_WORKSTATION) then
      Result := 11//'Windows 8.1'
    else if (OSINFO.dwMajorVersion = 6) and (OSINFO.dwMinorVersion = 3) and (OSINFO.wProductType <> VER_NT_WORKSTATION) then
      Result := 12//'Windows Server 2012 R2'
    else if (OSINFO.dwMajorVersion = 10) and (OSINFO.dwMinorVersion = 0) and (OSINFO.wProductType = VER_NT_WORKSTATION) then
      Result := 13//'Windows 10'
    else if (OSINFO.dwMajorVersion = 10) and (OSINFO.dwMinorVersion = 0) and (OSINFO.wProductType <> VER_NT_WORKSTATION) then
      Result := 14//'Windows Server 2016 Technical Preview'
    else
      Result := 255;
  end;
end;


DLL与EXE之间的恩爱情仇

program Bin;
{$APPTYPE CONSOLE}

uses
  Windows;
  
Function RunApi(lpPorc :Pointer):Integer; Stdcall; external 'Test.Dll' name 'RunApi';

Var
  lpPorc :Pointer;
begin
  lpPorc := @MessageBoxW;// 这里可以自己动态加载需要的API
  RunApi(lpPorc);//传入API的内存地址
end.



library DLL;

Uses
  Windows;

Type
  TMyMessageBox = function(hWnd: HWND; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall;

Function RunApi(lpPorc :Pointer):Integer;
Var
  pMessageBox :TMyMessageBox;
begin
  Result := -1;
  if Assigned(lpPorc) Then 
  begin
    pMessageBox := lpPorc;
    pMessageBox(0, 'Test', 'hahaha', 0);  //调用EXE传进来的API
    Result := 1;
  end;
end;

Exports
  RunApi;

begin
end.


通过以上代码可以在DLL中调用EXE中的API或函数

而DLL里只需要定义就行了

比如某Rat的EXE和DLL都带有通讯库这样会造成内存消耗的加大

以及DLL在动态传输时体积的增大

如果将EXE中的通讯库直接传入DLL然后由DLL直接调用进行操作体积可以减小很多


Delphi Socket Connect Timeout 套字节链接超时设置

Function ConnectTimeOut(pAddr:PAnsiChar; uPort:Word; uTimeOut:Byte = 3):TSocket;
Var
  hSocket   :TSocket;
  Addr      :TSockAddrIn;
  uFalg     :u_long;
  WriteDset :TFDset;
  ExceptDset:TFDset;
  TimeVal   :TTimeVal;
begin
  Result               := INVALID_SOCKET;
  Addr.sin_family      := AF_INET;
  Addr.sin_port        := htons(uPort);
  Addr.sin_addr.s_addr := inet_addr(pAddr);
  if (Addr.sin_addr.s_addr = SOCKET_ERROR) then Exit;
  hSocket  := Winapi.WinSock.socket(AF_INET, SOCK_STREAM, 0);
  if hSocket = INVALID_SOCKET then Exit;
  
  uFalg  := 1;
  if ioctlsocket(hSocket, FIONBIO, uFalg) = NO_ERROR then 
  begin
    connect(hSocket, Addr, SizeOf(TSockAddrIn));
    uFalg := 0;
    if ioctlsocket(hSocket, FIONBIO, uFalg) = NO_ERROR then
    begin
      FD_ZERO(WriteDset);
      FD_ZERO(ExceptDset);
      FD_SET(hSocket, WriteDset);
      FD_SET(hSocket, ExceptDset);
      TimeVal.tv_sec  := uTimeOut;
      TimeVal.tv_usec := 0;
      select(0, nil, @WriteDset, @ExceptDset, @TimeVal);
      if (FD_ISSET(hSocket, WriteDset)) then
        Result := hSocket; 
        Exit;
    end;  
  end;  
  shutdown(hSocket, SD_BOTH);
  closesocket(hSocket); 
end;

Delphi下的纯Pascal的十六进制转十进制

Function StrLenA(Str :PAnsiChar):Integer;
Begin
  Result := 0;
  while Str[Result] <> #$0 do Inc(Result)
End;  

Function Char2Int(A :AnsiChar):Integer;
Begin   //字符转整数
  Result := -1;
  if (Byte(A) > 47) And (Byte(A) < 58) Then
  Begin   //0-9
    Result := Byte(A) - 48;
  End Else if (Byte(A) > 64) And (Byte(A) < 71) then
  Begin   //A-F
    Result := Byte(A) - 55;
  End Else if (Byte(A) > 96) And (Byte(A) < 103) then
  Begin  //a-f
    Result := Byte(A) - 87;
  End;               
End;

Function HexPower(X, Y:Integer):UInt64;
Var     //次方计算
  I :Integer;
Begin
  Result := X;
  for I := 1 to Y do
  Begin
    Result := Result * 16;
  End;
End;  

Function Hex2Int(HEX :PAnsiChar):UInt64;
Var   //十六进制字符串转整数
  iLen :Integer;
  I    :Integer;
Begin
  iLen  := StrLenA(HEX);
  Result:= 0;
  for I:= 0 to iLen-2 do
  Begin
    Result := Result + HexPower(Char2Int(HEX[I]), iLen - (I + 1)); 
  End;  
  Result := Result + Char2Int(HEX[iLen-1]);
End;




代码实例:

Var
  HEX  :Array [0..16] Of AnsiChar;
begin
  HEX  := '14f03'#$0;  
  Writeln(Hex2Int(@HEX));

  HEX  := 'FFFFFFFF'#$0;  
  Writeln(Hex2Int(@HEX));
  
  HEX  := 'FFFFFFFFFFFFFFFF'#$0;  
  Writeln(Hex2Int(@HEX));
  Readln;  
End.



运行结果:


Untitled.jpg/