コード例 #1
0
int CEncryptedDatagramSocket::EncryptSendServer(uchar** ppbyBuf, int nBufLen, uint32 dwBaseKey) const{
	ASSERT( thePrefs.IsServerCryptLayerUDPEnabled() );
	ASSERT( dwBaseKey != 0 );
	
	uint8 byPadLen = 0;			// padding disabled for UDP currently
	uint32 nCryptedLen = nBufLen + byPadLen + CRYPT_HEADER_WITHOUTPADDING;
	uchar* pachCryptedBuffer = new uchar[nCryptedLen];
	
	uint16 nRandomKeyPart = (uint16)cryptRandomGen.GenerateWord32(0x0000, 0xFFFF);

	uchar achKeyData[7];
	memcpy(achKeyData, &dwBaseKey, 4);
	achKeyData[4] = MAGICVALUE_UDP_CLIENTSERVER;
	memcpy(achKeyData + 5, &nRandomKeyPart, 2);
	MD5Sum md5(achKeyData, sizeof(achKeyData));
	RC4_Key_Struct keySendKey;
	RC4CreateKey(md5.GetRawHash(), 16, &keySendKey, true);

	// create the semi random byte encryption header
	uint8 bySemiRandomNotProtocolMarker = 0;
	int i;
	for (i = 0; i < 128; i++){
		bySemiRandomNotProtocolMarker = cryptRandomGen.GenerateByte();
		if (bySemiRandomNotProtocolMarker != OP_EDONKEYPROT) // not allowed values
			break;
	}
	if (i >= 128){
		// either we have _real_ bad luck or the randomgenerator is a bit messed up
		ASSERT( false );
		bySemiRandomNotProtocolMarker = 0x01;
	}

	uint32 dwMagicValue = MAGICVALUE_UDP_SYNC_SERVER;
	pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker;
	memcpy(pachCryptedBuffer + 1, &nRandomKeyPart, 2);
	RC4Crypt((uchar*)&dwMagicValue, pachCryptedBuffer + 3, 4, &keySendKey);
	RC4Crypt((uchar*)&byPadLen, pachCryptedBuffer + 7, 1, &keySendKey);

	for (int j = 0; j < byPadLen; j++){
		uint8 byRand = (uint8)rand();	// they actually dont really need to be random, but it doesn't hurts either
		RC4Crypt((uchar*)&byRand, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + j, 1, &keySendKey);
	}
	RC4Crypt(*ppbyBuf, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen, nBufLen, &keySendKey);
	delete[] *ppbyBuf;
	*ppbyBuf = pachCryptedBuffer;

	//Xman
	// Maella -Accurate measure of bandwidth: eDonkey data + control, network adapter-
	/*
	theStats.AddUpDataOverheadCrypt(nCryptedLen - nBufLen);
	*/
	theApp.pBandWidthControl->AddeMuleOutObfuscationUDP(nCryptedLen - nBufLen);
	//Xman end
	return nCryptedLen;
}
コード例 #2
0
int CEncryptedDatagramSocket::DecryptReceivedServer(BYTE* pbyBufIn, int nBufLen, BYTE** ppbyBufOut, uint32 dwBaseKey, uint32 dbgIP) const{
	int nResult = nBufLen;
	*ppbyBufOut = pbyBufIn;
	
	if (nResult <= CRYPT_HEADER_WITHOUTPADDING || !thePrefs.IsServerCryptLayerUDPEnabled() || dwBaseKey == 0)
		return nResult;
	
	if(pbyBufIn[0] == OP_EDONKEYPROT)
			return nResult; // no encrypted packet (see description on top)

	// might be an encrypted packet, try to decrypt
	uchar achKeyData[7];
	memcpy(achKeyData, &dwBaseKey, 4);
	achKeyData[4] = MAGICVALUE_UDP_SERVERCLIENT;
	memcpy(achKeyData + 5, pbyBufIn + 1, 2); // random key part sent from remote server
	MD5Sum md5(achKeyData, sizeof(achKeyData));
	RC4_Key_Struct keyReceiveKey;
	RC4CreateKey(md5.GetRawHash(), 16, &keyReceiveKey, true);
	
	uint32 dwValue;
	RC4Crypt(pbyBufIn + 3, (uchar*)&dwValue, sizeof(dwValue), &keyReceiveKey);
	if (dwValue == MAGICVALUE_UDP_SYNC_SERVER){
		// yup this is an encrypted packet
		if (thePrefs.GetDebugServerUDPLevel() > 0)
			DEBUG_ONLY( DebugLog(_T("Received obfuscated UDP packet from ServerIP: %s"), ipstr(dbgIP)) );
		uint8 byPadLen;
		RC4Crypt(pbyBufIn + 7, (uchar*)&byPadLen, 1, &keyReceiveKey);
		byPadLen &= 15;
		nResult -= CRYPT_HEADER_WITHOUTPADDING;
		if (nResult <= byPadLen){
			DebugLogError(_T("Invalid obfuscated UDP packet from ServerIP: %s, Paddingsize (%u) larger than received bytes"), ipstr(dbgIP), byPadLen);
			return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
		}
		if (byPadLen > 0)
			RC4Crypt(NULL, NULL, byPadLen, &keyReceiveKey);
		nResult -= byPadLen;
		*ppbyBufOut = pbyBufIn + (nBufLen - nResult);
		RC4Crypt((uchar*)*ppbyBufOut, (uchar*)*ppbyBufOut, nResult, &keyReceiveKey);
		
		//Xman
		// Maella -Accurate measure of bandwidth: eDonkey data + control, network adapter-
		/*
		theStats.AddDownDataOverheadCrypt(nBufLen - nResult);
		*/
		theApp.pBandWidthControl->AddeMuleInObfuscation(nBufLen - nResult);
		//Xman end
		return nResult; // done
	}
	else{
		DebugLogWarning(_T("Obfuscated packet expected but magicvalue mismatch on UDP packet from ServerIP: %s"), ipstr(dbgIP));
		return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
	}
}
コード例 #3
0
int CEncryptedDatagramSocket::DecryptReceivedClient(BYTE* pbyBufIn, int nBufLen, BYTE** ppbyBufOut, uint32 dwIP) const{
	int nResult = nBufLen;
	*ppbyBufOut = pbyBufIn;
	
	if (nResult <= CRYPT_HEADER_WITHOUTPADDING || !thePrefs.IsClientCryptLayerSupported())
		return nResult;
	
	switch (pbyBufIn[0]){
		case OP_EMULEPROT:
		case OP_KADEMLIAPACKEDPROT:
		case OP_KADEMLIAHEADER:
		case OP_UDPRESERVEDPROT1:
		case OP_UDPRESERVEDPROT2:
		case OP_PACKEDPROT:
			return nResult; // no encrypted packet (see description on top)
	}
	// might be an encrypted packet, try to decrypt
	uchar achKeyData[23];
	md4cpy(achKeyData, thePrefs.GetUserHash());
	achKeyData[20] = MAGICVALUE_UDP;
	memcpy(achKeyData + 16, &dwIP, 4);
	memcpy(achKeyData + 21, pbyBufIn + 1, 2); // random key part sent from remote client
	MD5Sum md5(achKeyData, sizeof(achKeyData));
	RC4_Key_Struct keyReceiveKey;
	RC4CreateKey(md5.GetRawHash(), 16, &keyReceiveKey, true);
	
	uint32 dwValue;
	RC4Crypt(pbyBufIn + 3, (uchar*)&dwValue, sizeof(dwValue), &keyReceiveKey);
	if (dwValue == MAGICVALUE_UDP_SYNC_CLIENT){
		// yup this is an encrypted packet
		DEBUG_ONLY( DebugLog(_T("Received obfuscated UDP packet from clientIP: %s"), ipstr(dwIP)) );
		uint8 byPadLen;
		RC4Crypt(pbyBufIn + 7, (uchar*)&byPadLen, 1, &keyReceiveKey);
		nResult -= CRYPT_HEADER_WITHOUTPADDING;
		if (nResult <= byPadLen){
			DebugLogError(_T("Invalid obfuscated UDP packet from clientIP: %s, Paddingsize (%u) larger than received bytes"), ipstr(dwIP), byPadLen);
			return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
		}
		if (byPadLen > 0)
			RC4Crypt(NULL, NULL, byPadLen, &keyReceiveKey);
		nResult -= byPadLen;
		*ppbyBufOut = pbyBufIn + (nBufLen - nResult);
		RC4Crypt((uchar*)*ppbyBufOut, (uchar*)*ppbyBufOut, nResult, &keyReceiveKey);
		
		theStats.AddDownDataOverheadCrypt(nBufLen - nResult);
		return nResult; // done
	}
	else{
		DebugLogWarning(_T("Obfuscated packet expected but magicvalue mismatch on UDP packet from clientIP: %s"), ipstr(dwIP));
		return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
	}
}
コード例 #4
0
ファイル: warden.cpp プロジェクト: kwolekr/horizon
void WardenParseCommand5(char *data, int len, int index) {
	__int32 buf32;
	unsigned char tmpkey[0x102];
	if (!lpwdnFnTable)
		return;
	if (!lpwdnFnTable->wdnGenKeys) {
		AddChat(vbRed, "Unable to generate new RC4 keys (wdnGenKeys == NULL)!", bot[index]->hWnd_rtfChat);
		return;
	}
	newrc4 = NULL;
	__asm {
		push 4
		push offset wdnkeyseed
		mov ecx, lpWdnModClass 
		mov eax, lpwdnFnTable
		//call dword ptr [eax]
		call [eax]WARDENFNTABLE.wdnGenKeys
	}
	if (!newrc4) {
		AddChat(vbRed, "wdnGenKeys() failed!", bot[index]->hWnd_rtfChat);
		return;
	}
	char *tmpdata = (char *)malloc(len);
	memcpy(tmpdata, data, len);
	memcpy(tmpkey, newrc4 + 0x102, sizeof(tmpkey));
	RC4Crypt(tmpkey, (unsigned char *)tmpdata, len);
	memcpy(tmpkey, newrc4, sizeof(tmpkey));
	if (pendingwpacket)	{
		free(pendingwpacket);
		pendingwpacket = NULL;
	}
	__asm {
		lea eax, [buf32]
		push eax
		push len
		push tmpdata
		mov ecx, lpWdnModClass
		mov eax, lpwdnFnTable
		//call dword ptr [eax + 8]
		call [eax]WARDENFNTABLE.wdnHandlePacket
	}
	if (!pendingwpacket) {
		AddChat(vbRed, "wdnSendPacket() failed!", bot[index]->hWnd_rtfChat);
		return;
	}
	RC4Crypt(tmpkey, (unsigned char *)pendingwpacket, pendingwpacketlen);
	RC4Crypt((unsigned char *)bot[index]->wardenkey_out, (unsigned char *)pendingwpacket, pendingwpacketlen);
	memcpy(bot[index]->wardenkey_out, newrc4, 0x102);
	memcpy(bot[index]->wardenkey_in, (char *)newrc4 + 0x102, 0x102);
	InsertVoid(pendingwpacket, pendingwpacketlen);
	SendPacket(0x5E, index);
}
コード例 #5
0
ファイル: warden.cpp プロジェクト: kwolekr/horizon
void WardenParseCommand1(char *data, int len, int index) {
	char buf[128];
	if (rawmodule) {					
		memcpy(rawmodule + moddlprog, data + 3, *(__int16 *)(data + 1));
		moddlprog += *(__int16 *)(data + 1);
		//sprintf(buf, "%d/%d bytes (%d%%)", moddlprog, modsize,
		//	int((float)moddlprog / (float)modsize * 100.f));
		//AddChat(vbGreen, buf, bot[index]->hWnd_rtfChat);
	}		
	if (moddlprog >= modsize) {
		dling = 0;
		sprintf(buf, "Module downloaded, dl @ %d kB/s",
			(int)((float)(modsize) / (float)(GetTickCount() - startedtick)));
		AddChat(vbGreen, buf, bot[index]->hWnd_rtfChat);
		int fail = WardenDecryptInflateModule(modname, rawmodule, modsize, moddecryptkey, index);
		if (fail) {																					
			sprintf(buf, "Warden module decryption/inflation failure %d (%s).", 
				fail, wextracterrstrs[fail - 1]);
			AddChat(vbRed, buf, bot[index]->hWnd_rtfChat);
		} else {
			WardenPrepareModule(modname);
			WardenModuleInitalize((LPWMODHEADER)currentmodule);
			*buf = 1;
			RC4Crypt(bot[index]->wardenkey_out, (unsigned char *)buf, 1);
			InsertByte(*buf);
			SendPacket(0x5E, index);
		}
	}
}
コード例 #6
0
int CEncryptedStreamSocket::SendNegotiatingData(const void* lpBuf, uint32_t nBufLen, uint32_t nStartCryptFromByte, bool bDelaySend){	
	ASSERT( m_StreamCryptState == ECS_NEGOTIATING || m_StreamCryptState == ECS_ENCRYPTING );
	ASSERT( nStartCryptFromByte <= nBufLen );
	ASSERT( m_NegotiatingState == ONS_BASIC_SERVER_DELAYEDSENDING || !bDelaySend );

	BYTE* pBuffer = NULL;
	bool bProcess = false;
	if (lpBuf != NULL){
		pBuffer = (BYTE*)malloc(nBufLen);
		if (pBuffer == NULL)
			AfxThrowMemoryException();
		if (nStartCryptFromByte > 0)
			memcpy(pBuffer, lpBuf, nStartCryptFromByte);
		if (nBufLen > nStartCryptFromByte)
			RC4Crypt((uchar*)lpBuf + nStartCryptFromByte, pBuffer + nStartCryptFromByte, nBufLen - nStartCryptFromByte, m_pRC4SendKey);
		if (m_pfiSendBuffer != NULL){
			// we already have data pending. Attach it and try to send
			if (m_NegotiatingState == ONS_BASIC_SERVER_DELAYEDSENDING)
				m_NegotiatingState = ONS_COMPLETE;
			else
				ASSERT( false );
			m_pfiSendBuffer->SeekToEnd();
			m_pfiSendBuffer->Write(pBuffer, nBufLen);
			free(pBuffer);
			pBuffer = NULL;
			nStartCryptFromByte = 0;
			bProcess = true; // we want to try to send it right now
		}
	}
	if (lpBuf == NULL || bProcess){
		// this call is for processing pending data
		if (m_pfiSendBuffer == NULL || nStartCryptFromByte != 0){
			ASSERT( false );
			return 0;							// or not
		}
		nBufLen = (uint32_t)m_pfiSendBuffer->GetLength();
		pBuffer = m_pfiSendBuffer->Detach();
		delete m_pfiSendBuffer;
		m_pfiSendBuffer = NULL;
	}
    ASSERT( m_pfiSendBuffer == NULL );
	uint32_t result = 0;	
	if (!bDelaySend)
		result = CAsyncSocketEx::Send(pBuffer, nBufLen);
	if (result == (uint32_t)SOCKET_ERROR || bDelaySend){
		m_pfiSendBuffer = new CSafeMemFile(128);
		m_pfiSendBuffer->Write(pBuffer, nBufLen);
		free(pBuffer);
		return result;
    }
	else {
		if (result < nBufLen){
			m_pfiSendBuffer = new CSafeMemFile(128);
			m_pfiSendBuffer->Write(pBuffer + result, nBufLen - result);			
		}
		free(pBuffer);
		return result;
	}
}
コード例 #7
0
void CEncryptedStreamSocket::CryptPrepareSendData(uchar* pBuffer, uint32_t nLen){
	if (!IsEncryptionLayerReady()){
		ASSERT( false ); // must be a bug
		return;
	}
	if (m_StreamCryptState == ECS_UNKNOWN){
		//this happens when the encryption option was not set on a outgoing connection
		//or if we try to send before receiving on a incoming connection - both shouldn't happen
		m_StreamCryptState = ECS_NONE;
		DebugLogError(_T("CEncryptedStreamSocket: Overwriting State ECS_UNKNOWN with ECS_NONE because of premature Send() (%s)"), DbgGetIPString());
	}
	if (m_StreamCryptState == ECS_ENCRYPTING)
		RC4Crypt(pBuffer, pBuffer, nLen, m_pRC4SendKey);
}
コード例 #8
0
ファイル: warden.cpp プロジェクト: kwolekr/horizon
int WardenDecryptInflateModule(char *modulename, char *module, int modulelen, char *keyseed, int index) {
	unsigned long byts;
	unsigned char cryptkey[0x102];

	MD5((char *)module, modulelen, (char *)cryptkey);
	if (memcmp(modhash, cryptkey, 16))
		return 1;

	WardenKeyGenerate(cryptkey, (unsigned char *)keyseed, 0x10);
	RC4Crypt(cryptkey, (unsigned char *)module, modulelen);
	if (*(int *)(module + modulelen - 0x104) != 'SIGN')
		return 2;

	unsigned long extlen = *(int *)module;
	char *extmodule = (char *)malloc(extlen);
	if (uncompress((unsigned char *)extmodule, &extlen, (unsigned char *)module + 4, modulelen - 4)) {
		free(extmodule);
		return 3;
	}

	HANDLE hFile = CreateFile(modulename, GENERIC_WRITE, 0, NULL, CREATE_NEW,
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE) {
		free(extmodule);
		return 4;
	}

	if (!WriteFile(hFile, extmodule, extlen, &byts, NULL)) {
		free(extmodule);
		CloseHandle(hFile);
		return 5;
	}

	free(extmodule);
	CloseHandle(hFile);
	return 0;
}
コード例 #9
0
ファイル: warden.cpp プロジェクト: kwolekr/horizon
void Parse0x5E(char *data, int index) {
	char buf[128];
	unsigned int len = *(short *)(data + 2) - 4;
	data += 4;
	RC4Crypt(bot[index]->wardenkey_in, (unsigned char *)data, len);
	switch (data[0]) {
		case 0:	  
			WardenParseCommand0(data, len, index);
			break;
		case 1:
			WardenParseCommand1(data, len, index);
			break;
		case 2:
			WardenParseCommand2(data, len, index);
			break;				
		case 5:
			WardenParseCommand5(data, len, index);
			break;
		default:
			sprintf(buf, "Unhandled warden command 0x%02x!", (unsigned char)data[0]);
			AddChat(vbRed, buf, bot[index]->hWnd_rtfChat);
			StrToHexOut(data, len, bot[index]->hWnd_rtfChat);
	}
}
コード例 #10
0
ファイル: warden.cpp プロジェクト: kwolekr/horizon
void WardenParseCommand2(char *data, int len, int index) {
	char buf[512];
	char asdf[64];
	char *tosend = buf + 7;
	char *mods[8];
	void *address;
	int pos = 1, nummods = 0, length, lentoread;
	ZeroMemory(buf, sizeof(buf));
	//StrToHexOut(data, len, hWnd_status_re);
	while (data[pos]) {
		mods[nummods] = (char *)malloc(data[pos] + 1);
		memcpy(mods[nummods], data + pos + 1, data[pos]);
		*(mods[nummods] + data[pos]) = 0;
		nummods++;
		pos = pos + data[pos] + 1;
		if (nummods == 8)
			break;
	}
	pos++;
	int wc3 = ((bot[index]->fstate & BFS_WARCRAFT3) && 1); ///////////////////
	//if (!lpModuleImage[wc3]) {
	//	AddChat(vbRed, "Requested module is not loaded!", bot[index]->hWnd_rtfChat);
	//	goto freenret;
	//}																 
	while (pos + 1 < len) { 
		//data[i] ^= data[len - 1];
		if (pos >= 256) {
			AddChat(vbRed, "WARNING! WARDEN BUFFER OVER THRESHHOLD!", bot[index]->hWnd_rtfChat);
			break;
		}
		pos++; //skip command id
		if ((unsigned char)data[pos] <= nummods && !data[pos + 4]) { //memcheck
			/*
			(BYTE) String Index
			(DWORD) Address 
			(BYTE) Length to Read 
			*/
			//mods[data[pos]];
		
			//address = *(__int32 *)(data + pos + 1) - (data[pos] ? 0 : 0x400000)	+ lpModuleImage[wc3];
			address = GetAddress(*(void **)(data + pos + 1), mods, data[pos], nummods, wc3);
			if (address) {
				lentoread = data[pos + 5];
				if (IsBadReadPtr(address, lentoread)) {
					AddChatf(asdf, hWnd_status_re, vbRed,
						"[%d] Unreadable memcheck, addr 0x%08x, len %d. at pos %d!",
						index, address, lentoread, pos);
					StrToHexOut(data, len, hWnd_status_re);
					goto pagecheck;
				}
				*tosend++ = 0;
				memcpy(tosend, address, lentoread);
				tosend += lentoread;
			} else {
				AddChatf(asdf, hWnd_status_re, vbRed,
					"[%d] Unreadable memcheck, addr 0x%08x, len %d. at pos %d!",
					index, address, lentoread, pos);
				StrToHexOut(data, len, hWnd_status_re);
				goto pagecheck;
			}
			pos += 6;
		} else { //pagecheck
pagecheck:
			/*
			(DWORD) Seed 
			(DWORD)[5] SHA1 
			(DWORD) Address 
			(BYTE) Length to Read
			*/
			*tosend = (char)0xE9; //0;
			tosend++;
			pos += 29;
		}
	}
	length = tosend - buf;
	*buf = 2;
	*(__int16 *)(buf + 1) = length - 7;
	*(__int32 *)(buf + 3) = WardenGenerateChecksum(buf + 7, length - 7);
	RC4Crypt(bot[index]->wardenkey_out, (unsigned char *)buf, length);
	InsertVoid(buf, length);
	SendPacket(0x5E, index);
//freenret:
	while (nummods--)
		free(mods[nummods]);
}
コード例 #11
0
int CEncryptedStreamSocket::Negotiate(const uchar* pBuffer, uint32_t nLen){
	uint32_t nRead = 0;
	ASSERT( m_nReceiveBytesWanted > 0 );
	try{
		while (m_NegotiatingState != ONS_COMPLETE && m_nReceiveBytesWanted > 0){		
			if (m_nReceiveBytesWanted > 512){
				ASSERT( false );
				return 0;
			}
			
			if (m_pfiReceiveBuffer == NULL){
				BYTE* pReceiveBuffer = (BYTE*)malloc(512); // use a fixed size buffer
				if (pReceiveBuffer == NULL)
					AfxThrowMemoryException();
				m_pfiReceiveBuffer = new CSafeMemFile(pReceiveBuffer, 512);
			}
			const uint32_t nToRead =  min(nLen - nRead, m_nReceiveBytesWanted);
			m_pfiReceiveBuffer->Write(pBuffer + nRead, nToRead);
			nRead += nToRead;
			m_nReceiveBytesWanted -= nToRead;
			if (m_nReceiveBytesWanted > 0)
				return nRead;
			const uint32_t nCurrentBytesLen = (uint32_t)m_pfiReceiveBuffer->GetPosition();

			if (m_NegotiatingState != ONS_BASIC_CLIENTA_RANDOMPART && m_NegotiatingState != ONS_BASIC_SERVER_DHANSWER){ // don't have the keys yet
				BYTE* pCryptBuffer = m_pfiReceiveBuffer->Detach();
				RC4Crypt(pCryptBuffer, pCryptBuffer, nCurrentBytesLen, m_pRC4ReceiveKey);
				m_pfiReceiveBuffer->Attach(pCryptBuffer, 512);
			}
			m_pfiReceiveBuffer->SeekToBegin();

			switch (m_NegotiatingState){
				case ONS_NONE: // would be a bug
					ASSERT( false ); 
					return 0;
				case ONS_BASIC_CLIENTA_RANDOMPART:{
					ASSERT( m_pRC4ReceiveKey == NULL );

					uchar achKeyData[21];
					md4cpy(achKeyData, thePrefs.GetUserHash());
					achKeyData[16] = MAGICVALUE_REQUESTER;
					m_pfiReceiveBuffer->Read(achKeyData + 17, 4); // random key part sent from remote client

					MD5Sum md5(achKeyData, sizeof(achKeyData));
					m_pRC4ReceiveKey = RC4CreateKey(md5.GetRawHash(), 16, NULL);
					achKeyData[16] = MAGICVALUE_SERVER;
					md5.Calculate(achKeyData, sizeof(achKeyData));
					m_pRC4SendKey = RC4CreateKey(md5.GetRawHash(), 16, NULL);
						
					m_NegotiatingState = ONS_BASIC_CLIENTA_MAGICVALUE;
					m_nReceiveBytesWanted = 4;
					break;
				}
				case ONS_BASIC_CLIENTA_MAGICVALUE:{
					uint32_t dwValue = m_pfiReceiveBuffer->ReadUInt32();
					if (dwValue == MAGICVALUE_SYNC){
						// yup, the one or the other way it worked, this is an encrypted stream
						//DEBUG_ONLY( DebugLog(_T("Received proper magic value, clientIP: %s"), DbgGetIPString()) );
						// set the receiver key
						m_NegotiatingState = ONS_BASIC_CLIENTA_METHODTAGSPADLEN;
						m_nReceiveBytesWanted = 3;	
					}
					else{
						DebugLogError(_T("CEncryptedStreamSocket: Received wrong magic value from clientIP %s on a supposly encrytped stream / Wrong Header"), DbgGetIPString());
						OnError(ERR_ENCRYPTION);
						return (-1);
					}
					break;
			    }
				case ONS_BASIC_CLIENTA_METHODTAGSPADLEN:
					m_dbgbyEncryptionSupported = m_pfiReceiveBuffer->ReadUInt8();
					m_dbgbyEncryptionRequested = m_pfiReceiveBuffer->ReadUInt8();
					if (m_dbgbyEncryptionRequested != ENM_OBFUSCATION)
						AddDebugLogLine(DLP_LOW, false, _T("CEncryptedStreamSocket: Client %s preffered unsupported encryption method (%i)"), DbgGetIPString(), m_dbgbyEncryptionRequested);
					m_nReceiveBytesWanted = m_pfiReceiveBuffer->ReadUInt8();
					m_NegotiatingState = ONS_BASIC_CLIENTA_PADDING;
					//if (m_nReceiveBytesWanted > 16)
					//	AddDebugLogLine(DLP_LOW, false, _T("CEncryptedStreamSocket: Client %s sent more than 16 (%i) padding bytes"), DbgGetIPString(), m_nReceiveBytesWanted);
					if (m_nReceiveBytesWanted > 0)
						break;
				case ONS_BASIC_CLIENTA_PADDING:{
					// ignore the random bytes, send the response, set status complete
					CSafeMemFile fileResponse(26);
					fileResponse.WriteUInt32(MAGICVALUE_SYNC);
					const uint8_t bySelectedEncryptionMethod = ENM_OBFUSCATION; // we do not support any further encryption in this version, so no need to look which the other client preferred
					fileResponse.WriteUInt8(bySelectedEncryptionMethod);
					
					SOCKADDR_IN sockAddr = {0};
					int nSockAddrLen = sizeof(sockAddr);
					GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);	
					const uint8_t byPaddingLen = theApp.serverconnect->AwaitingTestFromIP(sockAddr.sin_addr.S_un.S_addr) ? 16 : (thePrefs.GetCryptTCPPaddingLength() + 1);
					uint8_t byPadding = (uint8_t)(cryptRandomGen.GenerateByte() % byPaddingLen);
					
					fileResponse.WriteUInt8(byPadding);
					for (int i = 0; i < byPadding; i++)
						fileResponse.WriteUInt8(static_cast<uint8_t>(rand() & 0xFF));
					SendNegotiatingData(fileResponse.GetBuffer(), (uint32_t)fileResponse.GetLength());
					m_NegotiatingState = ONS_COMPLETE;
					m_StreamCryptState = ECS_ENCRYPTING;
					//DEBUG_ONLY( DebugLog(_T("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (incoming)"), DbgGetIPString()) );
					break;
				}
				case ONS_BASIC_CLIENTB_MAGICVALUE:{
					if (m_pfiReceiveBuffer->ReadUInt32() != MAGICVALUE_SYNC){
						DebugLogError(_T("CEncryptedStreamSocket: EncryptedstreamSyncError: Client sent wrong Magic Value as answer, cannot complete handshake (%s)"), DbgGetIPString());
						OnError(ERR_ENCRYPTION);
						return (-1);
					}
					m_NegotiatingState = ONS_BASIC_CLIENTB_METHODTAGSPADLEN;
					m_nReceiveBytesWanted = 2;
					break;
				}
				case ONS_BASIC_CLIENTB_METHODTAGSPADLEN:{
					m_dbgbyEncryptionMethodSet = m_pfiReceiveBuffer->ReadUInt8();
					if (m_dbgbyEncryptionMethodSet != ENM_OBFUSCATION){
						DebugLogError( _T("CEncryptedStreamSocket: Client %s set unsupported encryption method (%i), handshake failed"), DbgGetIPString(), m_dbgbyEncryptionMethodSet);
						OnError(ERR_ENCRYPTION);
						return (-1);						
					}
					m_nReceiveBytesWanted = m_pfiReceiveBuffer->ReadUInt8();
					m_NegotiatingState = ONS_BASIC_CLIENTB_PADDING;
					if (m_nReceiveBytesWanted > 0)
						break;
				}
				case ONS_BASIC_CLIENTB_PADDING:
					// ignore the random bytes, the handshake is complete
					m_NegotiatingState = ONS_COMPLETE;
					m_StreamCryptState = ECS_ENCRYPTING;
					//DEBUG_ONLY( DebugLog(_T("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (outgoing)"), DbgGetIPString()) );
					break;
				case ONS_BASIC_SERVER_DHANSWER:{
					ASSERT( !m_cryptDHA.IsZero() );
					uchar aBuffer[PRIMESIZE_BYTES + 1];
					m_pfiReceiveBuffer->Read(aBuffer, PRIMESIZE_BYTES);
					CryptoPP::Integer cryptDHAnswer((byte*)aBuffer, PRIMESIZE_BYTES);
					CryptoPP::Integer cryptDHPrime((byte*)dh768_p, PRIMESIZE_BYTES);  // our fixed prime
					CryptoPP::Integer cryptResult = CryptoPP::a_exp_b_mod_c(cryptDHAnswer, m_cryptDHA, cryptDHPrime);
					
					m_cryptDHA = 0;
					DEBUG_ONLY( ZeroMemory(aBuffer, sizeof(aBuffer)) );
					ASSERT( cryptResult.MinEncodedSize() <= PRIMESIZE_BYTES );
					
					// create the keys
					cryptResult.Encode(aBuffer, PRIMESIZE_BYTES);					
					aBuffer[PRIMESIZE_BYTES] = MAGICVALUE_REQUESTER;
					MD5Sum md5(aBuffer, sizeof(aBuffer));
					m_pRC4SendKey = RC4CreateKey(md5.GetRawHash(), 16, NULL);
					aBuffer[PRIMESIZE_BYTES] = MAGICVALUE_SERVER;
					md5.Calculate(aBuffer, sizeof(aBuffer));
					m_pRC4ReceiveKey = RC4CreateKey(md5.GetRawHash(), 16, NULL);

					m_NegotiatingState = ONS_BASIC_SERVER_MAGICVALUE;
					m_nReceiveBytesWanted = 4;
					break;
				}
				case ONS_BASIC_SERVER_MAGICVALUE:{
					uint32_t dwValue = m_pfiReceiveBuffer->ReadUInt32();
					if (dwValue == MAGICVALUE_SYNC){
						// yup, the one or the other way it worked, this is an encrypted stream
						DebugLog(_T("Received proper magic value after DH-Agreement from Serverconnection IP: %s"), DbgGetIPString());
						// set the receiver key
						m_NegotiatingState = ONS_BASIC_SERVER_METHODTAGSPADLEN;
						m_nReceiveBytesWanted = 3;	
					}
					else{
						DebugLogError(_T("CEncryptedStreamSocket: Received wrong magic value after DH-Agreement from Serverconnection"), DbgGetIPString());
						OnError(ERR_ENCRYPTION);
						return (-1);
					}
					break;
			    }
				case ONS_BASIC_SERVER_METHODTAGSPADLEN:
					m_dbgbyEncryptionSupported = m_pfiReceiveBuffer->ReadUInt8();
					m_dbgbyEncryptionRequested = m_pfiReceiveBuffer->ReadUInt8();
					if (m_dbgbyEncryptionRequested != ENM_OBFUSCATION)
						AddDebugLogLine(DLP_LOW, false, _T("CEncryptedStreamSocket: Server %s preffered unsupported encryption method (%i)"), DbgGetIPString(), m_dbgbyEncryptionRequested);
					m_nReceiveBytesWanted = m_pfiReceiveBuffer->ReadUInt8();
					m_NegotiatingState = ONS_BASIC_SERVER_PADDING;
					if (m_nReceiveBytesWanted > 16)
						AddDebugLogLine(DLP_LOW, false, _T("CEncryptedStreamSocket: Server %s sent more than 16 (%i) padding bytes"), DbgGetIPString(), m_nReceiveBytesWanted);
					if (m_nReceiveBytesWanted > 0)
						break;
				case ONS_BASIC_SERVER_PADDING:{
					// ignore the random bytes (they are decrypted already), send the response, set status complete
					CSafeMemFile fileResponse(26);
					fileResponse.WriteUInt32(MAGICVALUE_SYNC);
					const uint8_t bySelectedEncryptionMethod = ENM_OBFUSCATION; // we do not support any further encryption in this version, so no need to look which the other client preferred
					fileResponse.WriteUInt8(bySelectedEncryptionMethod);
					uint8_t byPadding = (uint8_t)(cryptRandomGen.GenerateByte() % 16);
					fileResponse.WriteUInt8(byPadding);
					for (int i = 0; i < byPadding; i++)
						fileResponse.WriteUInt8(static_cast<uint8_t>(rand() & 0xFF));
					
					m_NegotiatingState = ONS_BASIC_SERVER_DELAYEDSENDING;
					SendNegotiatingData(fileResponse.GetBuffer(), (uint32_t)fileResponse.GetLength(), 0, true); // don't actually send it right now, store it in our sendbuffer
					m_StreamCryptState = ECS_ENCRYPTING;
					DEBUG_ONLY( DebugLog(_T("CEncryptedStreamSocket: Finished DH Obufscation handshake with Server %s"), DbgGetIPString()) );
					break;
				}
				default:
					ASSERT( false );
			}
			m_pfiReceiveBuffer->SeekToBegin();
		}
		if (m_pfiReceiveBuffer != NULL)
			free(m_pfiReceiveBuffer->Detach());
		delete m_pfiReceiveBuffer;
		m_pfiReceiveBuffer = NULL;
		return nRead;
	}
	catch(CFileException* error){
		// can only be caused by a bug in negationhandling, not by the datastream
		error->Delete();
		ASSERT( false );
		OnError(ERR_ENCRYPTION);
		if (m_pfiReceiveBuffer != NULL)
			free(m_pfiReceiveBuffer->Detach());
		delete m_pfiReceiveBuffer;
		m_pfiReceiveBuffer = NULL;
		return (-1);
	}

}
コード例 #12
0
int CEncryptedDatagramSocket::DecryptReceivedClient(BYTE* pbyBufIn, int nBufLen, BYTE** ppbyBufOut, uint32 dwIP, uint32* nReceiverVerifyKey, uint32* nSenderVerifyKey) const{
	int nResult = nBufLen;
	*ppbyBufOut = pbyBufIn;
	
	if (nReceiverVerifyKey == NULL || nSenderVerifyKey == NULL){
		ASSERT( false );
		return nResult;
	}
	
	*nReceiverVerifyKey = 0;
	*nSenderVerifyKey = 0;

	if (nResult <= CRYPT_HEADER_WITHOUTPADDING /*|| !thePrefs.IsClientCryptLayerSupported()*/)
		return nResult;	

	switch (pbyBufIn[0]){
		case OP_EMULEPROT:
		case OP_KADEMLIAPACKEDPROT:
		case OP_KADEMLIAHEADER:
		case OP_UDPRESERVEDPROT1:
		case OP_UDPRESERVEDPROT2:
		case OP_PACKEDPROT:
			return nResult; // no encrypted packet (see description on top)
	}

	// might be an encrypted packet, try to decrypt
	RC4_Key_Struct keyReceiveKey;
	uint32 dwValue = 0;
	// check the marker bit which type this packet could be and which key to test first, this is only an indicator since old clients have it set random
	// see the header for marker bits explanation
	byte byCurrentTry = ((pbyBufIn[0] & 0x03) == 3) ? 1 : (pbyBufIn[0] & 0x03); 
	byte byTries;
	if (Kademlia::CKademlia::GetPrefs() == NULL) {
		// if kad never run, no point in checking anything except for ed2k encryption
		byTries = 1;
		byCurrentTry = 1;
	}
	else
		byTries = 3;
	bool bKadRecvKeyUsed = false;
	bool bKad = false;
	do{
		byTries--;
		MD5Sum md5;
		if (byCurrentTry == 0) {
			// kad packet with NodeID as key
			bKad = true;
			bKadRecvKeyUsed = false;
			if (Kademlia::CKademlia::GetPrefs()) {
				uchar achKeyData[18];
				memcpy(achKeyData, Kademlia::CKademlia::GetPrefs()->GetKadID().GetData(), 16);
				memcpy(achKeyData + 16, pbyBufIn + 1, 2); // random key part sent from remote client
				md5.Calculate(achKeyData, sizeof(achKeyData));
			}
		}
		else if (byCurrentTry == 1) {
			// ed2k packet
			bKad = false;
			bKadRecvKeyUsed = false;
			uchar achKeyData[23];
			md4cpy(achKeyData, thePrefs.GetUserHash());
			achKeyData[20] = MAGICVALUE_UDP;
			memcpy(achKeyData + 16, &dwIP, 4);
			memcpy(achKeyData + 21, pbyBufIn + 1, 2); // random key part sent from remote client
			md5.Calculate(achKeyData, sizeof(achKeyData));
		}
		else if (byCurrentTry == 2) {
			// kad packet with ReceiverKey as key
			bKad = true;
			bKadRecvKeyUsed = true;
			if (Kademlia::CKademlia::GetPrefs()) {
				uchar achKeyData[6];
				PokeUInt32(achKeyData, Kademlia::CPrefs::GetUDPVerifyKey(dwIP));
				memcpy(achKeyData + 4, pbyBufIn + 1, 2); // random key part sent from remote client
				md5.Calculate(achKeyData, sizeof(achKeyData));
			}
		}
		else
			ASSERT( false );

		RC4CreateKey(md5.GetRawHash(), 16, &keyReceiveKey, true);
		RC4Crypt(pbyBufIn + 3, (uchar*)&dwValue, sizeof(dwValue), &keyReceiveKey);
		byCurrentTry = (byCurrentTry + 1) % 3;
	} while (dwValue != MAGICVALUE_UDP_SYNC_CLIENT && byTries > 0); // try to decrypt as ed2k as well as kad packet if needed (max 3 rounds)
	
	if (dwValue == MAGICVALUE_UDP_SYNC_CLIENT){
		// yup this is an encrypted packet
		// debugoutput notices
		// the following cases are "allowed" but shouldn't happen given that there is only our implementation yet
		if (bKad && (pbyBufIn[0] & 0x01) != 0)
			DebugLog(_T("Received obfuscated UDP packet from clientIP: %s with wrong key marker bits (kad packet, ed2k bit)"), ipstr(dwIP));
		else if (bKad && !bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) != 0)
			DebugLog(_T("Received obfuscated UDP packet from clientIP: %s with wrong key marker bits (kad packet, nodeid key, recvkey bit)"), ipstr(dwIP));
		else if (bKad && bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) == 0)
			DebugLog(_T("Received obfuscated UDP packet from clientIP: %s with wrong key marker bits (kad packet, recvkey key, nodeid bit)"), ipstr(dwIP));

		uint8 byPadLen;
		RC4Crypt(pbyBufIn + 7, (uchar*)&byPadLen, 1, &keyReceiveKey);
		nResult -= CRYPT_HEADER_WITHOUTPADDING;
		if (nResult <= byPadLen){
			DebugLogError(_T("Invalid obfuscated UDP packet from clientIP: %s, Paddingsize (%u) larger than received bytes"), ipstr(dwIP), byPadLen);
			return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
		}
		if (byPadLen > 0)
			RC4Crypt(NULL, NULL, byPadLen, &keyReceiveKey);
		nResult -= byPadLen;

		if (bKad){
			if (nResult <= 8){
				DebugLogError(_T("Obfuscated Kad packet with mismatching size (verify keys missing) received from clientIP: %s"), ipstr(dwIP));
				return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk;
			}
			// read the verify keys
			RC4Crypt(pbyBufIn + CRYPT_HEADER_WITHOUTPADDING + byPadLen, (uchar*)nReceiverVerifyKey, 4, &keyReceiveKey);
			RC4Crypt(pbyBufIn + CRYPT_HEADER_WITHOUTPADDING + byPadLen + 4, (uchar*)nSenderVerifyKey, 4, &keyReceiveKey);
			nResult -= 8;
		}
		*ppbyBufOut = pbyBufIn + (nBufLen - nResult);
		RC4Crypt((uchar*)*ppbyBufOut, (uchar*)*ppbyBufOut, nResult, &keyReceiveKey);
		//Xman
		// Maella -Accurate measure of bandwidth: eDonkey data + control, network adapter-
		/*
		theStats.AddDownDataOverheadCrypt(nBufLen - nResult);
		*/
		theApp.pBandWidthControl->AddeMuleInObfuscation(nBufLen - nResult);
		//Xman end
		//DEBUG_ONLY( DebugLog(_T("Received obfuscated UDP packet from clientIP: %s, Key: %s, RKey: %u, SKey: %u"), ipstr(dwIP), bKad ? (bKadRecvKeyUsed ? _T("ReceiverKey") : _T("NodeID")) : _T("UserHash")
		//	, nReceiverVerifyKey != 0 ? *nReceiverVerifyKey : 0, nSenderVerifyKey != 0 ? *nSenderVerifyKey : 0) );
		return nResult; // done
	}
	else{
		DebugLogWarning(_T("Obfuscated packet expected but magicvalue mismatch on UDP packet from clientIP: %s, Possible RecvKey: %u"), ipstr(dwIP), Kademlia::CPrefs::GetUDPVerifyKey(dwIP));
		return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
	}
}
コード例 #13
0
// Encrypt packet. Key used:
// pachClientHashOrKadID != NULL									-> pachClientHashOrKadID
// pachClientHashOrKadID == NULL && bKad && nReceiverVerifyKey != 0 -> nReceiverVerifyKey
// else																-> ASSERT
int CEncryptedDatagramSocket::EncryptSendClient(uchar** ppbyBuf, int nBufLen, const uchar* pachClientHashOrKadID, bool bKad, uint32 nReceiverVerifyKey, uint32 nSenderVerifyKey) const{
	ASSERT( theApp.GetPublicIP() != 0 || bKad );
	ASSERT( thePrefs.IsClientCryptLayerSupported() );
	ASSERT( pachClientHashOrKadID != NULL || nReceiverVerifyKey != 0 );
	ASSERT( (nReceiverVerifyKey == 0 && nSenderVerifyKey == 0) || bKad );

	uint8 byPadLen = 0;			// padding disabled for UDP currently
	const uint32 nCryptHeaderLen = byPadLen + CRYPT_HEADER_WITHOUTPADDING + (bKad ? 8 : 0);
	
	uint32 nCryptedLen = nBufLen + nCryptHeaderLen;
	uchar* pachCryptedBuffer = new uchar[nCryptedLen];
	bool bKadRecKeyUsed = false;
	
	uint16 nRandomKeyPart = (uint16)cryptRandomGen.GenerateWord32(0x0000, 0xFFFF);
	MD5Sum md5;
	if (bKad){
		if ((pachClientHashOrKadID == NULL || isnulmd4(pachClientHashOrKadID)) && nReceiverVerifyKey != 0) {
			bKadRecKeyUsed = true;
			uchar achKeyData[6];
			PokeUInt32(achKeyData, nReceiverVerifyKey);
			PokeUInt16(achKeyData+4, nRandomKeyPart);
			md5.Calculate(achKeyData, sizeof(achKeyData));
			//DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by ReceiverKey (%u)"), nReceiverVerifyKey) );  
		}
		else if (pachClientHashOrKadID != NULL && !isnulmd4(pachClientHashOrKadID)) {
			uchar achKeyData[18];
			md4cpy(achKeyData, pachClientHashOrKadID);
			PokeUInt16(achKeyData+16, nRandomKeyPart);
			md5.Calculate(achKeyData, sizeof(achKeyData));
			//DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by Hash/NodeID %s"), md4str(pachClientHashOrKadID)) );  
		}
		else {
			ASSERT( false );
			delete[] pachCryptedBuffer;
			return nBufLen;
		}
	}
	else{
		uchar achKeyData[23];
		md4cpy(achKeyData, pachClientHashOrKadID);
		uint32 dwIP = theApp.GetPublicIP();
		memcpy(achKeyData+16, &dwIP, 4);
		memcpy(achKeyData+21, &nRandomKeyPart, 2);
		achKeyData[20] = MAGICVALUE_UDP;
		md5.Calculate(achKeyData, sizeof(achKeyData));
	}
	RC4_Key_Struct keySendKey;
	RC4CreateKey(md5.GetRawHash(), 16, &keySendKey, true);

	// create the semi random byte encryption header
	uint8 bySemiRandomNotProtocolMarker = 0;
	int i;
	for (i = 0; i < 128; i++){
		bySemiRandomNotProtocolMarker = cryptRandomGen.GenerateByte();
		bySemiRandomNotProtocolMarker = bKad ? (bySemiRandomNotProtocolMarker & 0xFE) : (bySemiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit
		if (bKad)
			bySemiRandomNotProtocolMarker = bKadRecKeyUsed ? ((bySemiRandomNotProtocolMarker & 0xFE) | 0x02) : (bySemiRandomNotProtocolMarker & 0xFC); // set the ed2k/kad and nodeid/reckey markerbit
		else
			bySemiRandomNotProtocolMarker = (bySemiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit
		
		bool bOk = false;
		switch (bySemiRandomNotProtocolMarker){ // not allowed values
			case OP_EMULEPROT:
			case OP_KADEMLIAPACKEDPROT:
			case OP_KADEMLIAHEADER:
			case OP_UDPRESERVEDPROT1:
			case OP_UDPRESERVEDPROT2:
			case OP_PACKEDPROT:
				break;
			default:
				bOk = true;
		}
		if (bOk)
			break;
	}
	if (i >= 128){
		// either we have _really_ bad luck or the randomgenerator is a bit messed up
		ASSERT( false );
		bySemiRandomNotProtocolMarker = 0x01;
	}

	uint32 dwMagicValue = MAGICVALUE_UDP_SYNC_CLIENT;
	pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker;
	memcpy(pachCryptedBuffer + 1, &nRandomKeyPart, 2);
	RC4Crypt((uchar*)&dwMagicValue, pachCryptedBuffer + 3, 4, &keySendKey);
	RC4Crypt((uchar*)&byPadLen, pachCryptedBuffer + 7, 1, &keySendKey);

	for (int j = 0; j < byPadLen; j++){
		uint8 byRand = (uint8)rand();	// they actually dont really need to be random, but it doesn't hurts either
		RC4Crypt((uchar*)&byRand, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + j, 1, &keySendKey);
	}

	if (bKad){
		RC4Crypt((uchar*)&nReceiverVerifyKey, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen, 4, &keySendKey);
		RC4Crypt((uchar*)&nSenderVerifyKey, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen + 4, 4, &keySendKey);
	}

	RC4Crypt(*ppbyBuf, pachCryptedBuffer + nCryptHeaderLen, nBufLen, &keySendKey);
	delete[] *ppbyBuf;
	*ppbyBuf = pachCryptedBuffer;

	//Xman
	// Maella -Accurate measure of bandwidth: eDonkey data + control, network adapter-
	/*
	theStats.AddUpDataOverheadCrypt(nCryptedLen - nBufLen);
	*/
	theApp.pBandWidthControl->AddeMuleOutObfuscationUDP(nCryptedLen - nBufLen);
	//Xman end

	return nCryptedLen;
}
コード例 #14
0
int CEncryptedDatagramSocket::EncryptSendClient(uchar** ppbyBuf, int nBufLen, const uchar* pachClientHashOrKadID, bool bKad, uint16 nReceiverVerifyKey, uint16 nSenderVerifyKey) const{
	ASSERT( theApp.GetPublicIP() != 0 || bKad );
	ASSERT( thePrefs.IsClientCryptLayerSupported() );

	uint8 byPadLen = 0;			// padding disabled for UDP currently
	const uint32 nCryptHeaderLen = byPadLen + CRYPT_HEADER_WITHOUTPADDING + (bKad ? 4 : 0);
	uint32 nCryptedLen = nBufLen + nCryptHeaderLen;
	uchar* pachCryptedBuffer = new uchar[nCryptedLen];
	
	uint16 nRandomKeyPart = (uint16)cryptRandomGen.GenerateWord32(0x0000, 0xFFFF);
	MD5Sum md5;
	if (bKad){
		uchar achKeyData[18];
		md4cpy(achKeyData, pachClientHashOrKadID);
		memcpy(achKeyData+16, &nRandomKeyPart, 2);
		md5.Calculate(achKeyData, sizeof(achKeyData));
	}
	else{
		uchar achKeyData[23];
		md4cpy(achKeyData, pachClientHashOrKadID);
		uint32 dwIP = theApp.GetPublicIP();
		memcpy(achKeyData+16, &dwIP, 4);
		memcpy(achKeyData+21, &nRandomKeyPart, 2);
		achKeyData[20] = MAGICVALUE_UDP;
		md5.Calculate(achKeyData, sizeof(achKeyData));
	}
	RC4_Key_Struct keySendKey;
	RC4CreateKey(md5.GetRawHash(), 16, &keySendKey, true);

	// create the semi random byte encryption header
	uint8 bySemiRandomNotProtocolMarker = 0;
	int i;
	for (i = 0; i < 128; i++){
		bySemiRandomNotProtocolMarker = cryptRandomGen.GenerateByte();
		bySemiRandomNotProtocolMarker = bKad ? (bySemiRandomNotProtocolMarker & 0xFE) : (bySemiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit

		bool bOk = false;
		switch (bySemiRandomNotProtocolMarker){ // not allowed values
			case OP_EMULEPROT:
			case OP_KADEMLIAPACKEDPROT:
			case OP_KADEMLIAHEADER:
			case OP_UDPRESERVEDPROT1:
			case OP_UDPRESERVEDPROT2:
			case OP_PACKEDPROT:
				break;
			default:
				bOk = true;
		}
		if (bOk)
			break;
	}
	if (i >= 128){
		// either we have _real_ bad luck or the randomgenerator is a bit messed up
		ASSERT( false );
		bySemiRandomNotProtocolMarker = 0x01;
	}

	uint32 dwMagicValue = MAGICVALUE_UDP_SYNC_CLIENT;
	pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker;
	memcpy(pachCryptedBuffer + 1, &nRandomKeyPart, 2);
	RC4Crypt((uchar*)&dwMagicValue, pachCryptedBuffer + 3, 4, &keySendKey);
	RC4Crypt((uchar*)&byPadLen, pachCryptedBuffer + 7, 1, &keySendKey);

	for (int j = 0; j < byPadLen; j++){
		uint8 byRand = (uint8)rand();	// they actually dont really need to be random, but it doesn't hurts either
		RC4Crypt((uchar*)&byRand, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + j, 1, &keySendKey);
	}

	if (bKad){
		RC4Crypt((uchar*)&nReceiverVerifyKey, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen, 2, &keySendKey);
		RC4Crypt((uchar*)&nSenderVerifyKey, pachCryptedBuffer + CRYPT_HEADER_WITHOUTPADDING + byPadLen + 2, 2, &keySendKey);
	}

	RC4Crypt(*ppbyBuf, pachCryptedBuffer + nCryptHeaderLen, nBufLen, &keySendKey);
	delete[] *ppbyBuf;
	*ppbyBuf = pachCryptedBuffer;

	theStats.AddUpDataOverheadCrypt(nCryptedLen - nBufLen);
	return nCryptedLen;
}
コード例 #15
0
int CEncryptedDatagramSocket::DecryptReceivedClient(BYTE* pbyBufIn, int nBufLen, BYTE** ppbyBufOut, uint32 dwIP, uint16* nReceiverVerifyKey, uint16* nSenderVerifyKey) const{
	int nResult = nBufLen;
	*ppbyBufOut = pbyBufIn;
	
	if (nResult <= CRYPT_HEADER_WITHOUTPADDING /*|| !thePrefs.IsClientCryptLayerSupported()*/)
		return nResult;

	if (nReceiverVerifyKey == NULL || nSenderVerifyKey == NULL){
		ASSERT( false );
		return nResult;
	}
	
	switch (pbyBufIn[0]){
		case OP_EMULEPROT:
		case OP_KADEMLIAPACKEDPROT:
		case OP_KADEMLIAHEADER:
		case OP_UDPRESERVEDPROT1:
		case OP_UDPRESERVEDPROT2:
		case OP_PACKEDPROT:
			return nResult; // no encrypted packet (see description on top)
	}
	bool bKad = (pbyBufIn[0] & 0x01) == 0; // check the marker bit if this is a kad or ed2k packet, this is only an indicator since old clients have it set random
	// might be an encrypted packet, try to decrypt
	
	RC4_Key_Struct keyReceiveKey;
	uint32 dwValue = 0;
	bool bFlipTry = false;
	do{
		bKad = bFlipTry ? !bKad : bKad;
		MD5Sum md5;
		if (bKad){
			if (Kademlia::CKademlia::GetPrefs()) {
				uchar achKeyData[18];
				memcpy(achKeyData, Kademlia::CKademlia::GetPrefs()->GetKadID().GetData(), 16);
				memcpy(achKeyData + 16, pbyBufIn + 1, 2); // random key part sent from remote client
				md5.Calculate(achKeyData, sizeof(achKeyData));
			}
		}
		else{
			uchar achKeyData[23];
			md4cpy(achKeyData, thePrefs.GetUserHash());
			achKeyData[20] = MAGICVALUE_UDP;
			memcpy(achKeyData + 16, &dwIP, 4);
			memcpy(achKeyData + 21, pbyBufIn + 1, 2); // random key part sent from remote client
			md5.Calculate(achKeyData, sizeof(achKeyData));
		}
		RC4CreateKey(md5.GetRawHash(), 16, &keyReceiveKey, true);
		RC4Crypt(pbyBufIn + 3, (uchar*)&dwValue, sizeof(dwValue), &keyReceiveKey);
		bFlipTry = !bFlipTry; // next round try the other possibility
	} while (dwValue != MAGICVALUE_UDP_SYNC_CLIENT && bFlipTry); // try to decrypt as ed2k as well as kad packet if needed (max 2 rounds)
	
	if (dwValue == MAGICVALUE_UDP_SYNC_CLIENT){
		// yup this is an encrypted packet
		DEBUG_ONLY( DebugLog(_T("Received obfuscated UDP packet from clientIP: %s"), ipstr(dwIP)) );
		uint8 byPadLen;
		RC4Crypt(pbyBufIn + 7, (uchar*)&byPadLen, 1, &keyReceiveKey);
		nResult -= CRYPT_HEADER_WITHOUTPADDING;
		if (nResult <= byPadLen){
			DebugLogError(_T("Invalid obfuscated UDP packet from clientIP: %s, Paddingsize (%u) larger than received bytes"), ipstr(dwIP), byPadLen);
			return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
		}
		if (byPadLen > 0)
			RC4Crypt(NULL, NULL, byPadLen, &keyReceiveKey);
		nResult -= byPadLen;

		if (bKad){
			if (nResult <= 4){
				DebugLogError(_T("Obfuscated Kad packet with mismatching size (verify keys missing) received from clientIP: %s"), ipstr(dwIP));
				return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk;
			}
			// read the verify keys
			*nReceiverVerifyKey = PeekUInt16(pbyBufIn + CRYPT_HEADER_WITHOUTPADDING + byPadLen);
			*nSenderVerifyKey = PeekUInt16(pbyBufIn + CRYPT_HEADER_WITHOUTPADDING + byPadLen + 2);
			nResult -= 4;
		}
		else{
			*nReceiverVerifyKey = 0;
			*nSenderVerifyKey = 0;
		}
		*ppbyBufOut = pbyBufIn + (nBufLen - nResult);
		RC4Crypt((uchar*)*ppbyBufOut, (uchar*)*ppbyBufOut, nResult, &keyReceiveKey);
		theStats.AddDownDataOverheadCrypt(nBufLen - nResult);
		return nResult; // done
	}
	else{
		DebugLogWarning(_T("Obfuscated packet expected but magicvalue mismatch on UDP packet from clientIP: %s"), ipstr(dwIP));
		return nBufLen; // pass through, let the Receivefunction do the errorhandling on this junk
	}
}
コード例 #16
0
ファイル: main.c プロジェクト: gonboy/ChatServer
void* SomeAwesomeThings(void* Param){
	Client* theClient = (Client*)Param;
	char* message = (char*)malloc(4086);
	char sendMessage[4086];
	char encrypt[4086];
	char* receiver;
	char* tmp;
	char* ender;
	char* err;
	Client* ClientCounter;
	int msgSize;
	int usernameSet = 0;
	int nameLength;
	int sub_msg_len;
	int encrypt_len;

	//RC4 component
	RC4Container RC4key;
	int iter1;
	int iter2;
	RC4key.iter1 = &iter1;
	RC4key.iter2 = &iter2;
	int RC4KeySet = 0;
	//
	unsigned char hash_out[SHA_DIGEST_LENGTH + 1];
	char hash_string[SHA_DIGEST_LENGTH * 2 + 1];
	int iterator;
	memset(sendMessage, '\0', sizeof(sendMessage));
	err = (char*) malloc(130);

	//    if((msgSize = read(theClient->sockfd, message, sizeof(message) - 1)) > 0){
	//        message[msgSize] = '\0';
	//        int nameLength = strstr(message, "\r\n.\r\n") - message;
	//        for(msgSize = 0; msgSize < nameLength; msgSize++){
	//            theClient->Name[msgSize] = message[msgSize];
	//        }
	//        theClient->Name[nameLength] = '\0';
	//        printf("%s has connected\n", theClient->Name);
	//    }


	while((msgSize = read(theClient->sockfd, message, 4086 - 1)) > 0){

		message[msgSize] = '\0';
		sub_msg_len = 0;
		while((ender = strstr(message, "\r\n.\r\n")) != NULL){
			//            *ender = '\0';
			sub_msg_len += ender - message + 5;
			if(sub_msg_len > msgSize)
				break;

			//            printf("%s\n", message);
			//Do things here
			tmp = strstr(message, "\r\n");
			*tmp = '\0';
			printf("%s\n", message);
			if(strcmp(message, "Mode: Public") == 0){

				tmp = tmp + 2;
				nameLength = strstr(tmp, "\r\n.\r\n") - tmp + 5;
				sprintf(sendMessage,"%s\r\nUser: %s\r\n", message, theClient->Name);
				strncat(sendMessage, tmp, nameLength);

				for(ClientCounter = head; ClientCounter != NULL; ClientCounter = ClientCounter->Next){
					if(ClientCounter == theClient) continue;
					write(ClientCounter->sockfd, sendMessage, sizeof(sendMessage));
				}
			}
			else if((strcmp(message, "Mode: Private") == 0) || (strcmp(message, "Mode: InitPriv") == 0) || (strcmp(message, "Mode: AccPriv") == 0) ){

				tmp = tmp + 2;
				tmp = strstr(tmp, " ") + 1;
				receiver = tmp;
				tmp = strstr(tmp, "\r\n");
				*tmp = '\0';
				tmp = tmp + 2;
				nameLength = strstr(tmp, "\r\n.\r\n") - tmp + 5;

				sprintf(sendMessage,"%s\r\nUser: %s\r\n", message, theClient->Name);
				strncat(sendMessage, tmp, nameLength);

				for(ClientCounter = head; ClientCounter != NULL; ClientCounter = ClientCounter->Next){
					if(strcmp(receiver, ClientCounter->Name) == 0){
						write(ClientCounter->sockfd, sendMessage, sizeof(sendMessage));
						break;
					}
				}
			}
			else if(strcmp(message, "Mode: GetList") == 0){
				sprintf(sendMessage, "Mode: List\r\n");
				for(ClientCounter = head; ClientCounter != NULL; ClientCounter = ClientCounter->Next){
					if(ClientCounter == theClient)continue;
					strcat(sendMessage, ClientCounter->Name);
					strcat(sendMessage, "\r\n");
				}
				strcat(sendMessage, "\r\n.\r\n");

				write(theClient->sockfd, sendMessage, sizeof(sendMessage));
			}
			else if(strcmp(message, "Mode: Username") == 0){
				tmp = tmp + 2;
				if(usernameSet == 0){
					if(RC4KeySet == 1){
						printf("Setting username\n");
						nameLength = strstr(tmp, "\r\n.\r\n") - tmp;
						char* decode;
						int decode_len = Base64decode(tmp, (unsigned char**)&decode, nameLength);
						encrypt_len = RC4Crypt(decode_len, (unsigned char*)decode, (unsigned char*)encrypt, &RC4key);

						free(decode);

						tmp = strstr(encrypt, "\r\n.,\r\n");
						nameLength = tmp - encrypt;
						*tmp = '\0';
						tmp = tmp + 6;

						if(CheckHashValidation(nameLength, (unsigned char*)encrypt, tmp) == 1){
							for(msgSize = 0; msgSize < nameLength; msgSize++){
								theClient->Name[msgSize] = *(encrypt + msgSize);
							}
							theClient->Name[nameLength] = '\0';
							printf("%s\n", theClient->Name);
							usernameSet++;
						}
					}
				}
			}
			else if(strcmp(message, "Mode: GetCA") == 0){
				sprintf(sendMessage, "Mode: ServCA\r\n");
				strcat(sendMessage, public_key);
				strcat(sendMessage, "\r\n.\r\n");

				write(theClient->sockfd, sendMessage, sizeof(sendMessage));
			}
			else if(strcmp(message, "Mode: SetPubKey") == 0){
				tmp = tmp + 2;
				nameLength = strstr(tmp, "\r\n.\r\n") - tmp;
				if(RC4KeySet == 1){
					char* decoded;
					int decoded_len = Base64decode(tmp, (unsigned char**)&decoded, nameLength);
					encrypt_len = RC4Crypt(decoded_len, (unsigned char*)decoded, (unsigned char*)encrypt, &RC4key);
					free(decoded);
					encrypt[encrypt_len] = '\0';
					tmp = strstr(encrypt, "\r\n.,\r\n");
					nameLength = tmp - encrypt;
					*tmp = '\0';
					tmp = tmp + 6;
					if(CheckHashValidation(nameLength, (unsigned char*)encrypt, tmp) == 1){
						for(iterator = 0; iterator < nameLength; iterator++){
							*(theClient->public_key + iterator) = *(encrypt + iterator);
						}
						*(theClient->public_key + nameLength) = '\0';
					}
					else{
						//TODO: Return some error
						printf("Failed to set public key\n");
						sprintf(sendMessage, "Mode: FailPubKey\r\n.\r\n");
						write(theClient->sockfd, sendMessage, sizeof(sendMessage));
					}
				}
			}
			else if(strcmp(message, "Mode: SetRC4Key") == 0){
				if(RC4KeySet == 0){
					tmp = tmp + 2;
					nameLength = strstr(tmp, "\r\n.\r\n") - tmp;
					char* decoded;
					int dedoded_len = Base64decode(tmp, (unsigned char**)&decoded, nameLength);
					if((encrypt_len = private_decrypt((unsigned char*)decoded, dedoded_len, (unsigned char*)private_key, (unsigned char*)encrypt, RSA_PKCS1_OAEP_PADDING)) == -1){
						ERR_load_crypto_strings();
						ERR_error_string(ERR_get_error(), err);
						fprintf(stderr, "Error decrypting message: %s\n", err);
						sprintf(sendMessage, "Mode: FailRC4Key\r\n.\r\n");
						write(theClient->sockfd, sendMessage, sizeof(sendMessage));
					}
					else{
						tmp = strstr(encrypt, "\r\n.,\r\n");
						nameLength = tmp - encrypt;
						*tmp = '\0';
						tmp = tmp + 6;
						//TODO: Check if hash of encrypt is the same with tmp
						if(CheckHashValidation(nameLength, (unsigned char*)encrypt, tmp) == 1){
							initRC4key(&RC4key, encrypt, nameLength);
							RC4KeySet = 1;
						}
						else{
							sprintf(sendMessage, "Mode: FailRC4Key\r\n.\r\n");
							write(theClient->sockfd, sendMessage, sizeof(sendMessage));
						}
					}
					free(decoded);
				}
			}
			else if(strcmp(message, "Mode: GetPubKey") == 0){
				tmp = tmp + 2;
				tmp = strstr(tmp, " ") + 1;
				receiver = tmp;
				tmp = strstr(tmp, "\r\n");
				*tmp = '\0';
				for(ClientCounter = head; ClientCounter != NULL; ClientCounter = ClientCounter->Next){
					if(strcmp(receiver, ClientCounter->Name) == 0)
						break;
				}
				if(ClientCounter != NULL){
					if(ClientCounter->public_key[0] != '\0' && RC4KeySet == 1){
						SHA1((unsigned char*)ClientCounter->public_key, strlen(ClientCounter->public_key), (unsigned char*)hash_out);
						for(iterator = 0; iterator < SHA_DIGEST_LENGTH; iterator++){
							sprintf(&hash_string[iterator * 2], "%02x", (unsigned int)hash_out[iterator]);
						}
						sprintf(sendMessage, "%s\r\n.,\r\n%s", ClientCounter->public_key, hash_string);
						encrypt_len = RC4Crypt(strlen(sendMessage), (unsigned char*)sendMessage, (unsigned char*)encrypt, &RC4key);
						encrypt[encrypt_len] = '\0';
						char* encoded;
						int encoded_len = Base64encode(encrypt, encrypt_len, &encoded);
						encoded[encoded_len] = '\0';
						sprintf(sendMessage, "Mode: ClientPubKey\r\nUser: %s\r\n%s\r\n.\r\n", ClientCounter->Name, encoded);
						free(encoded);
						printf("%s\n", sendMessage);
						printf("%s\n", ClientCounter->public_key);
						write(theClient->sockfd, sendMessage, sizeof(sendMessage));
					}
					else{
						sprintf(sendMessage, "Mode: FailPubKey\r\nUser: %s\r\n.\r\n", ClientCounter->Name);
					}
				}
			}

			*ender = '\0';
			ender += 5;
			message = ender;
		}
	}

	printf("%s has been disconnected\n", theClient->Name);
	if(theClient == head){
		head = theClient->Next;
		if(head != NULL)head->Previous = NULL;
		else tail = NULL;
	}
	else{
		theClient->Previous->Next = theClient->Next;
		if(theClient == tail){
			tail = theClient->Previous;
		}
	}
	if(theClient->keypair != NULL)
		RSA_free(theClient->keypair);
	free(theClient);

	return NULL;
}
コード例 #17
0
int CEncryptedStreamSocket::Receive(void* lpBuf, int nBufLen, int nFlags){
	m_nObfuscationBytesReceived = CAsyncSocketEx::Receive(lpBuf, nBufLen, nFlags);
	m_bFullReceive = m_nObfuscationBytesReceived == (uint32_t)nBufLen;

	if(m_nObfuscationBytesReceived == SOCKET_ERROR || m_nObfuscationBytesReceived <= 0){
		return m_nObfuscationBytesReceived;
	}
	switch (m_StreamCryptState) {
		case ECS_NONE: // disabled, just pass it through
			return m_nObfuscationBytesReceived;
		case ECS_PENDING:
		case ECS_PENDING_SERVER:
			ASSERT( false );
			DebugLogError(_T("CEncryptedStreamSocket Received data before sending on outgoing connection"));
			m_StreamCryptState = ECS_NONE;
			return m_nObfuscationBytesReceived;
		case ECS_UNKNOWN:{
			uint32_t nRead = 1;
			bool bNormalHeader = false;
			switch (((uchar*)lpBuf)[0]){
				case OP_EDONKEYPROT:
				case OP_PACKEDPROT:
				case OP_EMULEPROT:
					bNormalHeader = true;
					break;
			}
			if (!bNormalHeader){
				StartNegotiation(false);
				const uint32_t nNegRes = Negotiate((uchar*)lpBuf + nRead, m_nObfuscationBytesReceived - nRead);
				if (nNegRes == (-1))
					return 0;
				nRead += nNegRes;
				if (nRead != (uint32_t)m_nObfuscationBytesReceived){
					// this means we have more data then the current negotiation step required (or there is a bug) and this should never happen
					// (note: even if it just finished the handshake here, there still can be no data left, since the other client didnt received our response yet)
					DebugLogError(_T("CEncryptedStreamSocket: Client %s sent more data then expected while negotiating, disconnecting (1)"), DbgGetIPString());
					OnError(ERR_ENCRYPTION);
				}
				return 0;
			}
			else{
				// doesn't seems to be encrypted
				m_StreamCryptState = ECS_NONE;

				// if we require an encrypted connection, cut the connection here. This shouldn't happen that often
				// at least with other up-to-date eMule clients because they check for incompability before connecting if possible
				if (thePrefs.IsClientCryptLayerRequired()){
					// TODO: Remove me when i have been solved
					// Even if the Require option is enabled, we currently have to accept unencrypted connection which are made
					// for lowid/firewall checks from servers and other from us selected client. Otherwise, this option would
					// always result in a lowid/firewalled status. This is of course not nice, but we can't avoid this walkarround
					// untill servers and kad completely support encryption too, which will at least for kad take a bit
					// only exception is the .ini option ClientCryptLayerRequiredStrict which will even ignore test connections
					// Update: New server now support encrypted callbacks

					SOCKADDR_IN sockAddr = {0};
					int nSockAddrLen = sizeof(sockAddr);
					GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);		
					if (thePrefs.IsClientCryptLayerRequiredStrict() || (!theApp.serverconnect->AwaitingTestFromIP(sockAddr.sin_addr.S_un.S_addr)
						&& !theApp.clientlist->IsKadFirewallCheckIP(sockAddr.sin_addr.S_un.S_addr)) )
					{
#if defined(_DEBUG) || defined(_BETA)
					// TODO: Remove after testing
					AddDebugLogLine(DLP_DEFAULT, false, _T("Rejected incoming connection because Obfuscation was required but not used %s"), DbgGetIPString() );
#endif
						OnError(ERR_ENCRYPTION_NOTALLOWED);
						return 0;
					}
					else
						AddDebugLogLine(DLP_DEFAULT, false, _T("Incoming unencrypted firewallcheck connection permitted despite RequireEncryption setting  - %s"), DbgGetIPString() );
				}

				return m_nObfuscationBytesReceived; // buffer was unchanged, we can just pass it through
			}
		}
		case ECS_ENCRYPTING:
			// basic obfuscation enabled and set, so decrypt and pass along
			RC4Crypt((uchar*)lpBuf, (uchar*)lpBuf, m_nObfuscationBytesReceived, m_pRC4ReceiveKey);
			return m_nObfuscationBytesReceived;
		case ECS_NEGOTIATING:{
			const uint32_t nRead = Negotiate((uchar*)lpBuf, m_nObfuscationBytesReceived);
			if (nRead == (-1))
				return 0;
			else if (nRead != (uint32_t)m_nObfuscationBytesReceived && m_StreamCryptState != ECS_ENCRYPTING){
				// this means we have more data then the current negotiation step required (or there is a bug) and this should never happen
				DebugLogError(_T("CEncryptedStreamSocket: Client %s sent more data then expected while negotiating, disconnecting (2)"), DbgGetIPString());
				OnError(ERR_ENCRYPTION);
				return 0;
			}
			else if (nRead != (uint32_t)m_nObfuscationBytesReceived && m_StreamCryptState == ECS_ENCRYPTING){
				// we finished the handshake and if we this was an outgoing connection it is allowed (but strange and unlikely) that the client sent payload
				DebugLogWarning(_T("CEncryptedStreamSocket: Client %s has finished the handshake but also sent payload on a outgoing connection"), DbgGetIPString());
				memmove(lpBuf, (uchar*)lpBuf + nRead, m_nObfuscationBytesReceived - nRead);
				return m_nObfuscationBytesReceived - nRead;
			}
			else
				return 0;
		}
		default:
			ASSERT( false );
			return m_nObfuscationBytesReceived;
	}
}
コード例 #18
0
ファイル: warden.cpp プロジェクト: kwolekr/horizon
void WardenParseCommand0(char *data, int len, int index) {
	char buf[128];
	unsigned char outbuf;
	*(__int32 *)(modname) = 'udom';	
	*(__int32 *)(modname + 4) = '\\sel';
	for (int i = 0; i != 16; i++)
		sprintf(modname + 8 + (i << 1), "%02x", (unsigned char)data[i + 1]);
	modname[40] = '.';
	*(int *)(modname + 41) = 'dom';
	sprintf(buf, "Warden module %s requested.", modname + 8);
	AddChat(vbYellow, buf, bot[index]->hWnd_rtfChat);
	if (currentmodule) {
		if (cmphash(modhash, data + 1)) {
			AddChat(vbGreen, "Module already loaded, using that.", bot[index]->hWnd_rtfChat);
			goto send1;
		} else {
			WardenUnloadModule();
			AddChat(vbYellow, "New warden module requested, loading that.", bot[index]->hWnd_rtfChat);
			goto contwprocessing;
		}
	} else {
contwprocessing:
		__asm {
			cld
			mov esi, data
			inc esi
			lea edi, [modhash]
			movsd
			movsd
			movsd
			movsd
			lea edi, [moddecryptkey]
			movsd
			movsd
			movsd
			movsd
			lea edi, [modsize]
			movsd
		}  
		/**(__int32 *)(modhash)        = *(__int32 *)(data + 1);
		*(__int32 *)(modhash + 0x04) = *(__int32 *)(data + 5);
		*(__int32 *)(modhash + 0x08) = *(__int32 *)(data + 9);
		*(__int32 *)(modhash + 0x0C) = *(__int32 *)(data + 13);

		*(__int32 *)(moddecryptkey)	       = *(__int32 *)(data + 17);
		*(__int32 *)(moddecryptkey + 0x04) = *(__int32 *)(data + 21);
		*(__int32 *)(moddecryptkey + 0x08) = *(__int32 *)(data + 25);
		*(__int32 *)(moddecryptkey + 0x0C) = *(__int32 *)(data + 29);

		modsize = *(__int32 *)(data + 33);
		*/
		if (GetFileAttributes(modname) == INVALID_FILE_ATTRIBUTES) {
			if (dling) {
				AddChat(vbYellow, "Module already being downloaded, waiting!", bot[index]->hWnd_rtfChat); 
				goto send1;
			}
			AddChat(vbYellow, "Module not found, downloading...", bot[index]->hWnd_rtfChat);
			rawmodule = (char *)malloc(modsize);
			moddlprog = 0;
			outbuf = 0;
			startedtick = GetTickCount();
			dling = 1;
		} else {
			WardenPrepareModule(modname);
			WardenModuleInitalize((LPWMODHEADER)currentmodule);
send1:
			outbuf = 1;
		}
	}
	RC4Crypt(bot[index]->wardenkey_out, &outbuf, 1);
	InsertByte(outbuf);
	SendPacket(0x5E, index);
}