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;
}