unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Windows, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,dynlibs;
type
fWCCryptAcquireContextA = Function (phProv: Pointer; pszContainer: LPCSTR; pszProvider: LPCSTR; dwProvType: DWORD; dwFlags: DWORD): BOOL; stdcall;
fWCCryptReleaseContext = Function (hProv: Pointer; dwFlags: DWORD): BOOL; stdcall;
fWCCryptGenRandom = Function (hProv: ULONG; dwLen: DWORD; pbBuffer: PBYTE): BOOL; stdcall;
type
TForm1 = class(TForm)
WinCryptGenRandom: TButton;
IntelDrng: TButton;
procedure WinCryptGenRandomClick(Sender: TObject);
procedure IntelDrngClick(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
function TryRdRand(out Value: Cardinal): Boolean;
begin
{$ASMMODE intel}
asm
db $0f
db $c7
db $f1
jc @success
xor eax,eax
ret
@success:
mov [eax],ecx
mov eax,1
end;
end;
procedure TForm1.WinCryptGenRandomClick(Sender: TObject);
var
hProvider: ULONG = 0;
WinCryptHndl: THandle = 0;
WCCryptAcquireContextA: fWCCryptAcquireContextA;
WCCryptReleaseContext: fWCCryptReleaseContext;
WCCryptGenRandom: fWCCryptGenRandom;
res: boolean;
dwLength: DWORD;
bBuffer: array[0..7] of byte;
outr: string;
i: integer;
begin
outr:='';
WinCryptHndl := LoadLibrary('advapi32.dll');
if WinCryptHndl = 0 then exit;
WCCryptAcquireContextA := fWCCryptAcquireContextA(GetProcAddress(WinCryptHndl,'CryptAcquireContextA'));
WCCryptReleaseContext := fWCCryptReleaseContext(GetProcAddress(WinCryptHndl,'CryptReleaseContext'));
WCCryptGenRandom := fWCCryptGenRandom(GetProcAddress(WinCryptHndl,'CryptGenRandom'));
if WCCryptAcquireContextA = nil then exit;
if WCCryptReleaseContext = nil then exit;
if WCCryptGenRandom = nil then exit;
WCCryptAcquireContextA(@hProvider, Nil, Nil, 1, $F0000000);
dwLength:=8;
res:=WCCryptGenRandom(hProvider, dwLength, @bBuffer[0]);
if res then begin
for i:=0 to 7 do
outr:=outr+' '+IntToStr(bBuffer[i]);
showmessage(outr);
end;
WCCryptReleaseContext(@hProvider, 0);
end;
procedure TForm1.IntelDrngClick(Sender: TObject);
var
rnd: Cardinal;
begin
if TryRdRand(rnd) then
showmessage(inttostr(rnd));
end;
end.