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