ive checked the other topic about opera and it worked fine for me with the latest version, i tried porting to delphi but seems pretty hard, thats y im asking for some help
thats the delphi code
Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DCPdes, DCPsha1, DCPmd5;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Run1;
function DecryptWandPass(const Key, Data: String): String;
procedure ProcessWandData(M: TMemoryStream);
end;
var
Form1: TForm1;
FormsList: TList;
AccountList: TList;
M: TMemoryStream;
type
POperaItem = ^TOperaItem;
TOperaItem = record
Site: String;
Params: TStringList;
end;
implementation
{$R *.dfm}
const
opera_magic_wand: array[0..10] of Byte = ($83, $7D, $FC, $0F, $8E, $B3, $E8, $69, $73, $AF, $FF);
procedure OperaDecrypt(key: Pointer; data, dataout: Pointer; len: Integer; magic: Pointer; magic_len: Integer);
var
out_1: array[0..63] of Byte;
out_2: array[0..63] of Byte;
digest_1: array[0..15] of Byte;
digest_2: array[0..15] of Byte;
des_key: array[0..23] of Byte;
md5: TDCP_md5;
Cipher: TDCP_3des;
begin
md5 := TDCP_md5.Create(nil);
md5.Init;
Move(magic^, out_1, magic_len);
Move(key^, out_1[magic_len], 8);
md5.Update(out_1, magic_len+8);
md5.Final(digest_1);
Move(digest_1, des_key, 16);
md5.Init;
Move(digest_1, out_2, 16);
Move(magic^, out_2[16], magic_len);
Move(key^, out_2[16+magic_len], 8);
md5.Update(out_2, 24+magic_len);
md5.Final(digest_2);
md5.Burn;
md5.Free;
Move(digest_2, des_key[16], 8);
Cipher := TDCP_3des.Create(nil);
Cipher.Init(des_key, 192, @digest_2[8]);
Cipher.DecryptCBC(data^, dataout^, len);
Cipher.Burn;
Cipher.Free;
end;
function TForm1.DecryptWandPass(const Key, Data: String): String;
begin
Result := '';
if Length(Key) <> 8 then Exit;
if (Length(Data) < 8) or (Length(Data) mod 8 <> 0) then Exit;
SetLength(Result, Length(Data));
OperaDecrypt(@Key[1], @Data[1], @Result[1], Length(Data), @opera_magic_wand, SizeOf(opera_magic_wand));
SetLength(Result, Length(Result)-Ord(Result[Length(Result)])); // Cut unused chars
Result := WideCharToString(@(Result+#0#0)[1]); // Wide>ANSI
end;
procedure TForm1.ProcessWandData(M: TMemoryStream);
var
P: POperaItem;
function Swap32(Value: LongWord): LongWord; assembler;
asm
bswap eax
end;
function ReadDWord: LongWord;
begin
M.ReadBuffer(Result,4);
Result := Swap32(Result);
end;
function ReadVariable(CLen: LongWord): String;
begin
SetLength(Result, CLen);
M.ReadBuffer(Result[1], CLen);
end;
function ReadSiteHeader: Integer;
var
Key, Data: String;
begin
if ReadDWord <= 4 then // Len
ReadDWord;
// Site name
Key := ReadVariable(ReadDWord);
Data := ReadVariable(ReadDWord);
New(P);
P.Params := TStringList.Create;
P.Site := DecryptWandPass(Key, Data);
FormsList.Add(P);
// Submit button name
if ReadDWord > 0 then begin
ReadVariable(ReadDWord); // Key
ReadVariable(ReadDWord); // Data
end;
ReadVariable(24); // Unknown
Result := ReadDWord; // Number of children
end;
procedure ReadSiteItem;
var
Key, Data, Key2, Data2: String;
begin
ReadVariable(1); // Unknown
if ReadDWord <= 4 then // Len
ReadDWord;
// Input name
Key := ReadVariable(ReadDWord);
showmessage(key);
Data := ReadVariable(ReadDWord);
if ReadDWord <= 4 then // Len
ReadDWord;
// Input value
Key2 := ReadVariable(ReadDWord);
showmessage('Key : ' +key2);
Data2 := ReadVariable(ReadDWord);
if P <> nil then
P.Params.Add(DecryptWandPass(Key, Data) + '=' + DecryptWandPass(Key2, Data2));
end;
var
i, j: Integer;
begin
if M.Size < 16 then begin showmessage('error 1'); Exit; end;
if ReadDWord <> 2 then begin showmessage('err 2'); Exit; end; // Version
if ReadDWord <> 0 then begin showmessage('err 3'); Exit; end; // 1 - crypted, 0 - not crypted
ReadVariable(8); // Unknown
P := nil;
// Header
ReadDWord; // Len
ReadVariable(ReadDWord); // Key
ReadVariable(ReadDWord); // Data
ReadVariable(37); // Unknown
// Data types?
for i := 1 to ReadDWord do begin
ReadVariable(1); // Unknown
ReadVariable(4); // Len
ReadVariable(ReadDWord); // Key
ReadVariable(ReadDWord); // Data
ReadVariable(8); // Unknown
end;
// LogProfile
ReadVariable(4); // Len
ReadVariable(ReadDWord); // Key
ReadVariable(ReadDWord); // Data
ReadVariable(1); // Boolean
// Sites
for i := 1 to ReadDWord do
for j := 1 to ReadSiteHeader do
ReadSiteItem;
end;
procedure TForm1.Run1;
var
result : string;
begin
M := TMemoryStream.Create;
M.LoadFromFile('wand.dat');
Memo1.Lines.LoadFromStream(M);
M.Position:=0;
ProcessWandData(M);
M.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Run1;
end;
end.
the problem lies in this line
if ReadDWord <> 2 then begin showmessage('err 2'); Exit; end; // Version
help?????
Edit : Opera wand is located at
C:\Documents and Settings\<Username>\Application Data\Opera\Opera\profile (Under XP)