• Unfortunately, we have experienced significant hard drive damage that requires urgent maintenance and rebuilding. The forum will be a state of read only until we install our new drives and rebuild all the configurations needed. Please follow our Facebook page for updates, we will be back up shortly! (The forum could go offline at any given time due to the nature of the failed drives whilst awaiting the upgrades.) When you see an Incapsula error, you know we are in the process of migration.

Algorithms of decryption *.bmd files

Newbie Spellweaver
Joined
Jan 13, 2010
Messages
98
Reaction score
118
In practice reverse engineering, I decided to start to decrypt Item.bmd. Actually that's a little code to decrypt the file Item.bmd.
By the way, main 1.07x (and versions above, may still be a couple of versions below, I have not tested it) before you start decoding file with XorEnc3, main decode something like a key, I have no idea what kind of key ...
Below is the actual code and decipher the key. This key is useless without it you can decrypt the file Item.bmd, in general reversal of all that was in the code.
The function gets the last argument like a key: DecryptKey ((int) pDstBuf, ITEM_TOTAL_SIZE, 0xE2F1U);
So, the return value is compared with the key EncKey and only after comparing the two keys to decrypt a file. (Well, at least as arranged with WebZen).
The structures may not be correct, so if you know the size and structure field names, I would be grateful for the help

* Note: Without this key, too, can decrypt the file, so simply arranged in webzen.


The code of decryption key

Before XorEnc3

Code:
int EncKey;
GetFileSize(&EncKey, 1, 4, fp);

Code:
int DecryptKey(int pSrcBuf, int Size, unsigned short EncKey)
{
  int Dst;
  int DecryptedKey = EncKey << 9;

  for (unsigned int i = 0; i <= Size - 4; i += 4)
  {
   memcpy(&Dst, (const void*)(i + pSrcBuf), 4U);

   int rest = (EncKey + (i >> 2)) % 2;

   if (rest)
   {
	if (rest == 1)
	 DecryptedKey += Dst;
   }
   else 
   {
	DecryptedKey ^= Dst;
   }
   
   if (!(i % 10)) 
	DecryptedKey ^= (unsigned int)(DecryptedKey + EncKey) >> ((i >> 2) % 8 + 1);
 }
 return DecryptedKey;
}

ALL DECRYPTED FILES FOR VERSION 1.07X (for lower version, and probably newer versions of files, but not for all)

Item.bmd.
Code:
#include <iostream>

#include <stdio.h>
#include <conio.h>
#include <windows.h>

const int ITEM_LINE_SIZE = 84;

struct ItemEx
{
  char ItemName[30];
  BYTE b31;
  BYTE b32;
  BYTE b33;
  BYTE b34;
  BYTE b35;
  BYTE b36;
  BYTE b37;
  BYTE b38;
  BYTE b39;
  BYTE b40;
  BYTE b41;
  BYTE b42;
  BYTE b43;
  BYTE b44;
  BYTE b45;
  BYTE b46;
  BYTE b47;
  BYTE b48;
  BYTE b49;
  BYTE b50;
  BYTE b51;
  BYTE b52;
  BYTE b53;
  BYTE b54;
  BYTE b55;
  BYTE b56;
  BYTE b57;
  BYTE b58;
  BYTE b59;
  BYTE b60;
  BYTE b61;
  BYTE b62;
  BYTE b63;
  BYTE b64;
  BYTE b65;
  BYTE b66;
  BYTE b67;
  BYTE b68;
  BYTE b69;
  BYTE b70;
  BYTE b71;
  BYTE b72;
  BYTE b73;
  BYTE b74;
  BYTE b75;
  BYTE b76;
  BYTE b77;
  BYTE b78;
  BYTE b79;
  BYTE b80;
  BYTE b81;
  BYTE b82;
  BYTE b83;
  BYTE b84;
}; 
ItemEx *pItem;

char *DecryptXorEnc(char *lpSrcBuf, int Size)
{
  BYTE XorKeys[3] = { 0xFC, 0xCF, 0xAB };

  for (int i = 0; i < Size; ++i)
	lpSrcBuf[i] ^= XorKeys[i % 3];
 
  return lpSrcBuf;
}

size_t GetFileSize(void *pSrcBuf, size_t Size, size_t Count, FILE *fp)
{ 
  fseek(fp, 0 , SEEK_END);
  int ItemSz = ftell(fp);
  rewind(fp);
  size_t Result = fread(pSrcBuf, Count, Size, fp);
  return Result;
}

bool ReadItemBmd(char *pFileName)
{
  const int ITEM_TOTAL_LINE_SIZE = ITEM_LINE_SIZE << 13;

  pItem = new ItemEx();

  char *lpDstBuf = new char[ITEM_TOTAL_LINE_SIZE];
  char *lpSrcBuf = new char[ITEM_TOTAL_LINE_SIZE];
	
  FILE *fp = NULL;
  if ((fp = fopen(pFileName, "rb")) == NULL)
	return false;

  FILE *sp = NULL;
  if ((sp = fopen(".\\ItemDec.txt", "w")) == NULL)
	return false;

   GetFileSize(lpDstBuf, 1, ITEM_TOTAL_LINE_SIZE , fp);

  for (int i = 0; i < ITEM_TOTAL_LINE_SIZE  / ITEM_LINE_SIZE; ++i)
  {
	lpSrcBuf = DecryptXorEnc(&lpDstBuf[i * ITEM_LINE_SIZE], ITEM_LINE_SIZE);
	memcpy(pItem, &lpSrcBuf[0], ITEM_LINE_SIZE);
	fprintf(sp, "[%30s][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d][%3d]\n", 
	 pItem->ItemName, pItem->b31, pItem->b32, pItem->b33, pItem->b34, pItem->b35, pItem->b36, pItem->b37, pItem->b38, pItem->b39, pItem->b40, pItem->b41, pItem->b42, pItem->b43, pItem->b44, pItem->b45, pItem->b46, pItem->b47, pItem->b48, pItem->b49, pItem->b50,
	 pItem->b51, pItem->b52, pItem->b53, pItem->b54, pItem->b55, pItem->b56, pItem->b57, pItem->b58, pItem->b59, pItem->b60, pItem->b61, pItem->b62, pItem->b63, pItem->b64, pItem->b65, pItem->b66, pItem->b67, pItem->b68, pItem->b69, pItem->b70, pItem->b71, pItem->b72, 
	 pItem->b73, pItem->b74, pItem->b75, pItem->b76, pItem->b77, pItem->b78, pItem->b79, pItem->b80, pItem->b81, pItem->b82, pItem->b83, pItem->b84);
  }

  delete [] lpDstBuf, lpSrcBuf;
  lpDstBuf = lpSrcBuf = NULL;
  delete pItem;
  pItem = NULL;

  fclose(fp);
  fclose(sp);
  return true;
}

int main(void)
{
  if (!ReadItemBmd(".\\Item.bmd"))
  {
   MessageBoxA(NULL, "Item.bmd - File corrupted.", "Error", MB_ICONERROR);
   ::ExitProcess(0);
  }
  std::cout << "Press key!" << std::endl;
  std::cin.get(); return 0;
};

Skill.bmd.
Code:
#include <iostream>

#include <stdio.h>
#include <conio.h>
#include <windows.h>

const int SKILL_LINE_SIZE = 80;
const int SKILL_TOTAL_LINE_SIZE = 600;

struct SkillEx
{
 char SkillName[32];
 WORD wLevel;	   // 34
 wORD wDamage;	 // 36
 WORD wReqMana;	// 38
 WORD wAG;	   // 40
 WORD wDistance;   // 42
 DWORD dwDelay;	// 46
 BYTE wMagic;	   // 47
 BYTE wLeader;	   // 48
 BYTE wResistance; // 49
 BYTE wType;	   // 50
 BYTE wUseType;	   // 51
 BYTE wBrand;	   // 52
 BYTE wCount;	   // 53
 BYTE wStatus1;	   // 54
 BYTE wStatus2;	   // 55
 BYTE wStatus3;	   // 56
 BYTE DW;	   // 57
 BYTE DK;	   // 58
 BYTE ELF;	   // 59
 BYTE MG;	   // 60
 BYTE DL;	   // 61
 BYTE SUM;	   // 62
 BYTE IconNumber;  // 63
 BYTE SkillType;   // 64
 BYTE Unkw1;	   // 65
 BYTE Unkw2;	   // 66
 BYTE Unkw3;	   // 67
 BYTE Unkw4;	   // 68
 BYTE Unkw5;	   // 69
 BYTE Unkw6;	   // 70
 BYTE Unkw7;	   // 71
 BYTE Unkw8;	   // 72
 BYTE Unkw9;	   // 73
 BYTE Unkw10;	  // 74
 BYTE Unkw11;	  // 75
 BYTE Unkw12;	  // 76
 BYTE Unkw13;	  // 77
 BYTE Unkw14;	  // 78
 BYTE Unkw15;	  // 79
 BYTE Unkw16;	  // 80
};
SkillEx *pSkill; // 80

char *DecryptXorEnc(char *lpSrcBuf, int Size)
{
  BYTE XorKeys[3] = { 0xFC, 0xCF, 0xAB };

  for (int i = 0; i < Size; ++i)
   lpSrcBuf[i] ^= XorKeys[i % 3];
 
  return lpSrcBuf;
}

size_t GetFileSize(void *pSrcBuf, size_t Size, size_t Count, FILE *fp)
{ 
  fseek(fp, 0 , SEEK_END);
  int ItemSz = ftell(fp);
  rewind(fp);
  size_t Result = fread(pSrcBuf, Count, Size, fp);
  return Result;
}

bool ReadSkillBmd(char *pFileName)
{
  pSkill = new SkillEx();

  char *lpDstBuf = new char[SKILL_TOTAL_LINE_SIZE * SKILL_LINE_SIZE];
  char *lpSrcBuf = new char[SKILL_TOTAL_LINE_SIZE * SKILL_LINE_SIZE];
	
  FILE *fp = NULL;
  if ((fp = fopen(pFileName, "rb")) == NULL)
   return false;

  FILE *sp = NULL;
  if ((sp = fopen(".\\SkillDec.txt", "w")) == NULL)
   return false;

  GetFileSize(lpDstBuf, 1, SKILL_TOTAL_LINE_SIZE * SKILL_LINE_SIZE, fp);

  for (int i = 0; i < SKILL_TOTAL_LINE_SIZE; ++i)
  {
   lpSrcBuf = DecryptXorEnc(&lpDstBuf[i * SKILL_LINE_SIZE], SKILL_LINE_SIZE);
   memcpy(pSkill, &lpSrcBuf[0], SKILL_LINE_SIZE);
  fprintf(sp, "[%s][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d  [%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d]", 
  pSkill->SkillName, pSkill->wLevel, pSkill->wDamage, pSkill->wReqMana, pSkill->wAG, pSkill->wDistance, pSkill->dwDelay, pSkill->wMagic, pSkill->wLeader, pSkill->wResistance,
  pSkill->wType, pSkill->wUseType, pSkill->wBrand, pSkill->wCount, pSkill->wStatus1, pSkill->Status2, pSkill->Status3, pSkill->DW, pSkill->DK, pSkill->ELF, pSkill->MG, pSkill->DL, pSkill->SUM
  pSkill->IconNumber, pSkill->SkillType, pSkill->Unkw1, pSkill->Unkw2, pSkill->Unkw3, pSkill->Unkw4, pSkill->Unkw5, pSkill->Unkw6, pSkill->Unkw7, pSkill->Unkw8, pSkill->Unkw9, pSkill->Unkw10, 
  pSkill->Unkw11, pSkill->Unkw12, pSkill->Unkw13, pSkill->Unkw14, pSkill->Unkw15, pSkill->Unkw16);
  }

  delete [] lpDstBuf, lpSrcBuf;
  lpDstBuf = lpSrcBuf = NULL;
  delete pSkill;
  pSkill = NULL;

  fclose(fp);
  fclose(sp);
  return true;
}

int main(void)
{
  if (!ReadSkillBmd(".\\Skill.bmd"))
  {
   MessageBoxA(NULL, "Skill.bmd - File corrupted.", "Error", MB_ICONERROR);
   ::ExitProcess(0);
  }
  std::cout << "Press key!" << std::endl;
  std::cin.get(); return 0;
};

Gate.bmd
Code:
#include <iostream>

#include <stdio.h>
#include <conio.h>
#include <windows.h>

const int GATE_LINE_SIZE = 14;
const int GATE_TOTAL_LINE_SIZE = 512

struct GateEx
{
  BYTE Flag; 
  BYTE Map; 
  BYTE X1;
  BYTE X2;
  BYTE Y1;
  BYTE Y2;
  WORD wGateNumber;
  BYTE Dir;
  BYTE bBattleZone;
  WORD wLevel; // Походу требуемый уровень для прохода
  WORD wBattleZoneLvlReq; 
}; 
GateEx *pGate; // 14

char *DecryptXorEnc(char *lpSrcBuf, int Size)
{
  BYTE XorKeys[3] = { 0xFC, 0xCF, 0xAB };
  for (int i = 0; i < Size; ++i)
	lpSrcBuf[i] ^= XorKeys[i % 3];
  return lpSrcBuf;
}

size_t GetFileSize(void *pSrcBuf, size_t Size, size_t Count, FILE *fp)
{
  fseek(fp, 0 , SEEK_END);
  int ItemSz = ftell(fp);
  rewind(fp);
  size_t Result = fread(pSrcBuf, Count, Size, fp);
  return Result;
}

bool ReadGateBmd(char *pFileName)
{
  pGate = new GateEx();

  char *lpDstBuf = new char[GATE_LINE_SIZE * GATE_TOTAL_LINE_SIZE];
  char *lpSrcBuf = new char[GATE_LINE_SIZE * GATE_TOTAL_LINE_SIZE];

  FILE *fp = NULL;
  if ((fp = fopen(pFileName, "rb")) == NULL)
	return false;

  FILE *sp = NULL;
  if ((sp = fopen(".\\GateDec.txt", "w")) == NULL)
	return false;

  GetFileSize(lpDstBuf, 1, GATE_LINE_SIZE * GATE_TOTAL_LINE_SIZE, fp);

  for (int i = 0; i < GATE_TOTAL_LINE_SIZE; ++i)
  {
	lpSrcBuf = DecryptXorEnc(&lpDstBuf[GATE_LINE_SIZE * i], GATE_LINE_SIZE);
	memcpy(pGate, &lpSrcBuf[0], GATE_LINE_SIZE);
	fprintf(sp, "[%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d]\n", 
	pGate->Flag, pGate->Map, pGate->X1, pGate->X2, pGate->Y1, pGate->Y2, pGate->wGateNumber, pGate->Dir, pGate->bBattleZone, pGate->wLevel, pGate->wBattleZoneLvlReq);
  }

  delete [] lpDstBuf, lpSrcBuf;
  lpDstBuf = lpSrcBuf = NULL;
  delete pGate;
  pGate = NULL;

  fclose(fp);
  fclose(sp);
  return true;
}

int main(void)
{
  if (!ReadGateBmd(".\\Gate.bmd"))
  {
   MessageBoxA(NULL, "Gate.bmd - File corrupted.", "Error", MB_ICONERROR);
   ::ExitProcess(0);
  }
  std::cout << "Press key!" << std::endl;
  std::cin.get(); return 0;
};

Filter.bmd
Code:
#include <iostream>

#include <stdio.h>
#include <conio.h>
#include <windows.h>

const int FILTER_LINE_SIZE = 20;
const int FILTER_TOTAL_LINE_SIZE = 1000;

struct FilterEx
{
 char FilterText[20];
};
FilterEx *pFilter; 

char *DecryptXorEnc(char *lpSrcBuf, int Size)
{
 BYTE XorKeys[3] = { 0xFC, 0xCF, 0xAB };
 for (int i = 0; i < Size; ++i)
  lpSrcBuf[i] ^= XorKeys[i % 3];
 return lpSrcBuf;
}

size_t GetFileSize(void *pSrcBuf, size_t Size, size_t Count, FILE *fp)
{ 
 fseek(fp, 0 , SEEK_END);
 int ItemSz = ftell(fp);
 rewind(fp);
 size_t Result = fread(pSrcBuf, Count, Size, fp);
 return Result;
}

bool ReadFilterBmd(char *pFileName)
{
 pFilter = new FilterEx();

 char *lpDstBuf = new char[FILTER_TOTAL_LINE_SIZE * FILTER_LINE_SIZE];
 char *lpSrcBuf = new char[FILTER_TOTAL_LINE_SIZE * FILTER_LINE_SIZE];
	
 FILE *fp = NULL;
 if ((fp = fopen(pFileName, "rb")) == NULL)
  return false;

 FILE *sp = NULL;
 if ((sp = fopen(".\\FilterDec.txt", "w")) == NULL)
  return false;

  GetFileSize(lpDstBuf, 1, FILTER_TOTAL_LINE_SIZE * FILTER_LINE_SIZE, fp);

  for (int i = 0; i < FILTER_TOTAL_LINE_SIZE; ++i)
  {
   lpSrcBuf = DecryptXorEnc(&lpDstBuf[i * FILTER_LINE_SIZE], FILTER_LINE_SIZE);
   memcpy(pFilter, &lpSrcBuf[0], FILTER_LINE_SIZE);
   fprintf(sp, "[%s]\n", pFilter->FilterText);
  }

  delete [] lpDstBuf, lpSrcBuf;
  lpDstBuf = lpSrcBuf = NULL;
  delete pFilter;
  pFilter = NULL;

  fclose(fp);
  fclose(sp);
  return true;
}

int main(void)
{
  if (!ReadFilterBmd(".\\Filter.bmd"))
  {
   MessageBoxA(NULL, "Filter.bmd - File corrupted.", "Error", MB_ICONERROR);
   ::ExitProcess(0);
  }
  std::cout << "Press key!" << std::endl;
  std::cin.get(); return 0;
};

FilterName.bmd
Code:
#include <iostream>

#include <stdio.h>
#include <conio.h>
#include <windows.h>

const int FILTERNAME_LINE_SIZE = 20;
const int FILTERNAME_TOTAL_LINE_SIZE = 500;

struct FilterNameEx
{
 char FilterNameText[20];
};
FilterNameEx *pFilterName; 

char *DecryptXorEnc(char *lpSrcBuf, int Size)
{
 BYTE XorKeys[3] = { 0xFC, 0xCF, 0xAB };
 for (int i = 0; i < Size; ++i)
  lpSrcBuf[i] ^= XorKeys[i % 3];
 return lpSrcBuf;
}

size_t GetFileSize(void *pSrcBuf, size_t Size, size_t Count, FILE *fp)
{ 
 fseek(fp, 0 , SEEK_END);
 int ItemSz = ftell(fp);
 rewind(fp);
 size_t Result = fread(pSrcBuf, Count, Size, fp);
 return Result;
}

bool ReadFilterNameBmd(char *pFileName)
{
 pFilterName = new FilterNameEx();

 char *lpDstBuf = new char[FILTERNAME_TOTAL_LINE_SIZE * FILTERNAME_LINE_SIZE];
 char *lpSrcBuf = new char[FILTERNAME_TOTAL_LINE_SIZE * FILTERNAME_LINE_SIZE];
	
 FILE *fp = NULL;
 if ((fp = fopen(pFileName, "rb")) == NULL)
  return false;

 FILE *sp = NULL;
 if ((sp = fopen(".\\FilterNameDec.txt", "w")) == NULL)
  return false;

  GetFileSize(lpDstBuf, 1, FILTERNAME_TOTAL_LINE_SIZE * FILTERNAME_LINE_SIZE, fp);

  for (int i = 0; i < FILTERNAME_TOTAL_LINE_SIZE; ++i)
  {
   lpSrcBuf = DecryptXorEnc(&lpDstBuf[i * FILTERNAME_LINE_SIZE], FILTERNAME_LINE_SIZE);
   memcpy(pFilterName, &lpSrcBuf[0], FILTERNAME_LINE_SIZE);
   fprintf(sp, "[%s]\n", pFilterName->FilterNameText);
  }

  delete [] lpDstBuf, lpSrcBuf;
  lpDstBuf = lpSrcBuf = NULL;
  delete pFilterName;
  pFilterName = NULL;

  fclose(fp);
  fclose(sp);
  return true;
}

int main(void)
{
 if (!ReadFilterNameBmd(".\\FilterName.bmd"))
 {
  MessageBoxA(NULL, "FilterName.bmd - File corrupted.", "Error", MB_ICONERROR);
  ::ExitProcess(0);
 }
 std::cout << "Press key!" << std::endl;
 std::cin.get(); return 0;
};

Dialog.bmd
Code:
#include <iostream>

#include <stdio.h>
#include <conio.h>
#include <windows.h>

const int DIALOG_LINE_SIZE = 1024;
const int DIALOG_TOTAL_LINES = 200;

struct DialogEx
{
 char DialogText[1024];
};
DialogEx *pDialog; 

char *DecryptXorEnc(char *lpSrcBuf, int Size)
{
 BYTE XorKeys[3] = { 0xFC, 0xCF, 0xAB };

 for (int i = 0; i < Size; ++i)
  lpSrcBuf[i] ^= XorKeys[i % 3];

 return lpSrcBuf;
}

size_t GetFileSize(char *pSrcBuf, size_t Size, size_t Count, FILE *fp)
{ 
 size_t Result = fread(pSrcBuf, Size, Count, fp);
 return Result;
}

bool ReadDialogBmd(char *pFileName)
{
 pDialog = new DialogEx();

 FILE *fp;
 if ((fp = fopen(pFileName, "rb")) == NULL)
  return false;

 FILE *sp;
 if ((sp = fopen(".\\DialogDec.txt", "w")) == NULL)
  return false;

 char *lpDstBuf = new char [DIALOG_LINE_SIZE ];	

 for (int i = 0; i < DIALOG_TOTAL_LINES; ++i)
 {		
  GetFileSize(lpDstBuf, DIALOG_LINE_SIZE, 1, fp);
  DecryptXorEnc(&lpDstBuf[0], DIALOG_LINE_SIZE);
  memcpy(pDialog, &lpDstBuf[0], DIALOG_LINE_SIZE);
  fprintf(sp, "[%s]\n", pDialog->DialogText);
 }

 delete pDialog;
 pDialog = NULL;

 delete [] lpDstBuf;
 lpDstBuf = NULL;

 fclose(fp);
 fclose(sp);

 return true;
}

int main(void)
{
 if (!ReadDialogBmd(".\\Dialog.bmd"))
 {
  MessageBoxA(NULL, "Dialog.bmd - File corrupted.", "Error", MB_ICONERROR);
  ::ExitProcess(0);
 }
 std::cout << "Press key!" << std::endl;
 std::cin.get(); return 0;
};

Text.bmd
Code:
#include <iostream>
#include <vector>
#include <windows.h>
#include <fstream>
 
#define FILE_PATH ".\\Text.bmd"

enum PROGRAM { SUCCESS = 0, WARNING = 1 };

struct TextEx
{
 char *Text;
};
TextEx *pText;

size_t GetFileSize(void *lpSrcBuf, size_t Size, size_t Count, FILE *fp)
{
 size_t result = fread(lpSrcBuf, Size, Count, fp);
 return result;
}

void DecryptXorEnc(char *lpSrcBuf, int Size)
{
 BYTE XorKeys[3] = { 0xFC, 0xCF, 0xAB };

 for (int i = 0; i < Size; ++i)
  lpSrcBuf[i] ^= XorKeys[i % 3];
}

bool ReadTextBmd(char pFileName[], int Size)
{
 FILE *fp, *sp;

 if ((fp = fopen(pFileName, "rb")) == NULL) return false;
 if ((sp = fopen(".\\TextDec.txt", "w")) == NULL) return false;

 char *lpSrcBuf	= (char*)malloc(strlen(pFileName) + 1);
 strcpy(&lpSrcBuf[0], pFileName);
 GetFileSize(&lpSrcBuf[0], 6, 1, fp);
 int TotalLines = HIWORD(*(int*)lpSrcBuf); // *(int*)lpSrcBuf + 2

 if ((*(int*)lpSrcBuf & 0xFFFF) == 0x5447) // Crc
 {
  pText = new TextEx();

  for (int i = 0; i < TotalLines; ++i)
  {
   GetFileSize((char*)lpSrcBuf, 8, 1, fp); 
   WORD LineIndex = *(WORD*)&lpSrcBuf[0];
   WORD LineTextSize = *(WORD*)&lpSrcBuf[4];
   printf("Line Index: %d Line Size: %d\n", LineIndex, LineTextSize);
   pText[LineIndex].Text = (char*)malloc(LineTextSize + 1);
   GetFileSize(&pText[LineIndex].Text[0], 1, LineTextSize, fp); 
   DecryptXorEnc(&pText[LineIndex].Text[0], LineTextSize);
   *(pText[LineIndex].Text + LineTextSize) = '\0';
   fprintf(sp, "[%d][%s]\n", LineIndex, pText[LineIndex].Text);
  }

  free((char*)lpSrcBuf); lpSrcBuf = NULL; 
 }

 fclose(fp);
 std::cout << "Decrypted!"; 
 std::cin.get();
 return true; 
}

int main(void)
{
 if (!ReadTextBmd(FILE_PATH, 64))
 {
  char Msg[30];
  sprintf(Msg, "%s - File corrupted.", FILE_PATH);
  MessageBoxA(NULL, Msg, "Error", MB_ICONERROR);
  return WARNING;
 } 

 std::cin.get(); 
 return SUCCESS;
}
 
Last edited:
Newbie Spellweaver
Joined
Jun 26, 2006
Messages
47
Reaction score
19
its not a key ... its CRC32 of the file ... and its the last 4 bytes of the file
 
Newbie Spellweaver
Joined
Jan 13, 2010
Messages
98
Reaction score
118
Thanks for the tip, now I'll know for what this key ;)

and its the last 4 bytes of the file
Yes, I noticed that the function "read file" gets the last 4 bytes. Not thought that this could be crc32 :)
 
Last edited:
Newbie Spellweaver
Joined
Jun 26, 2006
Messages
47
Reaction score
19
and what crc32 is after all ? -.- ...
 
Newbie Spellweaver
Joined
Jan 13, 2010
Messages
98
Reaction score
118
I think he meant that it was not standardized CRC32 (classic). But it's a custom crc32.
 
Newbie Spellweaver
Joined
Jan 13, 2010
Messages
98
Reaction score
118
Added Filter.bmd, FilterName.bmd
 
Last edited:
Newbie Spellweaver
Joined
Aug 4, 2011
Messages
23
Reaction score
2
Anyway very nice, i am testing each and adding to an app , so maybe have unified tool someday.
 
Newbie Spellweaver
Joined
Jan 13, 2010
Messages
98
Reaction score
118
Added Dec2.dat. Algorithm of keys decryption.
Soon...
* Save keys Dec2.dat
* Decrypt keys Enc1.dat
* Save keys Enc1.dat
* Server side too.
 
Last edited:
Newbie Spellweaver
Joined
Aug 4, 2011
Messages
23
Reaction score
2
Wow ! Are you planing to really do the tool ?

Its definitly a demand for a good tool, since Pentium abandoned MU.
 
Junior Spellweaver
Joined
Sep 3, 2008
Messages
146
Reaction score
75
Any news? item.bmd decryptor works perfectly! Tested on 1.04 and Season 6(1.03w)

This tool, only need to check columns ubication. Im working on that.
 
Back
Top