Просмотр полной версии : [Delphi] VK, как получить signature?
RedFern.89
14.05.2010, 15:43
отправлял картинку на стену, решил проснифать запрос. Увидел нечто такое:
http://savepic.ru/1131312.jpg
в контенте страниц я ничего ненашел.. где ж его искать то? о_О
AJAX?
Я хз, давно с ВК не работал.
Для снифа заюзай CommView и не парься. Когда всё сделаешь, то поищи в тексте слово signature и выдери из него значение. Затем поищи в тексте это значение. так и найдеш кто и когда его поставил
Jingo Bo
14.05.2010, 18:48
Этот хеш берется из флешки в которой рисуют граффити. После декомпиляции я понял как он генерируется, а именно :
1. Весь PNG файл конвертируется в base64
2. Из получееных данных берется первые 1024 байт и из них создаётся MD5 хэш, который собсна вы и видите.
З.Ы. Из инета не берите кодер base64, во флешке он специфичный немного.
RedFern.89
14.05.2010, 21:43
а какой же тогда нужен? оО
RedFern.89
14.05.2010, 21:56
при попытке отослать картинку, возникает ошибка: HTTP/1.1 413 Request Entity Too Large
исользован следующий код:
// ---- Отправка картинки на стену ----
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;
Jingo Bo
15.05.2010, 00:25
У меня не получилось отослать граффити, мне выдает 400/ Bad Request, что означает что контакт понял что не флешка граффити отправляет.
Короче, вот что я накалякал после декомпилирования флешки и портирования(с некоторым изменением на делфи), работает 100%
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 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw xyz0123456789+/=';
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 придётся немного пошаманить(когда след. код разбрешь - поймёшь что).
Вот код отправки(понять можно)
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, что меня немного напугало и я опыты оставил:)).
Jingo Bo
15.05.2010, 00:28
Кстати в нижнем коде в одном месте Exit стоит, его надо проигнорировать естественно, я его для отладки вставлял) А верхний код кривоват, т.к. не полностью оптимизировал текст после декомпиляции.
Jingo Bo
15.05.2010, 13:30
Блин нашёл почему граффити не отправляется, у них тоже переделаный немного MD5, вот придётся весь модуль декомпилировать и портировать. Если удастся, выложу сюда.
RedFern.89
15.05.2010, 14:07
Модули base64 и md5 брал из проги vkontakte picture. Щас все работает:) даже не надо нажимать кнопку отправить на странице, компонент сам парсит все запросы.
Jingo Bo
15.05.2010, 15:40
Модули base64 и md5 брал из проги vkontakte picture. Щас все работает даже не надо нажимать кнопку отправить на странице, компонент сам парсит все запросы.
Скинь в личку, покопаюсь)
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot