Quote:
Originally Posted by ImmortalYashi
And you do? i just asked for his opinion so stfu.
|
Unlike you, I have both experience in administration and programming. I reversed the encryption on my own, according to tao4229, there's hardly any people left in this section capable of doing that on their own :rolleyes:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ClassicConquerProxy
{
public unsafe class TQCryptographer
{
private static void CreateKeys(ref byte[] Key1, ref byte[] Key2, byte Key1Initial, byte Key2Initial)
{
// Disassembled from Conquer.exe at function:
// 0045CA84 /$ 53 PUSH EBX
#region Raw (high-level asm) Key1 Generation
/*
byte[] buffer = new byte[256];
int edx = 0x9d;
int eax;
int ecx;
for (int i = 0; i < 256; i++)
{
buffer[i] = (byte)edx;
ecx = edx; // mov cl,dl
eax = edx;
eax = (eax * 0xfa); // imul eax,eax,0fa
edx = eax % 0x100; // remainer from IDIV below
eax /= 0x100; // IDIV ebx(0x100 const)
eax = edx; // mov eax,edx => eax becomes the remainer from 0x9d/0x100
eax += 0x0f; // add eax,0f
eax = (eax * buffer[i]); // imul eax,ecx => ecx is the last byte we moved into buffer
eax += 0x13; // add eax,013
edx = eax % 0x100; // remainder from IDIV below
eax = eax / 0x100; // IDIV ebx(0x100 const)
}
*/
#endregion
#region Raw (high-level asm) Key2 Generation
/*
byte[] buffer = new byte[256];
int edx = 0x62;
for (int i = 0 ; i < 256; i++)
{
int ecx = 0x5c;
int eax = (edx * 0x5c);
ecx += 0x1d;
ecx -= (byte)eax;
eax = ((eax >> 8) << 8) | (byte)ecx;
eax *= edx;
eax += 0x6d;
buffer[i] = (byte)edx;
edx = eax;
}
*/
#endregion
int TempVar;
for (int i = 0; i < Key1.Length; i++)
{
Key1[i] = Key1Initial;
TempVar = ((((Key1Initial * 0xfa) % 0x100) + 0x0f) * Key1Initial) + 0x13;
Key1Initial = (byte)(TempVar % 0x100);
}
for (int i = 0; i < Key2.Length; i++)
{
Key2[i] = Key2Initial;
TempVar = (Key2Initial * 0x5c);
TempVar = ((TempVar >> 8) << 8) | ((0x5C + 0x1D) - (byte)TempVar);
Key2Initial = (byte)((TempVar * Key2Initial) + 0x6D);
}
}
#region Native structures for TQCryptographer
/*
typedef struct {
DWORD unknown; // dword ptr[offset]
int counter1; // dword ptr[offset+0x4]
int counter2; // dword ptr[offset+0x8]
char key1[256]; // dword ptr[offset+offset2+0x8]
char key2[256]; // dword ptr[offset+offset2+0x108]
} TQCRYPTO_KEY;
typedef struct {
union
{
struct {
BYTE Counter1;
BYTE Counter2;
} Counter;
WORD Position;
}
} TQCRYPTO_COUNTER;
*/
#endregion
[StructLayout(LayoutKind.Explicit)]
struct TQCounter
{
[FieldOffset(0)]
public byte Counter1;
[FieldOffset(1)]
public byte Counter2;
[FieldOffset(0)]
public ushort Position;
}
private TQCounter InCounter;
private TQCounter OutCounter;
private byte[] Key1;
private byte[] Key2;
public TQCryptographer()
{
InCounter = new TQCounter();
OutCounter = new TQCounter();
Key1 = new byte[256];
Key2 = new byte[256];
CreateKeys(ref Key1, ref Key2, 0x9d, 0x62);
}
public void Encrypt(byte* Packet, byte* Output, int Length)
{
// Reversed from:
// 0045CAE6 /$ 55 PUSH EBP
for (int i = 0; i < Length; i++)
{
//0045CB0D |. 8A4408 08 |MOV AL,BYTE PTR DS:[EAX+ECX+8]
//0045CB11 |. 3006 |XOR BYTE PTR DS:[ESI],AL
Output[i] = Packet[i];
Output[i] = (byte)(Output[i] ^ Key1[InCounter.Counter1]);
//0045CB18 |. 8A9C0B 0801000>|MOV BL,BYTE PTR DS:[EBX+ECX+108]
//0045CB1F |. 32D8 |XOR BL,AL
Output[i] = (byte)(Output[i] ^ Key2[InCounter.Counter2]);
//0045CB38 |> 8A06 |MOV AL,BYTE PTR DS:[ESI]
//0045CB3A |. 8AD8 |MOV BL,AL
//0045CB3C |. 80E3 0F |AND BL,0F
//0045CB3F |. C0E3 04 |SHL BL,4
//0045CB42 |. C0E8 04 |SHR AL,4
//0045CB45 |. 02D8 |ADD BL,AL
Output[i] = (byte)((Output[i] << 4) | (Output[i] >> 4));
//0045CB47 |. 80F3 AB |XOR BL,0AB
Output[i] = (byte)(Output[i] ^ 0xAB);
InCounter.Position++;
}
}
public void Decrypt(byte* Packet, byte* Output, int Length)
{
// Inversed ClientEncrypt()
for (int i = 0; i < Length; i++)
{
Output[i] = Packet[i];
Output[i] = (byte)(Output[i] ^ 0xAB);
Output[i] = (byte)((Output[i] << 4) | (Output[i] >> 4));
Output[i] = (byte)(Output[i] ^ Key2[OutCounter.Counter2]);
Output[i] = (byte)(Output[i] ^ Key1[OutCounter.Counter1]);
OutCounter.Position++;
}
}
}
}