biahn
9월 25, 2023, 6:50오전
1
제목 그대로, winform에서 엑셀파일을 불러오는 기능을 구현했는데
난독화 전에는 정상적으로 동작하지만, 난독화 후에는 아래와 같은 에러메세지가 발생하면서 불러오는데 실패합니다…
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'ProductRankTracker.Form1’에 'ReleaseObject’에 대한 정의가 없습니다.
위치: CallSite.Target(Closure , CallSite , Form1 , Object )
위치: System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
위치: ProductRankTracker.Form1.f(Object A_0, EventArgs A_1)
ReleaseObject에 대한 정의가 없다고 하는데 왜 난독화를 했을때만 정의가 없다고 하는걸까요…
2개의 좋아요
경태_왕
9월 25, 2023, 8:25오전
2
난독화 툴을 어떤것을 사용하시나요?
툴 마다 특정 클래스나 부분 정도를 난독화 하지 않도록 하는 옵션이 있습니다.
혹은 본인이 난독화가 필요하다고 판단되는 부분을 따로 라이브러리 프로젝트로 빼 내어 그 라이브러리 프로젝트만 난독화 시키는 전략도 유용 할 것 같습니다.
난독화와 함께 빌드를 하던 도중 비인딩을 포인팅하는 String 값역시 같이 난독화 되어, 오작동이 이러난 것이 아닐까하는 조심러운 추측을 해봅니다.
4개의 좋아요
biahn
9월 26, 2023, 1:44오전
3
난독화 툴은 PreEmptive Dotfuscator를 사용했습니다
아래 코드의 함수가 정의되지 않았다고 하는데, 함수의 위치를 바꿔보기도 해도 안되고 디버그모드로 확인도 못하니 이유가 짐작이 안가네요… ㅠㅠ
/// <summary>
/// 액셀 객체 해제 메소드
/// </summary>
/// <param name="obj"></param>
private void ReleaseObject(object obj)
{
try
{
if (obj != null)
{
Marshal.ReleaseComObject(obj); // 액셀 객체 해제
obj = null;
}
}
catch (Exception ex)
{
obj = null;
throw ex;
}
finally
{
GC.Collect(); // 가비지 수집
}
}
1개의 좋아요
biahn
9월 26, 2023, 4:52오전
5
답이 조금 늦었네요… 위와같은 속성을 적용했습니다.
제가 툴 사용에 서툴러서그런데 제외해야할 속성이 있을까요??
1개의 좋아요
이광석
9월 26, 2023, 7:21오전
6
전부 제거해서 빌드 한번 해보시고
이상이 없다면 하나씩 해보시는것도 나쁘지않을 것 같습니다
1개의 좋아요
ReleaseObject
함수를 직접호출하지 않고 dynamic
형식으로 호출하셔서 Expression Tree 형태로 컴파일 된 뒤 난독화 후 해당 메소드를 찾지 못하는 문제 같습니다.
해당 메소드를 Interface로 정의해서 호출해보는 방법도 해결책이 될 것 같습니다.
또는 메소드 정의 위에 [Obfuscation(Feature = "renaming", Exclude = true)]
와 같이 특성을 지정하면 해당 메소드에 대한 Rename 난독화 제외를 지정할 수 있는듯 합니다.
[Obfuscation(Feature = "renaming", Exclude = true)]
private void ReleaseObject(object obj)
{
...
3개의 좋아요
biahn
10월 4, 2023, 1:25오전
8
연휴가 껴있어서 확인이 늦었네요
저도 해당 프로그램을 다시 디컴파일해서 확인해보니까 해당 메소드명이 난독화로 바뀌면서 호출을 못하고
있는 문제를 확인했습니다.
호출은 이렇게 하는데 난독화과정에서 함수명이 바뀌어서 못찾고있더라구요…
Form1.b.d = CallSite<Action<CallSite, Form1, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.InvokeSimpleName | CSharpBinderFlags.ResultDiscarded, "ReleaseObject", (IEnumerable<System.Type>) null, typeof (Form1), (IEnumerable<CSharpArgumentInfo>) new CSharpArgumentInfo[2]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, (string) null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, (string) null)
}));
그래서 알려주신 해결책대로 해결했습니다
답변 감사합니다!
4개의 좋아요