HShieldEmu.h
#ifndef __HACKSHIELDEMU_H
#define __HACKSHIELDEMU_H
#include "global.h"
struct hshield_packet_ack_server {
DWORD IntegrityCheck1_offset_ragII_exe;
DWORD IntegrityCheck1_size_ragII_exe;
DWORD VerfiyCheck_data;
DWORD enabled_checks;
DWORD MemoryCheck_function_adresses[32];
};
struct hshield_packet_ack_client {
DWORD VerifyCheck_checksum[2];
BYTE IntegrityCheck1_checksum[16];
BYTE MemoryCheck_checksum[16];
BYTE IntegrityCheck2_checksum[16];
BYTE IntegrityCheck3_checksum[16];
};
static class HackShieldEmu {
enum doHShieldCheckFlags {
doMemoryCheck = 1, // calculate checksums of function addresses given by the server
doIntegrityCheck1 = 2, // calculate checksum of RagII.exe
doIntegrityCheck2 = 4, // calculate checksum of Ehsvc.dll and EGRNAP.dll
doIntegrityCheck3 = 8, // calculate checksum of v3warpds.v3d and v3warpns.v3d
};
// hshield MakeGUIDAckMsg() and MakeGUIDAck() functions
//
// calculates the GUIDAck answer for given challenge input (20 bytes)
// output is 20 bytes
// reuturns 0 if successful
int MakeGUIDAckMsg(unsigned char *input, unsigned char *ack_answer);
// input: 160 bytes from server->client ack packet
// ack_answer: 72 bytes for the client->server packet
// returns 0 if succesful
int MakeAckMSG(unsigned char *input, unsigned char *ack_answer);
// input: the first 16 bytes from hshield server packet
// output: 16 bytes aes key
void calculate_hshield_aeskey(unsigned char* input, unsigned char* output)
// internal functions, not documented here
int GetCustumMD5OfFile(char *filename,DWORD offset, DWORD size, BYTE *output);
int GetMemoryCheckData(hshield_packet_ack_server *ackData,hshield_packet_ack_client *ackAnswer);
int GetIntegrityCheck1Data(hshield_packet_ack_server *ackData,hshield_packet_ack_client *ackAnswer);
int GetIntegrityCheck2Data(hshield_packet_ack_server *ackData,hshield_packet_ack_client *ackAnswer);
int GetIntegrityCheck3Data(hshield_packet_ack_server *ackData,hshield_packet_ack_client *ackAnswer);
// hshield.log de-/encryption functions
//
// format of a hshield.log file:
//
// struct hshield_log_file {
// hshield_log_entry entries[x];
// };
//
// struct hshield_log_entry {
// int log_size;
// unsigned char log_data[log_size];
// };
//
// output: pointer to the output buffer (must have same size as input buffer)
// input: pointer to the input buffer
// sizeInput: size of the input buffer (in bytes)
// key: key used for de-/encryption (RO2 default key is 1252)
int encrypt_logfile_data(unsigned char *output, unsigned char *input, int sizeInput,DWORD key = 1252);
int decrypt_logfile_data(unsigned char *output, unsigned char *input, int sizeInput,DWORD key = 1252);
};
#endif
HShieldEmu.cpp
#include "HackShieldEmu.h"
int HackShieldEmu::MakeGUIDAckMsg(unsigned char *input, unsigned char *ack_answer)
{
unsigned char *encryption_key = new unsigned char[16];
calculate_hshield_aeskey(&input[0],encryption_key);
unsigned char guid_of_EhSvc_dll[]= { 0xF6 , 0x33 , 0x08 , 0x58 , 0x90 , 0x28 , 0x80 , 0x44 , 0x81 , 0xDF , 0xA5 , 0xC9 , 0x19 , 0x6D , 0x46 , 0xF7 };
memcpy(&guid_answer[4],guid_of_EhSvc_dll,16);
unsigned char *decrypted_input = new unsigned char[4];
Decrypt(&input[16],4, decrypted_input, encryption_key);
DWORD *a1 = (DWORD*)&decrypted_input[0];
DWORD *a2 = (DWORD*)&guid_answer[0];
*a2 = -1658038656 & (((*a1 >> 11) ^ *a1) << 7) ^ (*a1 >> 11) ^ *a1;
Encrypt(ack_answer,20,guid_answer,encryption_key);
delete[] encryption_key;
delete[] decrypted_input;
return 0;
}
int HackShieldEmu::MakeAckMSG(unsigned char *input, unsigned char *ack_answer)
{
hshield_packet_ack_client *ackAnswer = (hshield_packet_ack_client*)ack_answer;
memset(ackAnswer,0,72);
unsigned char *encryption_key = new unsigned char[16];
calculate_hshield_aeskey(&input[0],encryption_key);
hshield_packet_ack_server *ackData = new hshield_packet_ack_server();
Decrypt(&input[16],144, (BYTE*)ackData, encryption_key);
// always do VerifyCheck
ackAnswer->VerifyCheck_checksum[0] = -1658038656 & (((ackData->VerfiyCheck_data >> 11) ^ ackData->VerfiyCheck_data) << 7) ^ (ackData->VerfiyCheck_data >> 11) ^ ackData->VerfiyCheck_data;
ackAnswer->VerifyCheck_checksum[1] = ackData->VerfiyCheck_data ^ (ackData->VerfiyCheck_data << 15);
// do MemoryCheck if requested
if(ackData->enabled_checks & doMemoryCheck) {
if(GetMemoryCheckData(ackData,ackAnswer)) return 1;
}
// do IntegrityCheck1 if requested
if(ackData->enabled_checks & doIntegrityCheck1) {
if(GetIntegrityCheck1Data(ackData,ackAnswer)) return 2;
}
// do IntegrityCheck2 if requested
if(ackData->enabled_checks & doIntegrityCheck2) {
if(GetIntegrityCheck2Data(ackData,ackAnswer)) return 3;
}
// do IntegrityCheck3 if requested
if(ackData->enabled_checks & doIntegrityCheck3) {
if(GetIntegrityCheck3Data(ackData,ackAnswer)) return 4;
}
Encrypt((BYTE*)ackAnswer,72,(BYTE*)ackAnswer,encryption_key);
delete[] encryption_key;
delete ackData;
return 0;
}
int HackShieldEmu::GetCustumMD5OfFile(char *filename,DWORD offset, DWORD size, BYTE *output)
{
ifstream file (filename, ios::in|ios::binary|ios::ate);
if (file.is_open())
{
ifstream::pos_type fsize = file.tellg();
DWORD ifsize = (DWORD)fsize;
BYTE *filebuf = new unsigned char [fsize];
file.seekg (0, ios::beg);
file.read((char*)filebuf, fsize);
file.close();
md5_state_t state;
md5_init(&state);
if(offset || size) {
md5_append_hshield(&state, &filebuf[offset], size);
md5_append_hshield(&state, &filebuf[0], ifsize);
}
else {
md5_append_hshield(&state, &filebuf[0], 40);
md5_append_hshield(&state, &filebuf[60], ifsize-60);
}
md5_finish_hshield(&state, output);
delete[] filebuf;
return 0;
}
return 1;
}
int HackShieldEmu::GetMemoryCheckData(hshield_packet_ack_server *ackData,hshield_packet_ack_client *ackAnswer)
{
md5_state_t state;
md5_init(&state);
for(int i=0; i<32; i++) {
if(ackData->MemoryCheck_function_adresses[i] == 0) break;
DWORD pointer = ackData->MemoryCheck_function_adresses[i];
DWORD len = 0;
while(true) {
t_disasm da;
pointer += Disasm((char*)pointer,MAXCMDSIZE,0x400000,&da,DISASM_SIZE);
if(*(BYTE*)pointer == 0xC2 ) break; // ret value
else if(*(BYTE*)pointer == 0xC3 ) break; // ret
else if(*(BYTE*)pointer == 0xCA ) break; // retf value
else if(*(BYTE*)pointer == 0xCB ) break; // retf
}
DWORD length = pointer - ackData->MemoryCheck_function_adresses[i];
if(length > 0) {
unsigned char md5_buffer[16];
md5_get_hshield(&md5_buffer[0], (BYTE*)ackData->MemoryCheck_function_adresses[i], length);
md5_append_hshield(&state, &md5_buffer[0], 16);
}
}
md5_finish_hshield(&state, &ackAnswer->MemoryCheck_checksum[0]);
return 0;
}
int HackShieldEmu::GetIntegrityCheck1Data(hshield_packet_ack_server *ackData,hshield_packet_ack_client *ackAnswer)
{
return GetCustumMD5OfFile("..\\checksum_files\\RagII.exe", ackData->IntegrityCheck1_offset_ragII_exe, ackData->IntegrityCheck1_size_ragII_exe, &ackAnswer->IntegrityCheck1_checksum[0]);
}
int HackShieldEmu::GetIntegrityCheck2Data(hshield_packet_ack_server *ackData,hshield_packet_ack_client *ackAnswer)
{
md5_state_t state;
md5_init(&state);
unsigned char temp_md5[16];
if(GetCustumMD5OfFile("..\\checksum_files\\Ehsvc.dll", 0, 0, &temp_md5[0])) return 1;
md5_append_hshield(&state, &temp_md5[0], 16);
if(GetCustumMD5OfFile("..\\checksum_files\\EGRNAP.dll", 0, 0, &temp_md5[0])) return 2;
md5_append_hshield(&state, &temp_md5[0], 16);
md5_finish_hshield(&state, &ackAnswer->IntegrityCheck2_checksum[0]);
return 0;
}
int HackShieldEmu::GetIntegrityCheck3Data(hshield_packet_ack_server *ackData,hshield_packet_ack_client *ackAnswer)
{
md5_state_t state;
md5_init(&state);
unsigned char temp_md5[16];
if(GetCustumMD5OfFile("..\\checksum_files\\v3warpds.v3d", 0, 0, &temp_md5[0])) return 1;
md5_append_hshield(&state, &temp_md5[0], 16);
if(GetCustumMD5OfFile("..\\checksum_files\\v3warpns.v3d", 0, 0, &temp_md5[0])) return 2;
md5_append_hshield(&state, &temp_md5[0], 16);
md5_finish_hshield(&state, &ackAnswer->IntegrityCheck3_checksum[0]);
return 0;
}
void HackShieldEmu::calculate_hshield_aeskey(unsigned char* input, unsigned char* output)
{
unsigned char *temp = new unsigned char[20];
memcpy(temp, input, 16);
for(int i=0;i<5;i++)
{
md5_state_t state;
md5_init(&state);
md5_append_hshield(&state, temp, 16);
md5_finish_hshield(&state, temp);
for(int i=0; i<8;i++) temp[i] = temp[i] ^ temp[i+8];
}
unsigned char *temp2 = new unsigned char[20];
for(int i=0;i<4;i++)
{
DWORD *dtemp1 = (DWORD*)&temp[i*4];
DWORD *dtemp2 = (DWORD*)&temp2[i*4];
*dtemp2 = *dtemp1 & 0xFFFF0000;
*dtemp1 = (*dtemp1 * 69069 ) + 1;
*dtemp2 |= ( *dtemp1 & 0xFFFF0000 ) >> 16;
}
memcpy(output, temp2, 16);
delete[] temp;
delete[] temp2;
for(int i=0; i < 16; i++)
{
if(output[i] & 1) output[i] ^= 0xDF ^ (output[i] >> 1);
else output[i] ^= output[i] >> 1;
}
}
int HackShieldEmu::encrypt_logfile_data(unsigned char *output, unsigned char *input, int sizeInput,DWORD key)
{
if ( output && input && sizeOutput > 0 && sizeInput > 0 )
{
memset(output, 0, sizeInput);
if ( sizeInput > 0 )
{
unsigned char *v8 = new unsigned char[4];
DWORD *dword_v8 = (DWORD*)v8;
*v8 = 0x00000000;
unsigned char *temp_key = new unsigned char[4];
DWORD *dword_temp_key = (DWORD*)temp_key;
*dword_temp_key = key;
for(int i = 0; i < sizeInput; i++)
{
v8[1] = temp_key[1] ^ input[i]; // encrypt the input byte
output[i] = v8[1]; // write the encrypted input byte to the output
*dword_v8 = 12691 * (*dword_temp_key + v8[1]); // update v8
*dword_temp_key = 22719 - *dword_v8; // update tempkey
}
delete[] v8;
delete[] temp_key;
}
return 0;
}
return -1;
}
int HackShieldEmu::decrypt_logfile_data(unsigned char *output, unsigned char *input, int sizeInput,DWORD key = 1252)
{
if ( output && input && sizeOutput > 0 && sizeInput > 0 )
{
memset(output, 0, sizeInput);
if ( sizeInput > 0 )
{
unsigned char *v8 = new unsigned char[4];
DWORD *dword_v8 = (DWORD*)v8;
*v8 = 0x00000000;
unsigned char *temp_key = new unsigned char[4];
DWORD *dword_temp_key = (DWORD*)temp_key;
*dword_temp_key = key;
for(int i = 0; i < sizeInput; i++)
{
v8[1] = temp_key[1] ^ input[i]; // encrypt the input byte
output[i] = v8[1]; // write the encrypted input byte to the output
*dword_v8 = 12691 * (*dword_temp_key + input[i]); // update v8
*dword_temp_key = 22719 - *dword_v8; // update tempkey
}
delete[] v8;
delete[] temp_key;
}
return 0;
}
return -1;
}
here's my implementation: (modified md5 & aes libs and ollydbg lib is missing):
Suscribirse a:
Enviar comentarios (Atom)
0 comentarios:
Publicar un comentario