Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ILSpy generated code reference DisplayClass. #3202

Open
CreateAndInject opened this issue Apr 28, 2024 · 1 comment
Open

ILSpy generated code reference DisplayClass. #3202

CreateAndInject opened this issue Apr 28, 2024 · 1 comment
Labels
Bug Decompiler The decompiler engine itself

Comments

@CreateAndInject
Copy link
Contributor

file.zip

Check DefaultCheckCopyed:
image

Another error in Class148.GetItem:
image

@CreateAndInject CreateAndInject added Bug Decompiler The decompiler engine itself labels Apr 28, 2024
@ElektroKill
Copy link
Contributor

Issue in method Class148.DefaultCheckCopyed occurs because when TDCU executes it expects the first instruction of the init block of the display class to be the first assignment to the display class. This is not the case for this file for an unknown to me reason (i suspect its a result of obfuscation or deobfuscation though).

Displayclass init block:

Block IL_0020 (incoming: 1) {
	if (comp.i4(callvirt get_CopyedOption(ldloc option) == ldc.i4 1)) leave IL_0020 (ldc.i8 0)
	stloc has(ldc.i4 0)
	// Diplay class init start
	stobj System.Int64(delayex.ldflda iid(ldloca I_0), ldc.i8 0)
	// display class init end
	stobj System.Collections.Generic.IEnumerable`1[[System.String]](delayex.ldflda hist(ldloca I_0), nullable.rewrap(call Where(call Select(nullable.unwrap.o(await(call GetByOuterId(ldloc user, ldloc siteId, ldloc oid))), ILFunction <DefaultCheckCopyed>b__29_1[System.Func`2[[Class218],[System.String]]] {
		param _class218_0 : Class218(Index=0, LoadCount=1, AddressCount=0, StoreCount=1)

		BlockContainer {
			Block IL_0000 (incoming: 1) {
				leave IL_0000 (callvirt get_rst_link(ldloc _class218_0))
			}

		}
	}
	), ILFunction <DefaultCheckCopyed>b__29_2[System.Func`2[[System.String],[System.Boolean]]] {
		param _string_1 : System.String(Index=0, LoadCount=1, AddressCount=0, StoreCount=1)

		BlockContainer {
			Block IL_0000 (incoming: 1) {
				leave IL_0000 (comp.i4(call IsNullOrWhiteSpace(ldloc _string_1) == ldc.i4 0))
			}

		}
	}
	)))
	if (if (comp.o(ldobj System.Collections.Generic.IEnumerable`1[[System.String]](delayex.ldflda hist(ldloca I_0)) == ldnull)) ldc.i4 1 else comp.i4(call Any(ldobj System.Collections.Generic.IEnumerable`1[[System.String]](delayex.ldflda hist(ldloca I_0))) == ldc.i4 0)) Block IL_01ba {
		stobj System.Collections.Generic.IEnumerable`1[[System.String]](delayex.ldflda hist(ldloca I_0), await(call GetCopyHistory(ldloc user, ldloc siteId, ldloc oid)))
	}
	if (if (comp.o(ldobj System.Collections.Generic.IEnumerable`1[[System.String]](delayex.ldflda hist(ldloca I_0)) == ldnull)) ldc.i4 1 else comp.i4(call Any(ldobj System.Collections.Generic.IEnumerable`1[[System.String]](delayex.ldflda hist(ldloca I_0))) == ldc.i4 0)) leave IL_0020 (ldc.i8 0)
	if (if (comp.i4(callvirt get_UpdateMode(ldloc option) == ldc.i4 0)) comp.i4(callvirt get_CopyedOption(ldloc option) == ldc.i4 0) else ldc.i4 0) Block IL_01ff {
		call smethod_1(ldnull, ldloca I_0)
	}
	using (I_1 = callvirt GetEnumerator(call Take(ldobj System.Collections.Generic.IEnumerable`1[[System.String]](delayex.ldflda hist(ldloca I_0)), ldc.i4 5))) {
		BlockContainer {
			Block IL_0000 (incoming: 1) {
				BlockContainer (while-true) {
					Block IL_0289 (incoming: 2) {
						if (comp.i4(callvirt MoveNext(ldloc I_1) == ldc.i4 0)) leave IL_0289 (nop)
						if (if (call TryParse(callvirt get_Current(ldloc I_1), ldflda iid(ldloca I_0))) comp.i8.signed(ldobj System.Int64(delayex.ldflda iid(ldloca I_0)) > ldc.i8 0) else ldc.i4 0) Block IL_02be {
							stloc has(await(callvirt ExistItem(call get_Class155_0(ldloc this), ldobj System.Int64(delayex.ldflda iid(ldloca I_0)))))
							if (ldloc has) leave IL_0289 (nop)
						}
						br IL_0289
					}

				}
				leave IL_0000 (nop)
			}

		}
	}
	if (comp.i4(ldloc has == ldc.i4 0)) Block IL_0332 {
		if (comp.i4(callvirt get_CopyedOption(ldloc option) == ldc.i4 2)) Block IL_0334 {
			leave IL_0020 (ldc.i8 0)
		}
		if (callvirt get_UpdateMode(ldloc option)) Block IL_0358 {
			call smethod_1(ldstr "您已复制过此商品,但是已删除。若需要重新复制请修改选项", ldloca I_0)
		}
	}
	if (callvirt get_UpdateMode(ldloc option)) leave IL_0020 (ldobj System.Int64(delayex.ldflda iid(ldloca I_0)))
	call smethod_1(ldnull, ldloca I_0)
	leave IL_0020 (ldobj System.Int64(delayex.ldflda iid(ldloca I_0)))
} at IL_0020

I will try and investigate how to better pattern much the display class initializers in such cases.

The second issue with the async decompiler is once again a fail to pattern match due to a rather strange await code pattern. I'm still looking into that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Decompiler The decompiler engine itself
Projects
None yet
Development

No branches or pull requests

2 participants