PageRenderTime 65ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 1ms

/de4dot.code/renamer/Renamer.cs

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

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