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
|
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||||
# Visual Studio 2010
|
# 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}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "cecil\Mono.Cecil.csproj", "{D68133BD-1E63-496E-9EDE-4FBDBF77B486}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "de4dot.code", "de4dot.code\de4dot.code.csproj", "{4D10B9EB-3BF1-4D61-A389-CB019E8C9622}"
|
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyServer-x64", "AssemblyServer-x64\AssemblyServer-x64.csproj", "{F458A89A-AEAB-4965-AA4D-393C9F7411D0}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyServer-x64", "AssemblyServer-x64\AssemblyServer-x64.csproj", "{F458A89A-AEAB-4965-AA4D-393C9F7411D0}"
|
||||||
EndProject
|
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}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "blocks", "blocks\blocks.csproj", "{045B96F2-AF80-4C4C-8D27-E38635AC705E}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
|
@ -84,78 +77,6 @@ Global
|
||||||
winphone_Release|x86 = winphone_Release|x86
|
winphone_Release|x86 = winphone_Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
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.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|Any CPU.Build.0 = winphone_Debug|Any CPU
|
||||||
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Mixed Platforms.ActiveCfg = net_2_0_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|Win32.ActiveCfg = Release|x86
|
||||||
{F458A89A-AEAB-4965-AA4D-393C9F7411D0}.winphone_Release|x86.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
|
{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.ActiveCfg = Debug|Any CPU
|
||||||
{045B96F2-AF80-4C4C-8D27-E38635AC705E}.Debug|Any CPU.Build.0 = 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
|
{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