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

📄 uaccesstool.pas

📁 ACCESS 数据库管理工具
💻 PAS
字号:
unit uAccessTool;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComObj;
(*文件是否正在使用*)
const
  ENC_KEY = 'zqs+3#&@lph(g3=22_;2t|q8a/zfc>}s';
function IsFileInUse(sFileName: string): Boolean;
(*取得Access数据库文件密码*)
function GetAccessPwd(sFileName: string; var sPWD: string): Boolean;
(*检查Access数据库文件是否正在使用,如果不在使用,则开始破解文件,否则使用AYYSC.txt文件读取数据库密码*)
function GetAccessPwdExt(sFileName: string; var sPWD: string): Boolean;
(*压缩并加密或修改数据库密码*)
function PackDataBase(sFileName: string; OldPass: string; Pass: string): Boolean;
function PackDataBaseExt(sFileName: string; OldPass: string; Pass: string): Boolean;
implementation

function IsFileInUse(sFileName: string): Boolean;
var
  HFileRes: HFILE;
begin
  result := false;
  if not FileExists(sFileName) then
    Exit;
  HFileRes := CreateFile(pChar(sFileName), GENERIC_READ or GENERIC_WRITE,
    0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  result := (HFileRes = INVALID_HANDLE_VALUE);
  if not result then
    CloseHandle(HFileRes);
end;

function PackDataBaseExt(sFileName: string; OldPass: string; Pass: string): Boolean;
begin
  result := false;
  if IsFileInUse(sFileName) then (*如果文件正在使用,由于压缩数据库要独占*)
    Exit;
  result := PackDataBase(sFileName, OldPass, Pass);
end;

function PackDataBase(sFileName: string; OldPass: string; Pass: string): Boolean;
const
  SConnectionString = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;'
    + 'Jet OLEDB:Database Password=%s;';
var
  sPath, SFile: array[0..254] of Char;
  STempFileName: string;
  JE: OLEVariant;
begin
  //GetTempPath(40, sPath); //取得Windows的Temp路径
  //GetTempFileName(sPath, '~CP', 0, SFile); //取得Temp文件名,Windows将自动建立0字节文件
  //STempFileName := SFile ; //PChar->String
  STempFileName := sFileName + '~CP';
  DeleteFile(pChar(STempFileName)); //删除Windows建立的0字节文件
  try
    JE := CreateOleObject('JRO.JetEngine'); //建立OLE对象,函数结束OLE对象超过作用域自动释放
    OleCheck(JE.CompactDatabase(Format(SConnectionString, [sFileName, OldPass]),
      Format(SConnectionString, [STempFileName, Pass]))); //压缩数据库
    //复制并覆盖源数据库文件,如果复制失败则函数返回假,压缩成功但没有到函数的功能
    //result := CopyFile(pChar(STempFileName), pChar(sFileName), false);
    if IsFileInUse(sFileName) then
      Exit;
    if FileExists(sFileName + 'BK') then
      deleteFile(sFileName + 'BK');
    RenameFile(sFileName, sFileName + 'BK');
    RenameFile(STempFileName, sFileName);
    Result := True;
    //DeleteFile(pChar(STempFileName)); //删除临时文件
  except
    result := false; //压缩失败
  end;
end;

function HexToInt(AHex: string): integer;
begin
  result := StrToInt( '0x'+ AHex );
end;

{*******************************************************************************
名称:EncStr
描述:字符串加密函数
参数:AStr: string  需要加密的字符串
     ENC_KEY: string 密匙
返回:String   加密后得到的字符串
日期:2003-07-31
作者:
修改:
*******************************************************************************}

function EncStr(AStr, ENC_KEY: string): string;
var
  i: integer;
  LongKey: string;
  TmpStr: string;
begin
  result := '';
  for i := 0 to (Length(AStr) div Length(ENC_KEY)) do
    LongKey := LongKey + ENC_KEY;
  for i := 1 to Length(AStr) do
  begin
    TmpStr := IntToHex((Ord(AStr[i]) xor Ord(LongKey[i])), 2);
    result := result + TmpStr;
  end;
end;

{*******************************************************************************
名称:DecStr
描述:字符串解密函数
参数:AStr: string  需要解密的字符串
     ENC_KEY: string 密匙
返回:String   解密后得到的字符串
日期:2003-07-31
作者:
修改:
*******************************************************************************}

function DecStr(AStr, ENC_KEY: string): string;
var
  i: integer;
  LongKey: string;
  TmpStr: string;
begin
  result := '';
  for i := 0 to (Length(AStr) div Length(ENC_KEY)) do
    LongKey := LongKey + ENC_KEY;
  for i := 1 to (Length(AStr) div 2) do
    TmpStr := TmpStr + Chr(HexToInt(Copy(AStr, i * 2 - 1, 2)));
  for i := 1 to Length(TmpStr) do
    result := result + Chr((Ord(TmpStr[i]) xor Ord(LongKey[i])));
end;



function GetAccessPwdExt(sFileName: string; var sPWD: string): Boolean;
var Ms: TStringList;
begin
  Ms := TStringList.Create;
  if IsFileInUse(sFileName) then (*如果文件正在使用,使用AYYSC.txt文件读取数据库密码*)
  begin
    if FileExists(ExtractFilePath(sFileName) + 'AYYSC.TXT') then
    begin
    end
    else
    begin
      Ms.Clear;
      Ms.SaveToFile(ExtractFilePath(sFileName) + 'AYYSC.TXT');
    end;
    Ms.LoadFromFile(ExtractFilePath(sFileName) + 'AYYSC.TXT');
    if Ms.Text = '' then
      sPWD := ''
    else
      sPWD := DecStr(Ms.Strings[0], ENC_KEY);
    result := True;
  end
  else (*如果文件不在使用,读取数据库密码*)
  begin
    result := GetAccessPwd(sFileName, sPWD);
    if result then
    begin
      Ms.Clear;
      Ms.Text := EncStr(sPWD, ENC_KEY);
      Ms.SaveToFile(ExtractFilePath(sFileName) + 'AYYSC.TXT');
    end;
  end;
  freeandnil(Ms);
end;

function GetAccessPwd(sFileName: string; var sPWD: string): Boolean;
const
 //2079-06-05前  [EC37  9CFA  28E6  8A60  7B36  DFB1  1343  B133  795B  7C2A ]
//2079-06-05后  [ED37  9DFA  29E6  8B60  7A36  DEB1  1243  B033  785B  7D2A ]
{ 固定密钥 }
  InhereCode: array[0..9] of Word =
  ($37EC, $FA9C, $E628, $608A, $367B, $B1DF, $4313, $33B1, $5B79, $2A7C);

{  活动密钥 }
  UserCode8: array[0..9] of Word = //89年9月17日前
  ($8B86, $345D, $2EC6, $C613, $E454, $02F5, $8477, $DFCF, $1134, $C592);
  UserCode: array[0..9] of Word = //89年9月17日后
  ($7B86, $C45D, $DEC6, $3613, $1454, $F2F5, $7477, $2FCF, $E134, $3592);

  InCode97: array[0..19] of byte = //Access 97 固定密钥
  ($86, $FB, $EC, $37, $5D, $44, $9C, $FA, $C6, $5E,
    $28, $E6, $13, $00, $00, $00, $00, $00, $00, $00);
var sPassCode: string;
  Stream: TFileStream;
  i, n: integer;
  TP: TSearchRec;
  WTime: TDateTime;
  WSec: DWord;
  M, S: string;
  Buf: array[0..200] of byte;
  Date0: TDateTime;
  Date1: TDateTime;
  Date2: TDateTime;
  DateStr: DWord;
  //PassCode: WideString;
  EncodeArray: array[0..19] of Word;
  ReaderArray: array[0..19] of Word;

const
  XorStr = $823E6C94;
begin
  result := false;
  try
    sPWD := '';
    FindFirst(sFileName, faAnyFile, TP);
    Stream := TFileStream.Create(sFileName, fmOpenReadWrite);
    Stream.Seek($00, 00); Stream.Read(Buf[0], 200);
    if Buf[$14] = 0 then begin
      sPassCode := '';
      Stream.Seek($42, 00); Stream.Read(Buf[0], 20);
      for i := 0 to 19 do
        sPassCode := sPassCode + Chr(Buf[i] xor InCode97[i]);
      sPWD := sPassCode;
      Exit; // 按Access97版本处理
    end;

    Date0 := EncodeDate(1978, 7, 01);
    Date1 := EncodeDate(1989, 9, 17);
    Date2 := EncodeDate(2079, 6, 05);

    Stream.Seek($42, 00); Stream.Read(ReaderArray[0], 40);
    Stream.Seek($75, 00); Stream.Read(DateStr, 4);
    Stream.Free;
    for i := $42 to $42 + 55 do begin
      if i = $72 then M := '-' else M := '';
      S := S + #32 + M + IntToHex(Buf[i], 2);
    end;
    delete(S, 1, 1);
    if (DateStr >= $90000000) and (DateStr < $B0000000) then begin
      WSec := DateStr xor $903E6C94;
      WTime := Date2 + WSec / 8192 * 2;
    end else begin
      WSec := DateStr xor $803E6C94;
      WTime := Date1 + WSec / 8192;
      if WSec and $30000000 <> 0 then begin
        WSec := $40000000 - WSec;
        WTime := Date1 - WSec / 8192 / 2;
      end;
    end;
    if WTime < Date1 then begin
      for i := 0 to 9 do begin
        EncodeArray[i * 2] := (Trunc(WTime) - Trunc(Date0)) xor UserCode[i] xor $F000;
      // Xor $F000 就是“高位取反”
        EncodeArray[i * 2 + 1] := InhereCode[i];
      end;
    end;
    if (WTime >= Date1) and (WTime < Date2) then begin
      for i := 0 to 9 do begin
        EncodeArray[i * 2] := (Trunc(WTime) - Trunc(Date1)) xor UserCode[i];
        EncodeArray[i * 2 + 1] := InhereCode[i];
      end;
    end;
    if WTime >= Date2 then begin
      for i := 0 to 9 do begin
        EncodeArray[i * 2] := (Trunc(WTime) - Trunc(Date1)) xor UserCode[i];
        EncodeArray[i * 2 + 1] := InhereCode[i] xor 1;
      // Xor 1 就是“末位取反”
      end;
    end;
    sPassCode := '';
    for i := 0 to 19 do begin
      n := EncodeArray[i] xor ReaderArray[i];
      if n <> 0 then sPassCode := sPassCode + WideChar(n);
    end;
    sPWD := sPassCode;
    result := True;
  except
  end;
end;
end.

⌨️ 快捷键说明

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