Closed Dentrax closed 5 years ago
Which assembly are you trying to decompile? Do know which compiler was used to create it?
I don't know, but the output of Protection ID tool ;
File Type : 32-Bit Dll (Subsystem : Win CUI / 3), Size : 3386368 (033AC00h) Byte(s) | Machine: 0x14C (I386)
Compilation TimeStamp : 0x57B4A466 -> Wed 17th Aug 2016 17:52:38 (GMT)
[TimeStamp] 0x57B4A466 -> Wed 17th Aug 2016 17:52:38 (GMT) | PE Header | - | Offset: 0x00000088 | VA: 0x00400088 | -
[File Heuristics] -> Flag #1 : 00000000000001001100000000110000 (0x0004C030)
[Entrypoint Section Entropy] : 5.80 (section #0) ".text " | Size : 0x33A3C0 (3384256) byte(s)
[DllCharacteristics] -> Flag : (0x0000) -> NONE
[SectionCount] 3 (0x3) | ImageSize 0x342000 (3416064) byte(s)
[VersionInfo] Product Version : 0.0.0.0
[VersionInfo] File Version : 0.0.0.0
[VersionInfo] Original FileName : Assembly-CSharp.dll
[VersionInfo] Internal Name : Assembly-CSharp.dll
[ModuleReport] [IAT] Modules -> mscoree.dll
[.] .net @ FileOffset 0x13A644 | MetaData->Version 1.1 (struct version) -> v2.0.50727 (net version required)
[.] Flags : 0x0 | Streams : 0x5 (5) -> #~ | #Strings | #US | #Blob | #GUID
[!] [.net scan core] dotNetReactor detected!
[COR20] MajorRuntimeVersion 0x2 (2) | MinorRuntimeVersion 0x2 (2) -> 0x2.2 (2.2)
[COR20] Flags 0x1
[COR20 Flags] [x] IL_ONLY [ ] 32BITREQUIRED [ ] IL_LIBRARY
[COR20 Flags] [ ] STRONGNAME [ ] NATIVE_EP [ ] TRACKDEBUGDATA
[COR20 Flags] [ ] 32BITPREFERRED | 0x0 UNKNOWN
[COR20 Flags] Assembly is NOT strong name signed
[CdKeySerial] found "TestVersion" @ VA: 0x002C5A30 / Offset: 0x002C3C30
[CdKeySerial] found "TestVersion" @ VA: 0x002C5AB9 / Offset: 0x002C3CB9
[CdKeySerial] found "TestVersion" @ VA: 0x002C5ACB / Offset: 0x002C3CCB
[CdKeySerial] found "TestVersion" @ VA: 0x002C5BE2 / Offset: 0x002C3DE2
[CdKeySerial] found "TestVersion" @ VA: 0x002EB387 / Offset: 0x002E9587
- Scan Took : 1.640 Second(s) [000000550h (1360) tick(s)] [246 of 580 scan(s) done]
DIE :
Library : .NET(v2.0.50727)[-]
Linker : Microsoft Linker(6.0)[DLL32,console]
@siegfriedpammer
The compiler is with high confidence mcs, since the code snippet is using the UNITY game engine.
ILSpy have problems with mcs-compiler-generated state-machine classes (read: the compiler generated FSM classes generated for yield return
).
Until this is fixed, I can only suggest trying to decompile with dnSpy
- in my experience it works for this scenario.
It was not in the previous ILSpy version. Possibility to be fix in the next release? @siegfriedpammer
ILSpy 2 and 3 are different beasts. dnSpy is (AFAIK) based on ILSpy 2, so it makes sense they both work.
From my understanding, ILSpy 3 has so far been (user-observable) mostly about getting the decompiler up to speed on new language constructs, on code generated by the Microsoft compilers.
Recognition of a few Mono-isms have been added, but yield-return is not yet one of them. Other problematic areas are array-field-initialization, where it often gets pushed into static constructor, and some foreach
constructs.
Is there a chance that this problem is fixed? Because this problem is everywhere.
I just uploaded a sample of this problem: .cs file: https://pastebin.com/QEyr5Nvh .il file: https://pastebin.com/F5X4XMGX
Thanks... @siegfriedpammer
Mono is not our main priority. We do somewhat support mcs's 'yield return' pattern, but here this seems to be some interaction between yield and lambdas.
It might be really fine to give support for mono/mcs. :)
Our focus currently is on modern language features for modern platforms (think "Roslyn compilers"). We always try to strive for reach, and currently we are missing important language constructs such as tuples. Those definitely have priority over other more "niche" problems - and sorry to say, this is a niche problem.
Having said all that - we do absolutely welcome contributions in such areas.
I was able to partially assemble the IL file. Most of the problems visible in the corresponding C# file have been fixed (probably by the PR mentioned above). However, there's still some strange interaction between lambdas and the yield FSM going on.
For example:
private IEnumerator SignInToGoogleProcess(AsyncOperation op)
{
EventManager.Instance.Send<DisableNewsContentEventArgs>(new DisableNewsContentEventArgs(true));
bool gotInternet = false;
yield return CoroutineHelper.RunCoroutine(SingletonMonoBehaviour<Game>.Instance.IsInternetReachableCoroutineWithRetryPrompt(delegate(bool result)
{
base.<gotInternet>__0 = result;
}));
The DelegateConstruction transform would need some info that the <gotInternet>__0
field access should be transformed to a reference to the local variable introduced by the yield transform.
@siegfriedpammer
I can't figure out why there is an base.<gotInternet>__0
variable instead of gotInternet
. Why is decompiler doing it this way? Is there a conflict situation? Like:
For Conflict-1: base.<gotInternet>__0
For Conflict-2: base.<gotInternet>__1
For Conflict-3: base.<gotInternet>__2
... etc.
There is no conflict. We just have no support for this special case generated by mcs. Normally there is a separate type generated for each lambda. In this case, however, mcs reuses the type generated for the yield state machine to store the captured variables.
Minimal repro:
using System;
using System.Collections;
public class MonoTest
{
public static IEnumerator Issue1026()
{
bool captured = true;
yield return Test(a => captured = a);
if (captured) {
yield return 3;
}
}
public static object Test(Action<bool> test)
{
return null;
}
}
Is decompiled as:
using System;
using System.Collections;
public class MonoTest
{
public static IEnumerator Issue1026()
{
bool captured = true;
yield return Test(delegate(bool a)
{
base.<captured>__0 = a;
});
if (captured)
{
yield return 3;
}
}
public static object Test(Action<bool> test)
{
return null;
}
}
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Sometimes I see it in the iterator functions, not always. Is a decompile error ?