Search code examples
vb.netvisual-studio-2010vb6copymemory

How To I Write Copymem Lib "Kernel32" Alias "Rtlmovememory" In Vb.Net


below is my vb6 code

    Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)


Public Property Let Key(New_Value As String)

  Dim i As Long
  Dim j As Long
  Dim K As Long
  Dim dataX As Long
  Dim datal As Long
  Dim datar As Long
  Dim Key() As Byte
  Dim KeyLength As Long

  'Do nothing if the key is buffered
  If (m_KeyValue = New_Value) Then Exit Property
  m_KeyValue = New_Value

  'Convert the new key into a bytearray
  KeyLength = Len(New_Value)
  Key() = StrConv(New_Value, vbFromUnicode)

  'Create key-dependant p-boxes
  j = 0
  For i = 0 To (ROUNDS + 1)
    dataX = 0
    For K = 0 To 3
      Call CopyMem(ByVal VarPtr(dataX) + 1, dataX, 3) 'the problem is here
      dataX = (dataX Or Key(j))
      j = j + 1
      If (j >= KeyLength) Then j = 0
    Next
    m_pBox(i) = m_pBox(i) Xor dataX
  Next

End Property

CopyMem sub lib how do i use it in vb.net

now here is my vb.net code for the same

  Private Declare Sub CopyMem Lib "KERNEL32" Alias "RtlMoveMemory" (ByVal pDst As Object, ByVal pSrc As Object, ByVal ByteLen As Integer)


 Public WriteOnly Property Key() As String
        Set(ByVal Value As String)

            Dim i As Long
            Dim j As Long
            Dim K As Long
            Dim dataX As Long
            Dim datal As Long
            Dim datar As Long
            Dim Key() As Byte
            Dim KeyLength As Long

            'Do nothing if the key is buffered
            If (m_KeyValue = Value) Then Exit Property
            m_KeyValue = Value

            'Convert the new key into a bytearray
            KeyLength = Len(Value)

            Key = System.Text.Encoding.Unicode.GetBytes(Value)

            'Create key-dependant p-boxes
            j = 0

            For i = 0 To (ROUNDS + 1)
                dataX = 0
                For K = 0 To 3


                    CopyMem(VarPtr(dataX) + 1, dataX, 3) ' the problem is here
                    dataX = (dataX Or Key(j))
                    j = j + 1
                    If (j >= KeyLength) Then j = 0

                Next
                m_pBox(i) = m_pBox(i) Xor dataX
            Next
 End Property

here is code for VarPtr

Public Function VarPtr(ByVal e As Object) As Object
        Dim GC As GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned)
        Dim GC2 As Integer = GC.AddrOfPinnedObject.ToInt32
        GC.Free()
        Return GC2
    End Function

i have refered to Equivalent of CopyMemory in .NET

but still i am not getting this

please somebody help!!!


Solution

  • If you want to access data using pointers in .NET then you need to keep them pinned during the whole operation. The VarPtr method pins the object while getting the address to it, but then it unpins the object. That means that the object can be moved while you are doing the CopyMem call. Most of the time the object isn't moved, so it would seem to work fine, but when it is moved the CopyMem operation could change some other data. That could make any object in your application behave strangely, or crash the application.

    Anyhow, using memory copy is definitely overkill for moving a few bits in an integer. (The Long data type in VB 6 corresponds to the Integer data type in VB.NET by the way.)

    You can convert the integer to a byte array, use the Array.Copy method, and then convert it back:

    Dim temp As Byte() = BitConverter.GetBytes(dataX)
    Array.Copy(temp, 0, temp, 1, 3)
    dataX = BitConverter.ToInt32(temp, 0)
    

    You can also do it using bit operations:

    dataX = (dataX And &HFF) Or (dataX << 8)
    

    Side note: The Encoding.Unicode is for the UTF-16 encoding. That means that the byte array that GetBytes returns will be twice the length of the string, so you will be using only half of the string.