// Serialize 정보
public class UserData
{
public int Gold;
public int Jewel;
public int Level;
}
/*
json 변환 결과
{
"Gold":100,
"Jewel":200,
"Level":1,
}
*/
// 난독화 이후
public class 괌괌괈괋
{
public int 괌괆괎괍;
public int 괃괋괄괆;
public int 괏관괆괉;
}
/*
json 변환 결과
{
"괌괆괎괍":100,
"괃괋괄괆":200,
"괏관괆괉":1,
}
*/
Player
의 OnButton_Fire
, OnAnimation_Dead
메서드가 각각 Button, Animation 의 Event로 등록됐습니다. 만일 메서드 이름이 난독화되어 변경되면 유니티는 해당 메서드를 찾지 못하여 정상적인 실행이 되지 않습니다. 따라서 스크립트 상에서 Event 등록을 진행하거나 난독화에서 제외를 하여야 합니다.public class Player : MonoBehaviour
{
[Token(Token = "0x6000013")]
[Address(Offset = "0x2558C0", RVA = "0x2558C0", VA = "0x2558C0")]
public Player() {}
[Token(Token = "0x6000019")]
[Address(Offset = "0x2558DC", RVA = "0x2558DC", VA = "0x2558DC")]
public void OnButton_Fire() {} //<---------- 난독화 제외
[Token(Token = "0x6000017")]
[Address(Offset = "0x2558D4", RVA = "0x2558D4", VA = "0x2558D4")]
public void OnAnimation_Dead() {} //<---------- 난독화 제외
[Token(Token = "0x6000012")]
[Address(Offset = "0x2558BC", RVA = "0x2558BC", VA = "0x2558BC")]
public void 괇괄괋괂괏괃괇괇괃괈관() {}
[Token(Token = "0x6000014")]
[Address(Offset = "0x2558C8", RVA = "0x2558C8", VA = "0x2558C8")]
public void 괃괋괋괂괁괁괅괎괆괏괏() {}
[Token(Token = "0x6000015")]
[Address(Offset = "0x2558CC", RVA = "0x2558CC", VA = "0x2558CC")]
public void 괇괈괍괊괇괉괍괊괃괍관() {}
}
Foo.Bar
메서드를 사용할 경우, Bar
메서드의 난독화를 제외해야 합니다. GetMethod("BAR")
에서 string타입의 Bar
를 전달하여 메서드를 얻어오게 되는데, 이러한 경우 Bar
메서드 이름이 난독화되면 정상 작동하지 않을 수 있습니다. public static class Foo
{
// Reflection 사용을 위한 제외 필요함
public static void Bar()
{
Debug.Log("Bar");
}
}
public class ReflectionTest
{
public void Test()
{
Type type = typeof(Foo);
MethodInfo method = type.GetMethod("Bar");
method.Invoke(null, null);
}
}
[Address(Offset = "0x2558C8", RVA = "0x2558C8", VA = "0x2558C8")]
public void 괃괋괋괂괁괁괅괎괆괏괏() {}
[Token(Token = "0x6000015")]
[Address(Offset = "0x2558CC", RVA = "0x2558CC", VA = "0x2558CC")]
public void 괇괈괍괊괇괉괍괊괃괍관() {}
}
RuntimeInitializeOnLoadMethod
RuntimeInitializeOnLoadMethod
를 사용한 경우 해당 클래스, 메서드를 난독화에서 제외하여야 앱 실행 시 정상적인 호출이 가능합니다. 앱 시작 시 초기화 작업, 기타 등등의 이유로 메서드 호출이 필요한 경우RuntimeInitializeOnLoadMethod
어트리뷰트를 사용하게 됩니다. 이때 유니티는 메서드 이름을 기준으로 이를 감지하기 때문에 RuntimeInitializeOnLoadMethod
를 사용한 경우에는 해당 메서드와 클래스 이름이 난독화에서 제외돼야 합니다.// 난독화 전
public static class SecretManager
{
[RuntimeInitializeOnLoadMethod]
private static void Init()
{
// 중요 정보 초기화
}
private static void Method1()
{
}
}
RuntimeInitializeOnLoad.json
파일에 아래의 정보를 확인할 수 있습니다.RuntimeInitializeOnLoadMethod
어트리뷰트가 붙은 메서드를 파일에 저장하고, 실행 시 클래스, 메서드 이름을 기반으로 앱 실행시 호출하게 됩니다. 이때 난독화로 SecretManager.Init
의 이름이 바뀌면 유니티는 해당 클래스, 메서드를 찾지 못하여 호출이 불가능합니다. // 난독화 후
[Token(Token = "0x2000008")]
public static class SecretManager // <----- 난독화 제외
{
[Token(Token = "0x6000023")]
[Address(Offset = "0x255990", RVA = "0x255990", VA = "0x255990")]
[RuntimeInitializeOnLoadMethod]
private static void Init() // <----- 난독화 제외
{
}
[Token(Token = "0x6000024")]
[Address(Offset = "0x255994", RVA = "0x255994", VA = "0x255994")]
private static void 괍괅괌괏괁괋괃괏괁괄괁()
{
}
}
TextGold
는 MonoBehaviour
로부터 상속받아 구현하였습니다.// 난독화 전
public static class GoldManager
{
// 보유 골드
public static int Gold = 100;
}
//----------------------------------------------
// 난독화 전
// 골드를 Text에 표시
public class TextGold : MonoBehaviour
{
public Text _text;
private void Start()
{
// GoldManager에서 골드 가져와 Text에 표시
_text.text = GoldManager.Gold.ToString();
}
public void Method1() {}
}
// 난독화 후
public class TextGold : MonoBehaviour
{
public Text _text;
private void Start()
{
// BJJDFMFNAKN.BOGOAOLFNBE Gold에 관련된것 유추가능
this._text.text = BJJDFMFNAKN.BOGOAOLFNBE().ToString();
}
private void OGFAAFKDIKA()
{
}
}
TextGold
를 난독화에서 제외한 후 빌드를 하여야 하는데, 빌드 결과물을 디컴파일러로 복원하면 이러한 클래스의 이름이 그대로 드러나게 됩니다. 따라서 난독화된 BJJDFMFNAKN
클래스가 Gold
에 관련된 것이라고 유추할 수 있습니다.TextGold
의 이름을 변경하거나 GoldManager
를 직접 액세스 하기보다는 메시지, 이벤트 기반의 로직으로 변경하는 것을 권장합니다.