Hello everyone,

I am trying to get an XTEA algorithm to work. I read the key from another process of which I'm sure it has a valid key at a specific location in memory.

My encryption algorithm seemed to work, but when I tested it by making a buffer, encrypting and then decrypting I found out that it did not match the buffer.

I also hate the amount of char[3] to unsigned char* etc, etc conversions. I'm not rather good at trowing around variables so this really is hell to me.

Several things I'm sure of:
The key has 16 characters
The size of the packets gets rounded up to 8 correctly
It does not crash
As long as the key stays the same so do the packets (buffer, encrypted and decrypted)
I am using MSVC++ on Windows XP

My code so far:

// xtea.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <windows.h>

using namespace std;

unsigned char TEAKey[130];
HANDLE processHandle;
unsigned char* outbuf;
unsigned char* outbuffer;

#define ENCRYPT_KEY			0x0074B1A0 //The XTEA Key that is used for encrypting the packets



void GetEncryptionKey();
int Encrypt(unsigned char buf[], int length, unsigned char key[], 

unsigned char** outbuf);
unsigned char* Decrypt(unsigned char buf[], int length, unsigned char key[]);



int main(int argc, char* argv[])
{
	HWND hWnd; DWORD processId;
	hWnd = FindWindow("tibiaclient", NULL);	
	GetWindowThreadProcessId(hWnd, &processId);
	processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
	GetEncryptionKey();
	cout << "Starting to get XTEA key" << endl;
	cout << "XTEA Key: \t \t" << TEAKey << endl;

	 char buffer[2];
	 buffer[0] = 0x11;
	 buffer[1] = 0x05;
	 buffer[2] = 0x14;


	 cout << "Characters put inside buffer \n";
	 cout << "Original buffer:  \t"  << buffer[0] << buffer[1] << buffer[2] << buffer[3] << endl;
	 unsigned char* orig;
	 orig = (unsigned char*)buffer;
	 cout << "orig casted: \t\t" << orig << endl;
	 //std::cout << packet << endl;
	 
	 int len;
	 cout << "Encrypting... \n";
	 len = Encrypt((unsigned char*)buffer, 3, (unsigned char*)TEAKey, &outbuf);

	 cout << "Size of encrypted string: \t"<< len << endl;
	

	 unsigned char* decrypted;
	 //decrypted = Decrypt(outbuf, len, TEAKey);
	 //cout << "Decrypted: \t \t" << &decrypted << endl;

	return 0;
}


void GetEncryptionKey()
{
		// 0x006BFD70f
		//ReadProcessMemory(hTibiaHandle, (void*)lCheckPos, szTemp, 1, &nSize);

		SIZE_T readlen = 0;
		ReadProcessMemory(processHandle, (LPVOID)ENCRYPT_KEY, TEAKey, 16, &readlen);
}


int Encrypt(unsigned char buf[], int length, unsigned char key[], unsigned char** outbuf)
{
  if ((buf == NULL) || (key == NULL))
    return -1;

  int newsize = ((length+1)/8+1) * 8; // round up by 8
  *outbuf = new unsigned char[newsize+2];

  unsigned long delta = 0x9e3779b9;                   /* a key schedule constant */
  unsigned long sum;

  int n = 0;
  while (n < length)
  {
    sum = 0;
    unsigned long v0 = *((unsigned long*)(buf+n));
    unsigned long v1 = *((unsigned long*)(buf+n+4));

    for(int i=0; i < 32; i++)
    {
        v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((unsigned long*)key)[sum & 3]);
        sum += delta;
        v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((unsigned long*)key)[sum>>11 & 3]);
    }

    *((unsigned long*)(*outbuf+n+2)) = v0;
    *((unsigned long*)(*outbuf+n+6)) = v1;

    n += 8;
  }
  
  // put length back in the package 
  (*outbuf)[0] = newsize & 0xFF;
  (*outbuf)[1] = (newsize >> 8) & 0xFF;
  cout << "finished encrypting... \n";
  cout << "encrypted: \t \t-" << (char*)outbuf << "-" << endl;
  
	 unsigned char* decrypted;
	 cout << "starting to decrypt... \n";
	 decrypted = Decrypt((*outbuf), sizeof(outbuf), TEAKey);
	 cout << "Decrypted: \t \t" << decrypted << endl;
  return newsize+2;
}

unsigned char* Decrypt(unsigned char buf[], int length, unsigned char key[])
{
  if ((buf == NULL) || (key == NULL))
    return NULL;

  unsigned long delta = 0x9e3779b9;                   /* a key schedule constant */
  unsigned long sum;

  unsigned char* retbuf = new unsigned char[length];

  int n = 0;
  while (n < length)
  {
    sum = 0xC6EF3720;
    unsigned long v0 = *((unsigned long*)(buf+n));
    unsigned long v1 = *((unsigned long*)(buf+n+4));

    for(int i=0; i<32; i++)
    {
        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((unsigned long*)key)[sum>>11 & 3]);
        sum -= delta;
        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((unsigned long*)key)[sum & 3]);
    }

    *((unsigned long*)(retbuf+n))   = v0;
    *((unsigned long*)(retbuf+n+4)) = v1;

    n += 8;
  }
  cout << "finished decrypting, value of retbuf: \n";
  cout << "end of decrypt: \t" << retbuf << endl;
  return retbuf;
}

Recommended Answers

All 13 Replies

char buffer[2];
buffer[0] = 0x11;
buffer[1] = 0x05;
buffer[2] = 0x14;

be carefull, the size of buffer is 2 bytes and U assigned 3 bytes so this is a bug.

You're right, but it does not fix the problem.

Thanks anyway,
Eddy

I thought i would help but am getting this output.

Starting to get XTEA key
XTEA Key:
Characters put inside buffer
Original buffer:        ◄♣¶
orig casted:            ◄♣¶
Encrypting...
finished encrypting...
encrypted:              -ÿ
ä-
starting to decrypt...
finished decrypting, value of retbuf:
end of decrypt:         ╥ÿφ4╩╠≈⌠½½½½ε■ε■
Decrypted:              ╥ÿφ4╩╠≈⌠½½½½ε■ε■
Size of encrypted string:       10

Is this what you are getting ?
Just wanted to confirm.

Bye.

Because you don't have the program I load the key from, XTEAKey doesn't contain a key.

A key I get is ~9p<›¸*%-Zvæ7‘ .

But as you probably notice my computer can't handle some of these characters.

Let's all use aaaaaaaaaaaaaaaa (16*a) as key, okay?

New source (without the key-thingy):

// xtea.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <windows.h>

using namespace std;

unsigned char TEAKey[130] = "aaaaaaaaaaaaaaaa";
HANDLE processHandle;
unsigned char* outbuf;
unsigned char* outbuffer;




/*void GetEncryptionKey();*/
int Encrypt(unsigned char buf[], int length, unsigned char key[], unsigned char** outbuf);
unsigned char* Decrypt(unsigned char buf[], int length, unsigned char key[]);



int main(int argc, char* argv[])
{
	HWND hWnd; DWORD processId;
	hWnd = FindWindow("tibiaclient", NULL);	
	GetWindowThreadProcessId(hWnd, &processId);
	processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
	/*GetEncryptionKey();*/
	//cout << "Starting to get XTEA key" << endl;
	cout << "XTEA Key: \t \t" << TEAKey << endl;

	 char buffer[3];
	 buffer[0] = 0x11;
	 buffer[1] = 0x05;
	 buffer[2] = 0x14;


	 cout << "Characters put inside buffer \n";
	 cout << "Original buffer:  \t"  << buffer[0] << buffer[1] << buffer[2] << buffer[3] << endl;
	 unsigned char* orig;
	 orig = (unsigned char*)buffer;
	 cout << "orig casted: \t\t" << orig << endl;
	 //std::cout << packet << endl;
	 
	 int len;
	 cout << "Encrypting... \n";
	 len = Encrypt((unsigned char*)buffer, 3, (unsigned char*)TEAKey, &outbuf);

	 cout << "Size of encrypted string: \t"<< len << endl;
	

	 unsigned char* decrypted;
	 //decrypted = Decrypt(outbuf, len, TEAKey);
	 //cout << "Decrypted: \t \t" << &decrypted << endl;

	return 0;
}


/*void GetEncryptionKey()
{
		// 0x006BFD70f
		//ReadProcessMemory(hTibiaHandle, (void*)lCheckPos, szTemp, 1, &nSize);

		SIZE_T readlen = 0;
		ReadProcessMemory(processHandle, (LPVOID)ENCRYPT_KEY, TEAKey, 16, &readlen);
}*/


int Encrypt(unsigned char buf[], int length, unsigned char key[], unsigned char** outbuf)
{
  if ((buf == NULL) || (key == NULL))
    return -1;

  int newsize = ((length+1)/8+1) * 8; // round up by 8
  *outbuf = new unsigned char[newsize+2];

  unsigned long delta = 0x9e3779b9;                   /* a key schedule constant */
  unsigned long sum;

  int n = 0;
  while (n < length)
  {
    sum = 0;
    unsigned long v0 = *((unsigned long*)(buf+n));
    unsigned long v1 = *((unsigned long*)(buf+n+4));

    for(int i=0; i < 32; i++)
    {
        v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((unsigned long*)key)[sum & 3]);
        sum += delta;
        v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((unsigned long*)key)[sum>>11 & 3]);
    }

    *((unsigned long*)(*outbuf+n+2)) = v0;
    *((unsigned long*)(*outbuf+n+6)) = v1;

    n += 8;
  }
  
  // put length back in the package 
  (*outbuf)[0] = newsize & 0xFF;
  (*outbuf)[1] = (newsize >> 8) & 0xFF;
  cout << "finished encrypting... \n";
  cout << "encrypted: \t \t-" << (char*)outbuf << "-" << endl;
  
	 unsigned char* decrypted;
	 cout << "starting to decrypt... \n";
	 decrypted = Decrypt((*outbuf), sizeof(outbuf), TEAKey);
	 cout << "Decrypted: \t \t" << decrypted << endl;
  return newsize+2;
}

unsigned char* Decrypt(unsigned char buf[], int length, unsigned char key[])
{
  if ((buf == NULL) || (key == NULL))
    return NULL;

  unsigned long delta = 0x9e3779b9;                   /* a key schedule constant */
  unsigned long sum;

  unsigned char* retbuf = new unsigned char[length];

  int n = 0;
  while (n < length)
  {
    sum = 0xC6EF3720;
    unsigned long v0 = *((unsigned long*)(buf+n));
    unsigned long v1 = *((unsigned long*)(buf+n+4));

    for(int i=0; i<32; i++)
    {
        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((unsigned long*)key)[sum>>11 & 3]);
        sum -= delta;
        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((unsigned long*)key)[sum & 3]);
    }

    *((unsigned long*)(retbuf+n))   = v0;
    *((unsigned long*)(retbuf+n+4)) = v1;

    n += 8;
  }
  cout << "finished decrypting, value of retbuf: \n";
  cout << "end of decrypt: \t" << retbuf << endl;
  return retbuf;
}

I know the error is in the encryption function now, because it ALWAYS returns the same, no matter what the key is.

Thanks for your time,
Eddy

I still didn't fix it. The decrypted string is not equal to the buffer I start with.

Anyone, please help me. I posted the code in above post.


Greetz, Eddy

Maybe this would help you finding the actual fault in your program:

void encipher(unsigned int num_rounds, unsigned long* v, unsigned long* k) {
    unsigned long v0=v[0], v1=v[1], i;
    unsigned long sum=0, delta=0x9E3779B9;
    for(i=0; i<num_rounds; i++) {
        v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
        sum += delta;
        v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
    }
    v[0]=v0; v[1]=v1;
}

void decipher(unsigned int num_rounds, unsigned long* v, unsigned long* k) {
    unsigned long v0=v[0], v1=v[1], i;
    unsigned long delta=0x9E3779B9, sum=delta*num_rounds;
    for(i=0; i<num_rounds; i++) {
        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
        sum -= delta;
        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
    }
    v[0]=v0; v[1]=v1;

}

Hope it helped, bye.

That's the same as my code, except that my code splits it into 8-byte blocks... Thanks for your reply, but unfortunately it didn't help.


Greetz, Eddy

That's the same as my code, except that my code splits it into 8-byte blocks... Thanks for your reply, but unfortunately it didn't help.
Greetz, Eddy

Can you please post the output you are getting as well as a bit briefing on the feat you are trying to achieve and the program specifications ?
Maybe then i can try to do somehting.

Hope i am not asking too much, bye.

What I want to achieve:
I want to be able to encrypt and decrypt data with an XTEA algorithm. The key will get loaded from an external program.

What am I trying to do in the given code:
In the code I am trying to make a buffer, encode it and decode it and see if it has changed (If the buffer is the same as the output).

Program specifications:
At the moment all code I have is what is posted above. As soon as it's finished I will use this encryption algorithm to let 2 programs communicate using encrypted data.

Where I think the problem is:
The encryption. The encryption-output is smaller then the start-buffer.


Of course you're not asking too much, but I have a feeling that I'm not asking too much either, but still having only one member actively helping with problem (obviously ~S.O.S~) which might've caused my annoyed attitude before. My apologies.

'
Greetz, Eddy

What is my problem:
The buffer I start with is not the same as the output

Have you actually looked through your code, line by line (possibly while debugging)? How about these lines, in the encryption function:

// put length back in the package 
(*outbuf)[0] = newsize & 0xFF;
(*outbuf)[1] = (newsize >> 8) & 0xFF;

You seem to completely ignore that the first two bytes of the output buffer are not encrypted data when you go to decrypt:

unsigned long v0 = *((unsigned long*)(buf+n));
unsigned long v1 = *((unsigned long*)(buf+n+4));
//try
unsigned long v0 = *((unsigned long*)(buf+n+2));
unsigned long v1 = *((unsigned long*)(buf+n+6));

And it seems like you should be storing the original length of the buffer, so when you decrypt you can ignore the last x garbage bytes if the original buffer size wasn't a multiple of 8.

Explain these two lines to me.

unsigned long v0 = *((unsigned long*)(buf+n));
        unsigned long v1 = *((unsigned long*)(buf+n+4));

During the first iteration of n, ie n =0 ; the above code becomes

unsigned long v0 = *((unsigned long*)(buf));
        unsigned long v1 = *((unsigned long*)(buf+4));

Now, the length of buf is 3. So, isn't buf + 4 a location out of the data array?

Have you actually looked through your code, line by line (possibly while debugging)? How about these lines, in the encryption function:

// put length back in the package 
(*outbuf)[0] = newsize & 0xFF;
(*outbuf)[1] = (newsize >> 8) & 0xFF;

You seem to completely ignore that the first two bytes of the output buffer are not encrypted data when you go to decrypt:

unsigned long v0 = *((unsigned long*)(buf+n));
unsigned long v1 = *((unsigned long*)(buf+n+4));
//try
unsigned long v0 = *((unsigned long*)(buf+n+2));
unsigned long v1 = *((unsigned long*)(buf+n+6));

And it seems like you should be storing the original length of the buffer, so when you decrypt you can ignore the last x garbage bytes if the original buffer size wasn't a multiple of 8.

Wow... That's true, I must've totally overseen it. This is because this project involves data communication. Usually it will read the size of the packet, and then decrypt the rest. This might indeed have caused my the problem. Removing the lines that add the length back in to the packate won't help anyway, so even though you're probabl right about this, it is not the solution I was hoping for.

I've also noticed that using several variable types might also cause troubles because I'm using both MBS and SBS. The problem is that I don't know how to solve this. Trowing around with variables never been my strongest point, and this is "trowing around with varables"²

So: The problem is still there, even if I'm the problem.

Thanks for your replies,
Eddy

// xtea.cpp : Defines the entry point for the console application.
//

#include <stdafx.h>
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <string>

using namespace std;

unsigned char TEAKey[17] = "aaaaaaaaaaaaaaaa";
unsigned char* outbuf;




int Encrypt(unsigned char buf[], int length, unsigned char key[], unsigned char** outbuf);
unsigned char* Decrypt(unsigned char buf[], int length, unsigned char key[]);



int main(int argc, char* argv[])
{

	cout << "XTEA Key: \t \t" << TEAKey << endl;

	 unsigned char buffer[3];
	 buffer[0] = 0x01;
	 buffer[1] = 0xab;
	 buffer[2] = 0xab;

	 cout << "Original buffer:  \t"  << buffer << endl;
	 
	 int len;
	 cout << "Encrypting... \n";
	 len = Encrypt(buffer, 3, TEAKey, &outbuf);

	 cout << "Size of encrypted string: \t"<< len << endl;
	 cout << outbuf << endl;

	 unsigned char* decrypted;
	 decrypted = Decrypt(outbuf + 2, len, TEAKey);

	 cout << decrypted << endl;
	

	return 0;
}



int Encrypt(unsigned char buf[], int length, unsigned char key[], unsigned char** outbuf)
{
  if ((buf == NULL) || (key == NULL))
    return -1;

  int newsize = ((length+1)/8+1) * 8; // round up by 8
  *outbuf = new unsigned char[newsize+2];

  unsigned long delta = 0x9e3779b9;                   /* a key schedule constant */
  unsigned long sum;

  int n = 0;
  while (n < length)
  {
    sum = 0;
    unsigned long v0 = *((unsigned long*)(buf+n));
    unsigned long v1 = *((unsigned long*)(buf+n+4));

    for(int i=0; i < 32; i++)
    {
        v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((unsigned long*)key)[sum & 3]);
        sum += delta;
        v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((unsigned long*)key)[sum>>11 & 3]);
    }

    *((unsigned long*)(*outbuf+n+2)) = v0;
    *((unsigned long*)(*outbuf+n+6)) = v1;

    n += 8;
  }
  
  // put length back in the package 
  (*outbuf)[0] = newsize & 0xFF;
  (*outbuf)[1] = (newsize >> 8) & 0xFF;
  

  return newsize+2;
}

unsigned char* Decrypt(unsigned char buf[], int length, unsigned char key[])
{
  if ((buf == NULL) || (key == NULL))
    return NULL;

  unsigned long delta = 0x9e3779b9;                   /* a key schedule constant */
  unsigned long sum;

  unsigned char* retbuf = new unsigned char[length];

  int n = 0;
  while (n < length)
  {
    sum = 0xC6EF3720;
    unsigned long v0 = *((unsigned long*)(buf+n));
    unsigned long v1 = *((unsigned long*)(buf+n+4));

    for(int i=0; i<32; i++)
    {
        v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + ((unsigned long*)key)[sum>>11 & 3]);
        sum -= delta;
        v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + ((unsigned long*)key)[sum & 3]);
    }

    *((unsigned long*)(retbuf+n))   = v0;
    *((unsigned long*)(retbuf+n+4)) = v1;

    n += 8;
  }

  return retbuf;
}

Does the trick

Note that this algorithm is made for encrypting and decrypting packets of data sent from client to server.

I would like to thank you all for your help and support.


Greetz, Eddy

commented: Nice 2C a TY & successful solution post. +10
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.