[Development] MuOnline 99.6XT(1.0M) main.exe Methods Decompilation

Results 1 to 4 of 4
  1. #1
    Enthusiast vankyy26 is offline
    MemberRank
    Mar 2010 Join Date
    48Posts

    [Development] MuOnline 99.6XT(1.0M) main.exe Methods Decompilation


    Hello,
    as working on a project of mine, I decided to share with you some of my work, which I'm sure will be useful to people who deal with coding servers.

    The main thing to do is to decompile methods in main.exe of that version. Decompilation will be to understandable and running C ++ code, which can be used in .dll files with custom things in the client .

    The first method, you will get decompiled is that of Chaos Machine, where the client verifies that the items that are placed in the machine meet the requirements for combination. With this you can add custom combinations in Chaos Machine.

    1. Chaos Machine Decompilation:

    1.1. signed int ChaosMachineGetCombinationType(unsigned int item, int argument2, int argument3) //0x005D26B0



    Progress : 100%



    Optimisation : 75%


    Code:
    struct Item // Recovering Item struct
    {
    	short itemType; //0x0
    	int itemLevel; //0x4
    	int itemTypeTemp; //??
    	 
    	BYTE itemDurability; //0x1A
    	int ItemTypePlus40; //0x28
    };
    
    signed int ChaosMachineGetCombinationType(unsigned int item, int argument2, int argument3)
    {
    	int unknownGlobal = *(int*)0x056F3BBC;//  0x056F3BBC //val=1024 - might be static
    	int unknownGlobal2 = *(int*)0x0067196C; // 0x0067196C
    	int unknownGlobal3[] = { 5 }; //0x00671968
    	char unknownGlobal4 = *(char*)0x07CB2754; // 0x07CB2754
    	int unknownGlobal5 = *(int*)0x076E0C50; //0x076E0C50
    	int secondLvlWingsPercent = *(int*)0x07CB274C;// 0x07CB274C
    	int chaosCombinationType = *(int*)0x07CB2744; // 0x07CB2744
    	int allItemsCount;
    	int cnt = 0;
    	int v7;
    	int v11;
    	int v12;
    	unsigned __int8 v21;
    	signed int v22;
    	int v24;
    	BYTE v25;
    	//signed int ItemTypev27;
    	signed int result;
    	unsigned int additionalItemAddPercent = 0; 
    	int onlyWingsAddPercent = 0;
    	char *v64;
    	int v65;
    	int chaosCount = 0;
    	int v68 = 0;
    	int devilEyeCount = 0;
    	int devilKeyCount = 0;
    	int isLvl9 = 0;
    	int isLvl10 = 0;
    	int isLvl11 = 0;
    	int isLvl12 = 0;
    	int blessCount = 0;
    	int soulCount = 0;
    	int unrilaCount = 0;
    	int v78 = 0;
    	int creationCount = 0;
    	int featherCount = 0;
    	int FirstLvlWingsCount = 0;
    	int additionalItems_count = 0;
    	int secondLvlWings_count = 0;
    	int chaosWeapon_Count = 0;
    	int scrollOfArchangelCount = 0;
    	int bloodBoneCount = 0;
    	int CapeOfLordCount = 0;
    	int guardianCount = 0;
    	int devilsKey_Level = 0;
    	int devilsEye_Level = 0;
    	int scrollOfArchangel_Level = 0;
    	int bloodBone_Level = 0;
    	int feather_Level = 0;
    	char *v96;
    	void* v97;
    	int v98;
    
    	scrollOfArchangel_Level = 0;
    	additionalItemAddPercent = 0;
    	bloodBone_Level = 0;
    	onlyWingsAddPercent = 0;
    	feather_Level = 0;
    	*(int*)0x0067196C = 1; //unknounGlobal2
    	unknownGlobal3[0] = 1; //unknounGlobal3[0]
    
    	Item cmItem;
    
    
    	if (argument3 <= 0)
    	{
    		allItemsCount = 0;
    	}
    	else
    	{
    		allItemsCount = 0;
    		v97 = (LPVOID)argument3;
    		v7 = 72 * argument2;
    		v98 = 72 * argument2;
    		do
    		{
    			if ( argument2 > 0 )
    			{
    				v65 = argument2;
    				int i = 0;
    				do
    				{
    					if ( *(WORD *)item!= -1 )
    					{
    						cmItem.ItemTypePlus40 = item + 40;
    
    						if ( *(DWORD *)(item + 60) > 0 )
    						{
    							v96 = 0;
    							argument3 = 0;
    							allItemsCount++;
    							v64 = &unknownGlobal4;
    							v11 = unknownGlobal5 + 76 * *(WORD *)item;
    							if ( unknownGlobal3[0] <= *(BYTE *)(v11 + 34) ) //unknownGlobal3
    							{
    								*(int*)0x00671968 = *(BYTE *)(v11 + 34); //unknownGlobal3
    								unknownGlobal3[0] = *(BYTE *)(v11 + 34);
    							}
    							v12 = *(BYTE *)(v11 + 35);
    							if ( unknownGlobal2 <= v12 )
    								*(int*)0x0067196C = v12; //unknownGlobal2
    
    							cmItem.itemType = *(WORD *)item;
    							cmItem.itemLevel = (*(DWORD *)(item + 4) >> 3) & 0xF; //mask to get the 3rd byte, where the level is stored
    							cmItem.itemDurability = *(BYTE *)(item + 26);
    
    							if (cmItem.itemType < 384 || cmItem.itemType <= 390 || cmItem.itemType == 446 ) //ITEMGET(12,0) - Wings of Elf , ITEMGET(12,6) - Wings of Darkness , ITEMGET(13,30) - Cape of Lord
    							{
    								switch ( cmItem.itemLevel )
    								{
    								case 9:
    									++isLvl9;
    									*(char*)0x07CB2754 = 0; //unknownGlobal4
    									argument3 = 1;
    									v96 = &unknownGlobal4;
    									break;
    								case 10:
    									++isLvl10;
    									*(char*)0x07CB2754 = 0; //unknownGlobal4
    									argument3 = 1;
    									v96 = &unknownGlobal4;
    									break;
    								case 11:
    									++isLvl11;
    									*(char*)0x07CB2754 = 0; //unknownGlobal4
    									argument3 = 1;
    									v96 = &unknownGlobal4;
    									break;
    								case 12:
    									++isLvl12;
    									*(char*)0x07CB2754 = 0; //unknownGlobal4
    									argument3 = 1;
    									v96 = &unknownGlobal4;
    									break;
    								default:
    									break;
    								}
    							}
    
    							switch (cmItem.itemType)
    							{
    							case 465: //ITEMGET(14,17) - Devil's Eye
    								devilsKey_Level = cmItem.itemLevel;
    								++devilEyeCount;
    								break;
    							case 466: //ITEMGET(14,18) - Devil's Key
    								devilsEye_Level = cmItem.itemLevel;
    								++devilKeyCount;
    								break;
    							case 432: //ITEMGET(13,16) - Scroll of Archangel
    								scrollOfArchangel_Level = cmItem.itemLevel;
    								++scrollOfArchangelCount;
    								break;
    							case 433: //ITEMGET(13,17) - Blood Bone
    								bloodBone_Level = cmItem.itemLevel;
    								++bloodBoneCount;
    								break;
    							case 461: //ITEMGET(14,13) - Jewel of Bless
    								++blessCount;
    								break;
    							case 462: //ITEMGET(14,14) - Jewel of Soul
    								++soulCount;
    								break;
    							case 470: //ITEMGET(14,22) - Jewel of Creation
    								++creationCount;
    								break;
    							case 479: //ITEMGET(14,31) - Jewel of Guardian
    								++guardianCount;
    								break;
    							case 430: //ITEMGET(13,14) - Loch's Feather
    								feather_Level = cmItem.itemLevel;
    								++featherCount;
    								break;
    							case 384: //ITEMGET(12,0) - Wings of Elf
    							case 385: //ITEMGET(12,1) - Wings of Heaven
    							case 386: //ITEMGET(12,2) - Wings of Satan
    								v64 = (char *)&argument3 + 3;
    								*(int*)0x07CB2748 = 0; //unknownGlobal6
    								++FirstLvlWingsCount;
    								onlyWingsAddPercent = CalcItemAdditionalPercentAdd((signed int)((char *)&argument3 + 3), item, 0);
    
    								cnt = 0;
    								while ( cnt < *(BYTE *)cmItem.ItemTypePlus40 )
    								{
    									v21 = *(BYTE *)(cmItem.ItemTypePlus40 + cnt + 1);
    									if ( v21 >= 80 && (v21 <= 81 || v21 == 85) )
    									{
    										//if ( v21 <= 81 )
    										//{
    											*(int*)0x07CB2748 = *(BYTE *)(item + cnt + 49); //unknownGlobal6
    										//}
    										//else if ( v21 == 85 )
    										//{
    										//	*(int*)0x07CB2748 = 4 * *(BYTE *)(item + cnt + 49); //unknownGlobal6
    										//}
    									}
    									++cnt;
    								}
    								
    
    
    								if ( *(BYTE *)cmItem.ItemTypePlus40 )
    								{
    									int j = 0;
    									while ( j < *(BYTE *)cmItem.ItemTypePlus40 )
    									{
    										if ( *(BYTE *)(item + j + 41) == 84 )
    										{
    											char* cp = v96;
    											i = v96 == 0; // if(v96==0) i=1;
    											*v64 = 1;
    											if ( !i )
    												*cp = 1;
    										}
    										++j;
    									}
    								}
    
    								break;
    							case 418: //ITEMGET(13,2) - Horn of Uniria
    								if ( cmItem.itemDurability >= 255 )
    									++unrilaCount;
    								break;
    							case 399: //ITEMGET(12,15) - Jewel of Chaos
    								++chaosCount;
    								break;
    							case 446: //ITEMGET(13,30) - Cape of Lord
    								++CapeOfLordCount;
    								break;
    							default:
    								v22 = 0;
    								int j = 0;
    								if ( cmItem.itemType >= 384 || cmItem.itemLevel < 4 ) //ITEMGET(12,0) - Wings of Elf
    								{
    									if ( v24 <= 0 )
    									{
    										++v78;
    										BYTE test = *(BYTE *)(item + 27) & 0x3F;
    										if ( *(BYTE *)(item + 27) & 0x3F && cmItem.itemLevel >= 4 )
    										{
    											if (cmItem.itemType < 387 || cmItem.itemType > 390 ) //ITEMGET(12,3) - Wings of Spirits < > ITEMGET(12,6) - Wings of Darkness
    											{
    												++additionalItems_count;
    												additionalItemAddPercent += CalcItemAdditionalPercentAdd(LOWORD(cmItem.itemType), item, 0); 
    											}
    											else
    											{
    												++secondLvlWings_count;
    											}
    										}
    									}
    
    								}
    								else
    								{
    									*(char*)0x07CB2754 = 0; //unknownGlobal4
    									j = 0;
    
    									v24 = *(BYTE *)cmItem.ItemTypePlus40;
    									argument3 = 1;
    
    									do
    									{
    										v25 = *(BYTE *)(cmItem.ItemTypePlus40 + j + 1);
    										if ( v25 >= 80 && v25 <= 83 && !v22 )
    										{
    											++v68; // common with chaos weapon count
    											if (cmItem.itemType == 70 || cmItem.itemType == 134 || cmItem.itemType == 167 ) //ITEMGET(2,6) - Chaos Dragon Axe, ITEMGET(4,6) - Chaos Nature Bow, ITEMGET(5,7) - Chaos Lightning Staff
    												++chaosWeapon_Count;
    											v22 = 1;
    										}
    										++j;
    									}
    									while ( j < v24 );
    
    									if ( !v22 )
    									{
    										++v78;
    									}
    
    									BYTE asd = *(BYTE *)(item + 27) & 0x3F;
    									if ( *(BYTE *)(item + 27) & 0x3F && cmItem.itemLevel >= 4 )
    									{
    										if ( cmItem.itemType < 387 || cmItem.itemType > 390 ) //ITEMGET(12,3) - Wings of Spirits < > ITEMGET(12,6) - Wings of Darkness
    										{
    											++additionalItems_count;
    											additionalItemAddPercent += CalcItemAdditionalPercentAdd(LOWORD(cmItem.itemType), item, 0); 
    										}
    										else
    										{
    											++secondLvlWings_count;
    										}
    									}
    								}
    								break;
    							}
    
    							if ( argument3 )
    							{
    								int j = 0;
    								if ( *(BYTE *)cmItem.ItemTypePlus40 )
    								{
    									do
    									{
    										if ( *(BYTE *)(item + j + 41) == 84 )
    										{
    											char* cp = v96;
    											i = v96 == 0;
    											*v64 = 1;
    											if ( !i )
    												*cp = 1;
    										}
    										++j;
    									}
    									while ( j < *(BYTE *)cmItem.ItemTypePlus40 );
    								}
    							}
    						}
    					}
    					i = v65 == 1;
    					item += 72;
    					--v65;
    				}
    				while ( !i );
    				v7 = v98;
    			}
    			v97 = (char *)v97 - 1;
    		}
    		while ( v97 );
    	}
    
    
    	//Devil Square Ticket and Invisible Cloak Combinations
    	if ( allItemsCount == 3 && chaosCount == 1 )
    	{
    		if ( devilEyeCount == 1 && devilKeyCount == 1 ) //Check for Devil Square Ticket
    		{
    			if (devilsKey_Level == devilsEye_Level)
    			{
    				result = 2;
    				*(int*)0x07CB2744 = devilsKey_Level + 1; //set chaosCombinationType
    			}
    			else
    			{
    				result = -2;
    			}
    			return result;
    		}
    		if ( scrollOfArchangelCount == 1 && bloodBoneCount == 1 ) //Check for Blood Castle Ticket
    		{
    			if (scrollOfArchangel_Level == bloodBone_Level )
    			{
    				result = 8;
    				*(int*)0x07CB2744 = HIWORD(scrollOfArchangel_Level) + 1; //set chaosCombinationType
    			}
    			else
    			{
    				result = -8;
    			}
    			return result;
    		}
    	}
    
    	//First Level Combination
    	if ( FirstLvlWingsCount != 1 || secondLvlWings_count || featherCount != 1 || feather_Level != 1 )
    	{
    		if ( chaosCount == 1 && featherCount == 1 && !HIWORD(feather_Level) && FirstLvlWingsCount == 1 && !secondLvlWings_count && allItemsCount == additionalItems_count + 3 )
    		{
    			*(int*)0x07CB274C = onlyWingsAddPercent / 4000000 + additionalItemAddPercent / 40000; // secondLvlWingsPercent - calculating 2 lvl wings percent for probability
    			if ( (signed int)(onlyWingsAddPercent / 4000000 + additionalItemAddPercent / 40000) >= 90 )
    			{
    				*(int*)0x07CB274C = 90;  // max percent 90%
    			}
    			return 7;
    		}
    	}
    
    	if (allItemsCount == 0 )
    	{
    		return 0;
    	}
    	else if(allItemsCount == 4)
    	{
    		if ( isLvl9 == 1 && blessCount == 1 && soulCount == 1  && chaosCount == 1)
    		{
    			return 3;
    		}
    	}
    	else if ( allItemsCount == 6 )
    	{
    		if ( isLvl10 == 1 && blessCount == 2 && soulCount == 2 && chaosCount == 1) // +11 combination
    		{
    			return 4;
    		}
    	}
    	else if ( allItemsCount == 8 )
    	{
    		if ( isLvl11 == 1 && blessCount == 3 && soulCount == 3 && chaosCount == 1) // +12 combination
    		{
    			return 22;
    		}
    	}
    	else if ( allItemsCount == 10 )
    	{
    		if ( isLvl12 == 1 && blessCount == 4 && soulCount == 4 && chaosCount == 1) // +13 combination
    		{
    			return 23;
    		}
    	}
    	else if ( allItemsCount == 11 )
    	{
    		if ( unrilaCount == 10 && chaosCount == 1 )
    		{
    			return 5;
    		}
    	}
    
    
    	if ( chaosCount == 1 )
    	{
    		if ( v68 > 0 && !devilEyeCount && !devilKeyCount && !unrilaCount && !v78 && !creationCount && !featherCount && !FirstLvlWingsCount && !secondLvlWings_count && !scrollOfArchangelCount && !bloodBoneCount && !guardianCount )
    		{
    			return chaosWeapon_Count <= 0 ? 1 : 11;
    		}
    		else if ( allItemsCount == 2 && creationCount == 1 && chaosCount == 1 ) // Fruits Combination
    		{
    			return 6;
    		}
    	}
    
    	if ( allItemsCount == blessCount ) // Potion of Bless
    	{
    		return 15;
    	}
    	if ( allItemsCount == soulCount ) // Potion of Soul
    	{
    		return 16;
    	}
    
    	if ( allItemsCount != 12 || blessCount != 5 || soulCount != 5 || chaosCount != 1 || guardianCount != 1 )
    	{
    		return  0;
    	}
    	else
    	{
    		return 17;
    	}
    
    }
    
    static DWORD CalcItemAdditionalPercentAdd_Address = 0x0052DDE0;
    
    __declspec(naked) int __stdcall CalcItemAdditionalPercentAdd(int a1, int a2, int a3)
    {
    	__asm{
    		PUSH EBP
    			MOV EBP, ESP
    			PUSH a3
    			PUSH a2
    			PUSH EAX //a1
    			CALL CalcItemAdditionalPercentAdd_Address
    			MOV ESP,EBP;
    		POP EBP;
    		retn 12
    	}
    }
    Links for the Main.exe and the Hex-Rays decompilation of it :

    Main - https://mega.co.nz/#!DU03WJCD!iESI1_...E4Kr1txCPslFeo
    Decompilation - https://mega.co.nz/#!7BMzyTLK!O8OHJ2...h_UjzLhVL8fI7w

    Credits :
    Me ( vankyy26 a.k.a ^TheLast^ )
    WebZen - for main.exe



  2. #2
    LiveGuard Software Ltd Mecanik is offline
    MemberRank
    Jan 2012 Join Date
    404 Not FoundLocation
    343Posts

    re: [Development] MuOnline 99.6XT(1.0M) main.exe Methods Decompilation

    Can you explain us, what did you just do ? Open main.exe in HexRays and press "decompile" ?
    You might better use IDA for this...

    BTW:

    //----- (08CE9729) --------------------------------------------------------
    #error "8CE9742: positive sp value has been found (funcsize=10)"

    #error "There were 133 decompilation failure(s) on 4470 function(s)"

  3. #3
    Evolution Team Th3AnG3L is offline
    MemberRank
    Apr 2014 Join Date
    634Posts

    re: [Development] MuOnline 99.6XT(1.0M) main.exe Methods Decompilation

    IDA Pro is with Hex-Rays plugin added (cracked plugin ofc)
    Ctrl+F5 wont help only

  4. #4
    Enthusiast vankyy26 is offline
    MemberRank
    Mar 2010 Join Date
    48Posts

    re: [Development] MuOnline 99.6XT(1.0M) main.exe Methods Decompilation

    I know that's old thread but I wanna explain what was the idea there. Basically that's the function inside main.exe which decides are the items proper for a Chaos Machine combination. Once the Items are good the client enables the combination button. So basically if this function is remapped you can control the items required for a chaos combination. For example normal Level 1 Wings combination can require JoL, JoB, JoS, JoC and so on in order to become clickable. This won't allow creating totally custom combinations as that requires much more changes in other functions but the requirements for the existing ones can be easily changed. :)



Advertisement