none
VirtualAllocEx/WriteProcessMemory and writing C# char arrays.

    Question

  •  

     

    (Warning, I have not slept)

    Very long story short, I'm trying to pinvoke VirtualAllocEx and WriteProcessMemory to call CreateRemoteThread with LoadLibrary(A/W).  Aka DLL Inject, using C#.  The problem is that LoadLibrary doesn't seem to be working, if I change it to "ExitProcess" then my arbitrary victimized PIDs die--as anticipated.  I am somewhat following section 2 of this article: http://www.codeproject.com/KB/threads/winspy.aspx#section_2

     

    [DllImport("kernel32.dll", SetLastError = true)]
            static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
    
    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
            static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
               uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
            [Flags]
            public enum AllocationType
            {
                 Commit = 0x1000,
                 Reserve = 0x2000,
                 Decommit = 0x4000,
                 Release = 0x8000,
                 Reset = 0x80000,
                 Physical = 0x400000,
                 TopDown = 0x100000,
                 WriteWatch = 0x200000,
                 LargePages = 0x20000000
            }
    
            [Flags]
            public enum MemoryProtection
            {
                 Execute = 0x10,
                 ExecuteRead = 0x20,
                 ExecuteReadWrite = 0x40,
                 ExecuteWriteCopy = 0x80,
                 NoAccess = 0x01,
                 ReadOnly = 0x02,
                 ReadWrite = 0x04,
                 WriteCopy = 0x08,
                 GuardModifierflag = 0x100,
                 NoCacheModifierflag = 0x200,
                 WriteCombineModifierflag = 0x400
            }
    
    IntPtr processPtr = OpenProcess((int)ProcessAccessFlags.All, false, PID);
                    
    string LibraryPath = @"C:\Users\Nathan\Documents\Visual Studio 2010\Projects\InjectorForm\Debug\PMRecorder.dll";
    byte[] bLibraryPath = Encoding.Unicode.GetBytes(LibraryPath.ToCharArray());
    IntPtr pLibRemote = VirtualAllocEx(processPtr, IntPtr.Zero, (uint)bLibraryPath.Length, AllocationType.Commit, MemoryProtection.ReadWrite);
    UIntPtr dummy;
    WriteProcessMemory(processPtr, pLibRemote, bLibraryPath, (uint)bLibraryPath.Length, out dummy);
    IntPtr krnl32 = GetModuleHandle("Kernel32");
    IntPtr handle =
    CreateRemoteThread(processPtr, (IntPtr)null, 0, GetProcAddress(krnl32, "LoadLibraryW"), pLibRemote, 0, IntPtr.Zero);
    

     

    I've been looking, thinking, and completely lost on how to format a string at a low enough level for WriteProcessMemory (and be able to get it's size) The working C++ code I've been porting is as follows.

     

    HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    char szLibPath[MAX_PATH] = "C:\\Users\\Nathan\\Documents\\Visual Studio 2010\\Projects\\InjectorForm\\Debug\\PMRecorder.dll";
    
    void* pLibRemote = VirtualAllocEx(proc, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(proc, pLibRemote, (void*)szLibPath, sizeof(szLibPath), NULL);
    
    HMODULE hKernel32 = GetModuleHandle(TEXT("Kernel32"));
    				 
    HANDLE thread =
     CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32,"LoadLibraryA"), pLibRemote, 0, NULL);
    

     

     

    Does anybody have a clue where to start? I'm stumped on how to format it, and I don't want to have to move this code into a C++/CLI style wrapper.

     





    • Edited by BinarySpike Thursday, January 19, 2012 3:15 PM (cleaning up code)
    Thursday, January 19, 2012 2:58 PM

Answers

  • Well, my approach was on target.  I decided to write all the code from an 'ExitProcess' standpoint, then add VirtualAllocEx and WriteProcessMemory after-the-fact.  Hopefully this can help someone. (A little sleep goes a long way!)

    IntPtr processPtr, argumentPtr = IntPtr.Zero, threadPtr, dummy = IntPtr.Zero,
        krnl32 = GetModuleHandle("Kernel32");
    
    string bufferString = @"C:\Users\Nathan\Documents\Visual Studio 2010\Projects\InjectorForm\Debug\PMRecorder.dll";
    
    
    byte[] buffer = Encoding.Unicode.GetBytes(bufferString.ToCharArray());
    uint size = (uint)Encoding.Unicode.GetByteCount(bufferString.ToCharArray());
    
    // open process
    processPtr = OpenProcess((int)ProcessAccessFlags.All, false, PID);
    TrapError(processPtr);
    
    // allocate memory
    argumentPtr = VirtualAllocEx(processPtr, IntPtr.Zero, size, AllocationType.Commit, MemoryProtection.ReadWrite);
    TrapError(argumentPtr);
    
    // write memory
    if (!WriteProcessMemory(processPtr, argumentPtr, buffer, size, out dummy))
    {
        // err...
        Console.WriteLine("WriteProcessMemory false");
    }
    
                
    // create remote thread in process
    threadPtr = CreateRemoteThread(processPtr, IntPtr.Zero, 0, GetProcAddress(krnl32, "LoadLibraryW"), argumentPtr, 0, IntPtr.Zero);
    TrapError(threadPtr);
                
    // wait for thread to finish TODO
    UInt32 test = WaitForSingleObject(threadPtr, INFINITE);
    //TrapError(IntPtr.Zero);
    
    // close handle to thread
    if (!CloseHandle(threadPtr))
    {
        // err...
        Console.WriteLine("CloseHandle(threadPtr) false");
    }
    
    // release allocated memory
    VirtualFreeEx(processPtr, argumentPtr, size, FreeType.Release);
    
    // close handle to process
    if (!CloseHandle(processPtr))
    {
        // err...
        Console.WriteLine("CloseHandle(processPtr) false");
    }
    
    (syntax coloring isn't working...)
    Note I'm using the unicode LoadLibraryW.
    Sometimes getting your thoughts out is all it takes! Thanks

    • Edited by BinarySpike Friday, January 20, 2012 4:40 PM
    • Marked as answer by BinarySpike Friday, January 27, 2012 2:09 AM
    Friday, January 20, 2012 4:37 PM
  • How about this: 
    http://blogs.msdn.com/b/jmstall/archive/2006/09/28/managed-create-remote-thread.aspx
    http://stackoverflow.com/questions/24241/code-injection-with-c-sharp
    • Marked as answer by BinarySpike Friday, January 27, 2012 2:09 AM
    Saturday, January 21, 2012 3:17 AM

All replies

  • Well, my approach was on target.  I decided to write all the code from an 'ExitProcess' standpoint, then add VirtualAllocEx and WriteProcessMemory after-the-fact.  Hopefully this can help someone. (A little sleep goes a long way!)

    IntPtr processPtr, argumentPtr = IntPtr.Zero, threadPtr, dummy = IntPtr.Zero,
        krnl32 = GetModuleHandle("Kernel32");
    
    string bufferString = @"C:\Users\Nathan\Documents\Visual Studio 2010\Projects\InjectorForm\Debug\PMRecorder.dll";
    
    
    byte[] buffer = Encoding.Unicode.GetBytes(bufferString.ToCharArray());
    uint size = (uint)Encoding.Unicode.GetByteCount(bufferString.ToCharArray());
    
    // open process
    processPtr = OpenProcess((int)ProcessAccessFlags.All, false, PID);
    TrapError(processPtr);
    
    // allocate memory
    argumentPtr = VirtualAllocEx(processPtr, IntPtr.Zero, size, AllocationType.Commit, MemoryProtection.ReadWrite);
    TrapError(argumentPtr);
    
    // write memory
    if (!WriteProcessMemory(processPtr, argumentPtr, buffer, size, out dummy))
    {
        // err...
        Console.WriteLine("WriteProcessMemory false");
    }
    
                
    // create remote thread in process
    threadPtr = CreateRemoteThread(processPtr, IntPtr.Zero, 0, GetProcAddress(krnl32, "LoadLibraryW"), argumentPtr, 0, IntPtr.Zero);
    TrapError(threadPtr);
                
    // wait for thread to finish TODO
    UInt32 test = WaitForSingleObject(threadPtr, INFINITE);
    //TrapError(IntPtr.Zero);
    
    // close handle to thread
    if (!CloseHandle(threadPtr))
    {
        // err...
        Console.WriteLine("CloseHandle(threadPtr) false");
    }
    
    // release allocated memory
    VirtualFreeEx(processPtr, argumentPtr, size, FreeType.Release);
    
    // close handle to process
    if (!CloseHandle(processPtr))
    {
        // err...
        Console.WriteLine("CloseHandle(processPtr) false");
    }
    
    (syntax coloring isn't working...)
    Note I'm using the unicode LoadLibraryW.
    Sometimes getting your thoughts out is all it takes! Thanks

    • Edited by BinarySpike Friday, January 20, 2012 4:40 PM
    • Marked as answer by BinarySpike Friday, January 27, 2012 2:09 AM
    Friday, January 20, 2012 4:37 PM
  • How about this: 
    http://blogs.msdn.com/b/jmstall/archive/2006/09/28/managed-create-remote-thread.aspx
    http://stackoverflow.com/questions/24241/code-injection-with-c-sharp
    • Marked as answer by BinarySpike Friday, January 27, 2012 2:09 AM
    Saturday, January 21, 2012 3:17 AM