Search Results

Search found 42 results on 2 pages for 'badimageformatexception'.

Page 2/2 | < Previous Page | 1 2 

  • How to get application to use specific version of .NET?

    - by HN
    Hi, I am using pnunit to run nunit tests on remote machines, the pnunit agent loads the test and runs it in Windows 2008 but the test fails to load in Windows 2003, the agent error is INFO PNUnit.Agent.PNUnitAgent - Registering channel on port 9080 INFO PNUnit.Agent.PNUnitAgent - RunTest called for Test MyTest, AssemblyName test.dll, TestToRun test.Program.myDeployTest INFO PNUnit.Agent.PNUnitTestRunner - Spawning a new thread INFO PNUnit.Agent.PNUnitTestRunner - Thread entered for Test MyTest:test.Program.myDeployTest Assembly test.dll Unhandled Exception: System.BadImageFormatException: The format of the file 'test ' is invalid. File name: "test" Server stack trace: at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, B oolean isStringized, Evidence assemblySecurity, Boolean throwOnFileNotFound, Ass embly locationHint, StackCrawlMark& stackMark) On running procmon and monitoring the agent process i could see that the agent executable was using .NET 1.1 assemblies on Windows 2003 and .NET 2.0 on Windows 2008 which could be an explanation for this behavior. How do I get the agent to use .NET 2.0 on Windows 2003?

    Read the article

  • How to correctly load 32-bit DLL dependencies when running a program from a batch file

    - by neilwhitaker1
    I have written a tool that references Microsoft.TeamFoundation.VersionControl.Client.dll, which is a 32-bit DLL. When I build my tool on 64-bit Windows, I set Visual Studio to specifically target X86 in order to force it to a 32-bit build. Targetting X86 instead of All-CPU's prevents me from getting a BadImageFormatException, as long as I invoke the tool directly (e.g. by typing "myTool.exe" on the command line). However, if I run a batch file that invokes the tool, I still get the exception. This happens even if the batch file runs in a 32-bit command prompt (%WINDIR%\SysWOW64\cmd.exe). What else can I do to make this work?

    Read the article

  • How we run a .NET 32-bit application in a 64-bit Windows server?

    - by Geo
    We are installing a third party application in one of our 64-bit Windows servers. This application apparently was build with the compiler option set to choose the platform at run time. When we run the application it gives us an error: System.BadImageFormatException: is not a valid Win32 application. I have seen in MSDN forums that in order to fix this error I have to build the application set to 32-bit, and that way it will run fine on a 64-bit server. I check on other StackOverflow links Other Posts. How to get around this situation? For everyone that wants to know more information: The application is running fine in a 32-bit test server. IIS version 6 using SQL Server Express 2005 On the Web Service Extension there are both Framework64\v2.0.50727\aspnet_isapi.dll and Framework\v2.0.50727\aspnet_isapi.dll

    Read the article

  • How do I play a video through .net in windows 7

    - by Mykroft
    I had setup an app to play a video using the library suggested here this worked great for me for a long time until my machine was upgraded. In windows 7 I get the following exception that I'd never seen under XP: `System.BadImageFormatException: is not a valid Win32 application. (Exception from HRESULT: 0x800700C1) at MainApp.Controls.MediaControl.StopVideo() at System.Windows.Forms.Form.WmClose(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)` I've installed the June 2010 DirectX SDK and I'm still getting this error. Is there a different library I should be using or some setting that needs to be changed?

    Read the article

  • how to call a C++ dll from C# windows application project

    - by chathuradd
    I have created a dll in C++ using a Class Library project in Visual Studio. I need to call a method in the dll from a C# application. I got to know there are 2 approches. One is to add the dll project reference to C# project or use DllExport to export method. However when I tried in both ways it always gives the following error when the dll method is called in runtime. An unhandled exception of type 'System.BadImageFormatException' occurred in TestClient.exe Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) Can i know how to avoid this problem ? Thanks in advance!

    Read the article

  • Visual Studio 2010 64-bit COM Interop Issue

    - by Adam Driscoll
    I am trying to add a VC6 COM DLL to our VS2010RC C# solution. The DLL was compiled with the VC6 tools to create an x86 version and was compiled with the VC7 Cross-platform tools to generate a VC7 DLL. The x86 version of the assembly works fine as long as the consuming C# project's platform is set to x86. It doesn't matter whether the x64 or the x86 version of the DLL is actually registered. It works with both. If the platform is set to 'Any CPU' I receive a BadImageFormatException on the load of the Interop.<name>.dll. As for the x64 version, I cannot even get the project to build. I receive the tlbimp error: TlbImp : error TI0000: A single valid machine type compatible with the input type library must be specified. Has anyone seen this issue? EDIT: I've done a lot more digging into this issue and think this may be a Visual Studio bug. I have a clean solution. I bring in my COM assembly with language agnostic 'Any CPU' selected. The process architecture of the resulting Interop DLL is x86 rather than MSIL. May have to make the Interop by hand for now to get this to work. If anyone has another suggestion let me know.

    Read the article

  • NAudio demos not working anymore

    - by Kurru
    I just tried to run the NAudio demos and I'm getting a weird error: System.BadImageFormatException: Could not load file or a ssembly 'NAudio, Version=1.3.8.0, Culture=neutral, PublicKeyToken=null' or one o f its dependencies. An attempt was made to load a program with an incorrect form at. File name: 'NAudio, Version=1.3.8.0, Culture=neutral, PublicKeyToken=null' at NAudioWpfDemo.AudioGraph..ctor() at NAudioWpfDemo.ControlPanelViewModel..ctor(IWaveFormRenderer waveFormRender er, SpectrumAnalyser analyzer) in C:\Users\Admin\Downloads\NAudio-1.3\NAudio-1-3 \Source Code\NAudioWpfDemo\ControlPanelViewModel.cs:line 23 at NAudioWpfDemo.MainWindow..ctor() in C:\Users\Admin\Downloads\NAudio-1.3\NA udio-1-3\Source Code\NAudioWpfDemo\MainWindow.xaml.cs:line 15 WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\M icrosoft\Fusion!EnableLog] (DWORD) to 1. Note: There is some performance penalty associated with assembly bind failure lo gging. To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fus ion!EnableLog]. Since the last time I used NAudio demos I have changed from 32bit Windows XP to 64bit Windows 7. Would this cause this issue? Its very annoying as I was about to try my hand at audio in C# again

    Read the article

  • How to utilize WebDev.WebServer.exe (VS Web Server) in x64?

    - by Nick Craver
    Visual Studio is x86 until at least the 2010 release comes around, my question is can anyone think of a way or know of an independent ASP.NET debug server that's x64 for 2008? Background: Our ASP.NET application runs against Oracle as the DB. Since we're on 64-bit servers for memory concerns later, we need to use Oracle's 64-bit drivers (Instant Client). Setup: x64 OS (XP or Windows 7) IIS (5 or 7, both x64 App Pools) Oracle 64-bit Instant Client (Separate Directory, in the PATH) Visual Studio 2008 SP1 In IIS the application pool runs as 64-bit, uses the Oracle drivers as intended, however since WebDev.WebServer.exe is 32-bit you'll get a BadImageFormatException because it's trying to load 64-bit driver DLLs in a 32-bit environment. All of our developers would like to be able to use the quick debug server via Visual Studio 2008, but since it runs as 32-bit we're unable to. Some problems we run into are during application startup, so although we're attaching to the IIS process sometimes that isn't enough to track an issue down. Are there any alternatives, or work-arounds? We would like to match our Dev/Val/Prod tiers as much as possible, so everything running in x64 would be ideal.

    Read the article

  • Incompatibility between x86 and x64 in Installation solution

    - by rodnower
    Hello, I have installation solution that have installer project (not web installer but simple installer) that installs NT services, web service and web sites with help of additional two projects of dlls with my own code that performs my installation step. In user actions of installer project I call installer function of one of those projects, and this project calls to installer of second project: installer - MiddleCaller - InstallationCore. All this developing on Windows 7 and work fine when I compile all in 32 bit. The project must run on Windows 2008. Because of some reasons all must be in x64 bit. For this purpose, in MiddleCaller and InstallationCore I click right button of mouse on project - build - targer x64. For to move installer project to 64 bit in properties of installer (when project is active) I check: Target platform: x64. When I run installation on x86 I get error: The installation package is not supported by this processor type" And this is good, because now I know that my installation compiled in 64 bit, but when I run this on windows 2008 I get: Error 1001. Exception occured while initializing the instance: System.BadImageFormatException: could not load file or Assembly 'MiddleCaller, v...' or one of its dependencies. An attempt was made to load a program with an incorrect format. Any one has some idea what I need to do for run fine the installation on x64? May be I still not moved the installer project to x64 bit, if yes, where I do this? Thank you for ahead.

    Read the article

  • Cast exception when trying to create new Task Schedueler task.

    - by seaneshbaugh
    I'm attempting to create a new task in the Windows Task Scheduler in C#. What I've got so far is pretty much a copy and paste of http://bartdesmet.net/blogs/bart/archive/2008/02/23/calling-the-task-scheduler-in-windows-vista-and-windows-server-2008-from-managed-code.aspx Everything compiles just fine but come run time I get the following exception: Unable to cast COM object of type 'System.__ComObject' to interface type 'TaskScheduler.ITimeTrigger'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{B45747E0-EBA7-4276-9F29-85C5BB300006}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)). Here's all the code so you can see what I'm doing here without following the above link. TaskSchedulerClass Scheduler = new TaskSchedulerClass(); Scheduler.Connect(null, null, null, null); ITaskDefinition Task = Scheduler.NewTask(0); Task.RegistrationInfo.Author = "Test Task"; Task.RegistrationInfo.Description = "Just testing this out."; ITimeTrigger Trigger = (ITimeTrigger)Task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY); Trigger.Id = "TestTrigger"; Trigger.StartBoundary = "2010-05-12T06:15:00"; IShowMessageAction Action = (IShowMessageAction)Task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_SHOW_MESSAGE); Action.Id = "TestAction"; Action.Title = "Test Task"; Action.MessageBody = "This is a test."; ITaskFolder Root = Scheduler.GetFolder("\\"); IRegisteredTask RegisteredTask = Root.RegisterTaskDefinition("Background Backup", Task, (int)_TASK_CREATION.TASK_CREATE_OR_UPDATE, null, null, _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, ""); The line that is throwing the exception is this one ITimeTrigger Trigger = (ITimeTrigger)Task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY); The exception message kinda makes sense to me, but I'm afraid I don't know enough about COM to really know where to begin with this. Also, I should add that I'm using VS 2010 and I had to set the project to either be for x86 or x64 CPU's instead of the usual "Any CPU" because it kept giving me a BadImageFormatException. I doubt that's related to my current problem, but just in case I thought I might as well mention it.

    Read the article

  • How can I test blades in MVC Turbine with Rhino Mocks?

    - by Brandon Linton
    I'm trying to set up blade unit tests in an MVC Turbine-derived site. The problem is that I can't seem to mock the IServiceLocator interface without hitting the following exception: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) at System.Reflection.Emit.TypeBuilder._TermCreateClass(Int32 handle, Module module) at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() at System.Reflection.Emit.TypeBuilder.CreateType() at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options) at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors) at Rhino.Mocks.MockRepository.MockInterface(CreateMockState mockStateFactory, Type type, Type[] extras) at Rhino.Mocks.MockRepository.CreateMockObject(Type type, CreateMockState factory, Type[] extras, Object[] argumentsForConstructor) at Rhino.Mocks.MockRepository.Stub(Type type, Object[] argumentsForConstructor) at Rhino.Mocks.MockRepository.<>c__DisplayClass1`1.<GenerateStub>b__0(MockRepository repo) at Rhino.Mocks.MockRepository.CreateMockInReplay<T>(Func`2 createMock) at Rhino.Mocks.MockRepository.GenerateStub<T>(Object[] argumentsForConstructor) at XXX.BladeTest.SetUp() Everything I search for regarding this error leads me to 32-bit vs. 64-bit DLL compilation issues, but MVC Turbine uses the service locator facade everywhere and we haven't had any other issues, just with using Rhino Mocks to attempt mocking it. It blows up on the second line of this NUnit set up method: IRotorContext _context; IServiceLocator _locator; [SetUp] public void SetUp() { _context = MockRepository.GenerateStub<IRotorContext>(); _locator = MockRepository.GenerateStub<IServiceLocator>(); _context.Expect(x => x.ServiceLocator).Return(_locator); } Just a quick aside; I've tried implementing a fake implementing IServiceLocator, thinking that I could just keep track of calls to the type registration methods. This won't work in our setup, because we extend the service locator's interface in such a way that if the type isn't Unity-based, the registration logic is not invoked.

    Read the article

  • MSTest on x64 C++/CLI

    - by Oyvind
    I got a problem using MSTest on x64: The test project depends on a couple of C++/CLI assemblies, and fails to load for some reason. In Visual Studio, I get (stripped down): Error loading D:\xxx\Xxx.Test.dll: Unable to load the test container 'D:\xxx\Xxx.Test.dll' or one of its dependencies. Error details: System.BadImageFormatException: Could not load file or assembly 'Common.Geometry.Native, Version=1.1.4574.22395, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format. Running MSTest manually in a command prompt, I get: Unable to load the test container 'D:\xxx\Xxx.Test.dll' or one of its dependencies. Error details: System.IO.FileNotFoundException: Could not load file or assembly 'Common.Geometry.Native, Version=1.1.4574.22395, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. Details worth mentioning: The test project itself is compiled using 'Any Cpu'. I use a x64 specific testrunconfig Dependency walker shows no missing native dependencies in the C++/CLI assembly (Common.Geometry.Native) Even more interesting, there is another test project in the same solution using the same C++/CLI assembly (Common.Geometry.Native), and it runs without any problems. I have also verified that there are no 32bit assemblies/dlls interfering. Any suggestions is welcome !

    Read the article

  • Is it possible to load an assembly targeting a different .NET runtime version in a new app domain?

    - by Notre
    Hello, I've an application that is based on .NET 2 runtime. I want to add a little bit of support for .NET 4 but don't want to (in the short term), convert the whole application (which is very large) to target .NET 4. I tried the 'obvious' approach of creating an application .config file, having this: <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" /> </startup> but I ran into some problems that I noted here. I got the idea of creating a separate app domain. To test it, I created a WinForm project targeting .NET 2. I then created a class library targeting .NET 4. In my WinForm project, I added the following code: AppDomainSetup setup = new AppDomainSetup(); setup.ApplicationBase = "path to .NET 4 assembly"; setup.ConfigurationFile = System.Environment.CurrentDirectory + "\\DotNet4AppDomain.exe.config"; // Set up the Evidence Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; Evidence evidence = new Evidence(baseEvidence); // Create the AppDomain AppDomain dotNet4AppDomain = AppDomain.CreateDomain("DotNet4AppDomain", evidence, setup); try { Assembly doNet4Assembly = dotNet4AppDomain.Load( new AssemblyName("MyDotNet4Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=66f0dac1b575e793")); MessageBox.Show(doNet4Assembly.FullName); } finally { AppDomain.Unload(dotNet4AppDomain); } My DotNet4AppDomain.exe.config file looks like this: <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" /> </startup> Unfortunately, this throws the BadImageFormatException when dotNet4AppDomain.Load is executed. Am I doing something wrong in my code, or is what I'm trying to do just not going to work? Thank you!

    Read the article

  • Using C++ DLL in C# project

    - by Frank
    Hello, I got a C++ dll which has to be integrated in a C# project. I think I found the correct way to do it, but calling the dll gives me this error: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B) This is the function in the dll: extern long FAR PASCAL convert (LPSTR filename); And this is the code I'm using in C# namespace Test{ public partial class Form1 : Form { [DllImport("convert.dll", SetLastError = true)] static extern Int32 convert([MarshalAs(UnmanagedType.LPStr)] string filename); private void button1_Click(object sender, EventArgs e) { // generate textfile string filename = "testfile.txt"; StreamWriter sw = new StreamWriter(filename); sw.WriteLine("line1"); sw.WriteLine("line2"); sw.Close(); // add checksum Int32 ret = 0; try { ret = convert(filename); Console.WriteLine("Result of DLL: {0}", ret.ToString()); } catch (Exception ex) { lbl.Text = ex.ToString(); } } }} Any ideas on how to proceed with this? Thanks a lot, Frank

    Read the article

  • Cannot install windows service

    - by Matthew Dalton
    I have created a very simple window service using visual studio 2010 and .Net 4.0. This service has no functionality added from the default windows service project, other than an installer has been added. If i run installutil.exe appName.exe on my dev box or other windows 2008 R2 machines in our domain the windows service installs without issue. When i try to do this same thing on our customer site, it fails to install with the following error. Microsoft (R) .NET Framework Installation utility Version 4.0.30319.1 Copyright (c) Microsoft Corporation. All rights reserved. Exception occurred while initializing the installation: System.IO.FileLoadException: Could not load file or assembly 'file:///C:\TestService\WindowsService1.exe' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515). This solution has only 1 project and no dependencies added. I have tried it on multiple machines in our environment and two in our customers. The machines are all windows 2008 R2, both fresh installs. One machine has just .net 2.0 and .net 4.0. The other .net 2, 3, 3.5 and 4. I am a local admin on each of the machines. I have also tried the 64bit installer but get the following error, so i think the 32 bit one is the one to use. System.BadImageFormatException Any guidance would be appreciated. Thanks.

    Read the article

  • Problem using ‘useLegacyV2RuntimeActivationPolicy’ & supportedRuntime in an application

    - by Notre
    Hello, I've modified a couple of different applications' .config file like this: <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/> </startup> When I did this for devenv.exe.config (VS 2005 - don't ask :) ), things work great - most of the Visual Studio used .NET 2.0 but I was able to make use of an assembly targeting .NET 4.0 framework. I tried to do the same thing for a custom .exe, which happens to be based on MS CAB (slightly modified) and has a hybrid mix of WPF and WinForms content. As soon as I modified this application's app config file, I started getting this exception, sometime during application startup: The Undo operation encountered a context that is different from what was applied in the corresponding Set operation. The possible cause is that a context was Set on the thread and not reverted(undone). System.InvalidOperationException: The Undo operation encountered a context that is different from what was applied in the corresponding Set operation. The possible cause is that a context was Set on the thread and not reverted(undone). There's a big long stack trace that doesn't show anything in my application code directly (just a bunch of MS assemblies). If I modify the application's .config file to this: <startup useLegacyV2RuntimeActivationPolicy="true"> </startup> i.e.I remove the supportedRuntime element, then the application doesn't throw this exception. But when I go to the point in my code where I try to load my .NET 4 assembly, if fails with this: System.BadImageFormatException: Could not load file or assembly '' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. I guess this is expected. I have two questions: 1) Any idea why I'm getting the System.InvalidOperationException exception when I modify this application's configuration file to include the supportedRuntime element, adding .NET 4 support and any suggestions on what I can do about it? 2) If the answer is "no idea why/don't know what you can do about it", then is possible for my .NET 3.5 SP1 code (C#) to provide more fine grain support for conditionally adding .NET 4 runtime support for a certain assembly(ies) without converting my entire application to target .NET 4, or without using the declarative config file approach? At some point I would convert the entire application to target .NET 4, but for the short term this is daunting task and I'm hope for some short term solution/hack. Thank you very much for any advice you can give!

    Read the article

  • From Binary to Data Structures

    - by Cédric Menzi
    Table of Contents Introduction PE file format and COFF header COFF file header BaseCoffReader Byte4ByteCoffReader UnsafeCoffReader ManagedCoffReader Conclusion History This article is also available on CodeProject Introduction Sometimes, you want to parse well-formed binary data and bring it into your objects to do some dirty stuff with it. In the Windows world most data structures are stored in special binary format. Either we call a WinApi function or we want to read from special files like images, spool files, executables or may be the previously announced Outlook Personal Folders File. Most specifications for these files can be found on the MSDN Libarary: Open Specification In my example, we are going to get the COFF (Common Object File Format) file header from a PE (Portable Executable). The exact specification can be found here: PECOFF PE file format and COFF header Before we start we need to know how this file is formatted. The following figure shows an overview of the Microsoft PE executable format. Source: Microsoft Our goal is to get the PE header. As we can see, the image starts with a MS-DOS 2.0 header with is not important for us. From the documentation we can read "...After the MS DOS stub, at the file offset specified at offset 0x3c, is a 4-byte...". With this information we know our reader has to jump to location 0x3c and read the offset to the signature. The signature is always 4 bytes that ensures that the image is a PE file. The signature is: PE\0\0. To prove this we first seek to the offset 0x3c, read if the file consist the signature. So we need to declare some constants, because we do not want magic numbers.   private const int PeSignatureOffsetLocation = 0x3c; private const int PeSignatureSize = 4; private const string PeSignatureContent = "PE";   Then a method for moving the reader to the correct location to read the offset of signature. With this method we always move the underlining Stream of the BinaryReader to the start location of the PE signature.   private void SeekToPeSignature(BinaryReader br) { // seek to the offset for the PE signagure br.BaseStream.Seek(PeSignatureOffsetLocation, SeekOrigin.Begin); // read the offset int offsetToPeSig = br.ReadInt32(); // seek to the start of the PE signature br.BaseStream.Seek(offsetToPeSig, SeekOrigin.Begin); }   Now, we can check if it is a valid PE image by reading of the next 4 byte contains the content PE.   private bool IsValidPeSignature(BinaryReader br) { // read 4 bytes to get the PE signature byte[] peSigBytes = br.ReadBytes(PeSignatureSize); // convert it to a string and trim \0 at the end of the content string peContent = Encoding.Default.GetString(peSigBytes).TrimEnd('\0'); // check if PE is in the content return peContent.Equals(PeSignatureContent); }   With this basic functionality we have a good base reader class to try the different methods of parsing the COFF file header. COFF file header The COFF header has the following structure: Offset Size Field 0 2 Machine 2 2 NumberOfSections 4 4 TimeDateStamp 8 4 PointerToSymbolTable 12 4 NumberOfSymbols 16 2 SizeOfOptionalHeader 18 2 Characteristics If we translate this table to code, we get something like this:   [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct CoffHeader { public MachineType Machine; public ushort NumberOfSections; public uint TimeDateStamp; public uint PointerToSymbolTable; public uint NumberOfSymbols; public ushort SizeOfOptionalHeader; public Characteristic Characteristics; } BaseCoffReader All readers do the same thing, so we go to the patterns library in our head and see that Strategy pattern or Template method pattern is sticked out in the bookshelf. I have decided to take the template method pattern in this case, because the Parse() should handle the IO for all implementations and the concrete parsing should done in its derived classes.   public CoffHeader Parse() { using (var br = new BinaryReader(File.Open(_fileName, FileMode.Open, FileAccess.Read, FileShare.Read))) { SeekToPeSignature(br); if (!IsValidPeSignature(br)) { throw new BadImageFormatException(); } return ParseInternal(br); } } protected abstract CoffHeader ParseInternal(BinaryReader br);   First we open the BinaryReader, seek to the PE signature then we check if it contains a valid PE signature and rest is done by the derived implementations. Byte4ByteCoffReader The first solution is using the BinaryReader. It is the general way to get the data. We only need to know which order, which data-type and its size. If we read byte for byte we could comment out the first line in the CoffHeader structure, because we have control about the order of the member assignment.   protected override CoffHeader ParseInternal(BinaryReader br) { CoffHeader coff = new CoffHeader(); coff.Machine = (MachineType)br.ReadInt16(); coff.NumberOfSections = (ushort)br.ReadInt16(); coff.TimeDateStamp = br.ReadUInt32(); coff.PointerToSymbolTable = br.ReadUInt32(); coff.NumberOfSymbols = br.ReadUInt32(); coff.SizeOfOptionalHeader = (ushort)br.ReadInt16(); coff.Characteristics = (Characteristic)br.ReadInt16(); return coff; }   If the structure is as short as the COFF header here and the specification will never changed, there is probably no reason to change the strategy. But if a data-type will be changed, a new member will be added or ordering of member will be changed the maintenance costs of this method are very high. UnsafeCoffReader Another way to bring the data into this structure is using a "magically" unsafe trick. As above, we know the layout and order of the data structure. Now, we need the StructLayout attribute, because we have to ensure that the .NET Runtime allocates the structure in the same order as it is specified in the source code. We also need to enable "Allow unsafe code (/unsafe)" in the project's build properties. Then we need to add the following constructor to the CoffHeader structure.   [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct CoffHeader { public CoffHeader(byte[] data) { unsafe { fixed (byte* packet = &data[0]) { this = *(CoffHeader*)packet; } } } }   The "magic" trick is in the statement: this = *(CoffHeader*)packet;. What happens here? We have a fixed size of data somewhere in the memory and because a struct in C# is a value-type, the assignment operator = copies the whole data of the structure and not only the reference. To fill the structure with data, we need to pass the data as bytes into the CoffHeader structure. This can be achieved by reading the exact size of the structure from the PE file.   protected override CoffHeader ParseInternal(BinaryReader br) { return new CoffHeader(br.ReadBytes(Marshal.SizeOf(typeof(CoffHeader)))); }   This solution is the fastest way to parse the data and bring it into the structure, but it is unsafe and it could introduce some security and stability risks. ManagedCoffReader In this solution we are using the same approach of the structure assignment as above. But we need to replace the unsafe part in the constructor with the following managed part:   [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct CoffHeader { public CoffHeader(byte[] data) { IntPtr coffPtr = IntPtr.Zero; try { int size = Marshal.SizeOf(typeof(CoffHeader)); coffPtr = Marshal.AllocHGlobal(size); Marshal.Copy(data, 0, coffPtr, size); this = (CoffHeader)Marshal.PtrToStructure(coffPtr, typeof(CoffHeader)); } finally { Marshal.FreeHGlobal(coffPtr); } } }     Conclusion We saw that we can parse well-formed binary data to our data structures using different approaches. The first is probably the clearest way, because we know each member and its size and ordering and we have control about the reading the data for each member. But if add member or the structure is going change by some reason, we need to change the reader. The two other solutions use the approach of the structure assignment. In the unsafe implementation we need to compile the project with the /unsafe option. We increase the performance, but we get some security risks.

    Read the article

< Previous Page | 1 2