PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/de4dot.code/renamer/Renamer.cs

https://bitbucket.org/SquallATF/de4dot
C# | 1790 lines | 1563 code | 204 blank | 23 comment | 481 complexity | 46ec6177c7765c4f21bcc982cf48f3b1 MD5 | raw file
Possible License(s): GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. Copyright (C) 2011-2013 de4dot@gmail.com
  3. This file is part of de4dot.
  4. de4dot is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. de4dot is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with de4dot. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Text.RegularExpressions;
  18. using dnlib.DotNet;
  19. using dnlib.DotNet.Emit;
  20. using de4dot.code.renamer.asmmodules;
  21. using de4dot.code.resources;
  22. using de4dot.blocks;
  23. namespace de4dot.code.renamer {
  24. [Flags]
  25. public enum RenamerFlags {
  26. RenameNamespaces = 1,
  27. RenameTypes = 2,
  28. RenameProperties = 4,
  29. RenameEvents = 8,
  30. RenameFields = 0x10,
  31. RenameMethods = 0x20,
  32. RenameMethodArgs = 0x40,
  33. RenameGenericParams = 0x80,
  34. RestoreProperties = 0x100,
  35. RestorePropertiesFromNames = 0x200,
  36. RestoreEvents = 0x400,
  37. RestoreEventsFromNames = 0x800,
  38. DontCreateNewParamDefs = 0x1000,
  39. DontRenameDelegateFields = 0x2000,
  40. }
  41. public class Renamer {
  42. public RenamerFlags RenamerFlags { get; set; }
  43. public bool RenameNamespaces {
  44. get { return (RenamerFlags & RenamerFlags.RenameNamespaces) != 0; }
  45. set {
  46. if (value)
  47. RenamerFlags |= RenamerFlags.RenameNamespaces;
  48. else
  49. RenamerFlags &= ~RenamerFlags.RenameNamespaces;
  50. }
  51. }
  52. public bool RenameTypes {
  53. get { return (RenamerFlags & RenamerFlags.RenameTypes) != 0; }
  54. set {
  55. if (value)
  56. RenamerFlags |= RenamerFlags.RenameTypes;
  57. else
  58. RenamerFlags &= ~RenamerFlags.RenameTypes;
  59. }
  60. }
  61. public bool RenameProperties {
  62. get { return (RenamerFlags & RenamerFlags.RenameProperties) != 0; }
  63. set {
  64. if (value)
  65. RenamerFlags |= RenamerFlags.RenameProperties;
  66. else
  67. RenamerFlags &= ~RenamerFlags.RenameProperties;
  68. }
  69. }
  70. public bool RenameEvents {
  71. get { return (RenamerFlags & RenamerFlags.RenameEvents) != 0; }
  72. set {
  73. if (value)
  74. RenamerFlags |= RenamerFlags.RenameEvents;
  75. else
  76. RenamerFlags &= ~RenamerFlags.RenameEvents;
  77. }
  78. }
  79. public bool RenameFields {
  80. get { return (RenamerFlags & RenamerFlags.RenameFields) != 0; }
  81. set {
  82. if (value)
  83. RenamerFlags |= RenamerFlags.RenameFields;
  84. else
  85. RenamerFlags &= ~RenamerFlags.RenameFields;
  86. }
  87. }
  88. public bool RenameMethods {
  89. get { return (RenamerFlags & RenamerFlags.RenameMethods) != 0; }
  90. set {
  91. if (value)
  92. RenamerFlags |= RenamerFlags.RenameMethods;
  93. else
  94. RenamerFlags &= ~RenamerFlags.RenameMethods;
  95. }
  96. }
  97. public bool RenameMethodArgs {
  98. get { return (RenamerFlags & RenamerFlags.RenameMethodArgs) != 0; }
  99. set {
  100. if (value)
  101. RenamerFlags |= RenamerFlags.RenameMethodArgs;
  102. else
  103. RenamerFlags &= ~RenamerFlags.RenameMethodArgs;
  104. }
  105. }
  106. public bool RenameGenericParams {
  107. get { return (RenamerFlags & RenamerFlags.RenameGenericParams) != 0; }
  108. set {
  109. if (value)
  110. RenamerFlags |= RenamerFlags.RenameGenericParams;
  111. else
  112. RenamerFlags &= ~RenamerFlags.RenameGenericParams;
  113. }
  114. }
  115. public bool RestoreProperties {
  116. get { return (RenamerFlags & RenamerFlags.RestoreProperties) != 0; }
  117. set {
  118. if (value)
  119. RenamerFlags |= RenamerFlags.RestoreProperties;
  120. else
  121. RenamerFlags &= ~RenamerFlags.RestoreProperties;
  122. }
  123. }
  124. public bool RestorePropertiesFromNames {
  125. get { return (RenamerFlags & RenamerFlags.RestorePropertiesFromNames) != 0; }
  126. set {
  127. if (value)
  128. RenamerFlags |= RenamerFlags.RestorePropertiesFromNames;
  129. else
  130. RenamerFlags &= ~RenamerFlags.RestorePropertiesFromNames;
  131. }
  132. }
  133. public bool RestoreEvents {
  134. get { return (RenamerFlags & RenamerFlags.RestoreEvents) != 0; }
  135. set {
  136. if (value)
  137. RenamerFlags |= RenamerFlags.RestoreEvents;
  138. else
  139. RenamerFlags &= ~RenamerFlags.RestoreEvents;
  140. }
  141. }
  142. public bool RestoreEventsFromNames {
  143. get { return (RenamerFlags & RenamerFlags.RestoreEventsFromNames) != 0; }
  144. set {
  145. if (value)
  146. RenamerFlags |= RenamerFlags.RestoreEventsFromNames;
  147. else
  148. RenamerFlags &= ~RenamerFlags.RestoreEventsFromNames;
  149. }
  150. }
  151. public bool DontCreateNewParamDefs {
  152. get { return (RenamerFlags & RenamerFlags.DontCreateNewParamDefs) != 0; }
  153. set {
  154. if (value)
  155. RenamerFlags |= RenamerFlags.DontCreateNewParamDefs;
  156. else
  157. RenamerFlags &= ~RenamerFlags.DontCreateNewParamDefs;
  158. }
  159. }
  160. public bool DontRenameDelegateFields {
  161. get { return (RenamerFlags & RenamerFlags.DontRenameDelegateFields) != 0; }
  162. set {
  163. if (value)
  164. RenamerFlags |= RenamerFlags.DontRenameDelegateFields;
  165. else
  166. RenamerFlags &= ~RenamerFlags.DontRenameDelegateFields;
  167. }
  168. }
  169. Modules modules;
  170. MemberInfos memberInfos = new MemberInfos();
  171. DerivedFrom isDelegateClass;
  172. MergeStateHelper mergeStateHelper;
  173. bool isVerbose;
  174. static string[] delegateClasses = new string[] {
  175. "System.Delegate",
  176. "System.MulticastDelegate",
  177. };
  178. public Renamer(IDeobfuscatorContext deobfuscatorContext, IEnumerable<IObfuscatedFile> files, RenamerFlags flags) {
  179. RenamerFlags = flags;
  180. WarnIfXaml(files);
  181. modules = new Modules(deobfuscatorContext);
  182. isDelegateClass = new DerivedFrom(delegateClasses);
  183. mergeStateHelper = new MergeStateHelper(memberInfos);
  184. foreach (var file in files)
  185. modules.Add(new Module(file));
  186. }
  187. static void WarnIfXaml(IEnumerable<IObfuscatedFile> files) {
  188. foreach (var file in files) {
  189. foreach (var tmp in file.ModuleDefMD.Resources) {
  190. var rsrc = tmp as EmbeddedResource;
  191. if (rsrc == null)
  192. continue;
  193. if (UTF8String.IsNullOrEmpty(rsrc.Name))
  194. continue;
  195. if (!rsrc.Name.String.EndsWith(".g.resources"))
  196. continue;
  197. if (!HasXamlFiles(file.ModuleDefMD, rsrc))
  198. continue;
  199. Logger.w("File '{0}' contains XAML which isn't supported. Use --dont-rename.", file.Filename);
  200. return;
  201. }
  202. }
  203. }
  204. static bool HasXamlFiles(ModuleDef module, EmbeddedResource rsrc) {
  205. try {
  206. rsrc.Data.Position = 0;
  207. var rsrcSet = ResourceReader.Read(module, rsrc.Data);
  208. foreach (var elem in rsrcSet.ResourceElements) {
  209. if (elem.Name.EndsWith(".baml"))
  210. return true;
  211. }
  212. }
  213. catch {
  214. }
  215. return false;
  216. }
  217. public void Rename() {
  218. if (modules.Empty)
  219. return;
  220. isVerbose = !Logger.Instance.IgnoresEvent(LoggerEvent.Verbose);
  221. Logger.n("Renaming all obfuscated symbols");
  222. modules.Initialize();
  223. RenameResourceKeys();
  224. var groups = modules.InitializeVirtualMembers();
  225. memberInfos.Initialize(modules);
  226. RenameTypeDefs();
  227. RenameTypeRefs();
  228. modules.OnTypesRenamed();
  229. RestorePropertiesAndEvents(groups);
  230. PrepareRenameMemberDefs(groups);
  231. RenameMemberDefs();
  232. RenameMemberRefs();
  233. RemoveUselessOverrides(groups);
  234. RenameResources();
  235. modules.CleanUp();
  236. }
  237. void RenameResourceKeys() {
  238. foreach (var module in modules.TheModules) {
  239. if (!module.ObfuscatedFile.RenameResourceKeys)
  240. continue;
  241. new ResourceKeysRenamer(module.ModuleDefMD, module.ObfuscatedFile.NameChecker).Rename();
  242. }
  243. }
  244. void RemoveUselessOverrides(MethodNameGroups groups) {
  245. foreach (var group in groups.GetAllGroups()) {
  246. foreach (var method in group.Methods) {
  247. if (!method.Owner.HasModule)
  248. continue;
  249. if (!method.IsPublic())
  250. continue;
  251. var overrides = method.MethodDef.Overrides;
  252. for (int i = 0; i < overrides.Count; i++) {
  253. var overrideMethod = overrides[i].MethodDeclaration;
  254. if (method.MethodDef.Name != overrideMethod.Name)
  255. continue;
  256. if (isVerbose)
  257. Logger.v("Removed useless override from method {0} ({1:X8}), override: {2:X8}",
  258. Utils.RemoveNewlines(method.MethodDef),
  259. method.MethodDef.MDToken.ToInt32(),
  260. overrideMethod.MDToken.ToInt32());
  261. overrides.RemoveAt(i);
  262. i--;
  263. }
  264. }
  265. }
  266. }
  267. void RenameTypeDefs() {
  268. if (isVerbose)
  269. Logger.v("Renaming obfuscated type definitions");
  270. foreach (var module in modules.TheModules) {
  271. if (module.ObfuscatedFile.RemoveNamespaceWithOneType)
  272. RemoveOneClassNamespaces(module);
  273. }
  274. var state = new TypeRenamerState();
  275. foreach (var type in modules.AllTypes)
  276. state.AddTypeName(memberInfos.Type(type).oldName);
  277. PrepareRenameTypes(modules.BaseTypes, state);
  278. FixClsTypeNames();
  279. RenameTypeDefs(modules.NonNestedTypes);
  280. }
  281. void RemoveOneClassNamespaces(Module module) {
  282. var nsToTypes = new Dictionary<string, List<MTypeDef>>(StringComparer.Ordinal);
  283. foreach (var typeDef in module.GetAllTypes()) {
  284. List<MTypeDef> list;
  285. var ns = typeDef.TypeDef.Namespace.String;
  286. if (string.IsNullOrEmpty(ns))
  287. continue;
  288. if (module.ObfuscatedFile.NameChecker.IsValidNamespaceName(ns))
  289. continue;
  290. if (!nsToTypes.TryGetValue(ns, out list))
  291. nsToTypes[ns] = list = new List<MTypeDef>();
  292. list.Add(typeDef);
  293. }
  294. var sortedNamespaces = new List<List<MTypeDef>>(nsToTypes.Values);
  295. sortedNamespaces.Sort((a, b) => {
  296. return UTF8String.CompareTo(a[0].TypeDef.Namespace, b[0].TypeDef.Namespace);
  297. });
  298. foreach (var list in sortedNamespaces) {
  299. const int maxClasses = 1;
  300. if (list.Count != maxClasses)
  301. continue;
  302. if (isVerbose)
  303. Logger.v("Removing namespace: {0}", Utils.RemoveNewlines(list[0].TypeDef.Namespace));
  304. foreach (var type in list)
  305. memberInfos.Type(type).newNamespace = "";
  306. }
  307. }
  308. void RenameTypeDefs(IEnumerable<MTypeDef> typeDefs) {
  309. Logger.Instance.Indent();
  310. foreach (var typeDef in typeDefs) {
  311. Rename(typeDef);
  312. RenameTypeDefs(typeDef.NestedTypes);
  313. }
  314. Logger.Instance.DeIndent();
  315. }
  316. void Rename(MTypeDef type) {
  317. var typeDef = type.TypeDef;
  318. var info = memberInfos.Type(type);
  319. if (isVerbose)
  320. Logger.v("Type: {0} ({1:X8})", Utils.RemoveNewlines(typeDef.FullName), typeDef.MDToken.ToUInt32());
  321. Logger.Instance.Indent();
  322. renameGenericParams2(type.GenericParams);
  323. if (RenameTypes && info.GotNewName()) {
  324. var old = typeDef.Name;
  325. typeDef.Name = info.newName;
  326. if (isVerbose)
  327. Logger.v("Name: {0} => {1}", Utils.RemoveNewlines(old), Utils.RemoveNewlines(typeDef.Name));
  328. }
  329. if (RenameNamespaces && info.newNamespace != null) {
  330. var old = typeDef.Namespace;
  331. typeDef.Namespace = info.newNamespace;
  332. if (isVerbose)
  333. Logger.v("Namespace: {0} => {1}", Utils.RemoveNewlines(old), Utils.RemoveNewlines(typeDef.Namespace));
  334. }
  335. Logger.Instance.DeIndent();
  336. }
  337. void renameGenericParams2(IEnumerable<MGenericParamDef> genericParams) {
  338. if (!RenameGenericParams)
  339. return;
  340. foreach (var param in genericParams) {
  341. var info = memberInfos.GenericParam(param);
  342. if (!info.GotNewName())
  343. continue;
  344. param.GenericParam.Name = info.newName;
  345. if (isVerbose)
  346. Logger.v("GenParam: {0} => {1}", Utils.RemoveNewlines(info.oldFullName), Utils.RemoveNewlines(param.GenericParam.FullName));
  347. }
  348. }
  349. void RenameMemberDefs() {
  350. if (isVerbose)
  351. Logger.v("Renaming member definitions #2");
  352. var allTypes = new List<MTypeDef>(modules.AllTypes);
  353. allTypes.Sort((a, b) => a.Index.CompareTo(b.Index));
  354. Logger.Instance.Indent();
  355. foreach (var typeDef in allTypes)
  356. RenameMembers(typeDef);
  357. Logger.Instance.DeIndent();
  358. }
  359. void RenameMembers(MTypeDef type) {
  360. var info = memberInfos.Type(type);
  361. if (isVerbose)
  362. Logger.v("Type: {0}", Utils.RemoveNewlines(info.type.TypeDef.FullName));
  363. Logger.Instance.Indent();
  364. RenameFields2(info);
  365. RenameProperties2(info);
  366. RenameEvents2(info);
  367. RenameMethods2(info);
  368. Logger.Instance.DeIndent();
  369. }
  370. void RenameFields2(TypeInfo info) {
  371. if (!RenameFields)
  372. return;
  373. bool isDelegateType = isDelegateClass.Check(info.type);
  374. foreach (var fieldDef in info.type.AllFieldsSorted) {
  375. var fieldInfo = memberInfos.Field(fieldDef);
  376. if (!fieldInfo.GotNewName())
  377. continue;
  378. if (isDelegateType && DontRenameDelegateFields)
  379. continue;
  380. fieldDef.FieldDef.Name = fieldInfo.newName;
  381. if (isVerbose)
  382. Logger.v("Field: {0} ({1:X8}) => {2}",
  383. Utils.RemoveNewlines(fieldInfo.oldFullName),
  384. fieldDef.FieldDef.MDToken.ToUInt32(),
  385. Utils.RemoveNewlines(fieldDef.FieldDef.FullName));
  386. }
  387. }
  388. void RenameProperties2(TypeInfo info) {
  389. if (!RenameProperties)
  390. return;
  391. foreach (var propDef in info.type.AllPropertiesSorted) {
  392. var propInfo = memberInfos.Property(propDef);
  393. if (!propInfo.GotNewName())
  394. continue;
  395. propDef.PropertyDef.Name = propInfo.newName;
  396. if (isVerbose)
  397. Logger.v("Property: {0} ({1:X8}) => {2}",
  398. Utils.RemoveNewlines(propInfo.oldFullName),
  399. propDef.PropertyDef.MDToken.ToUInt32(),
  400. Utils.RemoveNewlines(propDef.PropertyDef.FullName));
  401. }
  402. }
  403. void RenameEvents2(TypeInfo info) {
  404. if (!RenameEvents)
  405. return;
  406. foreach (var eventDef in info.type.AllEventsSorted) {
  407. var eventInfo = memberInfos.Event(eventDef);
  408. if (!eventInfo.GotNewName())
  409. continue;
  410. eventDef.EventDef.Name = eventInfo.newName;
  411. if (isVerbose)
  412. Logger.v("Event: {0} ({1:X8}) => {2}",
  413. Utils.RemoveNewlines(eventInfo.oldFullName),
  414. eventDef.EventDef.MDToken.ToUInt32(),
  415. Utils.RemoveNewlines(eventDef.EventDef.FullName));
  416. }
  417. }
  418. void RenameMethods2(TypeInfo info) {
  419. if (!RenameMethods && !RenameMethodArgs && !RenameGenericParams)
  420. return;
  421. foreach (var methodDef in info.type.AllMethodsSorted) {
  422. var methodInfo = memberInfos.Method(methodDef);
  423. if (isVerbose)
  424. Logger.v("Method {0} ({1:X8})", Utils.RemoveNewlines(methodInfo.oldFullName), methodDef.MethodDef.MDToken.ToUInt32());
  425. Logger.Instance.Indent();
  426. renameGenericParams2(methodDef.GenericParams);
  427. if (RenameMethods && methodInfo.GotNewName()) {
  428. methodDef.MethodDef.Name = methodInfo.newName;
  429. if (isVerbose)
  430. Logger.v("Name: {0} => {1}", Utils.RemoveNewlines(methodInfo.oldFullName), Utils.RemoveNewlines(methodDef.MethodDef.FullName));
  431. }
  432. if (RenameMethodArgs) {
  433. foreach (var param in methodDef.AllParamDefs) {
  434. var paramInfo = memberInfos.Param(param);
  435. if (!paramInfo.GotNewName())
  436. continue;
  437. if (!param.ParameterDef.HasParamDef) {
  438. if (DontCreateNewParamDefs)
  439. continue;
  440. param.ParameterDef.CreateParamDef();
  441. }
  442. param.ParameterDef.Name = paramInfo.newName;
  443. if (isVerbose) {
  444. if (param.IsReturnParameter)
  445. Logger.v("RetParam: {0} => {1}", Utils.RemoveNewlines(paramInfo.oldName), Utils.RemoveNewlines(paramInfo.newName));
  446. else
  447. Logger.v("Param ({0}/{1}): {2} => {3}", param.ParameterDef.MethodSigIndex + 1, methodDef.MethodDef.MethodSig.GetParamCount(), Utils.RemoveNewlines(paramInfo.oldName), Utils.RemoveNewlines(paramInfo.newName));
  448. }
  449. }
  450. }
  451. Logger.Instance.DeIndent();
  452. }
  453. }
  454. void RenameMemberRefs() {
  455. if (isVerbose)
  456. Logger.v("Renaming references to other definitions");
  457. foreach (var module in modules.TheModules) {
  458. if (modules.TheModules.Count > 1 && isVerbose)
  459. Logger.v("Renaming references to other definitions ({0})", module.Filename);
  460. Logger.Instance.Indent();
  461. foreach (var refToDef in module.MethodRefsToRename)
  462. refToDef.reference.Name = refToDef.definition.Name;
  463. foreach (var refToDef in module.FieldRefsToRename)
  464. refToDef.reference.Name = refToDef.definition.Name;
  465. foreach (var info in module.CustomAttributeFieldRefs)
  466. info.cattr.NamedArguments[info.index].Name = info.reference.Name;
  467. foreach (var info in module.CustomAttributePropertyRefs)
  468. info.cattr.NamedArguments[info.index].Name = info.reference.Name;
  469. Logger.Instance.DeIndent();
  470. }
  471. }
  472. void RenameResources() {
  473. if (isVerbose)
  474. Logger.v("Renaming resources");
  475. foreach (var module in modules.TheModules) {
  476. if (modules.TheModules.Count > 1 && isVerbose)
  477. Logger.v("Renaming resources ({0})", module.Filename);
  478. Logger.Instance.Indent();
  479. RenameResources(module);
  480. Logger.Instance.DeIndent();
  481. }
  482. }
  483. void RenameResources(Module module) {
  484. var renamedTypes = new List<TypeInfo>();
  485. foreach (var type in module.GetAllTypes()) {
  486. var info = memberInfos.Type(type);
  487. if (info.oldFullName != info.type.TypeDef.FullName)
  488. renamedTypes.Add(info);
  489. }
  490. if (renamedTypes.Count == 0)
  491. return;
  492. new ResourceRenamer(module).Rename(renamedTypes);
  493. }
  494. // Make sure the renamed types are using valid CLS names. That means renaming all
  495. // generic types from eg. Class1 to Class1`2. If we don't do this, some decompilers
  496. // (eg. ILSpy v1.0) won't produce correct output.
  497. void FixClsTypeNames() {
  498. foreach (var type in modules.NonNestedTypes)
  499. FixClsTypeNames(null, type);
  500. }
  501. void FixClsTypeNames(MTypeDef nesting, MTypeDef nested) {
  502. int nestingCount = nesting == null ? 0 : nesting.GenericParams.Count;
  503. int arity = nested.GenericParams.Count - nestingCount;
  504. var nestedInfo = memberInfos.Type(nested);
  505. if (nestedInfo.renamed && arity > 0)
  506. nestedInfo.newName += "`" + arity;
  507. foreach (var nestedType in nested.NestedTypes)
  508. FixClsTypeNames(nested, nestedType);
  509. }
  510. void PrepareRenameTypes(IEnumerable<MTypeDef> types, TypeRenamerState state) {
  511. foreach (var typeDef in types) {
  512. memberInfos.Type(typeDef).PrepareRenameTypes(state);
  513. PrepareRenameTypes(typeDef.derivedTypes, state);
  514. }
  515. }
  516. void RenameTypeRefs() {
  517. if (isVerbose)
  518. Logger.v("Renaming references to type definitions");
  519. var theModules = modules.TheModules;
  520. foreach (var module in theModules) {
  521. if (theModules.Count > 1 && isVerbose)
  522. Logger.v("Renaming references to type definitions ({0})", module.Filename);
  523. Logger.Instance.Indent();
  524. foreach (var refToDef in module.TypeRefsToRename) {
  525. refToDef.reference.Name = refToDef.definition.Name;
  526. refToDef.reference.Namespace = refToDef.definition.Namespace;
  527. }
  528. Logger.Instance.DeIndent();
  529. }
  530. }
  531. void RestorePropertiesAndEvents(MethodNameGroups groups) {
  532. var allGroups = groups.GetAllGroups();
  533. RestoreVirtualProperties(allGroups);
  534. RestorePropertiesFromNames2(allGroups);
  535. ResetVirtualPropertyNames(allGroups);
  536. RestoreVirtualEvents(allGroups);
  537. RestoreEventsFromNames2(allGroups);
  538. ResetVirtualEventNames(allGroups);
  539. }
  540. void ResetVirtualPropertyNames(IEnumerable<MethodNameGroup> allGroups) {
  541. if (!this.RenameProperties)
  542. return;
  543. foreach (var group in allGroups) {
  544. MPropertyDef prop = null;
  545. foreach (var method in group.Methods) {
  546. if (method.Property == null)
  547. continue;
  548. if (method.Owner.HasModule)
  549. continue;
  550. prop = method.Property;
  551. break;
  552. }
  553. if (prop == null)
  554. continue;
  555. foreach (var method in group.Methods) {
  556. if (!method.Owner.HasModule)
  557. continue;
  558. if (method.Property == null)
  559. continue;
  560. memberInfos.Property(method.Property).Rename(prop.PropertyDef.Name.String);
  561. }
  562. }
  563. }
  564. void ResetVirtualEventNames(IEnumerable<MethodNameGroup> allGroups) {
  565. if (!this.RenameEvents)
  566. return;
  567. foreach (var group in allGroups) {
  568. MEventDef evt = null;
  569. foreach (var method in group.Methods) {
  570. if (method.Event == null)
  571. continue;
  572. if (method.Owner.HasModule)
  573. continue;
  574. evt = method.Event;
  575. break;
  576. }
  577. if (evt == null)
  578. continue;
  579. foreach (var method in group.Methods) {
  580. if (!method.Owner.HasModule)
  581. continue;
  582. if (method.Event == null)
  583. continue;
  584. memberInfos.Event(method.Event).Rename(evt.EventDef.Name.String);
  585. }
  586. }
  587. }
  588. void RestoreVirtualProperties(IEnumerable<MethodNameGroup> allGroups) {
  589. if (!RestoreProperties)
  590. return;
  591. foreach (var group in allGroups) {
  592. RestoreVirtualProperties(group);
  593. RestoreExplicitVirtualProperties(group);
  594. }
  595. }
  596. void RestoreExplicitVirtualProperties(MethodNameGroup group) {
  597. if (group.Methods.Count != 1)
  598. return;
  599. var propMethod = group.Methods[0];
  600. if (propMethod.Property != null)
  601. return;
  602. if (propMethod.MethodDef.Overrides.Count == 0)
  603. return;
  604. var theProperty = GetOverriddenProperty(propMethod);
  605. if (theProperty == null)
  606. return;
  607. CreateProperty(theProperty, propMethod, GetOverridePrefix(group, propMethod));
  608. }
  609. void RestoreVirtualProperties(MethodNameGroup group) {
  610. if (group.Methods.Count <= 1 || !group.HasProperty())
  611. return;
  612. MPropertyDef prop = null;
  613. List<MMethodDef> missingProps = null;
  614. foreach (var method in group.Methods) {
  615. if (method.Property == null) {
  616. if (missingProps == null)
  617. missingProps = new List<MMethodDef>();
  618. missingProps.Add(method);
  619. }
  620. else if (prop == null || !method.Owner.HasModule)
  621. prop = method.Property;
  622. }
  623. if (prop == null)
  624. return; // Should never happen
  625. if (missingProps == null)
  626. return;
  627. foreach (var method in missingProps)
  628. CreateProperty(prop, method, "");
  629. }
  630. void CreateProperty(MPropertyDef propDef, MMethodDef methodDef, string overridePrefix) {
  631. if (!methodDef.Owner.HasModule)
  632. return;
  633. var newPropertyName = overridePrefix + propDef.PropertyDef.Name;
  634. if (!DotNetUtils.HasReturnValue(methodDef.MethodDef))
  635. CreatePropertySetter(newPropertyName, methodDef);
  636. else
  637. CreatePropertyGetter(newPropertyName, methodDef);
  638. }
  639. void RestorePropertiesFromNames2(IEnumerable<MethodNameGroup> allGroups) {
  640. if (!RestorePropertiesFromNames)
  641. return;
  642. foreach (var group in allGroups) {
  643. var groupMethod = group.Methods[0];
  644. var methodName = groupMethod.MethodDef.Name.String;
  645. bool onlyRenamableMethods = !group.HasNonRenamableMethod();
  646. if (Utils.StartsWith(methodName, "get_", StringComparison.Ordinal)) {
  647. var propName = methodName.Substring(4);
  648. foreach (var method in group.Methods) {
  649. if (onlyRenamableMethods && !memberInfos.Type(method.Owner).NameChecker.IsValidPropertyName(propName))
  650. continue;
  651. CreatePropertyGetter(propName, method);
  652. }
  653. }
  654. else if (Utils.StartsWith(methodName, "set_", StringComparison.Ordinal)) {
  655. var propName = methodName.Substring(4);
  656. foreach (var method in group.Methods) {
  657. if (onlyRenamableMethods && !memberInfos.Type(method.Owner).NameChecker.IsValidPropertyName(propName))
  658. continue;
  659. CreatePropertySetter(propName, method);
  660. }
  661. }
  662. }
  663. foreach (var type in modules.AllTypes) {
  664. foreach (var method in type.AllMethodsSorted) {
  665. if (method.IsVirtual())
  666. continue; // Virtual methods are in allGroups, so already fixed above
  667. if (method.Property != null)
  668. continue;
  669. var methodName = method.MethodDef.Name.String;
  670. if (Utils.StartsWith(methodName, "get_", StringComparison.Ordinal))
  671. CreatePropertyGetter(methodName.Substring(4), method);
  672. else if (Utils.StartsWith(methodName, "set_", StringComparison.Ordinal))
  673. CreatePropertySetter(methodName.Substring(4), method);
  674. }
  675. }
  676. }
  677. MPropertyDef CreatePropertyGetter(string name, MMethodDef propMethod) {
  678. if (string.IsNullOrEmpty(name))
  679. return null;
  680. var ownerType = propMethod.Owner;
  681. if (!ownerType.HasModule)
  682. return null;
  683. if (propMethod.Property != null)
  684. return null;
  685. var sig = propMethod.MethodDef.MethodSig;
  686. if (sig == null)
  687. return null;
  688. var propType = sig.RetType;
  689. var propDef = CreateProperty(ownerType, name, propType, propMethod.MethodDef, null);
  690. if (propDef == null)
  691. return null;
  692. if (propDef.GetMethod != null)
  693. return null;
  694. if (isVerbose)
  695. Logger.v("Restoring property getter {0} ({1:X8}), Property: {2} ({3:X8})",
  696. Utils.RemoveNewlines(propMethod),
  697. propMethod.MethodDef.MDToken.ToInt32(),
  698. Utils.RemoveNewlines(propDef.PropertyDef),
  699. propDef.PropertyDef.MDToken.ToInt32());
  700. propDef.PropertyDef.GetMethod = propMethod.MethodDef;
  701. propDef.GetMethod = propMethod;
  702. propMethod.Property = propDef;
  703. return propDef;
  704. }
  705. MPropertyDef CreatePropertySetter(string name, MMethodDef propMethod) {
  706. if (string.IsNullOrEmpty(name))
  707. return null;
  708. var ownerType = propMethod.Owner;
  709. if (!ownerType.HasModule)
  710. return null;
  711. if (propMethod.Property != null)
  712. return null;
  713. var sig = propMethod.MethodDef.MethodSig;
  714. if (sig == null || sig.Params.Count == 0)
  715. return null;
  716. var propType = sig.Params[sig.Params.Count - 1];
  717. var propDef = CreateProperty(ownerType, name, propType, null, propMethod.MethodDef);
  718. if (propDef == null)
  719. return null;
  720. if (propDef.SetMethod != null)
  721. return null;
  722. if (isVerbose)
  723. Logger.v("Restoring property setter {0} ({1:X8}), Property: {2} ({3:X8})",
  724. Utils.RemoveNewlines(propMethod),
  725. propMethod.MethodDef.MDToken.ToInt32(),
  726. Utils.RemoveNewlines(propDef.PropertyDef),
  727. propDef.PropertyDef.MDToken.ToInt32());
  728. propDef.PropertyDef.SetMethod = propMethod.MethodDef;
  729. propDef.SetMethod = propMethod;
  730. propMethod.Property = propDef;
  731. return propDef;
  732. }
  733. MPropertyDef CreateProperty(MTypeDef ownerType, string name, TypeSig propType, MethodDef getter, MethodDef setter) {
  734. if (string.IsNullOrEmpty(name) || propType.ElementType == ElementType.Void)
  735. return null;
  736. var newSig = CreatePropertySig(getter, propType, true) ?? CreatePropertySig(setter, propType, false);
  737. if (newSig == null)
  738. return null;
  739. var newProp = ownerType.Module.ModuleDefMD.UpdateRowId(new PropertyDefUser(name, newSig, 0));
  740. newProp.GetMethod = getter;
  741. newProp.SetMethod = setter;
  742. var propDef = ownerType.FindAny(newProp);
  743. if (propDef != null)
  744. return propDef;
  745. propDef = ownerType.Create(newProp);
  746. memberInfos.Add(propDef);
  747. if (isVerbose)
  748. Logger.v("Restoring property: {0}", Utils.RemoveNewlines(newProp));
  749. return propDef;
  750. }
  751. static PropertySig CreatePropertySig(MethodDef method, TypeSig propType, bool isGetter) {
  752. if (method == null)
  753. return null;
  754. var sig = method.MethodSig;
  755. if (sig == null)
  756. return null;
  757. var newSig = new PropertySig(sig.HasThis, propType);
  758. newSig.GenParamCount = sig.GenParamCount;
  759. int count = sig.Params.Count;
  760. if (!isGetter)
  761. count--;
  762. for (int i = 0; i < count; i++)
  763. newSig.Params.Add(sig.Params[i]);
  764. return newSig;
  765. }
  766. void RestoreVirtualEvents(IEnumerable<MethodNameGroup> allGroups) {
  767. if (!RestoreEvents)
  768. return;
  769. foreach (var group in allGroups) {
  770. RestoreVirtualEvents(group);
  771. RestoreExplicitVirtualEvents(group);
  772. }
  773. }
  774. enum EventMethodType {
  775. None,
  776. Other,
  777. Adder,
  778. Remover,
  779. Raiser,
  780. }
  781. void RestoreExplicitVirtualEvents(MethodNameGroup group) {
  782. if (group.Methods.Count != 1)
  783. return;
  784. var eventMethod = group.Methods[0];
  785. if (eventMethod.Event != null)
  786. return;
  787. if (eventMethod.MethodDef.Overrides.Count == 0)
  788. return;
  789. MMethodDef overriddenMethod;
  790. var theEvent = GetOverriddenEvent(eventMethod, out overriddenMethod);
  791. if (theEvent == null)
  792. return;
  793. CreateEvent(theEvent, eventMethod, GetEventMethodType(overriddenMethod), GetOverridePrefix(group, eventMethod));
  794. }
  795. void RestoreVirtualEvents(MethodNameGroup group) {
  796. if (group.Methods.Count <= 1 || !group.HasEvent())
  797. return;
  798. EventMethodType methodType = EventMethodType.None;
  799. MEventDef evt = null;
  800. List<MMethodDef> missingEvents = null;
  801. foreach (var method in group.Methods) {
  802. if (method.Event == null) {
  803. if (missingEvents == null)
  804. missingEvents = new List<MMethodDef>();
  805. missingEvents.Add(method);
  806. }
  807. else if (evt == null || !method.Owner.HasModule) {
  808. evt = method.Event;
  809. methodType = GetEventMethodType(method);
  810. }
  811. }
  812. if (evt == null)
  813. return; // Should never happen
  814. if (missingEvents == null)
  815. return;
  816. foreach (var method in missingEvents)
  817. CreateEvent(evt, method, methodType, "");
  818. }
  819. void CreateEvent(MEventDef eventDef, MMethodDef methodDef, EventMethodType methodType, string overridePrefix) {
  820. if (!methodDef.Owner.HasModule)
  821. return;
  822. var newEventName = overridePrefix + eventDef.EventDef.Name;
  823. switch (methodType) {
  824. case EventMethodType.Adder:
  825. CreateEventAdder(newEventName, methodDef);
  826. break;
  827. case EventMethodType.Remover:
  828. CreateEventRemover(newEventName, methodDef);
  829. break;
  830. }
  831. }
  832. static EventMethodType GetEventMethodType(MMethodDef method) {
  833. var evt = method.Event;
  834. if (evt == null)
  835. return EventMethodType.None;
  836. if (evt.AddMethod == method)
  837. return EventMethodType.Adder;
  838. if (evt.RemoveMethod == method)
  839. return EventMethodType.Remover;
  840. if (evt.RaiseMethod == method)
  841. return EventMethodType.Raiser;
  842. return EventMethodType.Other;
  843. }
  844. void RestoreEventsFromNames2(IEnumerable<MethodNameGroup> allGroups) {
  845. if (!RestoreEventsFromNames)
  846. return;
  847. foreach (var group in allGroups) {
  848. var groupMethod = group.Methods[0];
  849. var methodName = groupMethod.MethodDef.Name.String;
  850. bool onlyRenamableMethods = !group.HasNonRenamableMethod();
  851. if (Utils.StartsWith(methodName, "add_", StringComparison.Ordinal)) {
  852. var eventName = methodName.Substring(4);
  853. foreach (var method in group.Methods) {
  854. if (onlyRenamableMethods && !memberInfos.Type(method.Owner).NameChecker.IsValidEventName(eventName))
  855. continue;
  856. CreateEventAdder(eventName, method);
  857. }
  858. }
  859. else if (Utils.StartsWith(methodName, "remove_", StringComparison.Ordinal)) {
  860. var eventName = methodName.Substring(7);
  861. foreach (var method in group.Methods) {
  862. if (onlyRenamableMethods && !memberInfos.Type(method.Owner).NameChecker.IsValidEventName(eventName))
  863. continue;
  864. CreateEventRemover(eventName, method);
  865. }
  866. }
  867. }
  868. foreach (var type in modules.AllTypes) {
  869. foreach (var method in type.AllMethodsSorted) {
  870. if (method.IsVirtual())
  871. continue; // Virtual methods are in allGroups, so already fixed above
  872. if (method.Event != null)
  873. continue;
  874. var methodName = method.MethodDef.Name.String;
  875. if (Utils.StartsWith(methodName, "add_", StringComparison.Ordinal))
  876. CreateEventAdder(methodName.Substring(4), method);
  877. else if (Utils.StartsWith(methodName, "remove_", StringComparison.Ordinal))
  878. CreateEventRemover(methodName.Substring(7), method);
  879. }
  880. }
  881. }
  882. MEventDef CreateEventAdder(string name, MMethodDef eventMethod) {
  883. if (string.IsNullOrEmpty(name))
  884. return null;
  885. var ownerType = eventMethod.Owner;
  886. if (!ownerType.HasModule)
  887. return null;
  888. if (eventMethod.Event != null)
  889. return null;
  890. var method = eventMethod.MethodDef;
  891. var eventDef = CreateEvent(ownerType, name, GetEventType(method));
  892. if (eventDef == null)
  893. return null;
  894. if (eventDef.AddMethod != null)
  895. return null;
  896. if (isVerbose)
  897. Logger.v("Restoring event adder {0} ({1:X8}), Event: {2} ({3:X8})",
  898. Utils.RemoveNewlines(eventMethod),
  899. eventMethod.MethodDef.MDToken.ToInt32(),
  900. Utils.RemoveNewlines(eventDef.EventDef),
  901. eventDef.EventDef.MDToken.ToInt32());
  902. eventDef.EventDef.AddMethod = eventMethod.MethodDef;
  903. eventDef.AddMethod = eventMethod;
  904. eventMethod.Event = eventDef;
  905. return eventDef;
  906. }
  907. MEventDef CreateEventRemover(string name, MMethodDef eventMethod) {
  908. if (string.IsNullOrEmpty(name))
  909. return null;
  910. var ownerType = eventMethod.Owner;
  911. if (!ownerType.HasModule)
  912. return null;
  913. if (eventMethod.Event != null)
  914. return null;
  915. var method = eventMethod.MethodDef;
  916. var eventDef = CreateEvent(ownerType, name, GetEventType(method));
  917. if (eventDef == null)
  918. return null;
  919. if (eventDef.RemoveMethod != null)
  920. return null;
  921. if (isVerbose)
  922. Logger.v("Restoring event remover {0} ({1:X8}), Event: {2} ({3:X8})",
  923. Utils.RemoveNewlines(eventMethod),
  924. eventMethod.MethodDef.MDToken.ToInt32(),
  925. Utils.RemoveNewlines(eventDef.EventDef),
  926. eventDef.EventDef.MDToken.ToInt32());
  927. eventDef.EventDef.RemoveMethod = eventMethod.MethodDef;
  928. eventDef.RemoveMethod = eventMethod;
  929. eventMethod.Event = eventDef;
  930. return eventDef;
  931. }
  932. TypeSig GetEventType(IMethod method) {
  933. if (DotNetUtils.HasReturnValue(method))
  934. return null;
  935. var sig = method.MethodSig;
  936. if (sig == null || sig.Params.Count != 1)
  937. return null;
  938. return sig.Params[0];
  939. }
  940. MEventDef CreateEvent(MTypeDef ownerType, string name, TypeSig eventType) {
  941. if (string.IsNullOrEmpty(name) || eventType == null || eventType.ElementType == ElementType.Void)
  942. return null;
  943. var newEvent = ownerType.Module.ModuleDefMD.UpdateRowId(new EventDefUser(name, eventType.ToTypeDefOrRef(), 0));
  944. var eventDef = ownerType.FindAny(newEvent);
  945. if (eventDef != null)
  946. return eventDef;
  947. eventDef = ownerType.Create(newEvent);
  948. memberInfos.Add(eventDef);
  949. if (isVerbose)
  950. Logger.v("Restoring event: {0}", Utils.RemoveNewlines(newEvent));
  951. return eventDef;
  952. }
  953. void PrepareRenameMemberDefs(MethodNameGroups groups) {
  954. if (isVerbose)
  955. Logger.v("Renaming member definitions #1");
  956. PrepareRenameEntryPoints();
  957. var virtualMethods = new GroupHelper(memberInfos, modules.AllTypes);
  958. var ifaceMethods = new GroupHelper(memberInfos, modules.AllTypes);
  959. var propMethods = new GroupHelper(memberInfos, modules.AllTypes);
  960. var eventMethods = new GroupHelper(memberInfos, modules.AllTypes);
  961. foreach (var group in GetSorted(groups)) {
  962. if (group.HasNonRenamableMethod())
  963. continue;
  964. else if (group.HasGetterOrSetterPropertyMethod() && GetPropertyMethodType(group.Methods[0]) != PropertyMethodType.Other)
  965. propMethods.Add(group);
  966. else if (group.HasAddRemoveOrRaiseEventMethod())
  967. eventMethods.Add(group);
  968. else if (group.HasInterfaceMethod())
  969. ifaceMethods.Add(group);
  970. else
  971. virtualMethods.Add(group);
  972. }
  973. var prepareHelper = new PrepareHelper(memberInfos, modules.AllTypes);
  974. prepareHelper.Prepare((info) => info.PrepareRenameMembers());
  975. prepareHelper.Prepare((info) => info.PrepareRenamePropsAndEvents());
  976. propMethods.VisitAll((group) => PrepareRenameProperty(group, false));
  977. eventMethods.VisitAll((group) => PrepareRenameEvent(group, false));
  978. propMethods.VisitAll((group) => PrepareRenameProperty(group, true));
  979. eventMethods.VisitAll((group) => PrepareRenameEvent(group, true));
  980. foreach (var typeDef in modules.AllTypes)
  981. memberInfos.Type(typeDef).InitializeEventHandlerNames();
  982. prepareHelper.Prepare((info) => info.PrepareRenameMethods());
  983. ifaceMethods.VisitAll((group) => PrepareRenameVirtualMethods(group, "imethod_", false));
  984. virtualMethods.VisitAll((group) => PrepareRenameVirtualMethods(group, "vmethod_", false));
  985. ifaceMethods.VisitAll((group) => PrepareRenameVirtualMethods(group, "imethod_", true));
  986. virtualMethods.VisitAll((group) => PrepareRenameVirtualMethods(group, "vmethod_", true));
  987. RestoreMethodArgs(groups);
  988. foreach (var typeDef in modules.AllTypes)
  989. memberInfos.Type(typeDef).PrepareRenameMethods2();
  990. }
  991. void RestoreMethodArgs(MethodNameGroups groups) {
  992. foreach (var group in groups.GetAllGroups()) {
  993. if (group.Methods[0].VisibleParameterCount == 0)
  994. continue;
  995. var argNames = GetValidArgNames(group);
  996. foreach (var method in group.Methods) {
  997. if (!method.Owner.HasModule)
  998. continue;
  999. var nameChecker = method.Owner.Module.ObfuscatedFile.NameChecker;
  1000. for (int i = 0; i < argNames.Length; i++) {
  1001. var argName = argNames[i];
  1002. if (argName == null || !nameChecker.IsValidMethodArgName(argName))
  1003. continue;
  1004. var info = memberInfos.Param(method.ParamDefs[i]);
  1005. if (nameChecker.IsValidMethodArgName(info.oldName))
  1006. continue;
  1007. info.newName = argName;
  1008. }
  1009. }
  1010. }
  1011. }
  1012. string[] GetValidArgNames(MethodNameGroup group) {
  1013. var methods = new List<MMethodDef>(group.Methods);
  1014. foreach (var method in group.Methods) {
  1015. foreach (var ovrd in method.MethodDef.Overrides) {
  1016. var overrideRef = ovrd.MethodDeclaration;
  1017. var overrideDef = modules.ResolveMethod(overrideRef);
  1018. if (overrideDef == null) {
  1019. var typeDef = modules.ResolveType(overrideRef.DeclaringType) ?? modules.ResolveOther(overrideRef.DeclaringType);
  1020. if (typeDef == null)
  1021. continue;
  1022. overrideDef = typeDef.FindMethod(overrideRef);
  1023. if (overrideDef == null)
  1024. continue;
  1025. }
  1026. if (overrideDef.VisibleParameterCount != method.VisibleParameterCount)
  1027. continue;
  1028. methods.Add(overrideDef);
  1029. }
  1030. }
  1031. var argNames = new string[group.Methods[0].ParamDefs.Count];
  1032. foreach (var method in methods) {
  1033. var nameChecker = !method.Owner.HasModule ? null : method.Owner.Module.ObfuscatedFile.NameChecker;
  1034. for (int i = 0; i < argNames.Length; i++) {
  1035. var argName = method.ParamDefs[i].ParameterDef.Name;
  1036. if (nameChecker == null || nameChecker.IsValidMethodArgName(argName))
  1037. argNames[i] = argName;
  1038. }
  1039. }
  1040. return argNames;
  1041. }
  1042. class PrepareHelper {
  1043. Dictionary<MTypeDef, bool> prepareMethodCalled = new Dictionary<MTypeDef, bool>();
  1044. MemberInfos memberInfos;
  1045. Action<TypeInfo> func;
  1046. IEnumerable<MTypeDef> allTypes;
  1047. public PrepareHelper(MemberInfos memberInfos, IEnumerable<MTypeDef> allTypes) {
  1048. this.memberInfos = memberInfos;
  1049. this.allTypes = allTypes;
  1050. }
  1051. public void Prepare(Action<TypeInfo> func) {
  1052. this.func = func;
  1053. prepareMethodCalled.Clear();
  1054. foreach (var typeDef in allTypes)
  1055. Prepare(typeDef);
  1056. }
  1057. void Prepare(MTypeDef type) {
  1058. if (prepareMethodCalled.ContainsKey(type))
  1059. return;
  1060. prepareMethodCalled[type] = true;
  1061. foreach (var ifaceInfo in type.interfaces)
  1062. Prepare(ifaceInfo.typeDef);
  1063. if (type.baseType != null)
  1064. Prepare(type.baseType.typeDef);
  1065. TypeInfo info;
  1066. if (memberInfos.TryGetType(type, out info))
  1067. func(info);
  1068. }
  1069. }
  1070. static List<MethodNameGroup> GetSorted(MethodNameGroups groups) {
  1071. var allGroups = new List<MethodNameGroup>(groups.GetAllGroups());
  1072. allGroups.Sort((a, b) => b.Count.CompareTo(a.Count));
  1073. return allGroups;
  1074. }
  1075. class GroupHelper {
  1076. MemberInfos memberInfos;
  1077. Dictionary<MTypeDef, bool> visited = new Dictionary<MTypeDef, bool>();
  1078. Dictionary<MMethodDef, MethodNameGroup> methodToGroup;
  1079. List<MethodNameGroup> groups = new List<MethodNameGroup>();
  1080. IEnumerable<MTypeDef> allTypes;
  1081. Action<MethodNameGroup> func;
  1082. public GroupHelper(MemberInfos memberInfos, IEnumerable<MTypeDef> allTypes) {
  1083. this.memberInfos = memberInfos;
  1084. this.allTypes = allTypes;
  1085. }
  1086. public void Add(MethodNameGroup group) {
  1087. groups.Add(group);
  1088. }
  1089. public void VisitAll(Action<MethodNameGroup> func) {
  1090. this.func = func;
  1091. visited.Clear();
  1092. methodToGroup = new Dictionary<MMethodDef, MethodNameGroup>();
  1093. foreach (var group in groups) {
  1094. foreach (var method in group.Methods)
  1095. methodToGroup[method] = group;
  1096. }
  1097. foreach (var type in allTypes)
  1098. Visit(type);
  1099. }
  1100. void Visit(MTypeDef type) {
  1101. if (visited.ContainsKey(type))
  1102. return;
  1103. visited[type] = true;
  1104. if (type.baseType != null)
  1105. Visit(type.baseType.typeDef);
  1106. foreach (var ifaceInfo in type.interfaces)
  1107. Visit(ifaceInfo.typeDef);
  1108. TypeInfo info;
  1109. if (!memberInfos.TryGetType(type, out info))
  1110. return;
  1111. foreach (var method in type.AllMethodsSorted) {
  1112. MethodNameGroup group;
  1113. if (!methodToGroup.TryGetValue(method, out group))
  1114. continue;
  1115. foreach (var m in group.Methods)
  1116. methodToGroup.Remove(m);
  1117. func(group);
  1118. }
  1119. }
  1120. }
  1121. static readonly Regex removeGenericsArityRegex = new Regex(@"`[0-9]+");
  1122. static string GetOverridePrefix(MethodNameGroup group, MMethodDef method) {
  1123. if (method == null || method.MethodDef.Overrides.Count == 0)
  1124. return "";
  1125. if (group.Methods.Count > 1) {
  1126. // Don't use an override prefix if the group has an iface method.
  1127. foreach (var m in group.Methods) {
  1128. if (m.Owner.TypeDef.IsInterface)
  1129. return "";
  1130. }
  1131. }
  1132. var overrideMethod = method.MethodDef.Overrides[0].MethodDeclaration;
  1133. if (overrideMethod.DeclaringType == null)
  1134. return "";
  1135. var name = overrideMethod.DeclaringType.FullName.Replace('/', '.');
  1136. name = removeGenericsArityRegex.Replace(name, "");
  1137. return name + ".";
  1138. }
  1139. static string GetRealName(string name) {
  1140. int index = name.LastIndexOf('.');
  1141. if (index < 0)
  1142. return name;
  1143. return name.Substring(index + 1);
  1144. }
  1145. void PrepareRenameEvent(MethodNameGroup group, bool renameOverrides) {
  1146. string methodPrefix, overridePrefix;
  1147. var eventName = PrepareRenameEvent(group, renameOverrides, out overridePrefix, out methodPrefix);
  1148. if (eventName == null)
  1149. return;
  1150. var methodName = overridePrefix + methodPrefix + eventName;
  1151. foreach (var method in group.Methods)
  1152. memberInfos.Method(method).Rename(methodName);
  1153. }
  1154. string PrepareRenameEvent(MethodNameGroup group, bool renameOverrides, out string overridePrefix, out string methodPrefix) {
  1155. var eventMethod = GetEventMethod(group);
  1156. if (eventMethod == null)
  1157. throw new ApplicationException("No events found");
  1158. var eventDef = eventMethod.Event;
  1159. if (eventMethod == eventDef.AddMethod)
  1160. methodPrefix = "add_";
  1161. else if (eventMethod == eventDef.RemoveMethod)
  1162. methodPrefix = "remove_";
  1163. else if (eventMethod == eventDef.RaiseMethod)
  1164. methodPrefix = "raise_";
  1165. else
  1166. methodPrefix = "";
  1167. overridePrefix = GetOverridePrefix(group, eventMethod);
  1168. if (renameOverrides && overridePrefix == "")
  1169. return null;
  1170. if (!renameOverrides && overridePrefix != "")
  1171. return null;
  1172. string newEventName, oldEventName;
  1173. var eventInfo = memberInfos.Event(eventDef);
  1174. bool mustUseOldEventName = false;
  1175. if (overridePrefix == "")
  1176. oldEventName = eventInfo.oldName;
  1177. else {
  1178. var overriddenEventDef = GetOverriddenEvent(eventMethod);
  1179. if (overriddenEventDef == null)
  1180. oldEventName = GetRealName(eventInfo.oldName);
  1181. else {
  1182. mustUseOldEventName = true;
  1183. EventInfo info;
  1184. if (memberInfos.TryGetEvent(overriddenEventDef, out info))
  1185. oldEventName = GetRealName(info.newName);
  1186. else
  1187. oldEventName = GetRealName(overriddenEventDef.EventDef.Name.String);
  1188. }
  1189. }
  1190. if (eventInfo.renamed)
  1191. newEventName = GetRealName(eventInfo.newName);
  1192. else if (mustUseOldEventName || eventDef.Owner.Module.ObfuscatedFile.NameChecker.IsValidEventName(oldEventName))
  1193. newEventName = oldEventName;
  1194. else {
  1195. mergeStateHelper.Merge(MergeStateFlags.Events, group);
  1196. newEventName = GetAvailableName("Event_", false, group, (group2, newName) => IsEventAvailable(group2, newName));
  1197. }
  1198. var newEventNameWithPrefix = overridePrefix + newEventName;
  1199. foreach (var method in group.Methods) {
  1200. if (method.Event != null) {
  1201. memberInfos.Event(method.Event).Rename(newEventNameWithPrefix);
  1202. var ownerInfo = memberInfos.Type(method.Owner);
  1203. ownerInfo.variableNameState.AddEventName(newEventName);
  1204. ownerInfo.variableNameState.AddEventName(newEventNameWithPrefix);
  1205. }
  1206. }
  1207. return newEventName;
  1208. }
  1209. MEventDef GetOverriddenEvent(MMethodDef overrideMethod) {
  1210. MMethodDef overriddenMethod;
  1211. return GetOverriddenEvent(overrideMethod, out overriddenMethod);
  1212. }
  1213. MEventDef GetOverriddenEvent(MMethodDef overrideMethod, out MMethodDef overriddenMethod) {
  1214. var theMethod = overrideMethod.MethodDef.Overrides[0].MethodDeclaration;
  1215. overriddenMethod = modules.ResolveMethod(theMethod);
  1216. if (overriddenMethod != null)
  1217. return overriddenMethod.Event;
  1218. var extType = theMethod.DeclaringType;
  1219. if (extType == null)
  1220. return null;
  1221. var extTypeDef = modules.ResolveOther(extType);
  1222. if (extTypeDef == null)
  1223. return null;
  1224. overriddenMethod = extTypeDef.FindMethod(theMethod);
  1225. if (overriddenMethod != null)
  1226. return overriddenMethod.Event;
  1227. return null;
  1228. }
  1229. MMethodDef GetEventMethod(MethodNameGroup group) {
  1230. foreach (var method in group.Methods) {
  1231. if (method.Event != null)
  1232. return method;
  1233. }
  1234. return null;
  1235. }
  1236. void PrepareRenameProperty(MethodNameGroup group, bool renameOverrides) {
  1237. string overridePrefix;
  1238. var propName = PrepareRenameProperty(group, renameOverrides, out overridePrefix);
  1239. if (propName == null)
  1240. return;
  1241. string methodPrefix;
  1242. switch (GetPropertyMethodType(group.Methods[0])) {
  1243. case PropertyMethodType.Getter:
  1244. methodPrefix = "get_";
  1245. break;
  1246. case PropertyMethodType.Setter:
  1247. methodPrefix = "set_";
  1248. break;
  1249. default:
  1250. throw new ApplicationException("Invalid property type");
  1251. }
  1252. var methodName = overridePrefix + methodPrefix + propName;
  1253. foreach (var method in group.Methods)
  1254. memberInfos.Method(method).Rename(methodName);
  1255. }
  1256. string PrepareRenameProperty(MethodNameGroup group, bool renameOverrides, out string overridePrefix) {
  1257. var propMethod = GetPropertyMethod(group);
  1258. if (propMethod == null)
  1259. throw new ApplicationException("No properties found");
  1260. overridePrefix = GetOverridePrefix(group, propMethod);
  1261. if (renameOverrides && overridePrefix == "")
  1262. return null;
  1263. if (!renameOverrides && overridePrefix != "")
  1264. return null;
  1265. string newPropName, oldPropName;
  1266. var propDef = propMethod.Property;
  1267. var propInfo = memberInfos.Property(propDef);
  1268. bool mustUseOldPropName = false;
  1269. if (overridePrefix == "")
  1270. oldPropName = propInfo.oldName;
  1271. else {
  1272. var overriddenPropDef = GetOverriddenProperty(propMethod);
  1273. if (overriddenPropDef == null)
  1274. oldPropName = GetRealName(propInfo.oldName);
  1275. else {
  1276. mustUseOldPropName = true;
  1277. PropertyInfo info;
  1278. if (memberInfos.TryGetProperty(overriddenPropDef, out info))
  1279. oldPropName = GetRealName(info.newName);
  1280. else
  1281. oldPropName = GetRealName(overriddenPropDef.PropertyDef.Name.String);
  1282. }
  1283. }
  1284. if (propInfo.renamed)
  1285. newPropName = GetRealName(propInfo.newName);
  1286. else if (mustUseOldPropName || propDef.Owner.Module.ObfuscatedFile.NameChecker.IsValidPropertyName(oldPropName))
  1287. newPropName = oldPropName;
  1288. else if (IsItemProperty(group))
  1289. newPropName = "Item";
  1290. else {
  1291. bool trySameName = true;
  1292. var propPrefix = GetSuggestedPropertyName(group);
  1293. if (propPrefix == null) {
  1294. trySameName = false;
  1295. propPrefix = GetNewPropertyNamePrefix(group);
  1296. }
  1297. mergeStateHelper.Merge(MergeStateFlags.Properties, group);
  1298. newPropName = GetAvailableName(propPrefix, trySameName, group, (group2, newName) => IsPropertyAvailable(group2, newName));
  1299. }
  1300. var newPropNameWithPrefix = overridePrefix + newPropName;
  1301. foreach (var method in group.Methods) {
  1302. if (method.Property != null) {
  1303. memberInfos.Property(method.Property).Rename(newPropNameWithPrefix);
  1304. var ownerInfo = memberInfos.Type(method.Owner);
  1305. ownerInfo.variableNameState.AddPropertyName(newPropName);
  1306. ownerInfo.variableNameState.AddPropertyName(newPropNameWithPrefix);
  1307. }
  1308. }
  1309. return newPropName;
  1310. }
  1311. bool IsItemProperty(MethodNameGroup group) {
  1312. foreach (var method in group.Methods) {
  1313. if (method.Property != null && method.Property.IsItemProperty())
  1314. return true;
  1315. }
  1316. return false;
  1317. }
  1318. MPropertyDef GetOverriddenProperty(MMethodDef overrideMethod) {
  1319. var theMethod = overrideMethod.MethodDef.Overrides[0].MethodDeclaration;
  1320. var overriddenMethod = modules.ResolveMethod(theMethod);
  1321. if (overriddenMethod != null)
  1322. return overriddenMethod.Property;
  1323. var extType = theMethod.DeclaringType;
  1324. if (extType == null)
  1325. return null;
  1326. var extTypeDef = modules.ResolveOther(extType);
  1327. if (extTypeDef == null)
  1328. return null;
  1329. var theMethodDef = extTypeDef.FindMethod(theMethod);
  1330. if (theMethodDef != null)
  1331. return theMethodDef.Property;
  1332. return null;
  1333. }
  1334. MMethodDef GetPropertyMethod(MethodNameGroup group) {
  1335. foreach (var method in group.Methods) {
  1336. if (method.Property != null)
  1337. return method;
  1338. }
  1339. return null;
  1340. }
  1341. string GetSuggestedPropertyName(MethodNameGroup group) {
  1342. foreach (var method in group.Methods) {
  1343. if (method.Property == null)
  1344. continue;
  1345. var info = memberInfos.Property(method.Property);
  1346. if (info.suggestedName != null)
  1347. return info.suggestedName;
  1348. }
  1349. return null;
  1350. }
  1351. string GetNewPropertyNamePrefix(MethodNameGroup group) {
  1352. const string defaultVal = "Prop_";
  1353. var propType = GetPropertyType(group);
  1354. if (propType == null)
  1355. return defaultVal;
  1356. var elementType = propType.ScopeType.ToTypeSig(false).RemovePinnedAndModifiers();
  1357. if (propType is GenericInstSig || elementType is GenericSig)
  1358. return defaultVal;
  1359. var prefix = GetPrefix(propType);
  1360. string name = elementType.TypeName;
  1361. int i;
  1362. if ((i = name.IndexOf('`')) >= 0)
  1363. name = name.Substring(0, i);
  1364. if ((i = name.LastIndexOf('.')) >= 0)
  1365. name = name.Substring(i + 1);
  1366. if (name == "")
  1367. return defaultVal;
  1368. return prefix.ToUpperInvariant() + UpperFirst(name) + "_";
  1369. }
  1370. static string UpperFirst(string s) {
  1371. return s.Substring(0, 1).ToUpperInvariant() + s.Substring(1);
  1372. }
  1373. static string GetPrefix(TypeSig typeRef) {
  1374. string prefix = "";
  1375. typeRef = typeRef.RemovePinnedAndModifiers();
  1376. while (typeRef is PtrSig) {
  1377. typeRef = typeRef.Next;
  1378. prefix += "p";
  1379. }
  1380. return prefix;
  1381. }
  1382. enum PropertyMethodType {
  1383. Other,
  1384. Getter,
  1385. Setter,
  1386. }
  1387. static PropertyMethodType GetPropertyMethodType(MMethodDef method) {
  1388. if (DotNetUtils.HasReturnValue(method.MethodDef))
  1389. return PropertyMethodType.Getter;
  1390. if (method.VisibleParameterCount > 0)
  1391. return PropertyMethodType.Setter;
  1392. return PropertyMethodType.Other;
  1393. }
  1394. // Returns property type, or null if not all methods have the same type
  1395. TypeSig GetPropertyType(MethodNameGroup group) {
  1396. var methodType = GetPropertyMethodType(group.Methods[0]);
  1397. if (methodType == PropertyMethodType.Other)
  1398. return null;

Large files files are truncated, but you can click here to view the full file