VB.NET ERR: 0x8007000B (Bad Image Format Exception)

0
__declspec(dllexport) void __cdecl  memcopy(void *pDst, const void *pSrc, unsigned int nSize) {             __asm {
                    mov esi, pSrc
                    mov edi, pDst
                    mov ecx, nSize $L1:
                    movq mm7, [esi]
                    add esi, 8
                    movq [edi], mm7
                    add edi, 8
                    dec ecx
                    jne $L1             };  }

This is the Code from CopyBlit8x8.dll

I successfully imported this .dll into a C++ Console Application and copied a string 'Hello World' from char * a, to char * b. Then echoed b succesfully showing 'Hello World'.

Then, as this is a generic memory copy routine that accepts two pointers to perform the copy, I did this below;

VB.NET Error In Picture Format

The picture basically said about the post title ~ Bad Image Format Exception. Err Code: 0x8007000B.

This is a generic error with little information as it applies to variety of scenarios. But, I can safely assume, its something to do with pointers.

What I want is a fast ASM module to perform generic memory copies,but for vb.NET images.

Any tips, Stack Overflow!

vb.net
image
format
pinvoke
asked on Stack Overflow Nov 13, 2016 by shotting.cc • edited Nov 13, 2016 by Visual Vincent

2 Answers

1

A BadImageFormatException is thrown when you try to load an assembly or dll that is compiled under a different bitness than the application. For instance if you try to load a 32-bit dll in a 64-bit application (or vice versa).

Make sure that the dll is compiled in the same bitness as the application. If the application is compiled as AnyCPU then either force it to be x86 or x64, or compile two dlls using each bitness, then import each function (but with different names) and call the correct one after checking the Environment.Is64BitProcess property.

This is an example of the AnyCPU solution:

'32-bit dll
<DllImport("CopyBlit8x8.dll")> _
Public Shared Function memcopy(<insert parameters here>)
End Function

'64-bit dll
<DllImport("CopyBlit8x8_x64.dll")> _
Public Shared Function memcopy64(<insert parameters here>)
End Function

Public Sub DoStuff()
    If Environment.Is64BitProcess = True Then
        memcopy64(...) 'Call 64-bit dll
    Else
        memcopy(...) 'Call 32-bit dll
    End If
End Sub

EDIT:

According to Hans Passant, ASM MMX instructions can't be used in x64, so my solution above would not work for you. However I'm leaving it there because it works for DLLs compiled using native C/C++ code.

answered on Stack Overflow Nov 13, 2016 by Visual Vincent • edited Nov 14, 2016 by Visual Vincent
0

Code: Select all

__declspec(dllexport) int  __cdecl testApp(long *dst, long *src)
{

   __asm {
         mov eax, src
         mov dst, eax
   };

   return *dst;
}

This code above is the working copy operation.

Code: Select all

Option Explicit On
Imports System.Runtime.InteropServices
Imports System.Text
Imports wow64

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


        Dim bm As New Bitmap("1.png")
        Dim bm2 As New Bitmap(640, 400)

        Dim sb As New StringBuilder
        sb.Append("Helo World.")

        Dim src() As Byte = ASCIIEncoding.ASCII.GetBytes("Hello")
        Dim dst() As Byte = ASCIIEncoding.ASCII.GetBytes("World")

        Dim a As IntPtr = Marshal.AllocHGlobal(10)
        Dim o As IntPtr = Marshal.AllocHGlobal(10)
        Dim i() As Integer = {2, 1}
        Marshal.Copy(i, 0, o, 2)
        a = (wow64.movq.testApp(a, o))
        Button1.Text = ASCIIEncoding.ASCII.GetChars(src)
        TextBox1.Text = Marshal.ReadIntPtr(a, 4).ToString
        Marshal.FreeHGlobal(a)
        'Marshal.FreeHGlobal(o)


    End Sub
End Class
Namespace wow64
    Public Class movq

        <DllImport("D:\CopyBlit8x8.dll", CallingConvention:=CallingConvention.Cdecl)> Public Shared Sub memcopy(ByRef pDsc As StringBuilder, ByRef pSrc As StringBuilder, ByVal nSize As Integer)

        End Sub
        <DllImport("D:\CopyBlit8x8.dll", CallingConvention:=CallingConvention.Cdecl)> Public Shared Function myPuts(ByRef str As StringBuilder) As Integer

        End Function
        <DllImport("D:\CopyBlit8x8.dll", CallingConvention:=CallingConvention.Cdecl)> Public Shared Function testApp(ByRef i As Long, ByRef p As Long) As Integer

        End Function

    End Class
End Namespace

This code is the copy operation implemented in VB.NET.

Code: Select all

TextBox1.Text = Marshal.ReadIntPtr(a, 4).ToString

This marshal routine uses 4^increments to read through the array.

Simple, eh?

answered on Stack Overflow Nov 14, 2016 by Belly Knots • edited Nov 14, 2016 by Smittey

User contributions licensed under CC BY-SA 3.0