begin process at 2012 05 30 16:59:35
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C++ & C++ .NET

 > 

Divers

 > 

Général

 > 

Savoir la compilation (Décompilation si possible ^^)


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Savoir la compilation (Décompilation si possible ^^)

vendredi 23 octobre 2009 à 02:17:43 | Savoir la compilation (Décompilation si possible ^^)

Clad38

Bonsoir à tous,

Je sais pas si je poste dans la bonne catégorie mais j'ai chercher sans succès.

J'ai plusieurs fichiers à décompilé, mais je sais pas comment ils sont compilé :(

J'ai décompilé les fichiers EPK et EIX avec un script pris sur le net

Code C/C++ :
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <sstream>

//--------------------------------------------------------------------------

// Dumps a complete archive
bool DumpArchive(const char * inFolder, const char * name);

//--------------------------------------------------------------------------

int main(int argc, char * argv[])
{
	system("cls");
	printf("Welcome to the Metin2 File Extractor!\n");
	printf("This program was made by pushedx for the elitepvpers' Metin2 community.\n");
	printf("This is a free tool for all to use.\n");
	printf("It should work on the US/DE version files but Korea is not tested.\n");
	printf("Enjoy :)\n\n");
	if(argc != 3)
	{
		printf("Usage: Metin2FileExtractor <Path to PAK folder> <Archive title>\n");
		printf("Examples:\n");
		printf("\tMetin2FileExtractor \"C:\\Program Files\\Subagames\\Metin2\\pack\" BGM\n");
		printf("\tMetin2FileExtractor \"C:\\Program Files\\Subagames\\Metin2\\pack\" PC\n");
		printf("\tMetin2FileExtractor \"C:\\Program Files\\Metin2_Germany\\pack\" ETC\n");
		printf("\tMetin2FileExtractor \"C:\\Program Files\\Metin2_Germany\\pack\" root\n");
		system("pause");
		return -1;
	}
	std::string safecheck = argv[2];
	if(safecheck.find_first_of("!@#$%^&*()+={}[]|\\:\";\'<>?,./") != std::string::npos)
	{
		printf("Error: The Archive title (%s) contains invalid characters. The program will now exit.\n", argv[2]);
		return -1;
	}
	printf("Beginning the archive dump. Please be patient while it finishes.\n\n");
	bool result = DumpArchive(argv[1], argv[2]);
	if(result == true)
	{
		printf("The archive dump was successful!\n");
	}
	else
	{
		printf("The archive dump was not successful.\n");
	}
	printf("Thank you for using the Metin2 File Extractor!\n");
	system("pause");
	return 0;
}

//--------------------------------------------------------------------------

// The expected magic header value
#define LZ_KEY 0x5A4F434D

//--------------------------------------------------------------------------

struct TEntry1
{
	DWORD index;
	char filename[160];
	DWORD dw1;
	DWORD dw2;
	DWORD dw3;
	DWORD dwSrcSize;
	DWORD unpackedCRC;
	DWORD dwFileOffset;
	BYTE packedType;
	BYTE b2;
	BYTE b3;
	BYTE b4;
};

struct TEntry2
{
	DWORD header;
	DWORD decryptedBlockSize;
	DWORD compressedBlockSize;
	DWORD decompressedBlockSize;
};

struct TEntry3
{
	DWORD header;
	DWORD version;
	DWORD fileCount;
};

//--------------------------------------------------------------------------

// For decompressing (ripped from client)
BYTE gLZOData[] = 
{
	0xB9, 0x9E, 0xB0, 0x02, 0x6F, 0x69, 0x81, 0x05, 
	0x63, 0x98, 0x9B, 0x28, 0x79, 0x18, 0x1A, 0x00, 
};

// For decrypting (ripped from client)
BYTE gLZOData2[] = 
{
	0x22, 0xB8, 0xB4, 0x04, 0x64, 0xB2, 0x6E, 0x1F, 
	0xAE, 0xEA, 0x18, 0x00, 0xA6, 0xF6, 0xFB, 0x1C, 
};

//--------------------------------------------------------------------------

// Utility decompress function
__declspec(naked) void ASM_LZO_FUNC1()
{
	__asm
	{
		MOV EDX, DWORD PTR SS:[ESP + 0x08]
		MOV ECX, DWORD PTR SS:[ESP + 0x04]
		PUSH EBX
		PUSH EBP
		PUSH ESI
		MOV ESI, DWORD PTR SS:[ESP + 0x18]
		PUSH EDI
		MOV EAX, 0xC6EF3720
		MOV EDI, 0x20
		LEA EBX, DWORD PTR DS:[EBX]
LABEL1:
		MOV EBX, EDX
		SHR EBX, 0x5
		MOV EBP, EDX
		SHL EBP, 0x4
		XOR EBX, EBP
		MOV EBP, EAX
		SHR EBP, 0x0B
		AND EBP, 0x03
		MOV EBP, DWORD PTR DS:[ESI + EBP * 0x04]
		ADD EBP, EAX
		ADD EBX, EDX
		XOR EBX, EBP
		SUB ECX, EBX
		MOV EBX, ECX
		SHR EBX, 0x05
		MOV EBP, ECX
		SHL EBP, 0x04
		XOR EBX, EBP
		ADD EAX, 0x61C88647
		MOV EBP, EAX
		AND EBP, 0x03
		MOV EBP, DWORD PTR DS:[ESI + EBP * 0x04]
		ADD EBX, ECX
		ADD EBP, EAX
		XOR EBX, EBP
		SUB EDX, EBX
		DEC EDI
	JNZ LABEL1
		MOV EAX, DWORD PTR SS:[ESP + 0x20]
		POP EDI
		POP ESI
		POP EBP
		MOV DWORD PTR DS:[EAX], EDX
		MOV DWORD PTR DS:[EAX + 0x04], ECX
		POP EBX
		RETN
	}
}

//--------------------------------------------------------------------------

// Decompress function in the client
__declspec(naked) void ASM_LZO_CHECKKEY()
{
	__asm
	{
		MOV EAX,DWORD PTR SS:[ESP + 0x10]
		MOV ECX, EAX
		AND ECX, 0x80000007
	JNG LABEL1
		DEC ECX
		OR ECX, 0xFFFFFFF8
		INC ECX
LABEL1:
	JE LABEL2
		SUB EAX, ECX
		ADD EAX, 8
		MOV DWORD PTR SS:[ESP + 0x10],EAX
	JMP LABEL3;
LABEL2:
		MOV DWORD PTR SS:[ESP + 0x10],EAX
LABEL3:
		PUSH EBX
		MOV EBX, EAX
		SAR EBX, 0x03
		TEST EBX, EBX
	JLE LABEL5

		PUSH EBP
		//MOV EBP, lzoData
		MOV EBP, [ESP + 0x14]

		PUSH ESI
		//MOV ESI, inData
		MOV ESI, [ESP + 0x14]

		PUSH EDI
		//MOV EDI, outBuffer
		MOV EDI, [ESP + 0x14]
LABEL4:
		MOV EAX,DWORD PTR DS:[ESI]
		MOV ECX,[ESI + 0x04]
		PUSH EDI
		PUSH EBP
		PUSH EAX
		PUSH ECX
	CALL ASM_LZO_FUNC1
		ADD ESP, 0x10
		ADD EDI, 0x08
		ADD ESI, 0x08
		DEC EBX
	JNZ LABEL4
		MOV EAX,DWORD PTR SS:[ESP + 0x20]
		POP EDI
		POP ESI
		POP EBP
LABEL5:
		POP EBX
		RET
	}
}

//--------------------------------------------------------------------------

// Wrapper function to decompress data
int LZObject_CheckKey(LPBYTE outBuffer, LPBYTE inData, LPBYTE lzoData, DWORD dwSize)
{
	int result = 1;
	__asm
	{
		mov edx, dwSize

		mov ecx, inData
		sub ecx, 4

		mov eax, lzoData

		mov edi, outBuffer

		push edx
		push eax
		push ecx
		push edi

		call ASM_LZO_CHECKKEY

		MOV EDX, DWORD PTR DS:[EDI]
		MOV EAX, LZ_KEY
		ADD ESP, 0x10
		CMP EDX, EAX
		JE LABEL1
		mov result, 0
LABEL1:
		NOP
	}
	return result;
}

//--------------------------------------------------------------------------

// Ripped from the client via OllyDbg. It was tedious, but simple work since
// you can set labels in OllyDbg for the new jump locations.
__declspec(naked) void ASM_LZO_DECOMPRESS()
{
	__asm
	{
		MOV EAX,DWORD PTR SS:[ESP+0x08]
		PUSH EBX
		MOV EBX,DWORD PTR SS:[ESP+0x14]
		PUSH EBP
		PUSH ESI
		MOV ESI,DWORD PTR SS:[ESP+0x10]
		MOV DWORD PTR DS:[EBX],0x00
		PUSH EDI
		MOV CL,BYTE PTR DS:[ESI]
		LEA EBP,DWORD PTR DS:[ESI+EAX]
		MOV EAX,DWORD PTR SS:[ESP+0x1C]
		CMP CL,0x11
	JBE label1
		AND ECX,0xFF
		SUB ECX,0x11
		INC ESI
		CMP ECX,0x04
	JB label2
label3:
		MOV DL,BYTE PTR DS:[ESI]
		MOV BYTE PTR DS:[EAX],DL
		INC EAX
		INC ESI
		DEC ECX
	JNZ label3
	JMP label4
label1:
		XOR ECX,ECX
		MOV CL,BYTE PTR DS:[ESI]
		INC ESI
		CMP ECX,0x10
	JNB label5
		TEST ECX,ECX
	JNZ label6
		CMP BYTE PTR DS:[ESI],0x00
	JNZ label7
label8:
		MOV DL,BYTE PTR DS:[ESI+0x01]
		ADD ECX,0xFF
		INC ESI
		TEST DL,DL
	JE label8
label7:
		XOR EDX,EDX
		MOV DL,BYTE PTR DS:[ESI]
		INC ESI
		LEA ECX,DWORD PTR DS:[ECX+EDX+0x0F]
label6:
		MOV EDX,DWORD PTR DS:[ESI]
		ADD ESI,0x04
		MOV DWORD PTR DS:[EAX],EDX
		ADD EAX,0x04
		DEC ECX                                             //  Switch (cases 1..4)
	JE label4
		CMP ECX,0x04
	JB label9
label10:
		MOV EDX,DWORD PTR DS:[ESI]                         //  Default case of switch 0055BACA
		SUB ECX,0x04
		MOV DWORD PTR DS:[EAX],EDX
		ADD EAX,0x04
		ADD ESI,0x04
		CMP ECX,0x04
	JNB label10
		TEST ECX,ECX
	JBE label4
label11:
		MOV DL,BYTE PTR DS:[ESI]
		MOV BYTE PTR DS:[EAX],DL
		INC EAX
		INC ESI
		DEC ECX
	JNZ label11
	JMP label4
label9:
		MOV DL,BYTE PTR DS:[ESI]                           //  Cases 2,3,4 of switch 0055BACA
		MOV BYTE PTR DS:[EAX],DL
		INC EAX
		INC ESI
		DEC ECX
	JNZ label9
label4:
		XOR ECX,ECX                                         //  Case 1 of switch 0055BACA
		MOV CL,BYTE PTR DS:[ESI]
		INC ESI
		CMP ECX,0x10
	JNB label5
		SHR ECX,0x02
		MOV EDX,EAX
		SUB EDX,ECX
		XOR ECX,ECX
		MOV CL,BYTE PTR DS:[ESI]
		SHL ECX,0x02
		SUB EDX,ECX
		MOV CL,BYTE PTR DS:[EDX-0x801]
		SUB EDX,0x0801
		INC ESI
		MOV BYTE PTR DS:[EAX],CL
		INC EAX
		INC EDX
lable28:
		MOV CL,BYTE PTR DS:[EDX]
		MOV BYTE PTR DS:[EAX],CL
		MOV DL,BYTE PTR DS:[EDX+0x01]
		INC EAX
		MOV BYTE PTR DS:[EAX],DL
		INC EAX
label14:
		MOV CL,BYTE PTR DS:[ESI-0x02]
		AND ECX,0x03
	JE label1
label2:
		MOV DL,BYTE PTR DS:[ESI]
		MOV BYTE PTR DS:[EAX],DL
		INC EAX
		INC ESI
		DEC ECX
	JNZ label2
		XOR ECX,ECX
		MOV CL,BYTE PTR DS:[ESI]
		INC ESI
label5:
		CMP ECX,0x40                                          //  Switch (cases 0..3F)
	JB label12
		MOV EDX,ECX                                         //  Default case of switch label5
		MOV EDI,EAX
		SHR EDX,0x02
		AND EDX,0x07
		SUB EDI,EDX
		XOR EDX,EDX
		MOV DL,BYTE PTR DS:[ESI]
		SHL EDX,0x03
		SUB EDI,EDX
		DEC EDI
		INC ESI
		SHR ECX,0x05
		DEC ECX
label25:
		MOV DL,BYTE PTR DS:[EDI]
		MOV BYTE PTR DS:[EAX],DL
		MOV DL,BYTE PTR DS:[EDI+0x01]
		INC EAX
		INC EDI
		MOV BYTE PTR DS:[EAX],DL
		INC EAX
		INC EDI
label13:
		MOV DL,BYTE PTR DS:[EDI]
		MOV BYTE PTR DS:[EAX],DL
		INC EAX
		INC EDI
		DEC ECX
	JNZ label13
	JMP label14
label12:
		CMP ECX,0x20
	JB label15
		AND ECX,0x1F                                          //  Cases 20,21,22,23,24,25,26,27,28,29,2A,2B,2C,2D,2E,2F,30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,3F of switch label5
	JNZ label16
		CMP BYTE PTR DS:[ESI],0
	JNZ label17
label18:
		MOV DL,BYTE PTR DS:[ESI+0x01]
		ADD ECX,0xFF
		INC ESI
		TEST DL,DL
	JE label18
label17:
		XOR EDX,EDX
		MOV DL,BYTE PTR DS:[ESI]
		INC ESI
		LEA ECX,DWORD PTR DS:[ECX+EDX+0x1F]
label16:
		XOR EDX,EDX
		MOV EDI,EAX
		MOV DX,WORD PTR DS:[ESI]
		SHR EDX,0x02
		SUB EDI,EDX
		DEC EDI
		ADD ESI,0x02
	JMP label19
label15:
		CMP ECX,0x10
	JB label20
		MOV EDX,ECX                                         //  Cases 10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F of switch label5
		MOV EDI,EAX
		AND EDX,0x08
		SHL EDX,0x0B
		SUB EDI,EDX
		AND ECX,0x07
	JNZ label21
		CMP BYTE PTR DS:[ESI],0x00
	JNZ label22
label23:
		MOV DL,BYTE PTR DS:[ESI+0x01]
		ADD ECX,0xFF
		INC ESI
		TEST DL,DL
	JE label23
label22:
		XOR EDX,EDX
		MOV DL,BYTE PTR DS:[ESI]
		INC ESI
		LEA ECX,DWORD PTR DS:[ECX+EDX+0x07]
label21:
		XOR EDX,EDX
		MOV DX,WORD PTR DS:[ESI]
		ADD ESI,0x02
		SHR EDX,0x02
		SUB EDI,EDX
		CMP EDI,EAX
	JE label24
		SUB EDI,0x4000
label19:
		CMP ECX,0x06
	JB label25
		MOV EDX,EAX
		SUB EDX,EDI
		CMP EDX,0x04
	JL label25
		MOV EDX,DWORD PTR DS:[EDI]
		ADD EDI,0x04
		MOV DWORD PTR DS:[EAX],EDX
		ADD EAX,0x04
		SUB ECX,0x02
label26:
		MOV EDX,DWORD PTR DS:[EDI]
		SUB ECX,0x04
		MOV DWORD PTR DS:[EAX],EDX
		ADD EAX,0x04
		ADD EDI,0x04
		CMP ECX,0x04
	JNB label26
		TEST ECX,ECX
	JBE label14
label27:
		MOV DL,BYTE PTR DS:[EDI]
		MOV BYTE PTR DS:[EAX],DL
		INC EAX
		INC EDI
		DEC ECX
	JNZ label27
	JMP label14
label20:
		SHR ECX,0x02                                           //  Cases 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F of switch label5
		MOV EDX,EAX
		SUB EDX,ECX
		XOR ECX,ECX
		MOV CL,BYTE PTR DS:[ESI]
		SHL ECX,0x02
		SUB EDX,ECX
		DEC EDX
		INC ESI
	JMP lable28
label24:
		MOV ECX,DWORD PTR SS:[ESP+0x1C]
		SUB EAX,ECX
		CMP ESI,EBP
		MOV DWORD PTR DS:[EBX],EAX
	JNZ label29
		POP EDI
		POP ESI
		POP EBP
		XOR EAX,EAX
		POP EBX
		RETN
label29:
		SBB EAX,EAX
		POP EDI
		AND AL,0xFC
		POP ESI
		POP EBP
		ADD EAX, -4
		POP EBX
		RETN
	}
}

//--------------------------------------------------------------------------

// Decompress wrapper function
void LZObject_Decompress(LPBYTE src, DWORD srcLen, LPBYTE dst, DWORD * ptrNewLen, void * workMemory)
{
	__asm
	{
		MOV EDI, src
		MOV EAX, dst
		push workMemory
		MOV EDX, ptrNewLen
		push EDX
		MOV EDX, srcLen
		PUSH EAX
		PUSH EDX
		ADD EDI, 4
		PUSH EDI
		call ASM_LZO_DECOMPRESS
		ADD ESP, 0x14
		TEST EAX, EAX
		JE LABEL1
		INT 3 // Error, don't continue
LABEL1:
		NOP
	}
}

//--------------------------------------------------------------------------

// Tokenizes a string into a vector
std::vector<std::string> TokenizeString(const std::string& str, const std::string& delim)
{
	// http://www.gamedev.net/community/forums/topic.asp?topic_id=381544#TokenizeString
	using namespace std;
	vector<string> tokens;
	size_t p0 = 0, p1 = string::npos;
	while(p0 != string::npos)
	{
		p1 = str.find_first_of(delim, p0);
		if(p1 != p0)
		{
			string token = str.substr(p0, p1 - p0);
			tokens.push_back(token);
		}
		p0 = str.find_first_not_of(delim, p1);
	}
	return tokens;
}

//--------------------------------------------------------------------------

// Saves the file to a specific folder based on the path. The root 
// directory I choose to use is named 'output'.
void SaveFile(const char * originalFilename, LPBYTE outBuffer, DWORD outBufferSize)
{
	std::stringstream dirPath;
	std::vector<std::string> pathTokens = TokenizeString(originalFilename, "\\/");

	dirPath << "output";
	CreateDirectoryA(dirPath.str().c_str(), NULL);
	dirPath << "\\";

	size_t index = 0;
	for(index = 0; index < pathTokens.size() - 1; ++index)
	{
		if(pathTokens[index].find_first_of(":") != std::string::npos)
			continue;
		dirPath << pathTokens[index];
		CreateDirectoryA(dirPath.str().c_str(), NULL);
		dirPath << "\\";
	}

	dirPath << pathTokens[index];

	FILE * of = fopen(dirPath.str().c_str(), "wb");
	if(of)
	{
		fwrite(outBuffer, 1, outBufferSize, of);
		fclose(of);
	}
	else
	{
		printf("Could not save the file %s\n", dirPath.str().c_str());
	}
}

//--------------------------------------------------------------------------

// Dumps a complete archive. I have combined two sets of logic for this,
// but you can separate them if you want a more unique tool that allows
// you to extract individual files or explore the contents.
bool DumpArchive(const char * inFolder, const char * name)
{
	HANDLE eixHandle = INVALID_HANDLE_VALUE;
	HANDLE epkHandle = INVALID_HANDLE_VALUE;
	SECURITY_ATTRIBUTES eixSecurity = {0};
	SECURITY_ATTRIBUTES epkSecurity = {0};
	DWORD eixFileSize = 0;
	DWORD epkFileSize = 0;
	HANDLE eixFileMapping = NULL;
	HANDLE epkFileMapping = NULL;
	LPBYTE eixFileBufferPtr = NULL;
	LPBYTE epkFileBufferPtr = NULL;
	bool bWasError = false;

	std::string eixName_ = inFolder;
	if(!(eixName_[eixName_.size() - 1] == '\\' || eixName_[eixName_.size() - 1] == '/'))
	{
		eixName_ += "\\";
	}
	eixName_ += name;
	eixName_ += ".eix";

	std::string epkName_ = inFolder;
	if(!(epkName_[epkName_.size() - 1] == '\\' || epkName_[epkName_.size() - 1] == '/'))
	{
		epkName_ += "\\";
	}
	epkName_ += name;
	epkName_ += ".epk";

	const char * eixName = eixName_.c_str();
	const char * epkName = epkName_.c_str();

	eixSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
	eixSecurity.bInheritHandle = TRUE;
	eixSecurity.lpSecurityDescriptor = NULL;

	epkSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
	epkSecurity.bInheritHandle = TRUE;
	epkSecurity.lpSecurityDescriptor = NULL;

	// Open the files to access
	while(bWasError == false)
	{
		eixHandle = CreateFileA(eixName, GENERIC_READ, FILE_SHARE_READ, &eixSecurity, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		if(eixHandle == INVALID_HANDLE_VALUE)
		{
			printf("Could not open the %s file. The program will now exit.\n", eixName);
			bWasError = true;
			break;
		}

		epkHandle = CreateFileA(epkName, GENERIC_READ, FILE_SHARE_READ, &epkSecurity, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		if(epkHandle == INVALID_HANDLE_VALUE)
		{
			printf("Could not open the %s file. The program will now exit.\n", epkName);
			bWasError = true;
			break;
		}
		break; // All done now
	}


	// Create the access handles for reading the files
	while(bWasError == false)
	{
		// We need to store the size of the file for file mapping
		eixFileSize = GetFileSize(eixHandle, NULL);
		if(eixFileSize == INVALID_FILE_SIZE)
		{
			DWORD dwError = GetLastError();
			if(dwError != NO_ERROR)
			{
				printf("There was an error [%i] getting the file size of the %s file. The program will now exit.\n", dwError, eixName);
				bWasError = true;
				break;
			}
		}

		// We need to store the size of the file for file mapping
		epkFileSize = GetFileSize(epkHandle, NULL);
		if(epkFileSize == INVALID_FILE_SIZE)
		{
			DWORD dwError = GetLastError();
			if(dwError != NO_ERROR)
			{
				printf("There was an error [%i] getting the file size of the %s file. The program will now exit.\n", dwError, epkName);
				bWasError = true;
				break;
			}
		}

		// Create a file mapping object
		eixFileMapping = CreateFileMapping(eixHandle, NULL, PAGE_READONLY, 0, eixFileSize, NULL);
		if(eixFileMapping == 0)
		{
			printf("Could not create a file mapping object for the %s file. The program will now exit.\n", eixName);
			bWasError = true;
			break;
		}

		// Create a file mapping object
		epkFileMapping = CreateFileMapping(epkHandle, NULL, PAGE_READONLY, 0, epkFileSize, NULL);
		if(epkFileMapping == 0)
		{
			printf("Could not create a file mapping object for the %s file. The program will now exit.\n", epkName);
			bWasError = true;
			break;
		}

		// Create a file mapping view
		eixFileBufferPtr = reinterpret_cast<LPBYTE>(MapViewOfFile(eixFileMapping, FILE_MAP_READ, 0, 0, eixFileSize));
		if(eixFileBufferPtr == 0)
		{
			printf("Could not create a view of the the %s file. The program will now exit.\n", eixName);
			bWasError = true;
			break;
		}

		// Create a file mapping view
		epkFileBufferPtr = reinterpret_cast<LPBYTE>(MapViewOfFile(epkFileMapping, FILE_MAP_READ, 0, 0, epkFileSize));
		if(epkFileBufferPtr == 0)
		{
			printf("Could not create a view of the the %s file. The program will now exit.\n", epkName);
			bWasError = true;
			break;
		}

		break; // All done now
	}


	// Now we need to verify the files we just loaded
	while(bWasError == false)
	{
		// We need at least 12 bytes
		if(eixFileSize < 0x0C)
		{
			printf("The file size for the %s file is too small. The program will now exit.\n", eixName);
			bWasError = true;
			break;
		}

		// Verify the header
		LPDWORD eixHeader = reinterpret_cast<LPDWORD>(eixFileBufferPtr);
		if(*eixHeader != 0x444B5045) // Some hard coded check
		{
			// Important: This value is read from the client itself. If the client updates, this value
			// would need to be updated as well if it ever changed.
			if(*eixHeader != LZ_KEY)
			{
				printf("The file header for the %s file is incorrect. The program will now exit.\n", eixName);
				bWasError = true;
				break;
			}

			// Get a file header pointer from the buffer
			TEntry2 * eixHeader = (TEntry2 *)eixFileBufferPtr;

			// Store a pointer to the encrypted data
			LPBYTE eixDataBuffer = eixFileBufferPtr + 0x14;

			// We don't care about this check because we will create the
			// buffers ourselves in dynamic memory. The game wants to be as
			// efficient as possible though.
			if(eixHeader->decompressedBlockSize <= 0x10000)
			{
			}

			// Allocate space for the decompressed buffer
			LPBYTE decompressedBuffer = new BYTE[eixHeader->decompressedBlockSize];
			memset(decompressedBuffer, 0, eixHeader->decompressedBlockSize);

			// If the contents of the file are not encrypted (no test data yet)
			// So, not going to add the implementation at this time.
			if(eixHeader->decryptedBlockSize == 0)
			{
				printf("[TODO] -- eixHeader of %s is not encrypted!\n", eixName);
				bWasError = true;
				delete [] decompressedBuffer;
				break;
			}

			// We don't care about this check because we will create the
			// buffers ourselves in dynamic memory. The game wants to be as
			// efficient as possible though.
			if(eixHeader->decryptedBlockSize < 0x2000)
			{
			}

			// Create a buffer to decrypt the contents of the exi header into
			LPBYTE compressedBuffer = new BYTE[eixHeader->decryptedBlockSize];
			memset(compressedBuffer, 0, eixHeader->decryptedBlockSize);

			// Try to decrypt the data
			int result = LZObject_CheckKey(compressedBuffer, eixDataBuffer, gLZOData, eixHeader->decryptedBlockSize);
			if(result == 0)
			{
				delete [] decompressedBuffer;
				delete [] compressedBuffer;
				printf("There was an error decrypting the data of the %s file. The program will now exit.\n", eixName);
				bWasError = true;
				break;
			}

			// Try to decompress the data now
			DWORD finalSize = 0;
			LZObject_Decompress(compressedBuffer, eixHeader->compressedBlockSize, decompressedBuffer, &finalSize, 0);

			// Make sure the file size matches
			if(finalSize != eixHeader->decompressedBlockSize)
			{
				delete [] decompressedBuffer;
				delete [] compressedBuffer;
				printf("There was an error decompressing the data of the %s file. The program will now exit.\n", eixName);
				bWasError = true;
				break;
			}

			// Get a pointer to the new file header
			TEntry3 * entry3 = (TEntry3 *)decompressedBuffer;

			// Check the file version
			if(entry3->version != 2)
			{
				delete [] decompressedBuffer;
				delete [] compressedBuffer;
				printf("The version of the %s file is incorrect. Expected (%i) Actual (%i). The program will now exit.\n", eixName, 2, entry3->version);
				bWasError = true;
				break;
			}

			// Make sure we have a match in the number of entries and the expected block size
			if(finalSize != (((entry3->fileCount + entry3->fileCount * 2) << 0x06) + 0x0C))
			{
				delete [] decompressedBuffer;
				delete [] compressedBuffer;
				printf("The pack index file size of the %s file is incorrect. The program will now exit.\n", eixName);
				bWasError = true;
				break;
			}

			// Store a pointer to the block of data
			LPBYTE decompressedBlock = decompressedBuffer + 0x0C;

			// If we have files to process
			if(entry3->fileCount > 0)
			{
				// Build a filename for our dump file
				std::string dumpFileName = eixName;
				dumpFileName = dumpFileName.substr(1 + dumpFileName.find_last_of("\\/"));
				dumpFileName = dumpFileName.substr(0, dumpFileName.find_first_of("."));
				dumpFileName += "_dump.txt";

				// Create the output file for the eix header dump
				FILE * of = fopen(dumpFileName.c_str(), "w");
				if(of == 0)
				{
					printf("There was an error creating the %s file. The header data will not be dumped.\n", dumpFileName.c_str());
				}

				// Loop through all of the files
				for(DWORD x = 0; x < entry3->fileCount; ++x)
				{
					// Create a pointer to the file entry block
					TEntry1 * pEntry = (TEntry1 *)decompressedBlock;

					// Make sure there is a value here
					if(pEntry->dw2 == 0)
					{
						printf("No dw2 field set for the file %s\n", pEntry->filename);
						continue;
					}

					// Simple entry dump
					if(of)
					{
						fprintf(of, "%i. ", pEntry->index);
						fprintf(of, "%s\n", pEntry->filename);
						fprintf(of, "[%.8X]", pEntry->dw1);
						fprintf(of, "[%.8X]", pEntry->dw2);
						fprintf(of, "[%.8X]", pEntry->dw3);
						fprintf(of, "[%.8X]", pEntry->dwSrcSize);
						fprintf(of, "[%.8X]", pEntry->unpackedCRC);
						fprintf(of, "[%.8X]", pEntry->dwFileOffset);
						fprintf(of, "[%.2X %.2X %.2X %.2X]", pEntry->packedType, pEntry->b2, pEntry->b3, pEntry->b4);
						fprintf(of, "\n");
					}

					// Not compressed, no extra header
					if(pEntry->packedType == 0)
					{
						SaveFile(pEntry->filename, epkFileBufferPtr + pEntry->dwFileOffset, pEntry->dwSrcSize);
					}

					// Header and compressed/encrypted
					else
					{
						// Decompress
						if(pEntry->packedType == 1)
						{
							// Calculate the data pointer to the entry data block
							LPBYTE pDataPtr = epkFileBufferPtr + pEntry->dwFileOffset;

							// Get a pointer to the header for this block
							TEntry2 * pEntryHeader = (TEntry2*)pDataPtr;

							// Make sure the header is correct
							DWORD h = *(reinterpret_cast<LPDWORD>(pDataPtr));
							if(h != LZ_KEY)
							{
								printf("The header for %s is incorrect. Expected (%x) Actual (%x).\n", pEntry->filename, LZ_KEY, h);
								continue;
							}

							// Allocate memory for the uncompressed data
							LPBYTE uncompressedData = new BYTE[pEntryHeader->decompressedBlockSize];
							memset(uncompressedData, 0, pEntryHeader->decompressedBlockSize);

							// Decompress the data
							LZObject_Decompress(pDataPtr + 16, pEntryHeader->compressedBlockSize, uncompressedData, &finalSize, 0);

							// Make sure the operation went right
							if(finalSize != pEntryHeader->decompressedBlockSize)
							{
								printf("File size for %s differs from expected. Expected (%i) Actual (%i).\n", pEntry->filename, pEntryHeader->decompressedBlockSize, finalSize);
							}
							else
							{
								SaveFile(pEntry->filename, uncompressedData, pEntryHeader->decompressedBlockSize);
							}

							// Cleanup now
							delete [] uncompressedData;
						}

						// Decrypt + Decompress
						else if(pEntry->packedType == 2)
						{
							// Calculate the data pointer to the entry data block
							LPBYTE pDataPtr = epkFileBufferPtr + pEntry->dwFileOffset;

							// Get a pointer to the header for this block
							TEntry2 * pEntryHeader = (TEntry2*)pDataPtr;

							DWORD h = *(reinterpret_cast<LPDWORD>(pDataPtr));
							if(h != LZ_KEY)
							{
								printf("The header for %s is incorrect. Expected (%x) Actual (%x).\n", pEntry->filename, LZ_KEY, h);
								continue;
							}

							// Create a buffer for the decrypted data
							LPBYTE decryptedData = new BYTE[pEntryHeader->decryptedBlockSize];
							memset(decryptedData, 0, pEntryHeader->decryptedBlockSize);

							// Decrypt the data
							int result = LZObject_CheckKey(decryptedData, pDataPtr + 20, gLZOData2, pEntryHeader->decryptedBlockSize);
							if(result == 0)
							{
								printf("There was an error decrypting the data for the %s file. It will be skipped.\n", pEntry->filename);
								delete [] decryptedData;
								continue;
							}

							// Create a buffer for the final uncompressed data
							LPBYTE uncompressedData = new BYTE[pEntryHeader->decompressedBlockSize];
							memset(uncompressedData, 0, pEntryHeader->decompressedBlockSize);

							// Decompress
							LZObject_Decompress(decryptedData, pEntryHeader->compressedBlockSize, uncompressedData, &finalSize, 0);

							// Make sure the file sizes match
							if(finalSize != pEntryHeader->decompressedBlockSize)
							{
								printf("File size for %s differs from expected. Expected (%i) Actual (%i)\n", pEntry->filename, pEntryHeader->decompressedBlockSize, finalSize);
							}
							else
							{
								SaveFile(pEntry->filename, uncompressedData, pEntryHeader->decompressedBlockSize);
							}

							// Cleanup now
							delete [] decryptedData;
							delete [] uncompressedData;
						}
					}
					decompressedBlock += 0xC0; // next block
				}

				// Close our output file for the header dump file
				if(of)
				{
					fclose(of);
				}
			}

			// Cleanup
			delete [] decompressedBuffer;
			delete [] compressedBuffer;
		}
		else
		{
			// If we get here, we are using an unsupported type of file that
			// was not accessible at the time this tool was written.
			printf("[TODO] -- if(*eixHeader != 0x444B5045)\n");
			bWasError = true;
			break;
		}

		break; // All done now
	}

	// Cleanup

	if(eixFileMapping != 0)
		CloseHandle(eixFileMapping);
	if(epkFileMapping != 0)
		CloseHandle(epkFileMapping);

	if(eixHandle != INVALID_HANDLE_VALUE)
		CloseHandle(eixHandle);
	if(epkHandle != INVALID_HANDLE_VALUE)
		CloseHandle(epkHandle);

	// Return the status
	return (bWasError == false);
}

//--------------------------------------------------------------------------


J'aimerai savoir si y'a un moyen de recompilé grâce à cette méthode ?
Je vous fourni 2 exemple de fichiers pour que vous voyez : http://www.megaupload.com/?d=POXQOHVR

Et mon 2ème problème serait pour savoir quel est la compilation de ce fichier : http://www.megaupload.com/?d=HHO0VS9J

Merci de vos réponses, et encore désolé si je me suis trompé de section

PS : Si le travail sur ces fichiers demande beaucoup de temps, je suis prêt à payer (J'ai les moyens) pour que l'on m'aide c'est très important pour moi

dimanche 25 octobre 2009 à 18:01:14 | Re : Savoir la compilation (Décompilation si possible ^^)

rt15

Membre Club Administrateur CodeS-SourceS
Salut,

Vu que tu es près à rémunéré, tu as un site emploi.

Je comprends pas tout ce que tu racontes, mais il me semble deviner deux ou trois truc via le code.
Quelqu'un à désassemblé (Avec OllyDbg) un .exe (Client) fait par un autre.
Il a récupéré du code assembleur sans chercher à trop le comprendre ou à le recoder en C++.
Il l'a simplement inclus dans son propre code C++, en faisant de l'assemblage en ligne.

Sur le plan technique c'est compliqué : celui qui a fait ça est pas mauvais et ça a dû lui prendre un certain temps.
C'est pas forcément très légal non plus...

Mais maintenant tu as un source visiblement compilable.
Ce source est manifestement du C++ (vector...) prévu pour Visual Studio. En effet, la façon de faire de l'assembleur en ligne (__asm{})est peu portable et on voit aussi __declspec(naked), qui est propre à VS.

Donc, si tout ce que tu veux, c'est le .exe correspondant à ce source, il faut que toi ou quelqu'un d'autre récupère un Visual Studio (Express, c'est gratuit, mais il te faudra aussi télécharger le Windows SDK pour avoir windows.h) et compile (Et corrige les éventuels soucis à la compilation...).
dimanche 25 octobre 2009 à 23:30:47 | Re : Savoir la compilation (Décompilation si possible ^^)

Clad38

Merci de ta réponse, j'irais voir le site.

Pour le programme je l'ai déjà compilé et il permet d'extraire les fichiers des extansion (Epk, et eix il marche ensemble)

Ce que je cherche c'est si il y à un moyen d'utilisé le code pour recompilé ?

Cordialement
lundi 26 octobre 2009 à 09:07:50 | Re : Savoir la compilation (Décompilation si possible ^^)

rt15

Membre Club Administrateur CodeS-SourceS
Ah je crois que j'ai compris en fait.

Tu mélangerais pas un peu "compiler" et "compresser" ?

Par exemple, pour le fichier :
http://www.megaupload.com/?d=HHO0VS9J

Ce n'est pas un fichier compilé : ce n'est pas un fichier exécutable issu de la compilation d'un code source.

C'est a priori un fichier compressé ou chiffré (Encrypté).

Et le code source ci-dessus permet de décompresser une archive. Ce code source a été plus ou moins décompilé et peut être recompilé.

Et ce que tu veux, ce n'est pas recompiler, mais que quelqu'un fasse un code source qui permet de compresser au même format que celui qu'est capable de décompresser le code ci-dessous. En gros, il faut renverser l'algo... Sachant qu'il est en partie en assembleur.

Alors là oui, effectivement, il y a du boulot...
lundi 26 octobre 2009 à 09:49:58 | Re : Savoir la compilation (Décompilation si possible ^^)

Clad38

Ah d'accord, c'est pour sa que je parler de rémunération.

Je crois pas que le site emploie sera le meilleur moyen, car les personne y sont pour un emploi fixe (J'ai un peu regarder hier)
Mais si quelqu'un passe par la :/ je suis prêt à donner pas mal d'argent sa dépend du boulot :)

Pour re-expliqué un peu, le fichiers dont tu parle : http://www.megaupload.com/?d=HHO0VS9J
Je cherche juste en quoi il as été compilé, car je ne sais pas du tout.

Enfaite les 2 choses que je cherche sont :

- Savoir "re-compresser" les fichiers Epk et Eix en inversant peut être le code (Désolé je m'y connais pas sinon je serais pas la ^^)

- Savoir décompresser, et recompresser ce fichier : http://www.megaupload.com/?d=HHO0VS9J

En tout cas merci de toute ces réponses, si par hasard tu serais intéresser on peut en parler en privé, sinon j'attendrais :/

Cordialement
lundi 2 novembre 2009 à 00:43:20 | Re : Savoir la compilation (Décompilation si possible ^^)

Clad38

Un petit UP :(


Cette discussion est classée dans : mov, ptr, eax, edx, ecx


Répondre à ce message

Sujets en rapport avec ce message

[Aide] Repackeur EPK/EIX [ par slam2 ] Bonjour, Je requière votre aide étant tout nouveau dans le milieu de la programmation C# & C++ . Afin de mener à bien mon projet, dans le but de pouv optimiser un codes asm [ par sajid_morad ] salut tout le monde , j ai une parti du code en c++, que j ai voulu optimiser , le l ai reécri en asm , mai ça donne pas grand chose, si quelqu un pou [EXPERTS]optimisation du c/asm [ par MrdJack ] Bonsoir, je suis en train de me renseigner sur le c et l'asm niveau vitesse d'execution. en detail je me demande comment créer un code en c pour que s asm dans WinMain :) [ par Joky ] Salut les gens ;) Donc voilà je comprend à moitié ce code __asm{    push    0     call    dword ptr GetModuleHandle     push  &nb ASM + C++, Aidez-moi SVP :D [ par belette321 ] Bonjour, voilla j'esseil de faire un anti-hack mais j'optien une erreur lors de se code... : [code=cpp]__asm{ mov eax, WriteProcessMemory; IAT mov Optimisation de code assembleur inclus dans du code C [ par fred_82 ] Bonjour,Alors j'explique le problème, j'aimerais faire une petite fonction en assembleur que j'inclus dans du code C, le probleme est que cette foncti problèmes avec le registre ESP (C++ et ASM) [ par DeadlyPredator ] Bonjour, je voudrais créer une fonction permettant d'appeller des APIs sans avoir besoins de déclarer leur prototype ni en utilisant les .lib. Lorsque ASM et C++ [ par sebastienbro ] Bonjour, j'aimerais savoir ce qui ne vas pas dans le code suivant. J'ai une erreur "error C2400: inline assembler syntax error in 'opcode'; found 'con petit pb de pointer [ par mirlaine ] en fait c tou simpleje cherche l 'équivalen à ca: LPCWSTR user LPBYTE *bufptr mov eax, [bufptr] mov eax, [eax] //LPUSER_INFO_0 mov eax, [e gestion de memoire [ par gyzmo1 ] Salut à tous, j ai un problème de fuite de mémoire, minime mais suffisamment important pour faire planter mon programme lorsque celui ci tourne des he


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,530 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales