这个也是好奇msn的协议还是2011年的时候写的, 就在网上找啊找啊, 可惜要不是不能用就是C++代码还有就是不完整, 到最后我也没弄成功,只到了下面这步就挂掉了......
登录成功
<=SBS 0 null
<=MSG Hotmail Hotmail 1261
=>BLP 8 BL
<=BLP 8 BL
=>ADL 9 11 <ml l="1"/>
断开与->64.4.44.92
现在公布出来吧, 代码写得不是很好, 有三个函数是改自某位老大的,不记得地方了,太久没碰了, 现在能不能用我都不知道了
- unit MSNClass;
-
- interface
-
- uses
- Windows, Classes, SysUtils, IdTCPConnection, IdTCPClient,
- xmldom, XMLIntf, msxmldom, XMLDoc, ComObj, Variants, wcrypt2, Forms, CnDebug;
-
- type
- tagMSGUSRKEY = record
- uStructHeaderSize: ULONG;
- uCryptMode: ULONG;
- uCipherType: ULONG;
- uHashType: ULONG;
- uIVLen: ULONG;
- uHashLen: ULONG;
- uCipherLen: ULONG;
- aIVBytes: array[0..07] of Byte;
- aHashBytes: array[0..19] of Byte;
- aCipherBytes: array[0..71] of Byte;
- end;
- TMSGUSERKEY = tagMSGUSRKEY;
- PMSGUSERKEY = ^TMSGUSERKEY;
- const
- STDKEYHDRSIZE = 12;
- cKeyStdHeader: array[0..11] of Byte = ($08, $02, $00, $00, $03, $66, $00, $00,
- $18, $00, $00, $00);
-
- type
- TMSN = class(TObject)
- private
-
-
-
- FServer: string;
- FPort: Integer;
-
- FStream: TMemoryStream;
- FPassport_url: string;
- FProtocol: string;
- FBuildver: string;
- Fprod_key: string;
- Fprod_id: string;
-
-
- Fpassport_policy: string;
-
-
-
-
- function HtmlSpecialChars(s: string): string;
-
- public
- Fuser: string;
- Fpassword: string;
- FBinarySecurityToken: string;
- FBinarySecret: string;
-
- constructor Create(UserName, PassWord: string);
- destructor Destroy; override;
-
- function http_Get(url: PAnsiChar): string;
- function http_Post(url, Param: PAnsiChar): string;
- function http_Post2(url, Param: PAnsiChar): Boolean;
- function PostXMLFile(UserName, Password: string): string;
- function GetXMLFile: Boolean;
- function Get_passport_ticket: Boolean;
- function GetSSOKey(Nonce: string): string;
- function GenerateLoginBlob(key: string; Challenge: string): string;
- end;
-
- function CryptStringToBinary(pszString: PChar; cchString: DWORD; dwFlags: DWORD;
- pbBinary: PByte; pcbBinary: PDWORD; pdwSkip: PDWORD; pdwFlags: PDWORD): BOOL;
- stdcall; external CRYPT32 Name ‘CryptStringToBinaryA‘;
- function CryptDuplicateKey(hKey: HCRYPTKEY; pdwReserved: PDWORD; dwFlags: DWORD;
- phKey: PHCRYPTKEY): BOOL; stdcall; external ADVAPI32 Name ‘CryptDuplicateKey‘;
- function CryptBinaryToString(pbBinary: PByte; cbBinary: DWORD; dwFlags: DWORD;
- pszString: PChar; pcchString: PDWORD): BOOL; stdcall; external CRYPT32 Name
- ‘CryptBinaryToStringA‘;
-
-
- implementation
-
- constructor TMSN.Create(UserName, PassWord: string);
- begin
- CoInitializeEx(nil, 2);
- Fuser := UserName;
- Fpassword := PassWord;
-
- FServer := ‘messenger.hotmail.com‘;
- FPort := 1863;
- FPassport_url := ‘https://login.live.com/RST.srf‘;
- FProtocol := ‘MSNP15‘;
- FBuildver := ‘8.1.0178‘;
- Fprod_key := ‘PK}_A_0N_K%O?A9S‘;
- Fprod_id := ‘PROD0114ES4Z%Q5W‘;
- Fpassport_policy := ‘MBI_KEY_OLD‘;
- FStream := TMemoryStream.Create;
-
-
- end;
-
- destructor TMSN.Destroy;
- begin
- FStream.Free;
-
-
-
-
- inherited;
- end;
-
-
- function TMSN.HtmlSpecialChars(s: string): string;
- var
- TEMP: string;
- begin
- TEMP := StringReplace(s, ‘&‘, ‘&‘, [rfReplaceAll]);
- TEMP := StringReplace(TEMP, ‘"‘, ‘"‘, [rfReplaceAll]);
- TEMP := StringReplace(TEMP, ‘‘‘‘, ‘‘‘, [rfReplaceAll]);
- TEMP := StringReplace(TEMP, ‘<‘, ‘<‘, [rfReplaceAll]);
- TEMP := StringReplace(TEMP, ‘>‘, ‘>‘, [rfReplaceAll]);
- Result := TEMP;
- end;
-
- function TMSN.http_Post(url, Param: PAnsiChar): string;
- var
- PostVar: Variant;
- begin
- Result := ‘‘;
- try
- PostVar := CreateOleObject(‘MSXML2.XMLHTTP‘);
- try
- PostVar.Open(‘POST‘, AnsiString(url), False);
- PostVar.SetRequestHeader(‘Accept‘, ‘text/html, */*‘);
- PostVar.SetRequestHeader(‘User-Agent‘,
- ‘Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)‘);
- PostVar.SetRequestHeader(‘Accept-Language‘, ‘zh-cn‘);
- PostVar.SetRequestHeader(‘Content-Type‘, ‘text/html‘);
- PostVar.SetRequestHeader(‘Connection‘, ‘keep-Alive‘);
- PostVar.Send(AnsiString(Param));
-
-
-
- Result := AnsiString(PostVar.ResponseText);
- finally
- PostVar := Unassigned;
- end;
- except
- on E: Exception do
- Result := E.message;
- end;
- end;
-
- function TMSN.http_Post2(url, Param: PAnsiChar): Boolean;
- var
- PostVar: Variant;
- s: PChar;
- begin
- Result := False;
- try
- PostVar := CreateOleObject(‘MSXML2.XMLHTTP‘);
- FStream.Clear;
- try
- PostVar.Open(‘POST‘, AnsiString(url), False);
- PostVar.SetRequestHeader(‘Accept‘, ‘text/html, */*‘);
- PostVar.SetRequestHeader(‘User-Agent‘,
- ‘Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)‘);
- PostVar.SetRequestHeader(‘Accept-Language‘, ‘zh-cn‘);
- PostVar.SetRequestHeader(‘Content-Type‘, ‘text/html‘);
- PostVar.SetRequestHeader(‘Connection‘, ‘keep-Alive‘);
- PostVar.Send(AnsiString(Param));
- s := PChar(AnsiString(PostVar.ResponseText));
- FStream.Seek(0, soBeginning);
- FStream.Write(s^, Length(s));
-
- Result := True;
- finally
- PostVar := Unassigned;
- end;
- except
- on E: Exception do
- OutputDebugString(PChar(E.Message));
-
- end;
- end;
-
- function TMSN.http_Get(url: PAnsiChar): string;
- var
- GetVar: Variant;
- begin
- Result := ‘‘;
- try
- GetVar := CreateOleObject(‘MSXML2.XMLHTTP‘);
- try
- GetVar.Open(‘GET‘, AnsiString(url), False);
- GetVar.SetRequestHeader(‘Accept‘, ‘text/html, */*‘);
- GetVar.SetRequestHeader(‘User-Agent‘,
- ‘Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)‘);
- GetVar.SetRequestHeader(‘Accept-Language‘, ‘zh-cn‘);
- GetVar.SetRequestHeader(‘Content-Type‘, ‘text/html‘);
- GetVar.SetRequestHeader(‘Connection‘, ‘keep-Alive‘);
- GetVar.Send(‘‘);
-
-
-
- Result := AnsiString(GetVar.ResponseText);
- finally
- GetVar := Unassigned;
- end;
- except
-
- end;
- end;
-
- function TMSN.PostXMLFile(UserName, Password: string): string;
- var
- Param: TStringList;
- begin
- Result := ‘‘;
- Param := TStringList.Create;
- Param.Clear;
- try
- Param.Add(‘<?xml version="1.0" encoding="UTF-8" ?> ‘);
- Param.Add(‘<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" ‘);
- Param.Add(‘xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" ‘);
- Param.Add(‘xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wssc="http://schemas.xmlsoap.org/ws/2004/04/sc" xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust">‘);
- Param.Add(‘<Header>‘);
- Param.Add(‘<ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="PPAuthInfo">‘);
- Param.Add(‘ <ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp> ‘);
- Param.Add(‘ <ps:BinaryVersion>4</ps:BinaryVersion> ‘);
- Param.Add(‘ <ps:UIVersion>1</ps:UIVersion> ‘);
- Param.Add(‘ <ps:Cookies /> ‘);
- Param.Add(‘ <ps:RequestParams>AQAAAAIAAABsYwQAAAAyMDUy</ps:RequestParams> ‘);
- Param.Add(‘ </ps:AuthInfo>‘);
- Param.Add(‘<wsse:Security>‘);
- Param.Add(‘<wsse:UsernameToken Id="user">‘);
- Param.Add(‘ <wsse:Username>‘ + UserName + ‘</wsse:Username> ‘);
- Param.Add(‘ <wsse:Password>‘ + Password + ‘</wsse:Password> ‘);
- Param.Add(‘ </wsse:UsernameToken>‘);
- Param.Add(‘ </wsse:Security>‘);
- Param.Add(‘ </Header>‘);
- Param.Add(‘<Body>‘);
- Param.Add(‘<ps:RequestMultipleSecurityTokens xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="RSTS">‘);
- Param.Add(‘<wst:RequestSecurityToken Id="RST0">‘);
- Param.Add(‘ <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType> ‘);
- Param.Add(‘<wsp:AppliesTo>‘);
- Param.Add(‘<wsa:EndpointReference>‘);
- Param.Add(‘ <wsa:Address>http://Passport.NET/tb</wsa:Address> ‘);
- Param.Add(‘ </wsa:EndpointReference>‘);
- Param.Add(‘ </wsp:AppliesTo>‘);
- Param.Add(‘ </wst:RequestSecurityToken>‘);
- Param.Add(‘<wst:RequestSecurityToken Id="RST1">‘);
- Param.Add(‘ <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType> ‘);
- Param.Add(‘<wsp:AppliesTo>‘);
- Param.Add(‘<wsa:EndpointReference>‘);
- Param.Add(‘ <wsa:Address>messengerclear.live.com</wsa:Address> ‘);
- Param.Add(‘ </wsa:EndpointReference>‘);
- Param.Add(‘ </wsp:AppliesTo>‘);
- Param.Add(‘ <wsse:PolicyReference URI="MBI_KEY_OLD" /> ‘);
- Param.Add(‘ </wst:RequestSecurityToken>‘);
- Param.Add(‘<wst:RequestSecurityToken Id="RST2">‘);
- Param.Add(‘ <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType> ‘);
- Param.Add(‘<wsp:AppliesTo>‘);
- Param.Add(‘<wsa:EndpointReference>‘);
- Param.Add(‘ <wsa:Address>messenger.msn.com</wsa:Address> ‘);
- Param.Add(‘ </wsa:EndpointReference>‘);
- Param.Add(‘ </wsp:AppliesTo>‘);
- Param.Add(‘ <wsse:PolicyReference URI="?id=507" /> ‘);
- Param.Add(‘ </wst:RequestSecurityToken>‘);
- Param.Add(‘<wst:RequestSecurityToken Id="RST3">‘);
- Param.Add(‘ <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType> ‘);
- Param.Add(‘<wsp:AppliesTo>‘);
- Param.Add(‘<wsa:EndpointReference>‘);
- Param.Add(‘ <wsa:Address>contacts.msn.com</wsa:Address> ‘);
- Param.Add(‘ </wsa:EndpointReference>‘);
- Param.Add(‘ </wsp:AppliesTo>‘);
- Param.Add(‘ <wsse:PolicyReference URI="MBI" /> ‘);
- Param.Add(‘ </wst:RequestSecurityToken>‘);
- Param.Add(‘<wst:RequestSecurityToken Id="RST4">‘);
- Param.Add(‘ <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType> ‘);
- Param.Add(‘<wsp:AppliesTo>‘);
- Param.Add(‘<wsa:EndpointReference>‘);
- Param.Add(‘ <wsa:Address>messengersecure.live.com</wsa:Address> ‘);
- Param.Add(‘ </wsa:EndpointReference>‘);
- Param.Add(‘ </wsp:AppliesTo>‘);
- Param.Add(‘ <wsse:PolicyReference URI="MBI_SSL" /> ‘);
- Param.Add(‘ </wst:RequestSecurityToken>‘);
- Param.Add(‘<wst:RequestSecurityToken Id="RST5">‘);
- Param.Add(‘ <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType> ‘);
- Param.Add(‘<wsp:AppliesTo>‘);
- Param.Add(‘<wsa:EndpointReference>‘);
- Param.Add(‘ <wsa:Address>spaces.live.com</wsa:Address> ‘);
- Param.Add(‘ </wsa:EndpointReference>‘);
- Param.Add(‘ </wsp:AppliesTo>‘);
- Param.Add(‘ <wsse:PolicyReference URI="MBI" /> ‘);
- Param.Add(‘ </wst:RequestSecurityToken>‘);
- Param.Add(‘<wst:RequestSecurityToken Id="RST6">‘);
- Param.Add(‘ <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType> ‘);
- Param.Add(‘<wsp:AppliesTo>‘);
- Param.Add(‘<wsa:EndpointReference>‘);
- Param.Add(‘ <wsa:Address>storage.msn.com</wsa:Address> ‘);
- Param.Add(‘ </wsa:EndpointReference>‘);
- Param.Add(‘ </wsp:AppliesTo>‘);
- Param.Add(‘ <wsse:PolicyReference URI="MBI" /> ‘);
- Param.Add(‘ </wst:RequestSecurityToken>‘);
- Param.Add(‘ </ps:RequestMultipleSecurityTokens>‘);
- Param.Add(‘ </Body>‘);
- Param.Add(‘ </Envelope>‘);
-
-
- Result := Param.Text;
- finally
- Param.Free;
- end;
- end;
-
-
- function TMSN.GetXMLFile: Boolean;
- var
- XML: TXMLDocument;
- Root, Parent, Child, SChild, BinarySecurityTokenNode, BinarySecretNode:
- IXMLNode;
- begin
- Result := False;
- if FStream.Size > 0 then
- begin
- XML := TXMLDocument.Create(Application);
- try
- try
- FStream.SaveToFile(‘test1.xml‘);
- XML.LoadFromStream(FStream);
-
- XML.Active := True;
- Root := XML.DocumentElement;
- Parent := Root.ChildNodes.First;
- while Parent <> nil do
- begin
- if Parent.NodeName = ‘S:Body‘ then
- begin
- Child := Parent.ChildNodes.First;
-
- if Child <> nil then
- begin
- SChild := Child.ChildNodes.First;
- SChild := SChild.NextSibling;
- while SChild <> nil do
- begin
- if SChild.NodeName = ‘wst:RequestSecurityTokenResponse‘ then
- begin
- BinarySecurityTokenNode :=
- SChild.ChildNodes.FindNode(‘wst:RequestedSecurityToken‘);
-
- BinarySecretNode :=
- SChild.ChildNodes.FindNode(‘wst:RequestedProofToken‘);
- if (BinarySecurityTokenNode <> nil) and (BinarySecretNode <>
- nil) then
- begin
- FBinarySecurityToken :=
- BinarySecurityTokenNode.ChildNodes.First.NodeValue;
- FBinarySecret :=
- BinarySecretNode.ChildNodes.First.NodeValue;
- Result := True;
- end;
-
- Break;
- end;
- SChild := SChild.NextSibling;
- end;
- end;
- Break;
- end;
- Parent := Parent.NextSibling;
- end;
-
- XML.Active := False;
- finally
- XML.Free;
- end;
- except
-
- end;
- end;
- end;
-
- function TMSN.Get_passport_ticket: Boolean;
- var
- user, password, passport_url: string;
- begin
- Result := False;
- user := Fuser;
- password := HtmlSpecialChars(Fpassword);
- passport_url := FPassport_url;
- try
- Result :=
- http_Post2(PChar(passport_url), PChar(PostXMLFile(user, password)));
- except
- on E: Exception do
- OutputDebugString(PChar(E.Message));
- end;
- end;
-
-
- function TMSN.GetSSOKey(Nonce: string): string;
- begin
- Result := GenerateLoginBlob(FBinarySecret, Nonce);
- end;
-
-
- function HMACHash(hProvider: HCRYPTPROV; hKey: HCRYPTKEY; HashAlgId: ALG_ID;
- pBytesOut: Pointer; dwLengthOut: DWORD; pBytesIn1: PByte; dwLengthIn1: DWORD;
- pBytesIn2: PByte; dwLengthIn2: DWORD): Boolean;
- var
- hHash: HCRYPTHASH;
- hmcinfo: HMAC_INFO;
- dwHashSize, dwParamSize: DWORD;
- begin
- Result := False;
-
- if CryptCreateHash(hProvider, CALG_HMAC, hKey, 0, @hHash) then
- begin
- ZeroMemory(@hmcinfo, sizeof(HMAC_INFO));
- hmcinfo.HashAlgid := HashAlgId;
- CryptSetHashParam(hHash, HP_HMAC_INFO, PBYTE(@hmcinfo), 0);
- if CryptHashData(hHash, pBytesIn1, dwLengthIn1, 0) then
- begin
- if (dwLengthIn2 <> 0) and (pBytesIn2 <> nil) then
- CryptHashData(hHash, pBytesIn2, dwLengthIn2, 0);
- dwParamSize := 4;
- if CryptGetHashParam(hHash, HP_HASHSIZE, PBYTE(@dwHashSize), @dwParamSize,
- 0) then
- begin
- if dwHashSize <= dwLengthOut then
- begin
- dwParamSize := dwLengthOut;
- if CryptGetHashParam(hHash, HP_HASHVAL, pBytesOut, @dwParamSize, 0)
- then
- Result := True;
- end;
- end;
- end;
- CryptDestroyHash(hHash);
- end;
- end;
-
- function DeriveLoginKey(key: PByte; dwKeySize: DWORD; magic: string; pOutBytes:
- PBYTE; dwOutLen: DWORD): Boolean;
- var
- hProvider: HCRYPTPROV;
- hCryptKey1: HCRYPTKEY;
- pImportKey: array of Byte;
- bHash1, bHash2, bHash3, bHash4: array[0..19] of Byte;
- begin
- Result := False;
- if CryptAcquireContext(@hProvider, nil, nil, PROV_RSA_FULL, 0) then
- begin
- SetLength(pImportKey, dwKeySize + STDKEYHDRSIZE);
- MoveMemory(pImportKey, @cKeyStdHeader[0], STDKEYHDRSIZE);
- MoveMemory(@pImportKey[STDKEYHDRSIZE], key, dwKeySize);
- pImportKey[2] := dwKeySize;
-
- if CryptImportKey(hProvider, PByte(pImportKey), dwKeySize + STDKEYHDRSIZE,
- 0, CRYPT_SF, @hCryptKey1) then
- begin
- HMACHash(hProvider, hCryptKey1, CALG_SHA1, @bHash1, 20,
- PBYTE(PChar(magic)), Length(magic), nil, 0);
- HMACHash(hProvider, hCryptKey1, CALG_SHA1, @bHash2, 20, @bHash1[0], 20,
- PBYTE(PChar(magic)), Length(magic));
- HMACHash(hProvider, hCryptKey1, CALG_SHA1, @bHash3, 20, @bHash1[0], 20,
- nil, 0);
- HMACHash(hProvider, hCryptKey1, CALG_SHA1, @bHash4, 20, @bHash3[0], 20,
- PBYTE(PChar(magic)), Length(magic));
- if dwOutLen >= 24 then
- begin
- MoveMemory(pOutBytes, @Bhash2[0], 20);
- Inc(pOutBytes, 20);
- MoveMemory(pOutBytes, @Bhash4[0], 4);
- Result := True;
- end;
- CryptDestroyKey(hCryptKey1);
- end;
- SetLength(pImportKey, 0);
- CryptReleaseContext(hProvider, 0);
- end;
- end;
-
- function TMSN.GenerateLoginBlob(key: string; Challenge: string): string;
- var
- key1, key2, key3: array[0..23] of Byte;
- hash: array[0..19] of Byte;
- Randomdata: array[0..7] of Byte;
- szRet: string;
- dwBase64Size: DWORD;
- hProvider: HCRYPTPROV;
-
- hCryptKey1, hCryptKey2: HCRYPTKEY;
-
- pImportKey: array of Byte;
-
- hKeyDupe1, hKeyDupe2: HCRYPTKEY;
- hHash: HCRYPTHASH;
-
- dwMode: DWORD;
-
- hmcinfo: HMAC_INFO;
- dwDataLen, dwData: DWORD;
- pEncryptBytes: array of Byte;
-
- usrkey: tagMSGUSRKEY;
-
- buffer: PChar;
- const
- CRYPT_STRING_BASE64 = $00000001;
-
- begin
- with usrkey do
- begin
- uStructHeaderSize := 28;
- uCryptMode := CRYPT_MODE_CBC;
- uCipherType := CALG_3DES;
- uHashType := CALG_SHA1;
- uIVLen := sizeof(aIVBytes);
- uHashLen := sizeof(aHashBytes);
- uCipherLen := sizeof(aCipherBytes);
- end;
-
- CryptStringToBinary(PChar(key), 0, CRYPT_STRING_BASE64, nil, @dwBase64Size,
- nil, nil);
- ASSERT(dwBase64Size <= 24);
- if dwBase64Size > 24 then
- begin
- Result := ‘‘;
- Exit;
- end;
- dwBase64Size := 24;
- CryptStringToBinary(PChar(key), 0, CRYPT_STRING_BASE64, @key1, @dwBase64Size,
- nil, nil);
-
- DeriveLoginKey(@key1[0], 24, ‘WS-SecureConversationSESSION KEY HASH‘, @key2,
- 24);
- DeriveLoginKey(@key1[0], 24, ‘WS-SecureConversationSESSION KEY ENCRYPTION‘,
- @key3, 24);
-
- if CryptAcquireContext(@hProvider, nil, nil, PROV_RSA_FULL, 0) then
- begin
- SetLength(pImportKey, 24 + STDKEYHDRSIZE);
-
- MoveMemory(pImportKey, @cKeyStdHeader[0], STDKEYHDRSIZE);
- MoveMemory(@pImportKey[STDKEYHDRSIZE], @key2[0], 24);
-
- CryptImportKey(hProvider, PByte(pImportKey), 24 + STDKEYHDRSIZE, 0,
- CRYPT_SF, @hCryptKey2);
-
- MoveMemory(@pImportKey[STDKEYHDRSIZE], @key3[0], 24);
-
- if CryptImportKey(hProvider, Pbyte(pImportKey), 24 + STDKEYHDRSIZE, 0,
- CRYPT_SF, @hCryptKey1) then
- begin
- CryptDuplicateKey(hCryptKey1, nil, 0, @hKeyDupe1);
- dwMode := CRYPT_MODE_CBC;
- CryptSetKeyParam(hKeyDupe1, KP_MODE, @dwMode, 0);
- if CryptCreateHash(hProvider, CALG_HMAC, hCryptKey2, 0, @hHash) then
- begin
- ZeroMemory(@hmcinfo, sizeof(HMAC_INFO));
- hmcinfo.HashAlgid := CALG_SHA1;
- CryptSetHashParam(hHash, HP_HMAC_INFO, @hmcinfo, 0);
- dwDataLen := Length(Challenge);
-
- CryptDuplicateKey(hKeyDupe1, nil, 0, @hKeyDupe2);
- CryptEncrypt(hKeyDupe2, 0, TRUE, 0, nil, @dwDataLen, 0);
- CryptDestroyKey(hKeyDupe2);
- if dwDataLen > 0 then
- begin
- CryptGenRandom(hProvider, 8, @RandomData);
- CryptSetKeyParam(hKeyDupe1, KP_IV, @RandomData[0], 0);
- SetLength(pEncryptBytes, dwDataLen);
- ZeroMemory(pEncryptBytes, dwDataLen);
- MoveMemory(pEncryptBytes, PChar(Challenge), Length(Challenge));
-
- dwData := Length(Challenge);
- if CryptEncrypt(hKeyDupe1, hHash, TRUE, 0, PByte(pEncryptBytes),
- @dwData, dwDataLen) then
- begin
- ASSERT(dwData = 72);
- dwData := 20;
-
- CryptGetHashParam(hHash, HP_HASHVAL, @hash, @dwData, 0);
-
- MoveMemory(@usrkey.aIVBytes[0], @RandomData[0], 8);
- MoveMemory(@usrkey.aHashBytes[0], @hash[0], 20);
- MoveMemory(@usrkey.aCipherBytes[0], pEncryptBytes, 72);
-
- CryptBinaryToString(@usrkey, Sizeof(tagMSGUSRKEY),
- CRYPT_STRING_BASE64, nil, @dwBase64Size);
- GetMem(buffer, dwBase64Size);
- try
- CryptBinaryToString(@usrkey, sizeof(tagMSGUSRKEY),
- CRYPT_STRING_BASE64, buffer, @dwBase64Size);
- szRet := StringReplace(buffer, #13#10, ‘‘, [rfReplaceAll]);
- finally
- FreeMem(buffer);
- end;
- end;
- SetLength(pEncryptBytes, 0);
- end;
- CryptDestroyHash(hHash);
- end;
- CryptDestroyKey(hKeyDupe1);
- CryptDestroyKey(hCryptKey1);
- end;
- SetLength(pImportKey, 0);
- if hCryptKey2 > 0 then
- CryptDestroyKey(hCryptKey2);
- CryptReleaseContext(hProvider, 0);
- end;
- Result := szRet;
- end;
-
- end.
- unit UMain;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, ScktComp, StdCtrls, ComObj, CnDebug, Sockets, StrUtils, MsnClass,
- IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;
- type
- TForm1 = class(TForm)
- btn1: TButton;
- mmo1: TMemo;
- btn2: TButton;
- btn4: TButton;
- clntsckt1: TClientSocket;
- btn3: TButton;
- IdTCPClient1: TIdTCPClient;
- btn5: TButton;
- lbl1: TLabel;
- edt1: TEdit;
- lbl2: TLabel;
- edt2: TEdit;
- edt3: TEdit;
- mmo2: TMemo;
- btn6: TButton;
- procedure btn1Click(Sender: TObject);
- procedure btn4Click(Sender: TObject);
- procedure btn2Click(Sender: TObject);
- procedure clntsckt1Connect(Sender: TObject; Socket: TCustomWinSocket);
- procedure clntsckt1Connecting(Sender: TObject;
- Socket: TCustomWinSocket);
- procedure clntsckt1Disconnect(Sender: TObject;
- Socket: TCustomWinSocket);
- procedure clntsckt1Error(Sender: TObject; Socket: TCustomWinSocket;
- ErrorEvent: TErrorEvent; var ErrorCode: Integer);
- procedure btn3Click(Sender: TObject);
- procedure clntsckt1Read(Sender: TObject; Socket: TCustomWinSocket);
- procedure IdTCPClient1Connected(Sender: TObject);
- procedure IdTCPClient1Disconnected(Sender: TObject);
- procedure btn5Click(Sender: TObject);
- procedure btn6Click(Sender: TObject);
- private
-
- public
-
- end;
-
- type
- TClientListen = class(TThread)
- private
- MSN: TMSN;
- FSecond: string;
- ProtocolNum: Integer;
- NSAddress: string;
- NSPort: Integer;
- FNonce: string;
- FSSOKey: string;
- FGivenPolicy :string;
-
- UserName, Password: string;
-
-
- public
- Msg: string;
- procedure SendCmd(Cmd: string; Params: string);
- function IncProNum: Integer;
- function GetCmd(s: string): string;
- function GetSecondCmd(s: string): string;
- procedure GetNSAddr(s: string);
- procedure GetNonce(s: string);
- function GetPolicySize(s:string):Cardinal;
-
- function GetMsn(s:string; Postion: integer):Variant;
- protected
- procedure Execute; override;
- procedure Start;
- end;
-
- var
- Form1: TForm1;
-
- ttclnt: TClientListen;
- MessageInfo: string;
-
-
- implementation
-
- uses Unit2;
-
- {$R *.dfm}
- function GenerateLoginBlob(key: PChar; challenge: PChar):PChar;stdcall; external ‘MSNSSOKey.dll‘;
-
- procedure TClientListen.Execute;
- begin
-
-
-
- MSN := TMSN.Create(UserName , Password);
- FreeOnTerminate := True;
- ProtocolNum := 1;
- while not Terminated do
- begin
- Start;
- Sleep(300);
- end;
- MSN.Free;
-
- end;
-
- procedure TClientListen.Start;
- var
- cmd, s, s2: string;
- begin
- try
- MessageInfo := ‘‘;
- MessageInfo := form1.IdTCPClient1.ReadLn();
- except
- Terminate;
- end;
-
-
- if MessageInfo <> ‘‘ then
- begin
- s := MessageInfo;
- cmd := GetCmd(s);
-
-
-
- Form1.mmo1.Lines.Add(‘<=‘ + s);
-
-
- if cmd = ‘VER‘ then
- SendCmd(‘CVR‘, ‘0x0804 winnt 5.1 i386 MSG80BETA 8.5.1238 msmsgs ‘ +
- MSN.FUser);
- if cmd = ‘CVR‘ then
- SendCmd(‘USR‘, ‘SSO I ‘ + MSN.FUser);
-
-
- if cmd = ‘XFR‘ then
- begin
- GetNSAddr(s);
-
-
- if form1.IdTCPClient1.Connected then
- form1.IdTCPClient1.Disconnect;
- Sleep(1000) ;
-
-
-
- Form1.IdTCPClient1.Host := NSAddress;
- form1.IdTCPClient1.Port := NSPort;
- repeat
-
-
-
-
- if not Form1.IdTCPClient1.Connected then
- form1.IdTCPClient1.Connect(8000);
- Sleep(1500);
-
- until (form1.IdTCPClient1.Connected) or (Terminated);
- SendCmd(‘VER‘, ‘MSNP15 CVR0‘);
- end;
-
-
- if cmd = ‘USR‘ then
- begin
- FSecond := GetSecondCmd(s);
-
-
- if FSecond = ‘OK‘ then
- Form1.mmo1.Lines.Add(‘登录成功‘)
- else if FSecond = ‘SSO‘ then
- begin
- MSN.Get_passport_ticket;
- MSN.GetXMLFile;
-
- if Form1.IdTCPClient1.Connected then
- begin
- GetNonce(s);
- if FNonce <> ‘‘ then
- begin
- FSSOKey := MSN.GetSSOKey(FNonce);
-
-
-
-
-
-
-
- SendCmd(‘USR‘, ‘SSO S ‘ + MSN.FBinarySecurityToken + ‘ ‘ + FSSOKey);
- end;
- end;
- end;
- end ;
-
- if cmd = ‘GCF‘ then
- begin
- FGivenPolicy := form1.IdTCPClient1.ReadString(GetPolicySize(s));
-
- end;
-
- if cmd = ‘MSG‘ then
- begin
- FGivenPolicy := Form1.IdTCPClient1.ReadString(GetMsn(s, 4));
- SendCmd(‘BLP‘, ‘BL‘);
- form1.mmo2.Lines.Add(FGivenPolicy);
- end;
-
- if cmd = ‘BLP‘ then
- SendCmd(‘ADL‘,‘11 <ml l="1"/>‘);
-
-
-
- end;
-
-
- end;
-
- procedure TClientListen.SendCmd(Cmd: string; Params: string);
- var
- s:string;
- begin
-
- if form1.IdTCPClient1.Connected then
- begin
- s := Format(‘%s %d %s‘
- form1.IdTCPClient1.WriteLn(s);
-
- form1.mmo1.Lines.Add(‘=>‘ + s);
- end;
- end;
-
- function TClientListen.IncProNum: Integer;
- begin
- Inc(ProtocolNum);
- Result := ProtocolNum;
- end;
-
- function TClientListen.GetCmd(s: string): string;
- begin
- Result := ‘‘;
- if s <> ‘‘ then
- Result := Trim(Copy(s, 1, 3));
-
- end;
-
- function TClientListen.GetSecondCmd(s: string): string;
- begin
- Result := Trim(Copy(s, 7, 3));
-
-
- end;
-
- procedure TClientListen.GetNSAddr(s: string);
- var
- p1, p2, p3, code: integer;
- s1: string;
- begin
- p1 := PosEx(‘NS ‘, S, 2);
- p2 := PosEx(‘ U D‘, s, p1);
- if (p1 > 0) and (p2 > 0) then
- begin
- s1 := Copy(s, p1 + 3, p2 - p1 - 3);
-
- p3 := Posex(‘:‘, s1, 2);
- if p3 > 0 then
- begin
- NSAddress := Trim(Copy(s1, 1, p3 - 1));
- Val(Copy(s1, p3 + 1, Length(s1) - p3), NSPort, code);
- end;
- end;
- end;
-
- procedure TClientListen.GetNonce(s: string);
- var
- p1: Integer;
- s1:string;
- begin
- s1 := ‘MBI_KEY‘;
- p1 := PosEx(s1, s, 2);
- if p1 > 0 then
- FNonce := Trim(Copy(s, p1 + Length(s1) + 1, Length(s) - p1 - Length(s1)));
- end;
-
- function TClientListen.GetPolicySize(s:string):Cardinal;
- var
- Code:Integer;
- List:TStringList;
- begin
- Result := 0;
- if s <> ‘‘ then
- begin
- List := TStringList.Create;
- try
- ExtractStrings([‘ ‘], [], PChar(s), List);
- if List.Count >= 3 then
- begin
- Val(List.Strings[2], Result, Code);
- end;
- finally
- List.Free;
-
- end;
- end;
- end;
-
-
- function TClientListen.GetMsn(s:string; Postion: integer):Variant;
- var
- List: TStringList;
- begin
- list := TStringList.Create;
- try
- ExtractStrings([‘ ‘], [], PChar(s), List);
- if list.Count >= Postion then
- Result := Trim(List.Strings[Postion - 1]);
- finally
- list.Free;
- end;
- end;
-
- procedure TForm1.btn1Click(Sender: TObject);
- begin
-
- IdTCPClient1.Connect(12000);
- ttclnt := TClientListen.Create(true);
- ttclnt.UserName := Trim(edt1.Text);
- ttclnt.Password := Trim(edt2.Text);
- ttclnt.Resume;
- end;
-
- procedure TForm1.btn4Click(Sender: TObject);
- var
- M: TMSN;
-
- begin
- M := TMSN.Create(<a target="_blank" href="mailto:‘ying_32@‘,‘">‘‘,‘‘</a>);
-
-
-
- M.Get_passport_ticket;
-
- M.GetXMLFile();
- mmo1.Lines.Add(M.FBinarySecurityToken);
- mmo1.Lines.Add(‘------------------------------------‘);
- mmo1.Lines.Add(m.FBinarySecret);
-
- m.Free;
- end;
-
- procedure TForm1.btn2Click(Sender: TObject);
- begin
- IdTCPClient1.Disconnect;
-
- ttclnt.Terminate;
- end;
-
- procedure TForm1.clntsckt1Connect(Sender: TObject;
- Socket: TCustomWinSocket);
- begin
- mmo1.Lines.Add(‘连接成功‘);
- end;
-
- procedure TForm1.clntsckt1Connecting(Sender: TObject;
- Socket: TCustomWinSocket);
- begin
- mmo1.Lines.Add(‘连接中。。‘);
- end;
-
- procedure TForm1.clntsckt1Disconnect(Sender: TObject;
- Socket: TCustomWinSocket);
- begin
- mmo1.Lines.Add(‘断开服务器‘);
-
-
-
- end;
-
- procedure TForm1.clntsckt1Error(Sender: TObject; Socket: TCustomWinSocket;
- ErrorEvent: TErrorEvent; var ErrorCode: Integer);
- begin
- mmo1.Lines.Add(‘Error: ‘ + IntToStr(ErrorCode));
- ErrorCode := 0;
- end;
-
- procedure TForm1.btn3Click(Sender: TObject);
- var
- m:TMSN;
- s1:string;
- begin
- m := TMSN.Create(‘‘, ‘‘);
-
- s1 :=
- m.GenerateLoginBlob(‘BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=‘, ‘BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=‘);
-
-
- mmo1.Lines.Add(s1);
- m.Free;
- mmo1.Lines.Add(‘-----------------------------------------------------‘);
- mmo1.Lines.Add(GenerateLoginBlob(‘BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=‘, ‘BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=‘));
- end;
-
- procedure TForm1.clntsckt1Read(Sender: TObject; Socket: TCustomWinSocket);
- begin
- MessageInfo := ‘‘;
- MessageInfo := Socket.ReceiveText;
- CnDebugger.LogMsg(MessageInfo);
- end;
-
- procedure TForm1.IdTCPClient1Connected(Sender: TObject);
- begin
- mmo1.Lines.Add(‘已连接至->‘ + IdTCPClient1.Host);
- if IdTCPClient1.Host = ‘messenger.hotmail.com‘ then
- begin
- IdTCPClient1.WriteLn(‘VER 1 MSNP15 MSNP14 MSNP13 CVR0‘);
- mmo1.Lines.Add(‘=>VER 1 MSNP15 MSNP14 MSNP13 CVR0‘);
- end;
- end;
-
- procedure TForm1.IdTCPClient1Disconnected(Sender: TObject);
- begin
- mmo1.Lines.Add(‘断开与->‘ + IdTCPClient1.Host)
- end;
-
- procedure TForm1.btn5Click(Sender: TObject);
- begin
- if IdTCPClient1.Connected then
- begin
- IdTCPClient1.WriteLn(Trim(edt3.Text));
- mmo1.Lines.Add(‘=>‘ + Trim(edt3.Text));
- end;
-
- end;
-
- procedure TForm1.btn6Click(Sender: TObject);
- begin
- Form2.Show;
- end;
-
- end.
http://blog.csdn.net/zyjying520/article/details/26161653
对Msn协议的一点点研究
原文:http://www.cnblogs.com/findumars/p/5017774.html