Fixed a bug reported by icy. It was causing crashes in executables without sections when calculating their PE size.
Tag: CFF Explorer
.NET MetaData Tables Reports
I updated the scripting language of the old CFF Explorer which now provides a function to automatically create reports of .NET metadata tables. The function is called LogPrintStruct and is to be used along with the logging functions the scripting provides. Here’s a small script you can find in the “Scripts” directory of the CFF Explorer which creates a report of all .NET tables contained in an assembly:
[cc lang=”lua”]– this script generates a report of a PE’s .NET metadata tables.
filename = GetOpenFile(“Open…”, “All\n*.*\nexe\n*.exe\ndll\n*.dll\n”)
if filename == null then
return
end
hPE = OpenFile(filename)
if hPE == null then
return
end
if GetOffset(hPE, PE_DotNETDirectory) == null then
MsgBox(“The current is not a valid .NET assembly.”, “Error”, MB_ICONEXCLAMATION)
end
repname = GetSaveFile(“Save Report As..”, “Text File\n*.txt\n”)
if repname == null then
return
end
hReport = CreateLog(repname)
if hReport == null then
return
end
fieldsToLog = {
PE_MetaDataTable_Module,
PE_MetaDataTable_TypeRef,
PE_MetaDataTable_TypeDef,
PE_MetaDataTable_Field,
PE_MetaDataTable_Method,
PE_MetaDataTable_Param,
PE_MetaDataTable_InterfaceImpl,
PE_MetaDataTable_MemberRef,
PE_MetaDataTable_Constant,
PE_MetaDataTable_CustomAttribute,
PE_MetaDataTable_FieldMarshal,
PE_MetaDataTable_DeclSecurity,
PE_MetaDataTable_ClassLayout,
PE_MetaDataTable_FieldLayout,
PE_MetaDataTable_StandAloneSig,
PE_MetaDataTable_EventMap,
PE_MetaDataTable_Event,
PE_MetaDataTable_PropertyMap,
PE_MetaDataTable_Property,
PE_MetaDataTable_MethodSemantics,
PE_MetaDataTable_MethodImpl,
PE_MetaDataTable_ModuleRef,
PE_MetaDataTable_TypeSpec,
PE_MetaDataTable_ImplMap,
PE_MetaDataTable_FieldRVA,
PE_MetaDataTable_Assembly,
PE_MetaDataTable_AssemblyProcessor,
PE_MetaDataTable_AssemblyOS,
PE_MetaDataTable_AssemblyRef,
PE_MetaDataTable_AssemblyRefProcessor,
PE_MetaDataTable_AssemblyRefOS,
PE_MetaDataTable_File,
PE_MetaDataTable_ExportedType,
PE_MetaDataTable_ManifestResource,
PE_MetaDataTable_NestedClass,
PE_MetaDataTable_GenericParam,
PE_MetaDataTable_MethodSpec,
PE_MetaDataTable_GenericParamConstraint
}
fieldNames = {
“Module”,
“TypeRef”,
“TypeDef”,
“Field”,
“Method”,
“Param”,
“InterfaceImpl”,
“MemberRef”,
“Constant”,
“CustomAttribute”,
“FieldMarshal”,
“DeclSecurity”,
“ClassLayout”,
“FieldLayout”,
“StandAloneSig”,
“EventMap”,
“Event”,
“PropertyMap”,
“Property”,
“MethodSemantics”,
“MethodImpl”,
“ModuleRef”,
“TypeSpec”,
“ImplMap”,
“FieldRVA”,
“Assembly”,
“AssemblyProcessor”,
“AssemblyOS”,
“AssemblyRef”,
“AssemblyRefProcessor”,
“AssemblyRefOS”,
“File”,
“ExportedType”,
“ManifestResource”,
“NestedClass”,
“GenericParam”,
“MethodSpec”,
“GenericParamConstraint”
}
LogPrint(hReport, “.NET metadata tables report for \”” .. filename .. “\”\n\n”)
loggedTables = 0
for i = 0, #fieldsToLog – 1 do
if GetOffset(hPE, fieldsToLog[i]) != null then
if loggedTables > 0 then
LogPrint(hReport, “\n\n\n”)
end
LogPrint(hReport, fieldNames[i] .. ” Table\n”)
LogPrint(hReport, “———————————————\n\n”)
LogPrintStruct(hPE, hReport, fieldsToLog[i])
loggedTables = loggedTables + 1
end
end
— Open the report?
CloseLog(hReport)
nRet = MsgBox(“Open report file?”, “.NET Tables Report”, MB_ICONQUESTION | MB_YESNO)
if nRet == IDYES then
ExecuteAppAndWait(@”C:\Windows\System32\notepad.exe”, GetShortPathName(repname))
end[/cc]
A generated report file looks like this:
[cc lang=”asm”].NET metadata tables report for “K:\Explorer Suite\Setup\Signature Explorer.exe”
Module Table
———————————————
1.
Generation: 0
Name: 1 (Signature Explorer.exe)
Mvid: 1
EncId: 0
EncBaseId: 0
TypeRef Table
———————————————
1.
ResolutionScope: 6
Name: 18 (Control)
Namespace: 20 (System.Windows.Forms)
2.
ResolutionScope: A
Name: 35 (Enum)
Namespace: 3A (System)
3.
ResolutionScope: 6
Name: 41 (Button)
Namespace: 20 (System.Windows.Forms)
4.
ResolutionScope: 6
Name: 48 (Form)
Namespace: 20 (System.Windows.Forms)
5.
ResolutionScope: A
Name: 4D (Object)
Namespace: 3A (System)
6.
ResolutionScope: A
Name: 54 (ValueType)
Namespace: 3A (System)
etc.[/cc]
I included this new feature because many developers asked me to. Reading the generated report files is much easier than manually reading the raw .NET format. The current scripting system won’t be implemented in the newer CFF Explorer, I only inserted this new feature because it will take me much more time to release the newer CFF Explorer.
Thanks to CodeRipper for signalling a corrupted .NET assembly which caused the CFF Explorer to crash when opening it. I improved the integrity checks.
Data Execution Prevention (NX) flag
As you probably know the DEP (Data Execution Prevention) was introduced in XPSP2 and it prevents code to be executed from data sections.
Let’s consider this code snippet:
[cc lang=”cpp”]unsigned char b = 0xC3; // ret
int _tmain(int argc, _TCHAR* argv[])
{
void *addr = &b;
__asm call addr;
getchar();
return 0;
}[/cc]
This code sample will crash if the DEP is enabled. DEP is a very important security improvement against buffer overlow exploits, but it might be generate incompatibility with older applications which rely on executing code inside the data section.
The DEP can be disabled individually for an executable. The only thing which needs to be done is to unset the “NX Compatibility” flag inside “Optional Header -> Characteristics”.
Make sure to have the latest CFF Explorer release. I also updated the flags of the “Characteristics” field, because they were outdated. Among the new flags there is the ASLR flag (DLL can move), which enables the executable to be relocated at a random (256 possibilities) address if it contains a relocation table.
Both the ASLR and the DEP flag are enabled by default in Visual C++.
Another flag is the “Code Integrity” one. This flag when set checks the digital signature of the executable and runs it only if the signature is correct.
Kernel: 3rd edition
I don’t want to show too much, this is just a small preview. Yes, it’s running on Ubuntu and it runs on OSX just as well.
I don’t know if I’m going to ship a Linux and an OSX version apart from the Windows one, maybe not immediately. It also depends on the number of requests for it.
Some insights into the new kernel:
– The kernel is now stream based, this means it can read files, memory, disks etc.
– Complete multithread support.
– A CFFStream can be shared among CFFObjects even if they’re owned by a different thread.
– The same CFFObject can be shared among threads.
– Complete endianess support: every file format has a default endianess but can be loaded with a different one. For instance: it is possible to load a PE file with all fields in big endian.
– Support for all most common string encodings.
– Support for integer types of infinite size.
– Support for multiple file formats.
– Easily exposable to scripting languages.
There is more and an impressive amount of work has still to be done, although the kernel is about to be finished. I won’t tell all the new features of the GUI, because it’s way too soon.
Multiple Updates
A serious bug in the CFF Explorer, Rebel.NET and Phoenix Protector has been fixed. The bug affected the ExportedType .NET metadata table where the member TypeDefID was declared as a TypeDef index, while it’s a dword. The table is declared correctly in my .NET article, but somehow I wrote the wrong type in the code.
Many thanks to Yaroslav Liulko for reporting the bug.