Dynamic methods decrypter code isn't needed anymore
This commit is contained in:
parent
f424e8eabf
commit
cbdcf1d8c1
151
de4dot.sln
151
de4dot.sln
|
@ -1,11 +1,6 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dumpMethods", "dumpMethods\dumpMethods.csproj", "{47E106B2-EF21-4AA4-9E99-AB1776254E21}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9} = {3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "cecil\Mono.Cecil.csproj", "{D68133BD-1E63-496E-9EDE-4FBDBF77B486}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "de4dot.code", "de4dot.code\de4dot.code.csproj", "{4D10B9EB-3BF1-4D61-A389-CB019E8C9622}"
|
||||
|
@ -28,8 +23,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyServer-x86", "Assem
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyServer-x64", "AssemblyServer-x64\AssemblyServer-x64.csproj", "{F458A89A-AEAB-4965-AA4D-393C9F7411D0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dumpMethodsN", "dumpMethodsN\dumpMethodsN.vcxproj", "{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "blocks", "blocks\blocks.csproj", "{045B96F2-AF80-4C4C-8D27-E38635AC705E}"
|
||||
EndProject
|
||||
Global
|
||||
|
@ -84,78 +77,6 @@ Global
|
|||
winphone_Release|x86 = winphone_Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Debug|Win32.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Debug|x86.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Debug|Win32.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Debug|x86.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Debug|x86.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Release|Any CPU.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Release|Win32.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Release|x86.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_2_0_Release|x86.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Debug|Win32.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Debug|x86.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Debug|x86.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Release|Any CPU.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Release|Win32.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Release|x86.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_3_5_Release|x86.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Debug|Win32.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Debug|x86.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Debug|x86.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Release|Any CPU.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Release|Win32.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Release|x86.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.net_4_0_Release|x86.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Release|Win32.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Release|x86.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.Release|x86.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Debug|Win32.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Debug|x86.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Debug|x86.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Release|Any CPU.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Release|Win32.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Release|x86.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.silverlight_Release|x86.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Debug|Win32.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Debug|x86.ActiveCfg = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Debug|x86.Build.0 = Debug|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Release|Any CPU.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Release|Win32.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Release|x86.ActiveCfg = Release|x86
|
||||
{47E106B2-EF21-4AA4-9E99-AB1776254E21}.winphone_Release|x86.Build.0 = Release|x86
|
||||
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.ActiveCfg = winphone_Debug|Any CPU
|
||||
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.Build.0 = winphone_Debug|Any CPU
|
||||
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Mixed Platforms.ActiveCfg = net_2_0_Debug|Any CPU
|
||||
|
@ -948,78 +869,6 @@ Global
|
|||
{F458A89A-AEAB-4965-AA4D-393C9F7411D0}.winphone_Release|Win32.ActiveCfg = Release|x86
|
||||
{F458A89A-AEAB-4965-AA4D-393C9F7411D0}.winphone_Release|x86.ActiveCfg = Release|x86
|
||||
{F458A89A-AEAB-4965-AA4D-393C9F7411D0}.winphone_Release|x86.Build.0 = Release|x86
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Debug|Win32.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Release|Win32.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Release|Win32.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_2_0_Release|x86.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Debug|Win32.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Release|Win32.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Release|Win32.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_3_5_Release|x86.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Debug|Win32.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Release|Win32.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Release|Win32.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.net_4_0_Release|x86.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Release|Win32.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.Release|x86.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Debug|Win32.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Release|Win32.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Release|Win32.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.silverlight_Release|x86.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Debug|Mixed Platforms.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Debug|Win32.Build.0 = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Release|Mixed Platforms.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Release|Mixed Platforms.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Release|Win32.ActiveCfg = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Release|Win32.Build.0 = Release|Win32
|
||||
{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}.winphone_Release|x86.ActiveCfg = Release|Win32
|
||||
{045B96F2-AF80-4C4C-8D27-E38635AC705E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{045B96F2-AF80-4C4C-8D27-E38635AC705E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{045B96F2-AF80-4C4C-8D27-E38635AC705E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<!-- Methods dumper works better with CLR 2.0 than 4.0 -->
|
||||
<supportedRuntime version="v2.0.50727"/>
|
||||
<supportedRuntime version="v4.0"/>
|
||||
</startup>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true"/>
|
||||
</runtime>
|
||||
</configuration>
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace dumpMethods {
|
||||
static class Log {
|
||||
static int indentLevel = 0;
|
||||
const int indentSize = 2;
|
||||
|
||||
public enum LogLevel {
|
||||
error,
|
||||
warning,
|
||||
normal,
|
||||
verbose,
|
||||
veryverbose,
|
||||
}
|
||||
public static LogLevel logLevel = LogLevel.normal;
|
||||
|
||||
public static void indent() {
|
||||
indentLevel++;
|
||||
}
|
||||
|
||||
public static void deIndent() {
|
||||
if (indentLevel <= 0)
|
||||
throw new ApplicationException("Can't de-indent!");
|
||||
indentLevel--;
|
||||
}
|
||||
|
||||
static void log(LogLevel l, string format, params object[] args) {
|
||||
if (l > logLevel)
|
||||
return;
|
||||
string indent = new string(' ', indentLevel * indentSize);
|
||||
if (l <= LogLevel.warning)
|
||||
indent = "";
|
||||
Console.WriteLine(indent + format, args);
|
||||
}
|
||||
|
||||
public static void e(string format, params object[] args) {
|
||||
log(LogLevel.error, format, args);
|
||||
}
|
||||
|
||||
public static void w(string format, params object[] args) {
|
||||
log(LogLevel.warning, format, args);
|
||||
}
|
||||
|
||||
public static void n(string format, params object[] args) {
|
||||
log(LogLevel.normal, format, args);
|
||||
}
|
||||
|
||||
public static void v(string format, params object[] args) {
|
||||
log(LogLevel.verbose, format, args);
|
||||
}
|
||||
|
||||
public static void vv(string format, params object[] args) {
|
||||
log(LogLevel.veryverbose, format, args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace dumpMethods {
|
||||
class ProtectedFile {
|
||||
string filename;
|
||||
string methodsFilename;
|
||||
|
||||
public string Filename {
|
||||
get { return filename; }
|
||||
}
|
||||
|
||||
public string MethodsFilename {
|
||||
get { return methodsFilename; }
|
||||
set { methodsFilename = value; }
|
||||
}
|
||||
|
||||
public ProtectedFile(string filename, string methodsFilename = null) {
|
||||
this.filename = filename;
|
||||
this.methodsFilename = methodsFilename;
|
||||
|
||||
if (this.methodsFilename == null)
|
||||
this.methodsFilename = this.filename + ".methods";
|
||||
}
|
||||
}
|
||||
|
||||
class Program {
|
||||
[DllImport(@"dumpMethodsN.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool initialize1(int logLevel, [MarshalAs(UnmanagedType.LPWStr)] string filename);
|
||||
|
||||
[DllImport(@"dumpMethodsN.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool initialize2();
|
||||
|
||||
[DllImport(@"dumpMethodsN.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool foundAssembly();
|
||||
|
||||
[DllImport(@"dumpMethodsN.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool dumpCode([MarshalAs(UnmanagedType.LPWStr)] string methodsFilename);
|
||||
|
||||
delegate void CallCctor();
|
||||
static int Main(string[] args) {
|
||||
try {
|
||||
if (Console.OutputEncoding.IsSingleByte)
|
||||
Console.OutputEncoding = new UTF8Encoding(false);
|
||||
|
||||
var files = parseCommandLine(args);
|
||||
if (files.Count != 1)
|
||||
exitError("Exactly one file must be given.");
|
||||
|
||||
foreach (var file in files) {
|
||||
Log.v("calling initialize1()");
|
||||
if (!initialize1((int)Log.logLevel, file.Filename))
|
||||
fatal("initialize1() failed");
|
||||
|
||||
Log.v("Loading assembly: {0}", file.Filename);
|
||||
Assembly assembly = Assembly.LoadFrom(file.Filename);
|
||||
|
||||
loadProtection(assembly);
|
||||
if (!foundAssembly())
|
||||
fatal("Could not find the assembly in memory");
|
||||
|
||||
Log.v("calling initialize2()");
|
||||
if (!initialize2())
|
||||
fatal("initialize2() failed");
|
||||
|
||||
Log.n("Dumping all methods...");
|
||||
if (!dumpCode(file.MethodsFilename))
|
||||
fatal("dumpCode() failed");
|
||||
Log.n("Done");
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
var line = new string('-', 78);
|
||||
Log.e("\n\nERROR: Caught an exception:\n\n");
|
||||
Log.e(line);
|
||||
Log.e("Message: {0}", ex.Message);
|
||||
Log.e("Type: {0}", ex.GetType());
|
||||
Log.e(line);
|
||||
Log.e("\n\nStack trace:\n{0}", ex.StackTrace);
|
||||
if (ex is ReflectionTypeLoadException) {
|
||||
var rex = (ReflectionTypeLoadException)ex;
|
||||
Log.e("\nReflectionTypeLoadException.LoaderExceptions =");
|
||||
foreach (var ex2 in rex.LoaderExceptions)
|
||||
Log.e(" {0}", ex2.Message);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void exit(int exitCode) {
|
||||
Environment.Exit(exitCode);
|
||||
}
|
||||
|
||||
static void fatal(string msg) {
|
||||
Log.e("{0}", msg);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
static void loadProtection(Assembly assembly) {
|
||||
Log.n("Loading protection...");
|
||||
foreach (var type2 in assembly.GetTypes()) {
|
||||
if (foundAssembly())
|
||||
return;
|
||||
var cctor = type2.TypeInitializer;
|
||||
if (cctor == null)
|
||||
continue;
|
||||
|
||||
// Tell the jitter to compile the method
|
||||
RuntimeHelpers.PrepareMethod(cctor.MethodHandle);
|
||||
}
|
||||
}
|
||||
|
||||
static IList<ProtectedFile> parseCommandLine(string[] args) {
|
||||
var files = new List<ProtectedFile>();
|
||||
|
||||
ProtectedFile file = null;
|
||||
for (int i = 0; i < args.Length; i++) {
|
||||
var arg = args[i];
|
||||
var next = i + 1 < args.Length ? args[i + 1] : null;
|
||||
|
||||
if (arg == "-h" || arg == "--help") {
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
else if (arg == "-v" || arg == "--verbose") {
|
||||
Log.logLevel = Log.LogLevel.verbose;
|
||||
}
|
||||
else if (arg == "-vv" || arg == "--veryverbose") {
|
||||
Log.logLevel = Log.LogLevel.veryverbose;
|
||||
}
|
||||
else if (arg == "-m" || arg == "--methods") {
|
||||
if (next == null)
|
||||
exitError("Missing methods filename");
|
||||
if (file == null)
|
||||
exitError("No input file given yet");
|
||||
file.MethodsFilename = next;
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
if (arg == "-f" || arg == "--file") {
|
||||
if (next == null)
|
||||
exitError("Missing filename");
|
||||
i++;
|
||||
arg = next;
|
||||
}
|
||||
|
||||
if (!new FileInfo(arg).Exists)
|
||||
exitError(string.Format("File \"{0}\" does not exist.", arg));
|
||||
files.Add(file = new ProtectedFile(arg));
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
static void exitError(string msg) {
|
||||
usage();
|
||||
Log.e("\n\nERROR: {0}\n", msg);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
static void usage() {
|
||||
string progName = getProgramBaseName();
|
||||
Log.n("Dumps encrypted .NET methods. This works only with the supported obfuscators.");
|
||||
Log.n("{0} [options] file", progName);
|
||||
Log.n("Options:");
|
||||
Log.n(" -v Verbose");
|
||||
Log.n(" -vv Very verbose");
|
||||
Log.n(" -f name Name of .NET file");
|
||||
Log.n(" -m name Name of .methods file");
|
||||
Log.n("Examples:");
|
||||
Log.n("{0} file1", progName);
|
||||
Log.n("{0} -f file1", progName);
|
||||
Log.n("{0} -f file1 -m file1.methods", progName);
|
||||
}
|
||||
|
||||
static string getProgramBaseName() {
|
||||
var name = Environment.GetCommandLineArgs()[0];
|
||||
int index = name.LastIndexOf(Path.DirectorySeparatorChar);
|
||||
if (index < 0)
|
||||
return name;
|
||||
return name.Substring(index + 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("dumpMethods")]
|
||||
[assembly: AssemblyDescription("Dumps encrypted .NET methods")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("dumpMethods")]
|
||||
[assembly: AssemblyCopyright("Copyright (C) 2011 de4dot@gmail.com")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: AssemblyVersion("1.1.3.3405")]
|
||||
[assembly: AssemblyFileVersion("1.1.3.3405")]
|
|
@ -1,53 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{47E106B2-EF21-4AA4-9E99-AB1776254E21}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>dumpMethods</RootNamespace>
|
||||
<AssemblyName>dumpMethods</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DLL_ALLOC_H
|
||||
#define DLL_ALLOC_H
|
||||
|
||||
#include <Windows.h>
|
||||
#include "strex.h"
|
||||
#include "common.h"
|
||||
|
||||
// Alloc code/data from the end of sections in a loaded DLL
|
||||
class DllAlloc {
|
||||
public:
|
||||
DllAlloc(HMODULE hMod) {
|
||||
hDll = hMod;
|
||||
if (!hDll)
|
||||
throw strex("Invalid hDll");
|
||||
imageBase = (unsigned char*)hDll;
|
||||
|
||||
idh = (IMAGE_DOS_HEADER*)imageBase;
|
||||
unsigned char* p = imageBase + idh->e_lfanew;
|
||||
p += 4; // Skip IMAGE_NT_SIGNATURE
|
||||
ifh = (_IMAGE_FILE_HEADER*)p;
|
||||
numSections = ifh->NumberOfSections;
|
||||
p += sizeof(_IMAGE_FILE_HEADER);
|
||||
ioh = (_IMAGE_OPTIONAL_HEADER*)p;
|
||||
p += ifh->SizeOfOptionalHeader;
|
||||
sections = (_IMAGE_SECTION_HEADER*)p;
|
||||
|
||||
textEnd = findEndOfSection(".text\0\0\0");
|
||||
}
|
||||
|
||||
void* alloc(size_t size) {
|
||||
textEnd -= ALIGNIT(size, sizeof(void*));
|
||||
return textEnd;
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t PAGE_SIZE = 0x1000;
|
||||
|
||||
void* rvaToPtr(unsigned rva) const {
|
||||
return imageBase + rva;
|
||||
}
|
||||
|
||||
_IMAGE_SECTION_HEADER* findSection(const char* name) const {
|
||||
for (size_t i = 0; i < numSections; i++) {
|
||||
if (!memcmp(sections[i].Name, name, 8))
|
||||
return §ions[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char* findEndOfSection(const char* name) const {
|
||||
_IMAGE_SECTION_HEADER* section = findSection(name);
|
||||
if (!section)
|
||||
throw strex("Could not find the section");
|
||||
|
||||
return (unsigned char*)rvaToPtr(ALIGNIT(section->VirtualAddress + section->SizeOfRawData, PAGE_SIZE));
|
||||
}
|
||||
|
||||
HMODULE hDll;
|
||||
unsigned char* imageBase;
|
||||
size_t numSections;
|
||||
IMAGE_DOS_HEADER* idh;
|
||||
_IMAGE_FILE_HEADER* ifh;
|
||||
_IMAGE_OPTIONAL_HEADER* ioh;
|
||||
_IMAGE_SECTION_HEADER* sections;
|
||||
unsigned char* textEnd;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,564 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include "DotNetFile.h"
|
||||
#include "strex.h"
|
||||
#include "common.h"
|
||||
|
||||
void DotNetFile::fread(long offset, void* buf, size_t size) const {
|
||||
if (fseek(file, offset, SEEK_SET))
|
||||
throw strex("Could not seek");
|
||||
fread(buf, size);
|
||||
}
|
||||
|
||||
void DotNetFile::fread(void* buf, size_t size) const {
|
||||
if (::fread(buf, 1, size, file) != size)
|
||||
throw strex("Could not read");
|
||||
}
|
||||
|
||||
DotNetFile::DotNetFile(const wchar_t* filename)
|
||||
: image(0), streams(0)
|
||||
{
|
||||
memset(&metaDataTypes, 0, sizeof(metaDataTypes));
|
||||
|
||||
if ((file = _wfopen(filename, L"rb")) == 0)
|
||||
throw strex("Could not open file");
|
||||
|
||||
_IMAGE_DOS_HEADER dosHeader;
|
||||
fread(0, &dosHeader, sizeof(dosHeader));
|
||||
if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE)
|
||||
throw strex("Not a EXE file");
|
||||
DWORD peMagic;
|
||||
fread(dosHeader.e_lfanew, &peMagic, sizeof(peMagic));
|
||||
if (peMagic != IMAGE_NT_SIGNATURE)
|
||||
throw strex("Invalid PE magic");
|
||||
_IMAGE_FILE_HEADER fileHeader;
|
||||
fread(&fileHeader, sizeof(fileHeader));
|
||||
if (fileHeader.Machine != IMAGE_FILE_MACHINE_I386)
|
||||
throw strex("Machine is not i386");
|
||||
if (fileHeader.SizeOfOptionalHeader != sizeof(_IMAGE_OPTIONAL_HEADER))
|
||||
throw strex("Invalid size of optional header");
|
||||
_IMAGE_OPTIONAL_HEADER optionalHeader;
|
||||
fread(&optionalHeader, sizeof(optionalHeader));
|
||||
if (optionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
throw strex("Not a 32-bit optional header");
|
||||
sizeOfHeaders = optionalHeader.SizeOfHeaders;
|
||||
loadImage(fileHeader, optionalHeader.SizeOfImage, optionalHeader.SizeOfHeaders);
|
||||
cor20Header = (IMAGE_COR20_HEADER*)rvaToPtr(optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress, sizeof(IMAGE_COR20_HEADER));
|
||||
if (cor20Header->cb < sizeof(IMAGE_COR20_HEADER))
|
||||
throw strex("Invalid IMAGE_COR20_HEADER size");
|
||||
metadata = (unsigned char*)rvaToPtr(cor20Header->MetaData.VirtualAddress, cor20Header->MetaData.Size);
|
||||
if (*(DWORD*)metadata != 0x424A5342)
|
||||
throw strex("Invalid metadata magic");
|
||||
initStreams();
|
||||
}
|
||||
|
||||
DotNetFile::~DotNetFile() {
|
||||
if (image)
|
||||
delete[] image;
|
||||
if (streams)
|
||||
delete[] streams;
|
||||
for (size_t i = 0; i < METADATA_TYPES; i++) {
|
||||
if (metaDataTypes[i])
|
||||
delete metaDataTypes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// file offset is at _IMAGE_SECTION_HEADER
|
||||
void DotNetFile::loadImage(const _IMAGE_FILE_HEADER& fileHeader, DWORD _imageSize, DWORD headerSize) {
|
||||
long sectionHeaderOffs = ftell(file);
|
||||
|
||||
imageSize = _imageSize;
|
||||
image = new unsigned char[imageSize];
|
||||
memset(image, 0, imageSize);
|
||||
|
||||
loadImage(0, 0, headerSize);
|
||||
|
||||
numSections = fileHeader.NumberOfSections;
|
||||
sectionHeaders = (_IMAGE_SECTION_HEADER*)rvaToPtr(sectionHeaderOffs, sizeof(_IMAGE_SECTION_HEADER) * numSections);
|
||||
for (size_t i = 0; i < numSections; i++) {
|
||||
if (sectionHeaders[i].VirtualAddress == 0)
|
||||
throw strex("Invalid section VirtualAddress");
|
||||
loadImage(sectionHeaders[i].VirtualAddress, sectionHeaders[i].PointerToRawData, sectionHeaders[i].SizeOfRawData);
|
||||
}
|
||||
}
|
||||
|
||||
void DotNetFile::loadImage(DWORD rva, DWORD fileOffset, DWORD sizeRawData) {
|
||||
if (rva + sizeRawData < rva || rva + sizeRawData > imageSize)
|
||||
throw strex("rva + size too large");
|
||||
fread(fileOffset, image + rva, sizeRawData);
|
||||
}
|
||||
|
||||
void* DotNetFile::rvaToPtr(DWORD rva, size_t size) const {
|
||||
if (rva + size < rva || rva + size > imageSize)
|
||||
throw strex("RVA + size is too big");
|
||||
return image + rva;
|
||||
}
|
||||
|
||||
size_t DotNetFile::ptrToRva(void* addr) const {
|
||||
size_t rva = (unsigned char*)addr - image;
|
||||
if (rva < imageSize)
|
||||
return rva;
|
||||
throw strex("Addr is not a VA");
|
||||
}
|
||||
|
||||
|
||||
void DotNetFile::initStreams() {
|
||||
unsigned char* p = metadata + 4 + 2 + 2 + 4; // magic, major, minor, reserved
|
||||
p += 4 + *(DWORD*)p; // Skip version string and string length
|
||||
p += 2; // Skip Flags
|
||||
numStreams = *(WORD*)p;
|
||||
p += 2;
|
||||
streams = new Stream[numStreams];
|
||||
for (size_t i = 0; i < numStreams; i++) {
|
||||
DWORD offs = *(DWORD*)p;
|
||||
DWORD size = *(DWORD*)(p+4);
|
||||
streams[i].init((unsigned char*)metaOffsToAddr(offs, size), size, (const char*)(p+8));
|
||||
p += 8;
|
||||
size_t len = strlen((const char*)p) + 1;
|
||||
p += (len+3)/4 * 4;
|
||||
}
|
||||
|
||||
streamTilde = findStream("#~");
|
||||
streamBlob = findStream("#Blob");
|
||||
streamStrings = findStream("#Strings");
|
||||
if (!streamTilde)
|
||||
throw strex("No #~ stream");
|
||||
if (!streamBlob)
|
||||
throw strex("No #Blob stream");
|
||||
if (!streamStrings)
|
||||
throw strex("No #Strings stream");
|
||||
|
||||
initMetadataTables();
|
||||
}
|
||||
|
||||
void* DotNetFile::metaOffsToAddr(DWORD offs, DWORD size) const {
|
||||
if (offs + size < offs || offs + size > cor20Header->MetaData.Size)
|
||||
throw strex("Invalid metadata offset");
|
||||
return metadata + offs;
|
||||
}
|
||||
|
||||
Stream* DotNetFile::findStream(const char* name) const {
|
||||
for (size_t i = 0; i < numStreams; i++) {
|
||||
if (!strcmp(name, streams[i].name))
|
||||
return &streams[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum MetaDataVarType {
|
||||
end,
|
||||
stop,
|
||||
byte1,
|
||||
byte2,
|
||||
byte4,
|
||||
stringIndex, // index into #String heap
|
||||
guidIndex, // index into #GUID heap
|
||||
blobIndex, // index into #Blob heap
|
||||
resolutionScope,
|
||||
typeDefOrRef,
|
||||
fieldIndex,
|
||||
methodDefIndex,
|
||||
paramIndex,
|
||||
typeDefIndex,
|
||||
eventIndex,
|
||||
propertyIndex,
|
||||
moduleRefIndex,
|
||||
assemblyRefIndex,
|
||||
genericParamIndex,
|
||||
memberRefParent,
|
||||
hasConstant,
|
||||
hasCustomAttribute,
|
||||
customAttributeType,
|
||||
hasFieldMarshal,
|
||||
hasDeclSecurity,
|
||||
hasSemantics,
|
||||
methodDefOrRef,
|
||||
memberForwarded,
|
||||
implementation,
|
||||
typeOrMethodDef,
|
||||
};
|
||||
|
||||
class MetaDataTypeBuilder {
|
||||
public:
|
||||
MetaDataTypeBuilder(int _heapOffsetSizes, const MetaDataTable* _metaDataTables)
|
||||
: heapOffsetSizes(_heapOffsetSizes), metaDataTables(_metaDataTables), numFields(0), offset(0) {
|
||||
}
|
||||
|
||||
MetaDataTypeBuilder& field(MetaDataVarType type) {
|
||||
if (numFields >= MAX_FIELDS)
|
||||
throw strex("Too many fields");
|
||||
|
||||
unsigned short size;
|
||||
switch (type) {
|
||||
case byte1:
|
||||
size = 1;
|
||||
break;
|
||||
case byte2:
|
||||
size = 2;
|
||||
break;
|
||||
case byte4:
|
||||
size = 4;
|
||||
break;
|
||||
case stringIndex:
|
||||
size = heapOffsetSizes & 1 ? 4 : 2;
|
||||
break;
|
||||
case guidIndex:
|
||||
size = heapOffsetSizes & 2 ? 4 : 2;
|
||||
break;
|
||||
case blobIndex:
|
||||
size = heapOffsetSizes & 4 ? 4 : 2;
|
||||
break;
|
||||
case resolutionScope: {
|
||||
static MetaDataIndex indexes[] = {iModule, iModuleRef, iAssemblyRef, iTypeRef};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 14);
|
||||
break;
|
||||
}
|
||||
case typeDefOrRef: {
|
||||
static MetaDataIndex indexes[] = {iTypeDef, iTypeRef, iTypeSpec};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 14);
|
||||
break;
|
||||
}
|
||||
case memberRefParent: {
|
||||
static MetaDataIndex indexes[] = {iTypeDef, iTypeRef, iModuleRef, iMethodDef, iTypeSpec};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 13);
|
||||
break;
|
||||
}
|
||||
case hasConstant: {
|
||||
static MetaDataIndex indexes[] = {iField, iParam, iProperty};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 14);
|
||||
break;
|
||||
}
|
||||
case hasCustomAttribute: {
|
||||
static MetaDataIndex indexes[] = {
|
||||
iMethodDef, iField, iTypeRef, iTypeDef, iParam, iInterfaceImpl,
|
||||
iMemberRef, iModule /*TODO:, iPermission*/, iProperty,
|
||||
iEvent, iStandAloneSig, iModuleRef, iTypeSpec, iAssembly,
|
||||
iAssemblyRef, iFile, iExportedType, iManifestResource,
|
||||
};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 11);
|
||||
break;
|
||||
}
|
||||
case customAttributeType: {
|
||||
static MetaDataIndex indexes[] = {iMethodDef, iMemberRef}; // others aren't used
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 13);
|
||||
break;
|
||||
}
|
||||
case hasFieldMarshal: {
|
||||
static MetaDataIndex indexes[] = {iField, iParam};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 15);
|
||||
break;
|
||||
}
|
||||
case hasDeclSecurity: {
|
||||
static MetaDataIndex indexes[] = {iTypeDef, iMethodDef, iAssembly};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 14);
|
||||
break;
|
||||
}
|
||||
case hasSemantics: {
|
||||
static MetaDataIndex indexes[] = {iEvent, iProperty};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 15);
|
||||
break;
|
||||
}
|
||||
case methodDefOrRef: {
|
||||
static MetaDataIndex indexes[] = {iMethodDef, iMemberRef};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 15);
|
||||
break;
|
||||
}
|
||||
case memberForwarded: {
|
||||
static MetaDataIndex indexes[] = {iField, iMethodDef};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 15);
|
||||
break;
|
||||
}
|
||||
case implementation: {
|
||||
static MetaDataIndex indexes[] = {iFile, iAssemblyRef, iExportedType};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 14);
|
||||
break;
|
||||
}
|
||||
case typeOrMethodDef: {
|
||||
static MetaDataIndex indexes[] = {iTypeDef, iMethodDef};
|
||||
size = getSize(indexes, NUM_ELEMS(indexes), 15);
|
||||
break;
|
||||
}
|
||||
case fieldIndex:
|
||||
size = getSize(iField);
|
||||
break;
|
||||
case methodDefIndex:
|
||||
size = getSize(iMethodDef);
|
||||
break;
|
||||
case paramIndex:
|
||||
size = getSize(iParam);
|
||||
break;
|
||||
case typeDefIndex:
|
||||
size = getSize(iTypeDef);
|
||||
break;
|
||||
case eventIndex:
|
||||
size = getSize(iEvent);
|
||||
break;
|
||||
case propertyIndex:
|
||||
size = getSize(iProperty);
|
||||
break;
|
||||
case moduleRefIndex:
|
||||
size = getSize(iModuleRef);
|
||||
break;
|
||||
case assemblyRefIndex:
|
||||
size = getSize(iAssemblyRef);
|
||||
break;
|
||||
case genericParamIndex:
|
||||
size = getSize(iGenericParam);
|
||||
break;
|
||||
default:
|
||||
throw strex("Unknown type");
|
||||
}
|
||||
|
||||
fields[numFields].offset = offset;
|
||||
fields[numFields].size = size;
|
||||
numFields++;
|
||||
offset += size;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
MetaDataType* create() {
|
||||
MetaDataType* mdt = new MetaDataType(fields, numFields);
|
||||
numFields = 0;
|
||||
offset = 0;
|
||||
return mdt;
|
||||
}
|
||||
|
||||
private:
|
||||
MetaDataTypeBuilder(const MetaDataTypeBuilder&);
|
||||
MetaDataTypeBuilder& operator=(const MetaDataTypeBuilder&);
|
||||
|
||||
size_t getMaxRows(const MetaDataIndex* indexes, size_t num) const {
|
||||
size_t maxRows = 0;
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
if (metaDataTables[indexes[i]].rows > maxRows)
|
||||
maxRows = metaDataTables[indexes[i]].rows;
|
||||
}
|
||||
return maxRows;
|
||||
}
|
||||
|
||||
unsigned short getSize(const MetaDataIndex* indexes, size_t num, int bits) const {
|
||||
const size_t maxNum = 1 << bits;
|
||||
const size_t maxRows = getMaxRows(indexes, num);
|
||||
return maxRows <= maxNum ? 2 : 4;
|
||||
}
|
||||
|
||||
unsigned short getSize(MetaDataIndex index) const {
|
||||
const MetaDataIndex indexes[1] = {index};
|
||||
return getSize(indexes, 1, 16);
|
||||
}
|
||||
|
||||
static const size_t MAX_FIELDS = 10;
|
||||
const int heapOffsetSizes;
|
||||
const MetaDataTable* metaDataTables;
|
||||
size_t numFields;
|
||||
MetaDataField fields[MAX_FIELDS];
|
||||
unsigned short offset;
|
||||
};
|
||||
|
||||
void DotNetFile::initMetadataTables() {
|
||||
unsigned char* p = streamTilde->addr;
|
||||
|
||||
p += 4 + 1 + 1; // skip reserved, major, minor
|
||||
unsigned char heapOffsetSizes = *p;
|
||||
p += 1 + 1; // Skip HeapOffsetSizes and reserved
|
||||
unsigned long long valid = *(unsigned long long*)p;
|
||||
p += 8 + 8; // Skip Valid and Sorted
|
||||
for (int i = 0; valid; i++, valid >>= 1) {
|
||||
if (valid & 1) {
|
||||
metaDataTables[i].rows = *(DWORD*)p;
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static MetaDataVarType types[] = {
|
||||
byte2, stringIndex, guidIndex, guidIndex, guidIndex, end, // 0
|
||||
resolutionScope, stringIndex, stringIndex, end, // 1
|
||||
byte4, stringIndex, stringIndex, typeDefOrRef, fieldIndex, methodDefIndex, end, // 2
|
||||
end, // 3
|
||||
byte2, stringIndex, blobIndex, end, // 4
|
||||
end, // 5
|
||||
byte4, byte2, byte2, stringIndex, blobIndex, paramIndex, end, // 6
|
||||
end, // 7
|
||||
byte2, byte2, stringIndex, end, // 8
|
||||
typeDefIndex, typeDefOrRef, end, // 9
|
||||
memberRefParent, stringIndex, blobIndex, end, // 10
|
||||
byte1, byte1, hasConstant, blobIndex, end, // 11
|
||||
hasCustomAttribute, customAttributeType, blobIndex, end, // 12
|
||||
hasFieldMarshal, blobIndex, end, // 13
|
||||
byte2, hasDeclSecurity, blobIndex, end, // 14
|
||||
byte2, byte4, typeDefIndex, end, // 15
|
||||
byte4, fieldIndex, end, // 16
|
||||
blobIndex, end, // 17
|
||||
typeDefIndex, eventIndex, end, // 18
|
||||
end, // 19
|
||||
byte2, stringIndex, typeDefOrRef, end, // 20
|
||||
typeDefIndex, propertyIndex, end, // 21
|
||||
end, // 22
|
||||
byte2, stringIndex, blobIndex, end, // 23
|
||||
byte2, methodDefIndex, hasSemantics, end, // 24
|
||||
typeDefIndex, methodDefOrRef, methodDefOrRef, end, // 25
|
||||
stringIndex, end, // 26
|
||||
blobIndex, end, // 27
|
||||
byte2, memberForwarded, stringIndex, moduleRefIndex, end, // 28
|
||||
byte4, fieldIndex, end, // 29
|
||||
end, // 30
|
||||
end, // 31
|
||||
byte4, byte2, byte2, byte2, byte2, byte4, blobIndex, stringIndex, stringIndex, end, // 32
|
||||
byte4, end, // 33
|
||||
byte4, byte4, byte4, end, // 34
|
||||
byte2, byte2, byte2, byte2, byte4, blobIndex, stringIndex, stringIndex, blobIndex, end, // 35
|
||||
byte4, assemblyRefIndex, end, // 36
|
||||
byte4, byte4, byte4, assemblyRefIndex, end, // 37
|
||||
byte4, stringIndex, blobIndex, end, // 38
|
||||
byte4, byte4, stringIndex, stringIndex, implementation, end,// 39
|
||||
byte4, byte4, stringIndex, implementation, end, // 40
|
||||
typeDefIndex, typeDefIndex, end, // 41
|
||||
byte2, byte2, typeOrMethodDef, stringIndex, end, // 42
|
||||
end, // 43
|
||||
genericParamIndex, typeDefOrRef, end, // 44
|
||||
end, // 45
|
||||
end, // 46
|
||||
end, // 47
|
||||
end, // 48
|
||||
end, // 49
|
||||
end, // 50
|
||||
end, // 51
|
||||
end, // 52
|
||||
end, // 53
|
||||
end, // 54
|
||||
end, // 55
|
||||
end, // 56
|
||||
end, // 57
|
||||
end, // 58
|
||||
end, // 59
|
||||
end, // 60
|
||||
end, // 61
|
||||
end, // 62
|
||||
end, // 63
|
||||
|
||||
stop
|
||||
};
|
||||
|
||||
MetaDataTypeBuilder builder(heapOffsetSizes, metaDataTables);
|
||||
for (int i = 0, j = 0; ; i++) {
|
||||
if (types[i] == end)
|
||||
metaDataTypes[j++] = builder.create();
|
||||
else if (types[i] == stop)
|
||||
break;
|
||||
else
|
||||
builder.field(types[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < METADATA_TYPES; i++) {
|
||||
metaDataTables[i].addr = p;
|
||||
p += metaDataTables[i].rows * metaDataTypes[i]->size();
|
||||
}
|
||||
|
||||
if (metaDataTables[iMethodDef].rows == 0)
|
||||
throw strex("No MethodDef in #~ stream");
|
||||
}
|
||||
|
||||
bool DotNetFile::isYourImageBase(void* addr) const {
|
||||
__try {
|
||||
unsigned char* p = (unsigned char*)addr;
|
||||
size_t offs = 0;
|
||||
|
||||
if (memcmp(image + offs, p + offs, sizeof(IMAGE_DOS_HEADER)))
|
||||
return false;
|
||||
offs = ((IMAGE_DOS_HEADER*)image)->e_lfanew;
|
||||
|
||||
if (memcmp(image + offs, p + offs, sizeof(DWORD) + sizeof(_IMAGE_FILE_HEADER)))
|
||||
return false;
|
||||
offs += sizeof(DWORD);
|
||||
size_t sizeOh = ((_IMAGE_FILE_HEADER*)(image+offs))->SizeOfOptionalHeader;
|
||||
size_t numSections = ((_IMAGE_FILE_HEADER*)(image+offs))->NumberOfSections;
|
||||
offs += sizeof(_IMAGE_FILE_HEADER);
|
||||
|
||||
// Ignore ImageBase field which could be different
|
||||
size_t lastSize = sizeOh + numSections * sizeof(_IMAGE_SECTION_HEADER);
|
||||
void* tempMem = new unsigned char[lastSize];
|
||||
memcpy(tempMem, image + offs, lastSize);
|
||||
((_IMAGE_OPTIONAL_HEADER*)tempMem)->AddressOfEntryPoint = ((_IMAGE_OPTIONAL_HEADER*)(p + offs))->AddressOfEntryPoint;
|
||||
((_IMAGE_OPTIONAL_HEADER*)tempMem)->ImageBase = ((_IMAGE_OPTIONAL_HEADER*)(p + offs))->ImageBase;
|
||||
if (memcmp(tempMem, p + offs, lastSize)) {
|
||||
delete[] tempMem;
|
||||
return false;
|
||||
}
|
||||
delete[] tempMem;
|
||||
offs += sizeOh + numSections * sizeof(_IMAGE_SECTION_HEADER);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void* DotNetFile::getMetaDataTableElem(MetaDataIndex metaIndex, unsigned index, void* imageBase) const {
|
||||
if (imageBase == 0)
|
||||
imageBase = image;
|
||||
index--;
|
||||
if (index >= metaDataTables[metaIndex].rows)
|
||||
throw strex("Invalid metatable index");
|
||||
|
||||
const MetaDataType* type = metaDataTypes[metaIndex];
|
||||
return metaDataTables[metaIndex].addr + type->size() * index;
|
||||
}
|
||||
|
||||
void* DotNetFile::getMethodDef(unsigned index, void* imageBase) const {
|
||||
return getMetaDataTableElem(iMethodDef, index, imageBase);
|
||||
}
|
||||
|
||||
void* DotNetFile::getMethodHeader(unsigned index, void* imageBase) const {
|
||||
void* methodDef = getMethodDef(index, imageBase);
|
||||
const MetaDataType* type = metaDataTypes[iMethodDef];
|
||||
return (unsigned char*)imageBase + type->read(methodDef, 0);
|
||||
}
|
||||
|
||||
const char* DotNetFile::getMethodName(unsigned index, void* imageBase) const {
|
||||
void* methodDef = getMethodDef(index, imageBase);
|
||||
const MetaDataType* type = metaDataTypes[iMethodDef];
|
||||
return (const char*)imageBase + ptrToRva(streamStrings->addr + type->read(methodDef, 3));
|
||||
}
|
||||
|
||||
size_t DotNetFile::getStandAloneSigBlobIndex(unsigned index, void* imageBase) const {
|
||||
void* elem = getMetaDataTableElem(iStandAloneSig, index, imageBase);
|
||||
const MetaDataType* type = metaDataTypes[iStandAloneSig];
|
||||
return type->read(elem, 0);
|
||||
}
|
||||
|
||||
size_t DotNetFile::getNumMethods() const {
|
||||
return metaDataTables[iMethodDef].rows;
|
||||
}
|
||||
|
||||
size_t DotNetFile::rvaToOffset(DWORD rva) const {
|
||||
if (rva < sizeOfHeaders)
|
||||
return rva;
|
||||
|
||||
for (size_t i = 0; i < numSections; i++) {
|
||||
if (rva >= sectionHeaders[i].VirtualAddress && rva < sectionHeaders[i].VirtualAddress + sectionHeaders[i].SizeOfRawData)
|
||||
return rva - sectionHeaders[i].VirtualAddress + sectionHeaders[i].PointerToRawData;
|
||||
}
|
||||
|
||||
throw strex("RVA is not part of file");
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DOTNETFILE_H
|
||||
#define DOTNETFILE_H
|
||||
|
||||
#include <Windows.h>
|
||||
#include <WinNT.h>
|
||||
#include <CorHdr.h>
|
||||
#include <stdio.h>
|
||||
#include "strex.h"
|
||||
|
||||
enum MetaDataIndex {
|
||||
iModule = 0,
|
||||
iTypeRef = 1,
|
||||
iTypeDef = 2,
|
||||
iField = 4,
|
||||
iMethodDef = 6,
|
||||
iParam = 8,
|
||||
iInterfaceImpl = 9,
|
||||
iMemberRef = 10,
|
||||
iConstant = 11,
|
||||
iCustomAttribute = 12,
|
||||
iFieldMarshal = 13,
|
||||
iDeclSecurity = 14,
|
||||
iClassLayout = 15,
|
||||
iFieldLayout = 16,
|
||||
iStandAloneSig = 17,
|
||||
iEventMap = 18,
|
||||
iEvent = 20,
|
||||
iPropertyMap = 21,
|
||||
iProperty = 23,
|
||||
iMethodSemantics = 24,
|
||||
iMethodImpl = 25,
|
||||
iModuleRef = 26,
|
||||
iTypeSpec = 27,
|
||||
iImplMap = 28,
|
||||
iFieldRVA = 29,
|
||||
iAssembly = 32,
|
||||
iAssemblyProcessor = 33,
|
||||
iAssemblyOS = 34,
|
||||
iAssemblyRef = 35,
|
||||
iAssemblyRefProcessor = 36,
|
||||
iAssemblyRefOS = 37,
|
||||
iFile = 38,
|
||||
iExportedType = 39,
|
||||
iManifestResource = 40,
|
||||
iNestedClass = 41,
|
||||
iGenericParam = 42,
|
||||
iGenericParamConstraint = 44,
|
||||
};
|
||||
|
||||
struct Stream {
|
||||
Stream() : addr(0), size(0), name(0) {}
|
||||
~Stream() {
|
||||
if (name)
|
||||
free((void*)name);
|
||||
}
|
||||
|
||||
void init(unsigned char* addr, size_t size, const char* name) {
|
||||
this->addr = addr;
|
||||
this->size = size;
|
||||
this->name = _strdup(name);
|
||||
}
|
||||
|
||||
unsigned char* addr;
|
||||
size_t size;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
struct MetaDataTable {
|
||||
MetaDataTable() : addr(0), rows(0) {}
|
||||
unsigned char* addr;
|
||||
size_t rows;
|
||||
};
|
||||
|
||||
struct MetaDataField {
|
||||
unsigned short offset;
|
||||
unsigned short size;
|
||||
};
|
||||
|
||||
class MetaDataType {
|
||||
public:
|
||||
MetaDataType(const MetaDataField* _fields, size_t _numFields)
|
||||
: totalSize(0), numFields(_numFields), fields(0) {
|
||||
fields = new MetaDataField[numFields];
|
||||
for (size_t i = 0; i < numFields; i++) {
|
||||
fields[i] = _fields[i];
|
||||
totalSize += fields[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
~MetaDataType() {
|
||||
if (fields)
|
||||
delete[] fields;
|
||||
}
|
||||
|
||||
size_t size() const { return totalSize; }
|
||||
|
||||
size_t read(void* addr, size_t field) const {
|
||||
if (field >= numFields)
|
||||
throw strex("Invalid field index");
|
||||
void* p = (unsigned char*)addr + fields[field].offset;
|
||||
switch (fields[field].size) {
|
||||
case 1: return *(unsigned char*)p; break;
|
||||
case 2: return *(unsigned short*)p; break;
|
||||
case 4: return *(unsigned int*)p; break;
|
||||
default: throw strex("Invalid field size");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
MetaDataType(const MetaDataType&);
|
||||
MetaDataType& operator=(const MetaDataType&);
|
||||
|
||||
size_t totalSize;
|
||||
size_t numFields;
|
||||
MetaDataField* fields;
|
||||
};
|
||||
|
||||
class DotNetFile {
|
||||
public:
|
||||
DotNetFile(const wchar_t* filename);
|
||||
~DotNetFile();
|
||||
|
||||
bool isYourImageBase(void* addr) const;
|
||||
void* getMethodHeader(unsigned index, void* imageBase = 0) const;
|
||||
const char* getMethodName(unsigned index, void* imageBase = 0) const;
|
||||
void* getMethodDef(unsigned index, void* imageBase) const;
|
||||
size_t getNumMethods() const;
|
||||
const MetaDataType* getMethodType() const { return metaDataTypes[iMethodDef]; }
|
||||
const MetaDataType* getType(MetaDataIndex t) const { return metaDataTypes[t]; }
|
||||
size_t getStandAloneSigBlobIndex(unsigned index, void* imageBase) const;
|
||||
|
||||
private:
|
||||
static const size_t METADATA_TYPES = 64;
|
||||
DotNetFile(const DotNetFile&);
|
||||
DotNetFile& operator=(const DotNetFile&);
|
||||
|
||||
void fread(long offset, void* buf, size_t size) const;
|
||||
void fread(void* buf, size_t size) const;
|
||||
void loadImage(const _IMAGE_FILE_HEADER& fileHeader, DWORD imageSize, DWORD headerSize);
|
||||
void loadImage(DWORD rva, DWORD fileOffset, DWORD sizeRawData);
|
||||
void* rvaToPtr(DWORD rva, size_t size) const;
|
||||
size_t ptrToRva(void* addr) const;
|
||||
size_t rvaToOffset(DWORD rva) const;
|
||||
void* metaOffsToAddr(DWORD offs, DWORD size) const;
|
||||
void initStreams();
|
||||
Stream* findStream(const char* name) const;
|
||||
void initMetadataTables();
|
||||
void* getMetaDataTableElem(MetaDataIndex metaIndex, unsigned index, void* imageBase) const;
|
||||
|
||||
FILE* file;
|
||||
_IMAGE_SECTION_HEADER* sectionHeaders;
|
||||
size_t numSections;
|
||||
unsigned char* image;
|
||||
size_t imageSize;
|
||||
size_t sizeOfHeaders;
|
||||
IMAGE_COR20_HEADER* cor20Header;
|
||||
unsigned char* metadata;
|
||||
Stream* streams;
|
||||
size_t numStreams;
|
||||
Stream* streamTilde;
|
||||
Stream* streamBlob;
|
||||
Stream* streamStrings;
|
||||
MetaDataTable metaDataTables[METADATA_TYPES];
|
||||
MetaDataType* metaDataTypes[METADATA_TYPES];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MAKE_WRITABLE_H
|
||||
#define MAKE_WRITABLE_H
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
class MakeWritable {
|
||||
public:
|
||||
MakeWritable(void* _addr, size_t _size) : addr(_addr), size(_size) {
|
||||
VirtualProtect(addr, size, PAGE_READWRITE, &oldProtect);
|
||||
}
|
||||
~MakeWritable() {
|
||||
VirtualProtect(addr, size, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
private:
|
||||
void* addr;
|
||||
size_t size;
|
||||
DWORD oldProtect;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
|
||||
void dumpMem(void* mem, int size, const char* msg) {
|
||||
unsigned char* p = (unsigned char*)mem;
|
||||
|
||||
logvv("\nDUMP %08X (%d) - %s\n", p, size, msg);
|
||||
while (size > 0) {
|
||||
logvv("%08X", p);
|
||||
for (int j = 0; j < 16 && size > 0; j++, size--)
|
||||
logvv(" %02X", *p++);
|
||||
logvv("\n");
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#define ALIGNIT(v, a) (((v)+(a)-1)/(a)*(a))
|
||||
#define ALIGN_DOWN(a, v) ((a) & ~((v)-1))
|
||||
#define IS_ALIGNED(v, a) (((v) & ((a)-1)) == 0)
|
||||
#define NUM_ELEMS(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
extern void dumpMem(void* mem, int size, const char* msg = "");
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID) {
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -1,598 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <metahost.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <vector>
|
||||
#include "DotNetFile.h"
|
||||
#include "MakeWritable.h"
|
||||
#include "DllAlloc.h"
|
||||
#include "strex.h"
|
||||
#include "log.h"
|
||||
#include "common.h"
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct CORINFO_METHOD_INFO {
|
||||
void* ftn;
|
||||
void* scope;
|
||||
unsigned char* ILCode;
|
||||
unsigned ILCodeSize;
|
||||
unsigned short maxStack;
|
||||
unsigned short EHcount;
|
||||
char other[0x64];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct ScopeInfo {
|
||||
void* imageBase;
|
||||
CORINFO_METHOD_INFO cmi;
|
||||
};
|
||||
|
||||
static const unsigned int DUMPED_METHODS_HEADER_MAGIC = 0x12345678;
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct DumpedMethodsHeader {
|
||||
unsigned int magic;
|
||||
unsigned int numMethods;
|
||||
};
|
||||
|
||||
struct DumpedMethod {
|
||||
// method header fields
|
||||
unsigned short mhFlags; // method header Flags
|
||||
unsigned short mhMaxStack; // method header MaxStack
|
||||
unsigned int mhCodeSize; // method header CodeSize
|
||||
unsigned int mhLocalVarSigTok; // method header LocalVarSigTok
|
||||
|
||||
// methodDef fields
|
||||
unsigned short mdImplFlags; // methodDef ImplFlags
|
||||
unsigned short mdFlags; // methodDef Flags
|
||||
unsigned int mdName; // methodDef Name (index into #String)
|
||||
unsigned int mdSignature; // methodDef Signature (index into #Blob)
|
||||
unsigned int mdParamList; // methodDef ParamList (index into Param table)
|
||||
|
||||
// Misc
|
||||
unsigned int token; // metadata token
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
void hookCompileMethod();
|
||||
const ScopeInfo* findDotNetAssembly(const DotNetFile* dotNetFile);
|
||||
|
||||
DotNetFile* dotNetFile = 0;
|
||||
DllAlloc* dllAlloc = 0;
|
||||
HMODULE hJitDll = 0; // eg. HMODULE of "clrjit.dll"
|
||||
void* dotNetAssemblyBase = 0; // Image base of .NET assembly we should dump
|
||||
CORINFO_METHOD_INFO defaultCmi;
|
||||
std::wstring inputFilename; // Path of input file
|
||||
|
||||
typedef void* (__stdcall *getJit_t)(void);
|
||||
typedef int (__stdcall* compileMethod_t)(void* self, void* comp,
|
||||
CORINFO_METHOD_INFO* info, unsigned flags, BYTE** nativeEntry,
|
||||
ULONG* nativeSizeOfCode);
|
||||
compileMethod_t original_compileMethod = 0;
|
||||
compileMethod_t ourObfuscatedCompileMethod = 0;
|
||||
getJit_t getJit_func = 0;
|
||||
|
||||
struct MyCorinfoMethodInfo {
|
||||
static const int SIG = 0xFA149C31;
|
||||
|
||||
MyCorinfoMethodInfo(const CORINFO_METHOD_INFO& _cmi)
|
||||
: cmi(_cmi), sig(SIG) {
|
||||
}
|
||||
|
||||
CORINFO_METHOD_INFO cmi; // Must be first field
|
||||
void* data;
|
||||
int sig; // Always SIG so we know when we're dumping methods
|
||||
};
|
||||
|
||||
struct DumpMethodContext {
|
||||
DumpMethodContext() : f(0), numMethods(0) {}
|
||||
~DumpMethodContext() {
|
||||
if (f)
|
||||
fclose(f);
|
||||
}
|
||||
FILE* f;
|
||||
unsigned numMethods;
|
||||
unsigned token;
|
||||
const char* name;
|
||||
size_t methodHeaderRva;
|
||||
unsigned char* methodHeader;
|
||||
size_t headerSize;
|
||||
void* methodBody;
|
||||
unsigned LocalVarSigTok;
|
||||
unsigned short flags;
|
||||
void* methodDef;
|
||||
const MetaDataType* type;
|
||||
};
|
||||
|
||||
getJit_t getGetJitFunc() {
|
||||
getJit_t getJit_func = (getJit_t)GetProcAddress(hJitDll, "getJit");
|
||||
if (!getJit_func)
|
||||
throw strex("Could not get address of getJit() function");
|
||||
return getJit_func;
|
||||
}
|
||||
|
||||
static const char* wtoa(const wchar_t* s) {
|
||||
static char buf[8*1024];
|
||||
int i = 0;
|
||||
do {
|
||||
if (i >= sizeof(buf))
|
||||
throw strex("Buffer overflow in wtoa");
|
||||
buf[i] = (char)s[i];
|
||||
i++;
|
||||
} while (s[i] != 0);
|
||||
return buf;
|
||||
}
|
||||
|
||||
HMODULE getJitDllModule() {
|
||||
#if 0
|
||||
ICLRMetaHost* mh;
|
||||
if (CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&mh) != S_OK)
|
||||
throw strex("Could not get ref to CLRMetaHost");
|
||||
ICLRRuntimeInfo* rtti;
|
||||
// Version must match a version dir in %WINDIR%\Microsoft.NET\Framework
|
||||
if (mh->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&rtti) != S_OK)
|
||||
throw strex("Could not get ref to ICLRRuntimeInfo");
|
||||
HMODULE hClr;
|
||||
if (rtti->LoadLibrary(L"clrjit.dll", &hClr) != S_OK)
|
||||
throw strex("Could not load JIT dll file");
|
||||
return hClr;
|
||||
#else
|
||||
HMODULE hClr = LoadLibraryW(L"clrjit.dll");
|
||||
if (hClr != 0) {
|
||||
logv("Loaded CLR JIT DLL %s\n", "clrjit.dll");
|
||||
return hClr;
|
||||
}
|
||||
wchar_t name[1024];
|
||||
DWORD size = sizeof(name);
|
||||
DWORD len;
|
||||
if (GetCORSystemDirectory(name, size, &len) != S_OK)
|
||||
throw strex("Could not get CLR installation directory");
|
||||
wcscat(name, L"mscorjit.dll");
|
||||
hClr = LoadLibraryW(name);
|
||||
if (hClr != 0) {
|
||||
logv("Loaded CLR JIT DLL %s\n", wtoa(name));
|
||||
return hClr;
|
||||
}
|
||||
throw strex("Could not load JIT DLL");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns base addr or NULL
|
||||
void* findModule(void* addr) {
|
||||
HANDLE hSnap;
|
||||
for (;;) {
|
||||
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
|
||||
if (hSnap != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
if (GetLastError() != ERROR_BAD_LENGTH)
|
||||
break;
|
||||
}
|
||||
if (hSnap == INVALID_HANDLE_VALUE)
|
||||
throw strex("Could not get module snapshot");
|
||||
|
||||
MODULEENTRY32 me32;
|
||||
me32.dwSize = sizeof(me32);
|
||||
void* baseAddr = 0;
|
||||
for (BOOL res = Module32First(hSnap, &me32); res; res = Module32Next(hSnap, &me32)) {
|
||||
if (me32.modBaseAddr <= addr && addr <= me32.modBaseAddr + me32.modBaseSize - 1) {
|
||||
baseAddr = me32.modBaseAddr;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hSnap);
|
||||
return baseAddr;
|
||||
}
|
||||
|
||||
bool hasProtectionHookedJit() {
|
||||
compileMethod_t* jit_vtbl = *(compileMethod_t**)getJit_func();
|
||||
return *jit_vtbl != ourObfuscatedCompileMethod;
|
||||
}
|
||||
|
||||
// Used only by the following two methods
|
||||
static const char* dump_methodName = 0;
|
||||
static unsigned dump_token = 0;
|
||||
const char* __stdcall returnNameOfMethod(void* arg1, void* arg2, void* arg3) {
|
||||
(void)arg1; (void)arg2; (void)arg3;
|
||||
return dump_methodName;
|
||||
}
|
||||
|
||||
unsigned __stdcall returnMethodToken(void* arg1, void* arg2) {
|
||||
(void)arg1; (void)arg2;
|
||||
return dump_token;
|
||||
}
|
||||
|
||||
bool dumpMethodIndex(unsigned index, DumpMethodContext* ctx) {
|
||||
dump_token = 0x06000000 + index;
|
||||
dump_methodName = dotNetFile->getMethodName(index, dotNetAssemblyBase);
|
||||
logvv("\n========================================================\n");
|
||||
logvv("Method name: '%s' (%08X), token: %08X\n", dump_methodName, dump_methodName, dump_token);
|
||||
|
||||
unsigned char* methodHeader = (unsigned char*)dotNetFile->getMethodHeader(index, dotNetAssemblyBase);
|
||||
if (!methodHeader)
|
||||
throw strex("Could not get method header");
|
||||
if (methodHeader != dotNetAssemblyBase)
|
||||
dumpMem(methodHeader, 16, "methodHeader");
|
||||
|
||||
size_t headerSize, codeSize, LocalVarSigTok, methodHeaderRva;
|
||||
unsigned short maxStack, flags;
|
||||
void* methodBody;
|
||||
if (methodHeader == dotNetAssemblyBase) {
|
||||
headerSize = 0;
|
||||
maxStack = 0;
|
||||
codeSize = 0;
|
||||
flags = 0;
|
||||
LocalVarSigTok = 0;
|
||||
methodBody = 0;
|
||||
methodHeaderRva = 0;
|
||||
}
|
||||
else if ((*methodHeader & 3) == 2) { // Tiny header
|
||||
headerSize = 1;
|
||||
maxStack = 8;
|
||||
codeSize = *methodHeader >> 2;
|
||||
flags = 2;
|
||||
LocalVarSigTok = 0;
|
||||
methodBody = methodHeader + headerSize;
|
||||
methodHeaderRva = methodHeader - (unsigned char*)dotNetAssemblyBase;
|
||||
}
|
||||
else { // Fat header
|
||||
headerSize = (methodHeader[1] >> 4) * 4;
|
||||
maxStack = *(unsigned short*)(methodHeader + 2);
|
||||
codeSize = *(unsigned int*)(methodHeader + 4);
|
||||
flags = *(WORD*)methodHeader;
|
||||
LocalVarSigTok = *(DWORD*)(methodHeader + 8);
|
||||
methodBody = methodHeader + headerSize;
|
||||
methodHeaderRva = methodHeader - (unsigned char*)dotNetAssemblyBase;
|
||||
}
|
||||
|
||||
ctx->token = dump_token;
|
||||
ctx->name = dump_methodName;
|
||||
ctx->methodHeaderRva = methodHeaderRva;
|
||||
ctx->methodHeader = methodHeader;
|
||||
ctx->headerSize = headerSize;
|
||||
ctx->methodBody = methodBody;
|
||||
ctx->flags = flags;
|
||||
ctx->LocalVarSigTok = LocalVarSigTok;
|
||||
ctx->methodDef = dotNetFile->getMethodDef(index, dotNetAssemblyBase);
|
||||
ctx->type = dotNetFile->getMethodType();
|
||||
|
||||
MyCorinfoMethodInfo info = defaultCmi;
|
||||
info.data = ctx;
|
||||
info.cmi.ILCode = (BYTE*)methodBody;
|
||||
info.cmi.ILCodeSize = codeSize;
|
||||
info.cmi.maxStack = maxStack;
|
||||
|
||||
void* mem[0x10];
|
||||
memset(mem, 0, sizeof(mem));
|
||||
mem[1] = &mem[2];
|
||||
mem[3] = (void*)0x14;
|
||||
mem[5] = (void*)0x1C;
|
||||
mem[6] = &mem[7];
|
||||
mem[7] = returnNameOfMethod;
|
||||
mem[8] = &mem[0];
|
||||
mem[13] = returnMethodToken; // Older .NET version
|
||||
mem[14] = returnMethodToken; // Newer .NET version
|
||||
|
||||
void* self = getJit_func();
|
||||
BYTE* nativeEntry = 0;
|
||||
ULONG nativeSizeOfCode = 0;
|
||||
void* comp = mem;
|
||||
compileMethod_t compileMethod = **(compileMethod_t**)self;
|
||||
logvv("Calling protection to decrypt code, scope: %08X, token: %08X\n", info.cmi.scope, dump_token);
|
||||
compileMethod(self, comp, &info.cmi, 0, &nativeEntry, &nativeSizeOfCode);
|
||||
logvv("Calling protection to decrypt code: DONE\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) int __stdcall dumpCode(const wchar_t* methodsFilename) {
|
||||
try {
|
||||
if (!hasProtectionHookedJit()) {
|
||||
// CliSecure sometimes fails to load for an unknown reason. It happens rarely, but
|
||||
// it doesn't seem to happen when I use .NET 2.0, only 4.0.
|
||||
loge("Protection hasn't hooked JIT yet! Try again or try .NET != 4.0!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::wstring name(inputFilename + L".methods");
|
||||
if (methodsFilename != 0 && *methodsFilename != 0)
|
||||
name = methodsFilename;
|
||||
|
||||
DumpMethodContext ctx;
|
||||
ctx.f = _wfopen(name.c_str(), L"wb");
|
||||
if (!ctx.f)
|
||||
throw strex("Could not create methods file");
|
||||
|
||||
DumpedMethodsHeader header = {0};
|
||||
header.magic = DUMPED_METHODS_HEADER_MAGIC;
|
||||
|
||||
if (fwrite(&header, 1, sizeof(header), ctx.f) != sizeof(header))
|
||||
throw strex("Could not write to dumped methods file");
|
||||
|
||||
const size_t numMethods = dotNetFile->getNumMethods(); (void)numMethods;
|
||||
for (size_t i = 1; i <= numMethods; i++)
|
||||
dumpMethodIndex(i, &ctx);
|
||||
|
||||
if (fseek(ctx.f, 0, SEEK_SET))
|
||||
throw strex("Could not seek #3");
|
||||
header.numMethods = ctx.numMethods;
|
||||
if (fwrite(&header, 1, sizeof(header), ctx.f) != sizeof(header))
|
||||
throw strex("Could not write to dumped methods file");
|
||||
}
|
||||
catch (std::exception& ex) {
|
||||
loge("EXCEPTION #3: %s\n", ex.what());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define PE_ALIGNMENT 0x10000
|
||||
|
||||
bool isPeImage(void* addr) {
|
||||
__try {
|
||||
if (!addr)
|
||||
return false;
|
||||
if (!IS_ALIGNED((size_t)addr, PE_ALIGNMENT))
|
||||
return false;
|
||||
|
||||
unsigned char* p = (unsigned char*)addr;
|
||||
IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)p;
|
||||
if (idh->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return false;
|
||||
p += idh->e_lfanew;
|
||||
if (*(DWORD*)p != IMAGE_NT_SIGNATURE)
|
||||
return false;
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void* __getImagebase1(void* addr) {
|
||||
HMODULE hMod;
|
||||
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)addr, &hMod) == 0)
|
||||
return 0;
|
||||
return (void*)hMod;
|
||||
}
|
||||
|
||||
static void* __getImagebase2(void* addr) {
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
if (VirtualQuery(addr, &mbi, sizeof(mbi)) == 0)
|
||||
return 0;
|
||||
return mbi.AllocationBase;
|
||||
}
|
||||
|
||||
static void* __getImagebase3(void* addr) {
|
||||
size_t offs = ALIGN_DOWN((size_t)addr, PE_ALIGNMENT);
|
||||
for ( ; offs; offs -= PE_ALIGNMENT) {
|
||||
if (IsBadReadPtr((const void*)offs, 1))
|
||||
return 0; // A PE image shouldn't have empty holes >= PE_ALIGNMENT
|
||||
if (isPeImage((void*)offs))
|
||||
return (void*)offs;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* filterImageBase(void* addr) {
|
||||
if (isPeImage(addr))
|
||||
return addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* findImageBase(void* addr) {
|
||||
void* imageBase = 0;
|
||||
if (imageBase == 0)
|
||||
imageBase = filterImageBase(findModule(addr));
|
||||
if (imageBase == 0)
|
||||
imageBase = filterImageBase(__getImagebase1(addr));
|
||||
if (imageBase == 0)
|
||||
imageBase = filterImageBase(__getImagebase2(addr));
|
||||
if (imageBase == 0)
|
||||
imageBase = filterImageBase(__getImagebase3(addr));
|
||||
return imageBase;
|
||||
}
|
||||
|
||||
std::vector<ScopeInfo> imageBases;
|
||||
|
||||
void addImageBase(void* imageBase, const CORINFO_METHOD_INFO* info) {
|
||||
if (!imageBase)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < imageBases.size(); i++) {
|
||||
if (imageBases[i].imageBase == imageBase) {
|
||||
if (imageBases[i].cmi.scope != info->scope)
|
||||
logw("===WARNING=== new scope but same imageBase! %08X vs %08X\n", imageBases[i].cmi.scope, info->scope);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
logv("%d. Added imageBase %08X\n", imageBases.size() + 1, imageBase);
|
||||
ScopeInfo si;
|
||||
si.cmi = *info;
|
||||
si.imageBase = imageBase;
|
||||
imageBases.push_back(si);
|
||||
}
|
||||
|
||||
const ScopeInfo* findDotNetAssembly(const DotNetFile* dotNetFile) {
|
||||
for (size_t i = 0; i < imageBases.size(); i++) {
|
||||
if (dotNetFile->isYourImageBase(imageBases[i].imageBase)) {
|
||||
return &imageBases[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __stdcall myCompileMethod(void* self, void* comp,
|
||||
CORINFO_METHOD_INFO* info, unsigned flags, BYTE** nativeEntry,
|
||||
ULONG* nativeSizeOfCode) {
|
||||
|
||||
if (((MyCorinfoMethodInfo*)info)->sig == MyCorinfoMethodInfo::SIG) {
|
||||
// We're dumping methods
|
||||
|
||||
logvv("code: %08X, size: %08X, maxStack: %04X\n", info->ILCode, info->ILCodeSize, info->maxStack);
|
||||
|
||||
DumpMethodContext* ctx = (DumpMethodContext*)((MyCorinfoMethodInfo*)info)->data;
|
||||
dumpMem(info->ILCode, info->ILCodeSize, "ILCode");
|
||||
dumpMem(ctx->methodDef, ctx->type->size(), "methodDef table");
|
||||
if (ctx->methodHeader)
|
||||
dumpMem(ctx->methodHeader, 16, "method header");
|
||||
|
||||
DumpedMethod dm;
|
||||
|
||||
dm.mhFlags = ctx->flags;
|
||||
dm.mhMaxStack = info->maxStack;
|
||||
dm.mhCodeSize = info->ILCodeSize;
|
||||
dm.mhLocalVarSigTok = ctx->LocalVarSigTok;
|
||||
|
||||
dm.mdImplFlags = (unsigned short)ctx->type->read(ctx->methodDef, 1);
|
||||
dm.mdFlags = (unsigned short)ctx->type->read(ctx->methodDef, 2);
|
||||
dm.mdName = ctx->type->read(ctx->methodDef, 3);
|
||||
dm.mdSignature = ctx->type->read(ctx->methodDef, 4);
|
||||
dm.mdParamList = ctx->type->read(ctx->methodDef, 5);
|
||||
|
||||
dm.token = ctx->token;
|
||||
|
||||
dumpMem(&dm, sizeof(dm), "DumpedMethod");
|
||||
|
||||
if (fwrite(&dm, 1, sizeof(dm), ctx->f) != sizeof(dm))
|
||||
throw strex("Could not write DumpedMethod");
|
||||
if (fwrite(info->ILCode, 1, info->ILCodeSize, ctx->f) != info->ILCodeSize)
|
||||
throw strex("Could not write ILCode");
|
||||
|
||||
ctx->numMethods++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
void* imageBase = findImageBase(info->ILCode);
|
||||
addImageBase(imageBase, info);
|
||||
logvv("myCompileMethod: called. %08X (%3d), base: %08X, info: %08X, scope: %08X\n", info->ILCode, info->ILCodeSize, imageBase, info, info->scope);
|
||||
|
||||
return original_compileMethod(self, comp, info, flags, nativeEntry, nativeSizeOfCode);
|
||||
}
|
||||
}
|
||||
|
||||
// dest => memory to write to (start of method). Must be HOOK_METHOD_SIZE bytes.
|
||||
// destFunc => the real func we should execute
|
||||
void createHookMethod(void* dest, void* destFunc) {
|
||||
/*
|
||||
* Obfuscate the code a little bit just in case a protection checks
|
||||
* for JMP XYZ.
|
||||
* B8 xx xx xx xx mov eax, xxxxxxxx
|
||||
* 2D xx xx xx xx sub eax, xxxxxxxx
|
||||
* 50 push eax
|
||||
* C3 retn
|
||||
*/
|
||||
#define HOOK_METHOD_SIZE 12
|
||||
|
||||
const size_t offs = (size_t)destFunc;
|
||||
unsigned char* p = (unsigned char*)dest;
|
||||
*p++ = 0xB8;
|
||||
*(DWORD*)p = offs + 0xC0DEBEEF;
|
||||
p += 4;
|
||||
*p++ = 0x2D;
|
||||
*(DWORD*)p = 0xC0DEBEEF;
|
||||
p += 4;
|
||||
*p++ = 0x50;
|
||||
*p++ = 0xC3;
|
||||
}
|
||||
|
||||
void hookCompileMethod() {
|
||||
ourObfuscatedCompileMethod = (compileMethod_t)dllAlloc->alloc(HOOK_METHOD_SIZE);
|
||||
{
|
||||
MakeWritable dummy(ourObfuscatedCompileMethod, HOOK_METHOD_SIZE);
|
||||
createHookMethod(ourObfuscatedCompileMethod, myCompileMethod);
|
||||
}
|
||||
|
||||
getJit_func = getGetJitFunc();
|
||||
compileMethod_t* jit_vtbl = *(compileMethod_t**)getJit_func();
|
||||
original_compileMethod = *jit_vtbl;
|
||||
{
|
||||
MakeWritable dummy(jit_vtbl, sizeof(void*));
|
||||
*jit_vtbl = ourObfuscatedCompileMethod;
|
||||
}
|
||||
logv("Original compileMethod: %p\n", original_compileMethod);
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) int __stdcall initialize1(int logLevel, const wchar_t* filename) {
|
||||
static bool initialized = false;
|
||||
int ret = 1;
|
||||
if (!initialized) {
|
||||
try {
|
||||
setLogLevel(logLevel);
|
||||
|
||||
hJitDll = getJitDllModule();
|
||||
|
||||
dllAlloc = new DllAlloc(hJitDll);
|
||||
hookCompileMethod();
|
||||
|
||||
inputFilename = filename;
|
||||
dotNetFile = new DotNetFile(filename);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
catch (std::exception& ex) {
|
||||
loge("EXCEPTION #1: %s\n", ex.what());
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) int __stdcall initialize2() {
|
||||
static bool initialized = false;
|
||||
int ret = 1;
|
||||
if (!initialized) {
|
||||
try {
|
||||
const ScopeInfo* si = findDotNetAssembly(dotNetFile);
|
||||
if (!si)
|
||||
throw strex("Could not find .NET assembly's image base");
|
||||
dotNetAssemblyBase = si->imageBase;
|
||||
defaultCmi = si->cmi;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
catch (std::exception& ex) {
|
||||
loge("EXCEPTION #2: %s\n", ex.what());
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) int __stdcall foundAssembly() {
|
||||
return findDotNetAssembly(dotNetFile) != 0;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void __stdcall debug_addImageBase(void* imageBase) {
|
||||
CORINFO_METHOD_INFO info = {0};
|
||||
addImageBase(imageBase, &info);
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{3D97F8AF-494F-4AB2-82ED-E1BE532E4CB9}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>dumpMethodsN</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;USE_DEPRECATED_CLR_API_WITHOUT_WARNING;_DEBUG;_WINDOWS;_USRDLL;DOTNETDUMPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>
|
||||
</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;MSCorEE.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;USE_DEPRECATED_CLR_API_WITHOUT_WARNING;NDEBUG;_WINDOWS;_USRDLL;DOTNETDUMPER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>
|
||||
</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;MSCorEE.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="common.h" />
|
||||
<ClInclude Include="DllAlloc.h" />
|
||||
<ClInclude Include="DotNetFile.h" />
|
||||
<ClInclude Include="log.h" />
|
||||
<ClInclude Include="MakeWritable.h" />
|
||||
<ClInclude Include="strex.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="common.cpp" />
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dumpMethodsN.cpp" />
|
||||
<ClCompile Include="DotNetFile.cpp" />
|
||||
<ClCompile Include="log.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,50 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DotNetFile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="strex.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MakeWritable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DllAlloc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="log.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DotNetFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="common.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="log.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dumpMethodsN.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "log.h"
|
||||
|
||||
enum {
|
||||
error,
|
||||
warning,
|
||||
normal,
|
||||
verbose,
|
||||
veryverbose,
|
||||
};
|
||||
|
||||
static int logLevel = normal;
|
||||
|
||||
void setLogLevel(int level) {
|
||||
logLevel = level;
|
||||
}
|
||||
|
||||
static void log(int level, const char* format, va_list valist) {
|
||||
if (level <= logLevel)
|
||||
vprintf(format, valist);
|
||||
}
|
||||
|
||||
void loge(const char* format, ...) {
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
log(error, format, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void logw(const char* format, ...) {
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
log(warning, format, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void logn(const char* format, ...) {
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
log(normal, format, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void logv(const char* format, ...) {
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
log(verbose, format, argptr);
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void logvv(const char* format, ...) {
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
log(veryverbose, format, argptr);
|
||||
va_end(argptr);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
void setLogLevel(int level);
|
||||
void loge(const char* format, ...);
|
||||
void logw(const char* format, ...);
|
||||
void logn(const char* format, ...);
|
||||
void logv(const char* format, ...);
|
||||
void logvv(const char* format, ...);
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2011 de4dot@gmail.com
|
||||
|
||||
This file is part of de4dot.
|
||||
|
||||
de4dot is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
de4dot is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef STREX_H
|
||||
#define STREX_H
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
class strex : public std::exception {
|
||||
public:
|
||||
strex(std::string str) : s(str) {}
|
||||
const char* what() const throw() { return s.c_str(); }
|
||||
private:
|
||||
std::string s;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user