[Delphi] VK, как получить signature?

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by RedFern.89, 14 May 2010.

  1. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    отправлял картинку на стену, решил проснифать запрос. Увидел нечто такое:
    [​IMG]

    в контенте страниц я ничего ненашел.. где ж его искать то? о_О
     
  2. Tigger

    Tigger Elder - Старейшина

    Joined:
    27 Aug 2007
    Messages:
    936
    Likes Received:
    527
    Reputations:
    204
    AJAX?

    Я хз, давно с ВК не работал.
     
  3. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Для снифа заюзай CommView и не парься. Когда всё сделаешь, то поищи в тексте слово signature и выдери из него значение. Затем поищи в тексте это значение. так и найдеш кто и когда его поставил
     
  4. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Этот хеш берется из флешки в которой рисуют граффити. После декомпиляции я понял как он генерируется, а именно :
    1. Весь PNG файл конвертируется в base64
    2. Из получееных данных берется первые 1024 байт и из них создаётся MD5 хэш, который собсна вы и видите.

    З.Ы. Из инета не берите кодер base64, во флешке он специфичный немного.
     
  5. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    а какой же тогда нужен? оО
     
  6. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    при попытке отослать картинку, возникает ошибка: HTTP/1.1 413 Request Entity Too Large
    исользован следующий код:

    Code:
    // ---- Отправка картинки на стену ----
    procedure TidVKClient.PostWallPicture(const to_id, AFile: string);
    var
     Multi : TIdMultiPartFormDataStream;
     Signature : string;
     URL : string;
    begin
     Multi := TIdMultiPartFormDataStream.Create;
    
     Signature := StrTobase64(file_get_contents(AFile), 0);
     Signature := Copy(Signature, 0, 1024);
     ShowMessage(IntToStr(Length(Signature)));
     Signature := GetMD5(Signature);
    
     url := 'http://vkontakte.ru/graffiti.php?to_id=' + to_id + '&group_id=0';
    
    
     Multi.AddFormField('Signature', Signature);
     Multi.AddFile('Filedata', AFile, 'image/png');
     HTTP.Post(url, multi);
    end;
    
     
    #6 RedFern.89, 14 May 2010
    Last edited: 14 May 2010
  7. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    У меня не получилось отослать граффити, мне выдает 400/ Bad Request, что означает что контакт понял что не флешка граффити отправляет.
    Короче, вот что я накалякал после декомпилирования флешки и портирования(с некоторым изменением на делфи), работает 100%
    Code:
    unit EncryptsUnit;
    
    interface
    
    Uses Windows, SysUtils;
    
    type TByteArray = array of Byte;
    
    
    function base64_encodeByteArray(data : TByteArray) : String;
    function base64_decodeToByteArray(data : String) : TByteArray;
    
    function base64_encode(inStr : String) : String;
    function base64_decode(inStr : String) : String;
    implementation
    
    {---------------------------------------------------------------}
    {--BASE64 Encode, Decode----------------------------------------}
    {---------------------------------------------------------------}
    const version : String = '1.0.0';
          BASE64_CHARS : String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    function BASE64_Index(c : Char) : Byte;
    Var ci : Byte;
    Begin
        ci := Ord(c);
        if ci <= $3D then
        Begin
            if (ci <= $39) then
            Begin
                if (ci >= $30) then
                  Result := 53 + (ci - $30) else
                Begin
                    if ci = $2B then Result := 63 else
                      if ci = $2F then Result := 64;
                end;
            end else
              Result := 65;
            Exit;
        end;
        if ci <= $5A then
        Begin
            Result := ci - $40;
            Exit;
        end;
        if ci <= $7A then
        Begin
            Result := 26 + ci - $60;
            Exit;
        end;
        Result := 65;
    end;
    function base64_encode(inStr : String) : String;
    Var ba : TByteArray;
        utf : String;
    Begin
        utf := AnsiToUtf8(inStr);
        SetLength(ba, Length(utf));
        Move(utf[1], ba[0], Length(utf));
        Result := base64_encodeByteArray(ba);
    end;
    function base64_encodeByteArray(data : TByteArray) : String;
    Var inBuf : Array of Byte;
        i, j, k : Cardinal;
        outBuf : array[0..3] of Byte;
        dataPos : Cardinal;
    Begin
        dataPos := 0; Result := '';
        i := 0;
        while (dataPos <= High(data)) do
        Begin
            SetLength(inBuf, 3);
            FillChar(inBuf[0], 3, 0);
            i := 0;
            while ((i < 3) and (dataPos <= High(data))) do
            Begin
                inBuf[i] := data[dataPos];
                i := i + 1;
                Inc(dataPos);
            end;
            outBuf[0] := (inBuf[0] and 252) shr 2;
            outBuf[1] := ((inBuf[0] and 3) shl 4) or (inBuf[1] shr 4);
            outBuf[2] := ((inBuf[1] and 15) shl 2) or (inBuf[2] shr 6);
            outBuf[3] := inBuf[2] and 63;
            while (i < 3) do
            Begin
                outBuf[(i + 1)] := 64;
                i := i + 1;
            end;
            k := 0;
            while (k < 4) do
            Begin
                Result := Result + BASE64_CHARS[outBuf[k]+1];
                k := k + 1;
            end;
        end;
    end;
    
    function base64_decode (inStr : String) : String;
    Var ba : TByteArray;
        utf : String;
    Begin
        ba := base64_decodeToByteArray(inStr);
        SetLength(utf, High(ba)+1);
        Move(ba[0], utf[1], High(ba)+1);
        Result := System.Utf8ToAnsi(utf);
    end;
    
    function base64_decodeToByteArray(data : String) : TByteArray;
    Var
        i, j, k : Cardinal;
        inBuf : Array[0..3] of Byte;
        outBuf : Array[0..2] of Byte;
        _HypArray : TByteArray;
        _HypLength : Cardinal;
    const ReAlignStep = 1024*1024*2; {Эт для того что бы менеджер память по байту не насиловать}
    Begin
        i := 0; _HypLength := 0;
        SetLength(_HypArray, ReAlignStep);
        while (i < Length(data)) do
        Begin
            j := 0;
            while ((j < 4) and (i + j < Length(data))) do
            Begin
                 inBuf[j] := BASE64_Index(data[i + j + 1]) - 1;
                 Inc(j);
            end;
            outBuf[0] := (inBuf[0] shl 2) + ((inBuf[1] and 48) shr 4);
            outBuf[1] := ((inBuf[1] and 15) shl 4) + ((inBuf[2] and 60) shr 2);
            outBuf[2] := ((inBuf[2] and 3) shl 6) + inBuf[3];
            k := 0;
            while (k < 3) do
            Begin
                if (inBuf[(k + 1)] = 64) then
                  Break;
                _HypArray[_HypLength] := outBuf[k];
                Inc(_HypLength);
                if _HypLength > High(_HypArray) then
                    SetLength(_HypArray, High(_HypArray)+ReAlignStep+1);
                Inc(k);
            end;
            Inc(i, 4);
        end;
        SetLength(Result, _HypLength);
        Move(_HypArray[0], Result[0], _HypLength);
    end;
    
    end.
    Модуль MD5 берется стандартный. А вот над TIdMultiPartFormDataStream придётся немного пошаманить(когда след. код разбрешь - поймёшь что).
    Вот код отправки(понять можно)
    Code:
                    SetLength(signature, wallMem.Size);
                    Move(PByte(wallMem.Memory)^, signature[1], wallMem.Size);
                    signature := base64_encode(signature);
                    SetLength(signature, Min(1024, Length(signature)));
                    signature := StrMD5(signature);
                    {Заполняем поля в запрос}
                    wallPost := TIdMultiPartFormDataStream.Create;
                    wallPost.Boundary := '--OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST';
                    wallPost.RequestContentType := sContentType + wallPost.Boundary;
                    wallPost.AddFormField('Signature', LowerCase(signature));
                    Exit;
                    wallPost.AddObject('Filedata', 'image/png', wallMem, 'graffiti.png');
                    wallPost.AddFormField('Upload', 'Submit Query');
    {дальше отправка wallPost}
    
    Примечание - в wallMem : TMemoryStream хранится весь PNG файл.

    Есть ещё трабла с TIdMultiPartFormDataStream в том что флешка немного не так завершает POST данные и это единственное различие, осталось только его переписать и тогда граффити отправится(один раз кстати у меня получилось отправить но потом контакт выдал System Error, что меня немного напугало и я опыты оставил:)).
     
  8. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Кстати в нижнем коде в одном месте Exit стоит, его надо проигнорировать естественно, я его для отладки вставлял) А верхний код кривоват, т.к. не полностью оптимизировал текст после декомпиляции.
     
    #8 Jingo Bo, 15 May 2010
    Last edited: 15 May 2010
  9. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Блин нашёл почему граффити не отправляется, у них тоже переделаный немного MD5, вот придётся весь модуль декомпилировать и портировать. Если удастся, выложу сюда.
     
  10. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    Модули base64 и md5 брал из проги vkontakte picture. Щас все работает:) даже не надо нажимать кнопку отправить на странице, компонент сам парсит все запросы.
     
  11. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Скинь в личку, покопаюсь)