1、定位pc微信图片的保存路径。
2、打开文件夹。
3、编写程序查看dat加密图片。(通用函数,感谢编写其中一些函数的网友)
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls,system.strutils, Vcl.ExtCtrls,system.contnrs,vcl.imaging.jpeg;
function CalcMagicCode(const AHeadCode: Word; var AMagicCode: Word; var AFileExt: string): Boolean;// 计算xor的差值以及图片类型
const
C_TypeCodeArr: array of Word = [$4D42, $D8FF, $4947, $5089];
C_TypeExtArr: array of string = ['.bmp', '.jpeg', '.gif', '.png'];
var
I: Integer;
LByte1, LByte2: Byte;
LMagicCode: Word;
begin
Result := False;
LByte1 := Byte(AHeadCode);
LByte2 := HiByte(AHeadCode);
for I := Low(C_TypeCodeArr) to High(C_TypeCodeArr) do
begin
LMagicCode := Byte(C_TypeCodeArr[I]) xor LByte1;
if LMagicCode = (HiByte(C_TypeCodeArr[I]) xor LByte2) then
begin
AMagicCode := LMagicCode;
AFileExt := C_TypeExtArr[I];
Result := True;
end;
end;
end;
procedure MakeFileList(const Path, FileExt: string; AFileList: TStrings);
var
sch: TSearchRec;
tmpPath: string;
begin
if RightStr(Trim(Path), 1) <> '\' then
tmpPath := Trim(Path) + '\'
else
tmpPath := Trim(Path);
if not DirectoryExists(tmpPath) then
Exit;
if FindFirst(tmpPath + '*', faAnyFile, sch) = 0 then
begin
repeat
if ((sch.Name = '.') or (sch.Name = '..')) then
Continue;
if (UpperCase(ExtractFileExt(tmpPath + sch.Name)) = UpperCase(FileExt)) or (FileExt = '.*') then
AFileList.Add(tmpPath + sch.Name);
until FindNext(sch) <> 0;
System.SysUtils.FindClose(sch);
end;
end;
procedure DecryptWXImgFile(const ASrcFile, ASavePath: string);//位异或流文件保存为jpg文件
var
LSrcStream: TMemoryStream;
LDesStream: TFileStream;
LFilesize, LPos: Integer;
LBuffer: Word;
LSrcByte, LDesByte: Byte;
LMagicCode: Word;
LFileExt, LFileName: string;
begin
LSrcStream := TMemoryStream.Create;
try
LSrcStream.LoadFromFile(ASrcFile);
LSrcStream.Position := 0;
LSrcStream.ReadBuffer(LBuffer, 2);
if CalcMagicCode(LBuffer, LMagicCode, LFileExt) then
begin
LFileName := ASavePath + ChangeFileExt(ExtractFileName(ASrcFile), LFileExt);
LDesStream := TFileStream.Create(LFileName, fmCreate);
try
LPos := 0;
LFilesize := LSrcStream.Size;
while LPos < LFilesize do
begin
LSrcStream.Position := LPos;
LSrcStream.ReadBuffer(LSrcByte, 1);
LDesByte := LSrcByte xor LMagicCode;
LDesStream.WriteBuffer(LDesByte, 1);
Inc(LPos);
end;
finally
LDesStream.Free;
end;
end;
finally
LSrcStream.Free;
end;
end;
Function ExtractFileNameNoExt(FileString: String): String;//从完整路径中获得不含后缀名的文件名
Var
FileWithExtString: String;
FileExtString: String;
LenExt: Integer;
LenNameWithExt: Integer;
Begin
FileWithExtString := ExtractFileName(FileString);
LenNameWithExt := Length(FileWithExtString); FileExtString := ExtractFileExt(FileString); LenExt := Length(FileExtString);
If LenExt = 0 Then
Begin
Result := FileWithExtString;
End
Else
Begin
Result := Copy(FileWithExtString,1,(LenNameWithExt-LenExt));
End;
End;
procedure TForm1.SearchFile(path: PChar; fileExt: string; fileList: TStringList);//遍历指定文件夹文件
var
searchRec: TSearchRec;
found: Integer;
tmpStr: string;
curDir: string;
dirs: TQueue;
pszDir: PChar;
begin
dirs := TQueue.Create; //创建目录队列
dirs.Push(path); //将起始搜索路径入队
pszDir := dirs.Pop;
curDir := StrPas(pszDir); //出队
{开始遍历,直至队列为空(即没有目录需要遍历)}
while (True) do
begin
//加上搜索后缀,得到类似'c:\*.*' 、'c:\windows\*.*'的搜索路径
tmpStr := curDir + '\*.*';
//在当前目录查找第一个文件、子目录
found := FindFirst(tmpStr, faAnyFile, searchRec);
while found = 0 do //找到了一个文件或目录后
begin
//如果找到的是个目录
if (searchRec.Attr and faDirectory) <> 0 then
begin
{在搜索非根目录(C:\、D:\)下的子目录时会出现'.','..'的"虚拟目录"
大概是表示上层目录和下层目录吧。。。要过滤掉才可以}
if (searchRec.Name <> '.') and (searchRec.Name <> '..') then
begin
{由于查找到的子目录只有个目录名,所以要添上上层目录的路径
searchRec.Name = 'Windows';
tmpStr:='c:\Windows';
加个断点就一清二楚了
}
tmpStr := curDir + '\' + searchRec.Name;
{将搜索到的目录入队。让它先晾着。
因为TQueue里面的数据只能是指针,所以要把string转换为PChar
同时使用StrNew函数重新申请一个空间存入数据,否则会使已经进
入队列的指针指向不存在或不正确的数据(tmpStr是局部变量)。}
dirs.Push(StrNew(PChar(tmpStr)));
end;
end
else //如果找到的是个文件
begin
{Result记录着搜索到的文件数。可是我是用CreateThread创建线程
来调用函数的,不知道怎么得到这个返回值。。。我不想用全局变量}
//把找到的文件加到Memo控件
if fileExt = '.*' then
fileList.Add(curDir + '\' + searchRec.Name)
else
begin
if SameText(RightStr(curDir + '\' + searchRec.Name, Length(fileExt)), fileExt) then
fileList.Add(curDir + '\' + searchRec.Name);
end;
end;
//查找下一个文件或目录
found := FindNext(searchRec);
end;
{当前目录找到后,如果队列中没有数据,则表示全部找到了;
否则就是还有子目录未查找,取一个出来继续查找。}
if dirs.Count > 0 then
begin
pszDir := dirs.Pop;
curDir := StrPas(pszDir);
StrDispose(pszDir);
end
else
break;
end;
//释放资源
dirs.Free;
FindClose(searchRec);
end;
遍历指定文件夹。
procedure TForm1.Button2Click(Sender: TObject);
var
tmpstr: TStringList;
icount: integer;
begin
try
tmpstr := tstringlist.Create;
SearchFile(PChar(Edit1.Text), edtext.Text, tmpstr);
for icount := 0 to tmpstr.Count - 1 do
begin
listbox1.items.Add(tmpstr.Strings[icount])
end;
finally
tmpstr.Free;
end;
end;
点击选中的 dat解码。
procedure TForm1.ListBox1Click(Sender: TObject);
var
tmpstr:string;
begin
tmpstr:= self.ListBox1.Items[Self.ListBox1.ItemIndex];
DecryptWXImgFile(tmpstr,'D:\weixinchehuizhaopian\output\images\');
Sleep(2000);
if FileExists('D:\weixinchehuizhaopian\output\images\'+ExtractFileNameNoExt(self.ListBox1.Items[Self.ListBox1.ItemIndex])+'.jpg') then
Image1.Picture.LoadFromFile( 'D:\weixinchehuizhaopian\output\images\'+ExtractFileNameNoExt(self.ListBox1.Items[Self.ListBox1.ItemIndex])+'.jpg');
end;
结果。