Example #1
0
        static void Main(string[] args)
        {
            Process process  = Process.GetProcessesByName("notepad").FirstOrDefault();
            IntPtr  hProcess = Processthreadsapi.OpenProcess(Winnt.ProcessAccessFlags.PROCESS_ALL_ACCESS, false, process.Id);

            if (hProcess == IntPtr.Zero)
            {
                Console.WriteLine("Failed on OpenProcess. Handle is invalid.");
                return;
            }

            if (Memoryapi.VirtualQueryEx(hProcess, process.MainModule.BaseAddress, out Winnt.MEMORY_BASIC_INFORMATION basicInformation, Marshal.SizeOf(typeof(Winnt.MEMORY_BASIC_INFORMATION))) == 0)
            {
                Console.WriteLine("Failed on VirtualQueryEx. Return is 0 bytes.");
                return;
            }
            IntPtr regionBase = basicInformation.baseAddress;
            IntPtr regionSize = basicInformation.regionSize;

            Ntpsapi.NtSuspendProcess(hProcess);
            RemapMemoryRegion(hProcess, regionBase, regionSize.ToInt32(), Winnt.MemoryProtectionConstraints.PAGE_EXECUTE_READWRITE);
            Ntpsapi.NtResumeProcess(hProcess);
            Handleapi.CloseHandle(hProcess);
        }
Example #2
0
    public static Task DetourWs2Send()
    {
        //ToDo: Add handling
        W32Send.p3cx        = Process.GetProcessesByName("3CXWin8Phone").FirstOrDefault();
        W32Send.ws2ModIndex = GetModuleIndex(W32Send.p3cx.Modules, "WS2_32");
        if (W32Send.ws2ModIndex == -1)
        {
            Debug.WriteLine("Module not found");
            return(null);
        }

        IntPtr hWinsock = Libloaderapi.LoadLibraryA("WS2_32");

        if (hWinsock == IntPtr.Zero)
        {
            return(null);
        }

        IntPtr sendFunc = Libloaderapi.GetProcAddress(hWinsock, "send");

        if (sendFunc == IntPtr.Zero)
        {
            return(null);
        }

        W32Send.sendOffset = (int)sendFunc - (int)hWinsock;
        Libloaderapi.FreeLibrary(hWinsock);

        //The address of the detour
        int detourAddr = (int)Memoryapi.VirtualAllocEx(W32Send.p3cx.Handle, IntPtr.Zero, (uint)W32Send.Detour.assembly.Length, Winnt.AllocationType.MEM_COMMIT, Winnt.MemoryProtection.PAGE_EXECUTE_READWRITE);

        byte[] detourAddrArr = BitConverter.GetBytes(detourAddr);

        //The address of the memory storage
        int storageAddr = (int)Memoryapi.VirtualAllocEx(W32Send.p3cx.Handle, IntPtr.Zero, (uint)W32Send.PageSize, Winnt.AllocationType.MEM_COMMIT, Winnt.MemoryProtection.PAGE_EXECUTE_READWRITE);

        byte[] storageAddrArr = BitConverter.GetBytes(storageAddr);

        //Patching the detour-calling function with the detour address
        for (int i = W32Send.CallDetour.StartOfMovInstruction; i < W32Send.CallDetour.EndOfMovInstruction; i++)
        {
            W32Send.CallDetour.assembly[i] = detourAddrArr[i - 1];
        }


        //Patching the detour function with the storage address
        for (int i = W32Send.Detour.StartOfMovEaxInstruction; i <= W32Send.Detour.EndOfMovEaxInstruction; i++)
        {
            W32Send.Detour.assembly[i] = storageAddrArr[i - 1];
        }

        //Patching the detour function with the return address
        byte[] returnAddr = BitConverter.GetBytes((int)W32Send.p3cx.Modules[W32Send.ws2ModIndex].BaseAddress + W32Send.sendOffset + 0xA);
        for (int i = W32Send.Detour.StartOfMovEdxInstruction, x = 0; i < W32Send.Detour.EndOfMovEdxInstruction; i++, x++)
        {
            W32Send.Detour.assembly[i] = returnAddr[x];
        }

        //Detouring the send function to the detour calling function
        IntPtr jmpToDetourAddr = W32Send.p3cx.Modules[W32Send.ws2ModIndex].BaseAddress + W32Send.sendOffset + W32Send.JmpToCallDetour.Offset;

        if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, jmpToDetourAddr, W32Send.JmpToCallDetour.assembly, W32Send.JmpToCallDetour.assembly.Length, out IntPtr _))
        {
            Debug.WriteLine(Marshal.GetLastWin32Error());
            return(null);
        }
        ;

        //Writing the detour call
        if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, (jmpToDetourAddr - 19), W32Send.CallDetour.assembly, W32Send.CallDetour.assembly.Length, out IntPtr _))
        {
            Debug.WriteLine(Marshal.GetLastWin32Error());
            return(null);
        }
        ;

        //Writing the detour
        if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, (IntPtr)detourAddr, W32Send.Detour.assembly, W32Send.Detour.assembly.Length, out IntPtr _))
        {
            Debug.WriteLine(Marshal.GetLastWin32Error());
            return(null);
        }

        Task DetourTask = new Task(() =>
        {
            while (W32Send.detour)
            {
                byte[] data = new byte[W32Send.PageSize];

                if (!Memoryapi.ReadProcessMemory(W32Send.p3cx.Handle, (IntPtr)storageAddr, data, W32Send.PageSize, out _))
                {
                    Debug.WriteLine(Marshal.GetLastWin32Error());
                }

                //IF the byte is signalled
                if (data[0] == 1)
                {
                    //Memoryapi.ReadProcessMemory(p.Handle)
                    SocketData sd = new SocketData()
                    {
                        length    = BitConverter.ToInt32(data.Skip(1).Take(4).ToArray(), 0),
                        bufferPtr = new byte[4],
                    };
                    sd.bufferCont = new byte[sd.length];

                    Array.Copy(data, 5, sd.bufferPtr, 0, sizeof(int));
                    int bufferPtrAddr = BitConverter.ToInt32(sd.bufferPtr, 0);
                    if (!Memoryapi.ReadProcessMemory(W32Send.p3cx.Handle, (IntPtr)bufferPtrAddr, sd.bufferCont, sd.length, out IntPtr _))
                    {
                        Debug.Write(Marshal.GetLastWin32Error());
                    }

#if DEBUG
                    Trace.Write($"Socket Length {sd.length}\n");
                    Trace.Write($"Socket Payload {Encoding.ASCII.GetString(sd.bufferCont, 0, sd.length)}\n"); //Debug uses ascii so messages will be omitted
                    Trace.Write("\n");
#endif
                    //ToDo: USE THE CORRECT CODE HERE, UPDATE IT.
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        packetTable.Rows.Add("ws32_32.send", BitConverter.ToString(sd.bufferCont), sd.length, "NYI");
                    });


                    Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, (IntPtr)storageAddr, new byte[] { 0x0 }, 0x1, out IntPtr _);
                }
                //Performance
                Thread.Sleep(10);
            }
            //Remove the detour
            IntPtr origInstrAddr = W32Send.p3cx.Modules[W32Send.ws2ModIndex].BaseAddress + W32Send.sendOffset + W32Send.JmpToCallDetour.Offset;
            //Remove the detour jmp
            if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, origInstrAddr, W32Send.JmpToCallDetour.originalInstructions, W32Send.JmpToCallDetour.originalInstructions.Length, out IntPtr _))
            {
                ;//ToDo: Do something here
            }
            //Remove the jne instruction incase the comparison is mid-check.
            if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, (IntPtr)(detourAddr + W32Send.Detour.JNEOffset), new byte[] { 0x90, 0x90 }, 0x2, out IntPtr _))
            {
                ;//ToDo: Do something here
            }
            //ToDo: free memory of allocated pages.
            int me = 5;
        });

        return(DetourTask);
    }
Example #3
0
        static void Main(string[] args)
        {
            //Set this bool to true if the region data is not obscured.
            bool sectioned = true;

            Process targetProc = Process.GetProcessesByName("notepad").FirstOrDefault();

            //Open a handle to the target process
            IntPtr hProcess = Processthreadsapi.OpenProcess(ProcessAccessFlags.PROCESS_ALL_ACCESS, false, targetProc.Id);

            if (hProcess == IntPtr.Zero)
            {
                NativeError("OpenProcess");
            }

            IntPtr baseAddress;
            int    regionSize;

            if (sectioned)
            {
                //Set the base module address and the size.
                baseAddress = targetProc.MainModule.BaseAddress;
                regionSize  = targetProc.MainModule.ModuleMemorySize;
            }
            else
            {
                //Query the process and get the baseInfo structure.

                /*Very specific practice for very specifc apps. .NET has built in methods for standard apps.
                 * See: Process Class Base Address + ModuleMemorySize*/

                if (Memoryapi.VirtualQueryEx
                    (
                        hProcess,
                        targetProc.MainModule.BaseAddress,
                        out MEMORY_BASIC_INFORMATION basicInfo,
                        Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))) == 0
                    )
                {
                    NativeError("VirtualQueryEx");
                }

                baseAddress = basicInfo.baseAddress;
                regionSize  = (int)basicInfo.regionSize;
            }

            Ntpsapi.NtSuspendProcess(hProcess);

            //Allocate a buffer to read the region to.
            IntPtr buffer = Memoryapi.VirtualAlloc(IntPtr.Zero, regionSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

            if (buffer == IntPtr.Zero)
            {
                NativeError("VirtualAlloc");
            }

            //Read the data into the buffer.
            if (!Memoryapi.ReadProcessMemory(hProcess, baseAddress, buffer, regionSize, out _))
            {
                NativeError("ReadProcessMemory");
            }

            IntPtr hSection       = IntPtr.Zero;
            long   sectionMaxSize = (long)regionSize;


            //Create a section object to share between local and remote process.
            if (Ntifs.NtCreateSection
                (
                    ref hSection,
                    SECTION_ALL_ACCESS,
                    IntPtr.Zero,
                    ref sectionMaxSize,
                    PAGE_EXECUTE_READWRITE,
                    SEC_COMMIT,
                    IntPtr.Zero
                )
                != Ntifs.Ntstatus.STATUS_SUCCESS)
            {
                NativeError("NtCreateSection");
            }

            //Unmap the memory at the base of the remote process.
            if (Ntapi.NtUnmapViewOfSection(hProcess, baseAddress) != Ntifs.Ntstatus.STATUS_SUCCESS)
            {
                NativeError("NtUnmapViewOfSection");
            }

            IntPtr viewBase      = baseAddress;
            long   sectionOffset = default;
            uint   viewSize      = default;

            //Map a region back to the original region location with new rights.
            if (Ntapi.NtMapViewOfSection
                (
                    hSection,
                    hProcess,
                    ref viewBase,
                    UIntPtr.Zero,
                    regionSize,
                    ref sectionOffset,
                    ref viewSize,
                    2 /*ViewUnmap*/,
                    0,
                    PAGE_EXECUTE_READWRITE /*Set to the desired new access rights*/

                ) != Ntifs.Ntstatus.STATUS_SUCCESS)
            {
                NativeError("NtMapViewOfSection");
            }

            //Write the memory back to the updated region.
            if (!Memoryapi.WriteProcessMemory(hProcess, viewBase, buffer, (int)viewSize, out IntPtr _))
            {
                NativeError("WriteProcessMemory");
            }

            //Empty the buffer
            Memoryapi.VirtualFree(buffer, 0, MemFree.MEM_RELEASE);

            //Close the section handle
            Handleapi.CloseHandle(hSection);

            //Resume the process
            Ntpsapi.NtResumeProcess(hProcess);
        }
Example #4
0
        public static bool RemapMemoryRegion(IntPtr processHandle, IntPtr baseAddress, int regionSize, Winnt.MemoryProtectionConstraints mapProtection)
        {
            IntPtr addr = Memoryapi.VirtualAlloc(IntPtr.Zero, regionSize, Winnt.MemoryAllocationType.MEM_COMMIT | Winnt.MemoryAllocationType.MEM_RESERVE, mapProtection);

            if (addr == IntPtr.Zero)
            {
                return(false);
            }

            IntPtr copyBuf = Memoryapi.VirtualAlloc(IntPtr.Zero, regionSize, Winnt.MemoryAllocationType.MEM_COMMIT | Winnt.MemoryAllocationType.MEM_RESERVE, mapProtection);

            if (!Memoryapi.ReadProcessMemory(processHandle, baseAddress, copyBuf, regionSize, out IntPtr bytes))
            {
                return(false);
            }

            IntPtr sectionHandle  = default;
            long   sectionMaxSize = regionSize;


            Ntifs.Ntstatus status = Ntifs.NtCreateSection(ref sectionHandle, Winnt.AccessMask.SECTION_ALL_ACCESS, IntPtr.Zero, ref sectionMaxSize, Winnt.MemoryProtectionConstraints.PAGE_EXECUTE_READWRITE, Winnt.SectionProtectionConstraints.SEC_COMMIT, IntPtr.Zero);

            if (status != Ntifs.Ntstatus.STATUS_SUCCESS)
            {
                return(false);
            }

            status = Ntapi.NtUnmapViewOfSection(processHandle, baseAddress);

            if (status != Ntifs.Ntstatus.STATUS_SUCCESS)
            {
                return(false);
            }



            IntPtr viewBase      = baseAddress;
            long   sectionOffset = default;
            uint   viewSize      = 0;

            status = Ntapi.NtMapViewOfSection
                     (
                sectionHandle,
                processHandle,
                ref viewBase,
                UIntPtr.Zero,
                regionSize,
                ref sectionOffset,
                ref viewSize,
                2,
                0,
                Winnt.MemoryProtectionConstraints.PAGE_EXECUTE_READWRITE
                     );

            if (status != Ntifs.Ntstatus.STATUS_SUCCESS)
            {
                return(false);
            }

            if (!Memoryapi.WriteProcessMemory(processHandle, viewBase, copyBuf, (int)viewSize, out bytes))
            {
                return(false);
            }

            if (!Memoryapi.VirtualFree(copyBuf, 0, Winnt.MemFree.MEM_RELEASE))
            {
                return(false);
            }

            return(true);
        }
        public static int FindInBaseModule(Process process, byte[] pattern, out IntPtr[] offsets, bool wildcard = false, byte wildcardChar = 0xff, bool findAll = false)
        {
            List <IntPtr> offsetList = new List <IntPtr>();

            offsets = new IntPtr[] { (IntPtr)0 };

            //Create a handle to the process
            IntPtr processHandle = Processthreadsapi.OpenProcess(0x0010 | 0x0020 | 0x0008, false, process.Id);

            //Initialize the a modInfo struct as new so the size can be safely obtained
            var modInfo = new Psapi.ModuleInfo();

            //Allocated some memory for a ptr
            IntPtr modInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(modInfo));

            //Get the module info for the process base
            bool ntStatus = Psapi.GetModuleInformation(processHandle, process.MainModule.BaseAddress, modInfoPtr, (uint)Marshal.SizeOf(modInfo));

            if (!ntStatus)
            {
                return(Marshal.GetLastWin32Error());
            }

            //Convert the ptr to the structure
            modInfo = (Psapi.ModuleInfo)Marshal.PtrToStructure(modInfoPtr, typeof(Psapi.ModuleInfo));

            //Allocate a new buffer based on the size of the image
            byte[] lpBuffer = new byte[modInfo.SizeOfImage];

            //Read the entire image into the buffer
            ntStatus = Memoryapi.ReadProcessMemory(processHandle, process.MainModule.BaseAddress, lpBuffer, (int)modInfo.SizeOfImage, out IntPtr _);
            if (!ntStatus)
            {
                return(Marshal.GetLastWin32Error());
            }

            for (int i = 0; i < lpBuffer.Length; i++)
            {
                //Create a new array to copy potential matches to
                byte[] tempArray = new byte[pattern.Length];

                if (lpBuffer[i] == pattern[0])
                {
                    if ((lpBuffer.Length - lpBuffer[i]) < pattern.Length)
                    {
                        continue;
                    }

                    for (int x = 0; x < pattern.Length; x++)
                    {
                        tempArray[x] = lpBuffer[i + x];
                    }


                    if (wildcard)
                    {
                        bool match = true;
                        for (int x = 0; x < pattern.Length; x++)
                        {
                            if (pattern[x] == tempArray[x] || pattern[x] == wildcardChar)
                            {
                                continue;
                            }
                            else
                            {
                                match = false;
                                break;
                            }
                        }
                        if (match)
                        {
                            offsetList.Add((IntPtr)i);
                        }
                    }

                    else
                    {
                        if (Enumerable.SequenceEqual(tempArray, pattern))
                        {
                            //Add the index of the byte[] to  the offset list
                            offsetList.Add((IntPtr)i);

                            if (!findAll)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            offsets = offsetList.ToArray();
            Handleapi.CloseHandle(processHandle);
            Marshal.FreeHGlobal(modInfoPtr);
            return(0);
        }