secana / penet Goto Github PK
View Code? Open in Web Editor NEWPortable Executable (PE) library written in .Net
License: Apache License 2.0
Portable Executable (PE) library written in .Net
License: Apache License 2.0
Hi,
I need to I get a list of imported dll from pe by using PeNet (which class and functions can i use).
Regardings Microsoft, the issue with parsing PKCS7 certificates on Linux should be fixed with .NET Core 3.0
Issue: https://github.com/dotnet/corefx/issues/2910#issuecomment-500718982
If the fix is available, it would make sense to switch to .NET Core 3.0 to get rid of PeNet.ASN.
PeFile.IsSignatureValid
returns false
for the attached firefox.exe
(which is from 2012). I didn't look that deep into it, but from a first glance, the reason is that the Authenticode
property is null
.
This package is amazing, but I'm needing a version that is strongly-name to avoid the following errors:
System.IO.FileLoadException: Could not load file or assembly 'PeNet, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)
File name: 'PeNet, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null
I consistently get a null value for the TLSDirectory of multiple PE images that have valid TLS Directories (confirmed through CFF Explorer & my own PE Parser.)
The DllCharacteristics.IMAGE_DLLCHARACTERISTICS_NO_SEH Flag is never set when examining a PE file regardless of whether the PE uses safeseh or not.
It's either that or I am being a moron and not using it correctly. :D
The following code demonstrates the problem, however you will have to supply a non safeseh dll on your system to test with:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var peHeader = new PeNet.PeFile(@"C:\Windows\System32\ntdll.dll"); //try a non safeseh file as well
var File_Characteristics = peHeader.ImageNtHeaders.OptionalHeader.DllCharacteristics;
PeNet.Constants.OptionalHeaderDllCharacteristics safe_seh = (PeNet.Constants.OptionalHeaderDllCharacteristics)File_Characteristics;
if (safe_seh.HasFlag(PeNet.Constants.OptionalHeaderDllCharacteristics.IMAGE_DLLCHARACTERISTICS_NO_SEH))
{
Console.WriteLine("flag is set");
}
else
{
Console.WriteLine("flag is not set");
}
Console.ReadKey();
}
}
}
Since the conversion to .NET Core and .NET Standard NuGet in VS 2015 doesn't allow PeNet to be referenced by .NET Framework projects.
Could not install package 'PeNet 0.5.0'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.6.1', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
What license model does this code follow?
THe ".Net Framework test binary" from the PeNet testing project is missing in the binary folder of the PeNet test project which leads to failing test.
Copy the test binary to the binary folder of the PeNet test project and make sure the binary gets checked in this time.
The "IsValidPeFile" function returns "false" for "c:\windows\system32\calc.exe" which is an valid PE file.
Find out, why the function thinks it's invalid and repair the function.
Hi,
Here are some files that reproduce a few minor bugs, they are all clean Windows files.
I also have some malware files that have similar issues, but I think fixing these minor bugs will fix the exceptions for the malware files, if not, I will let you know.
You can download the files here:
www.desktopfolders.com/FilesWithErrors.zip
Thank you!
Automated test builds using https://travis-ci.org/
using System;
namespace Test
{
class Program
{
private byte[] _myFile = null;
public byte[] MyFile {
get {
if(_myFile == null)
{
_myFile = System.IO.File.ReadAllBytes(@"c:\foo.bar");
}
return _myFile;
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
becomes
using System;
namespace Test
{
class Program
{
private byte[] _myFile = null;
public byte[] MyFile => _myFile ??= System.IO.File.ReadAllBytes(@"c:\foo.bar");
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Hello,
Could you please add support of .Net v4.0 for nuget package.
It seems that your library can be compiled targeting this version of .Net
Hi,
first of all thanks for PeNet, it is a great library!
I have one feature request - the ability to parse PE file directly from memory, without the need to copy the contents to another buffer.
I tried to implement this myself using Streams, but I got stuck since the byte array usage is used in every parser and it seems to me that switch to memory streams would be very consuming (although I might be wrong).
Thanks,
aelth
The authenticode implementation in PeNet works only for x32 binaries but not for x64 binaries. The hash that is read from the certificate is correct, but the computed hash is wrong.
Example 32 bit:
var peFile = new PeFile(@"c:\windows\syswow64\kernel32.dll");
Assert.True(peFile.IsSignatureValid); // OK
Example 64 bit:
var peFile = new PeFile(@"c:\windows\system32\kernel32.dll");
Assert.True(peFile.IsSignatureValid); // FAILS
Hi, I am not sure that the TLS Callbacks are working correctly. Files that use TLS callbacks are somewhat rare, so I searched for a sample and analyzed it with another PE utility, and it showed the TLS callbacks, but for some reason, they are not showing in PeNet.
For example if you download and compile this code:
Here is the website where I got the above link: http://waleedassar.blogspot.com/2010/10/quick-look-at-tls-callbacks.html
One quick question... what is purpose of the AhoCorasick class? It looks really cool, but I do not see anything that calls it. Just curious. Thank you!
Hi secana,
Sometimes, the debug directory has more than one entry, but PeNet parsers only the first one.
For example,
Debug Directories
Time Type Size RVA Pointer
-------- ------- -------- -------- --------
AEA44997 cv 22 00002228 E28 Format: RSDS, {A2E56CF0-FB64-CC3D-EABD-4F16EB0AAB11}, 1, csrss.pdb
AEA44997 coffgrp 1A4 0000224C E4C 50475500 (PGU)
AEA44997 repro 24 000023F0 FF0 F0 6C E5 A2 64 FB 3D CC EA BD 4F 16 EB 0A AB 11 56 E5 54 A5 89 68 C0 8A 07 66 50 24 97 49 A4 AE
IsDriver is checking if the subsystem is native to determine if an image is a driver or not. This is insufficient. There are native Windows executables (i.e. not linked to a subsystem), such as SMSS.EXE that are user-mode applications. The correct way to determine if an image is a kernel-mode driver is to check if the subsystem is native AND the image is linked against NTOSKRNL.EXE. Windows applications cannot link against NTOSKRNL, and are instead linked against NTDLL.DLL
What do you think is missing for a 1.0 version step? We'd like to use your library, however our company has a kind of "no beta libraries" policy and we're concerned because of the 0.x version indicator. Would you think that the library can be used to parse the IMAGE_FILE_EXECUTABLE_IMAGE flag or do you think that your library isn't that far and we should consider implementing this ourselves instead?
Best regards,
D.R.
The parsing of X509Certifcate2 throws an exception under Linux but works under Windows.
This means that the validity of the Authenticode certificate cannot be checked.
See official issue in the Dotnet Core repo: dotnet/core#1145
Example:
public class CnCDBConfig
{
public string ConString { get; }
public int UpdateAllSeconds { get; }
public CnCDBConfig(string conString, int updateAllSeconds)
=> (ConString, UpdateAllSeconds) = (conString, updateAllSeconds);
}
First of all, PeNet is awesome. I'm just missing the ability to write modified headers / file back to disk. Is this feature really not implemented or did I miss something? In case its really missing is there a chance to see it implemented in the future?
Remove the Newtonsoft.JSON dependency and instead discribe the way to export a PE file as JSON in the help files.
Not all exports could be a functions. It could be a data also. How to distinguish them?
It appears that signed file checks may have an issue, have only tested with a few known signed x64 binaries, no other info at the moment.
> PeNet.Utilities.SignatureInformation.IsSigned("C:\Windows\System32\kernel32.dll");;
val it : bool = false
> PeNet.Utilities.SignatureInformation.IsSigned("C:\Users\me\Downloads\SysinternalsSuite\ADExplorer.exe");;
val it : bool = false
> PeNet.Utilities.SignatureInformation.IsSigned("C:\Windows\explorer.exe");;
val it : bool = false```
I forgot to mention this, but one last thing...
I noticed that if I open several files (especially large files), the memory utilization of the PeNet process continues to increase.
Should PeNet dispose of the opened file after it is finished displaying the results?
Thank you!
When a code or documentation is committed to the master branch, it builds and deploys to Nuget. The deploy fails, because there exists an package with the same version already.
Split build an deploy, such that the build and test run without triggering the deploy to Nuget.
I've been digging through the source, but I can't figure out how to take an Address or Pointer and use it to read the section. Specifically I am looking for the hash/signature and age in the ImageDebugDirectory
data. Any pointers would be appreciated.
hi , when I debuging a 32bit app(PeNet.Test\Binaries\NetFrameworkConsole.exe),
why PeFile.ImageNtHeaders.OptionalHeader.ImageBase is a ulong field ,not uint ?
There does not appear to be any way to easily translate an imported function to its IAT address (for mapping an image into memory.) The following code works. 64 bit only, was in a hurry!
public struct BetterImportedFunction
{
/// <summary>
/// The module of the import.
/// </summary>
public string Module;
/// <summary>
/// The function being imported.
/// </summary>
public string Function;
/// <summary>
/// The ordinal being imported.
/// </summary>
public int Ordinal;
/// <summary>
/// The IAT address to fill.
/// </summary>
public ulong FillAddress;
}
public static class PeFileExtensions
{
private const ulong OrdinalBit = 0x8000000000000000ul;
private const ulong OrdinalMask = 0x7FFFFFFFFFFFFFFFul;
public static void IterateImports(this PeFile file, Action<BetterImportedFunction> handler)
{
var headers = file.ImageSectionHeaders;
foreach (var import in file.ImageImportDescriptors)
{
var module = file.Buff.GetCString(import.Name.RVAtoFileMapping(headers));
var round = 0u;
var thunkAddr = import.FirstThunk.RVAtoFileMapping(headers);
var thunk = new IMAGE_THUNK_DATA(file.Buff, thunkAddr, true);
while (thunk.AddressOfData != 0)
{
if ((thunk.Ordinal & OrdinalBit) == OrdinalBit)
{
handler.Invoke(new BetterImportedFunction
{
Module = module,
Function = null,
Ordinal = (ushort)(thunk.Ordinal & OrdinalMask),
FillAddress = import.FirstThunk + (round * 8)
});
}
else
{
var addrOfNameData = ((uint)thunk.AddressOfData).RVAtoFileMapping(headers);
var nameData = new IMAGE_IMPORT_BY_NAME(file.Buff, addrOfNameData);
handler.Invoke(new BetterImportedFunction
{
Module = module,
Function = nameData.Name,
Ordinal = -1,
FillAddress = import.FirstThunk + (round * 8)
});
}
round += 1;
thunk = new IMAGE_THUNK_DATA(file.Buff, thunkAddr + (round * 8u), true);
}
}
}
}
`
The API documentation wasn't updated in a long time. The old sandcastle API generator is deprecated. Switch to DocFx to autogenerate the API reference.
Add the API reference build step to the Cake script with automatic upload if possible.
Add a CI job to build an deploy the master branch automatically based on a commit.
CI Pipeline
Azure Pipeline PeNet
I've got a patch to throw a new PeNetException instead of Exception so I can ignore it from PeNet (the way we use it creates a lot of exception chatter)
But should I apply it to master or devel or core, or what? I can't tell what's going on
Hi.
I found some malware that freeze your project. It looks like it is an easy fix, and some of these are the same issue, but I figured I would send all of them to you just in case.
This is real malware, so I zipped the files with the password: infected
You can download the malware files from here:
www.desktopfolders.com/Malware.zip
Thank you!
Implement the .Net header in PeNet
PeNet/src/PEditor/TabItems/Imports.xaml.cs
Lines 37 to 58 in 0458c44
Is functionally same as
public void SetImports(PeFile peFile)
{
_peFile = peFile;
lbImportDlls.Items.Clear();
if (peFile.ImportedFunctions == null)
return;
foreach (var dllName in peFile.ImportedFunctions?.Select(x => x.DLL).Distinct())
{
lbImportDlls.Items.Add(new { DLL = dllName });
}
}
Currently only the property value can be accessed by its name. Add the raw (file) and virtual offset to each property. Show resolved values as a extra property.
E.g.:
PropertyType PropertyName = Property<string>(value, rawOffset, virtualOffset);
var value = PropertyName.Value;
var rawOffset = PropertyName.RawOffset;
var virtualOffset = PropertyName.VirtualOffset;
var resolvedValue = PropertyName.ResolvedValue;
Hi, I found a simple bug... Digital Signature Friendly Name is not working, it does not show the value. Thank you!
Hey, here are a few more samples that reproduce bugs… they are all malware, so the zipped file is password protected with the password “infected”.
The Resource.ResourceDirectory.Manifest Crash.exe will crash PeNet when you navigate to the Resource tab, then expand Resource Directory, and then expand Manifest.
The other two files have invalid values under the Sections tab… I believe because they contain embedded files.
http://www.desktopfolders.com/Malware2.zip
Thank you!
I hope to build the runtime target .Net Framework 2.0 for it.
The check for PeFile.IsSignatureValid
is implemented in the private method AuthenticodeInfo.CheckSignature
which basically does this:
var hash = ComputeAuthenticodeHash();
return SignedHash.SequenceEqual(hash);
This shows that the check only compares whether the hash from the signature matches the computed hash of the PE file, but the signature itself isn't checked at all. It should be verified with the certificate.
Hi, there is an "index was outside the bounds of the array" exception in the ImageDelayImportDescriptor when opening certain files.
SupremoControl is a file that will help reproduce the issue.
http://www.supremocontrol.com/
Here is the download
http://www.supremocontrol.com/download.aspx?file=Supremo.exe&id_sw=7&ws=supremocontrol.com
Keep up the great work!!!
I'm getting a null NullReferenceException. Somehow t.Fail is null.
at PeNet.PatternMatching.Trie2.<Find>d__3.MoveNext() in D:\Users\Clint\Documents\Visual Studio 2015\Projects\ConsoleApplication1\PeNet2\PatternMatching\AhoCorasick.cs:line 163
at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)
at ConsoleApplication1.Program.Main(String[] args) in d:\users\clint\documents\visual studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 26
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
This is my program:
class Program
{
static void Main(string[] args)
{
var pe = new PeFile(@"c:\windows\system32\calc.exe");
var trie = new Trie();
var nsisSig = StringToByteArray("83 EC 20 53 55 56 33 DB 57 89 5C 24 18 C7 44 24 10");
var s = BitConverter.ToString(nsisSig);
trie.Add(nsisSig, "NSIS");
var matches = trie.Find(pe.Buff);
var count = matches.Count();
foreach (var match in matches)
{
Console.WriteLine($"Pattern {match.Item1} at offset {match.Item2}");
}
}
public static byte[] StringToByteArray(string hex)
{
hex = hex.Replace(" ", "");
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
}
In the File Header characteristics is a typo: NetRunFroMSwap
The M has to be lower case
Hey, sorry to keep bugging you, but here are some Windows files that crash PeNet... they are all standard Microsoft Windows files.
www.desktopfolders.com/Issues.zip
Thank you!
Currently PeNet uses the Windows Native API to check if a sample has a valid signature. This brings the problem, that the check does not run under non-Windows systems.
Mono has an implementation that can be used instead or adapted to work with PeNet.
Use this as a base to get rid of the Windows dependency here.
Some DLLs have functions that are exported by ordinal only. These functions do not have a name at all, so NumberOfNames is not equal to NumberOfFunctions. I have modified PeFile.ParseExportedFunctions, and can confirm that this code works on my test file:
private PeFile.ExportFunction[] ParseExportedFunctions(byte[] buff, Structures.IMAGE_EXPORT_DIRECTORY ed, Structures.IMAGE_SECTION_HEADER[] sh)
{
var expFuncs = new PeFile.ExportFunction[ed.NumberOfFunctions];
var funcOffsetPointer = Utility.RVAtoFileMapping(ed.AddressOfFunctions, sh);
var ordOffset = Utility.RVAtoFileMapping(ed.AddressOfNameOrdinals, sh);
var nameOffsetPointer = Utility.RVAtoFileMapping(ed.AddressOfNames, sh);
var funcOffset = Utility.BytesToUInt32(buff, funcOffsetPointer);
//Get addresses
for (uint i = 0; i < expFuncs.Length; i++)
{
var ordinal = i + ed.Base;
var address = Utility.BytesToUInt32(buff, funcOffsetPointer + sizeof(uint) * i);
expFuncs[i] = new PeFile.ExportFunction(null, address, (ushort)ordinal);
}
//Associate names
for (uint i = 0; i < ed.NumberOfNames; i++)
{
var namePtr = Utility.BytesToUInt32(buff, nameOffsetPointer + sizeof(uint) * i);
var nameAdr = Utility.RVAtoFileMapping(namePtr, sh);
var name = Utility.GetName(nameAdr, buff);
var ordinalIndex = (uint)Utility.GetOrdinal(ordOffset + sizeof (ushort)*i, buff);
expFuncs[ordinalIndex] = new PeFile.ExportFunction(name, expFuncs[ordinalIndex].Address, expFuncs[ordinalIndex].Ordinal);
}
return expFuncs;
}
My reference for this modification was http://web.archive.org/web/20160306071658/http://win32assembly.programminghorizon.com/pe-tut7.html
Add icon to the PeNet library repo.
Add icon to "Icon URL" in PeNet package description.
The IsExe attribute ALWAYS returns True for .exe AND .dll files...
While the IsDll attribute returns True only for .dll files. (So this makes sense)
Is the IsExe attribute supposed to return True for ALL .dll files?
Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.