function GetPasswordFromAccess(AFileName: string): string;
var
  myms: TMemoryStream;
  b: array of Byte;
  a: array[0..33] of Byte;
  mysFileName, mysPwd: string;
  I: Integer;
  ver: Byte;
  mybyte1, mybyte2: byte;
const
  ar_key: array[0..31] of Integer=($39,$59,$EC,$37,$E2,$e6,$9C,$FA,$79,$FC,$28,$E6,$AC,$14,$8A,$60,$EB,$36,$7B,$36,$4A,
  $D0,$DF,$B1,$C8,$56,$13,$43,$70,$0D,$b1,$33);
  flagbyte1 = $8b;
  flagbyte2 = $C3;
begin
  if not FileExists(AFileName) then Exit;
  mysFileName := AFileName;
  myms := TMemoryStream.Create;
  try
    myms.LoadFromFile(mysFileName);
    myms.Position := 0;
    myms.Seek($14, 0);
    myms.Read(ver, SizeOf(Byte)); //here we get access version ,1 is 2000 and 0 is97
    SetLength(b, 2);
    myms.Seek($42, 0);
    myms.Read(a[0], sizeof(a));
    mybyte1 := a[32] xor flagbyte1;
    mybyte2 := a[33] xor flagbyte2;
    for I := 0 to 15 do
    begin
      b[0] := ar_key[i*2] xor a[i*2];
      b[1] := ar_key[i*2+1] xor a[i*2+1];
      if (i mod 2 = 0) and (ver = 1) then
      begin
        b[0] := b[0] xor mybyte1;
        b[1] := b[1] xor mybyte2;
      end;
      mysPwd := mysPwd + Char(b[0]+b[1]);
    end;
    Result := mysPwd;
  finally
    SetLength(b, 0);
    myms.Free;
  end;
end;

04-28 11:35