Esempio n. 1
0
 /// <summary>
 /// Helper function for implementing memset.  Could be more efficient if we 
 /// could P/Invoke or call some otherwise native code to do this.
 /// </summary>
 private static IntPtr MemSet(IntPtr dest, byte value, IntPtr length) {            
     IntPtr end = dest.Add(length.ToInt32());
     for (IntPtr cur = dest; cur != end; cur = new IntPtr(cur.ToInt64() + 1)) {
         Marshal.WriteByte(cur, value);
     }
     return dest;
 }
Esempio n. 2
0
        internal static PyType GetPyType(IntPtr po, bool derived)
        {
            if (!_initialized)
                InitializeStructures();

            if (po == IntPtr.Zero)
                return PyType.Invalid;

            PyType type;
            var pyType = Marshal.ReadIntPtr(po.Add(4));
            if (!_types.TryGetValue(pyType, out type))
            {
                type = GetPyType(pyType, true);
                _types.Add(pyType, type);
                return type;
            }

            if (derived)
            {
                var s = type.ToString();
                type = (PyType) Enum.Parse(typeof (PyType), "Derived" + s);
            }

            return type;
        }
        public BonfireStates GetBonfireState(BonfireFlags bonfire)
        {
            IntPtr pointer = (IntPtr)0x137E204;

            pointer = (IntPtr)MemoryTools.ReadInt(handle, pointer);
            pointer = (IntPtr)MemoryTools.ReadInt(handle, IntPtr.Add(pointer, 0xB48));
            pointer = (IntPtr)MemoryTools.ReadInt(handle, IntPtr.Add(pointer, 0x24));
            pointer = (IntPtr)MemoryTools.ReadInt(handle, pointer);

            IntPtr bonfirePointer = (IntPtr)MemoryTools.ReadInt(handle, IntPtr.Add(pointer, 0x8));

            while (bonfirePointer != IntPtr.Zero)
            {
                int bonfireId = MemoryTools.ReadInt(handle, IntPtr.Add(bonfirePointer, 0x4));

                if (bonfireId == (int)bonfire)
                {
                    int bonfireState = MemoryTools.ReadInt(handle, IntPtr.Add(bonfirePointer, 0x8));

                    return((BonfireStates)bonfireState);
                }

                pointer        = (IntPtr)MemoryTools.ReadInt(handle, pointer);
                bonfirePointer = (IntPtr)MemoryTools.ReadInt(handle, IntPtr.Add(pointer, 0x8));
            }

            return(BonfireStates.Undiscovered);
        }
        internal static void CopyUnmanagedMemory(IntPtr srcPtr, int srcOffset, IntPtr dstPtr, int dstOffset, int count)
        {
            srcPtr = srcPtr.Add<byte>( srcOffset );
            dstPtr = dstPtr.Add<byte>( dstOffset );

            memcpy(dstPtr, srcPtr, (UInt32)count );
        }
Esempio n. 5
0
 /// <summary>
 ///     Adds the specified integer to the module address supplied.
 /// </summary>
 /// <param name="addressToRebase">The address to rebase to the module address.</param>
 /// <param name="moduleAddress">The address of the module being rebased to.</param>
 /// <returns></returns>
 public static IntPtr Add(this int addressToRebase, IntPtr moduleAddress) => moduleAddress.Add(addressToRebase);
Esempio n. 6
0
        public override bool Unload(IntPtr hModule, IntPtr hProcess)
        {
            // Unloading a manually mapped file is fairly straightforward. There is no need to call FreeLibrary or anything
            // because the file was never actually injected using LoadLibrary and doesn't need to clear any PEB entries etc.
            // basically just call the Entry Point again with DLL_PROCESS_DETACH flag and not-null for the lpReserved parameter
            // and then VirtualFree the remote memory.
            ClearErrors();

            if (hModule.IsNull())
                throw new ArgumentNullException("hModule", "Invalid module handle");

            if (hProcess.IsNull() || hProcess.Compare(-1))
                throw new ArgumentException("Invalid process handle.", "hProcess");

            IntPtr pStub = IntPtr.Zero;
            uint nBytes = 0;
            try
            {
                uint entry = FindEntryPoint(hProcess, hModule);
                if (entry != 0)
                {
                    var stub = (byte[])DLLMAIN_STUB.Clone();
                    BitConverter.GetBytes(hModule.ToInt32()).CopyTo(stub, 0x0B);
                    BitConverter.GetBytes((uint)0).CopyTo(stub, 0x06);
                    BitConverter.GetBytes((uint)1000).CopyTo(stub, 0x01);

                    pStub = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)DLLMAIN_STUB.Length, 0x1000 | 0x2000, 0x40);
                    if (pStub.IsNull() || (!WinAPI.WriteProcessMemory(hProcess, pStub, stub, stub.Length, out nBytes) || nBytes != (uint)stub.Length))
                        throw new InvalidOperationException("Unable to write stub to the remote process.");

                    IntPtr hStubThread = WinAPI.CreateRemoteThread(hProcess, 0, 0, pStub, (uint)hModule.Add(entry).ToInt32(), 0, 0);
                    if (WinAPI.WaitForSingleObject(hStubThread, 5000) == 0x0L)
                    {
                        WinAPI.VirtualFreeEx(hProcess, pStub, 0, 0x8000);
                        WinAPI.CloseHandle(hStubThread);
                        return WinAPI.VirtualFreeEx(hProcess, hModule, 0, 0x8000);
                    }
                    return false;
                }
                else
                {
                    return WinAPI.VirtualFreeEx(hProcess, hModule, 0, 0x8000);
                }
            }
            catch (Exception e)
            {
                SetLastError(e);
                return false;
            }
        }
Esempio n. 7
0
        private static void MapSections(PortableExecutable image, IntPtr hProcess, IntPtr pModule)
        {
            //very straightforward really. Just iterate through all the sections and map them to their desired virtual addresses in the remote process.
            //I'm not 100% sure about how well masking the section header characteristics and passing them off as memory protection constants goes. But
            //so far I haven't hit any issues. (i.e a section header with characteristics "IMAGE_SCN_TYPE_NO_PAD" will set "PAGE_WRITECOPY" memory protection.
            byte[] databuffer;
            uint n;

            foreach (var pSecHd in image.EnumSectionHeaders())
            {
                databuffer = new byte[pSecHd.SizeOfRawData];
                if (image.Read(pSecHd.PointerToRawData, SeekOrigin.Begin, databuffer))
                {
                    if ((pSecHd.Characteristics & 0x02000000) == 0) //can actually ignore this section (usually the reloc section)
                    {
                        WinAPI.WriteProcessMemory(hProcess, pModule.Add(pSecHd.VirtualAddress), databuffer, databuffer.Length, out n);
                        WinAPI.VirtualProtectEx(hProcess, pModule.Add(pSecHd.VirtualAddress), pSecHd.SizeOfRawData, pSecHd.Characteristics & 0x00FFFFFF, out n);
                    }
                }
                else
                {
                    throw image.GetLastError();
                }
            }
        }
Esempio n. 8
0
        /**
         * Find the entry point of a loaded module
         * based on its Base Address. Reverses the PE
         * structure to find the entry point
         */
        private static uint FindEntryPoint(IntPtr hProcess, IntPtr hModule)
        {
            if (hProcess.IsNull() || hProcess.Compare(-1))
                throw new ArgumentException("Invalid process handle.", "hProcess");
            if (hModule.IsNull())
                throw new ArgumentException("Invalid module handle.", "hModule");

            byte[] bDosHeader = WinAPI.ReadRemoteMemory(hProcess, hModule, (uint)Marshal.SizeOf(typeof(IMAGE_DOS_HEADER)));
            if (bDosHeader != null)
            {
                ushort e_magic = BitConverter.ToUInt16(bDosHeader, 0);
                uint e_lfanew = BitConverter.ToUInt32(bDosHeader, 0x3C);
                if (e_magic == 23117)
                {
                    byte[] bNtHeader = WinAPI.ReadRemoteMemory(hProcess, hModule.Add(e_lfanew), (uint)Marshal.SizeOf(typeof(IMAGE_NT_HEADER32)));
                    if (bNtHeader != null && BitConverter.ToUInt32(bNtHeader, 0) == 17744)
                    {
                        IMAGE_NT_HEADER32 ntHd = default(IMAGE_NT_HEADER32);
                        using (var buffer = new UnmanagedBuffer(256))
                            if (buffer.Translate<IMAGE_NT_HEADER32>(bNtHeader, out ntHd))
                                return ntHd.OptionalHeader.AddressOfEntryPoint;
                    }
                }
            }
            return 0;
        }
        public int GetGameTimeInMilliseconds()
        {
            IntPtr pointer = (IntPtr)MemoryTools.ReadInt(handle, (IntPtr)0x1378700);

            return(MemoryTools.ReadInt(handle, IntPtr.Add(pointer, 0x68)));
        }
Esempio n. 10
0
        public static string ReadRemoteString(IntPtr hProcess, IntPtr lpAddress, Encoding encoding = null)
        {
            if (encoding == null)
                encoding = Encoding.ASCII;

            var builder = new StringBuilder(); //easiest and cleanest way to build an unknown-length string.
            byte[] buffer = new byte[256];
            uint nbytes = 0;
            int terminator = -1, index = 0;

            while (terminator < 0 && ReadProcessMemory(hProcess, lpAddress, buffer, buffer.Length, out nbytes) && nbytes > 0)
            {
                lpAddress = lpAddress.Add(nbytes); //advance where we're reading from.
                index = builder.Length; //micro-optimization for .IndexOf
                builder.Append(encoding.GetString(buffer, 0, (int)nbytes)); //append the data to the StringBuilder
                terminator = builder.ToString().IndexOf('\0', index); //check if there's a null-byte in the string yet (strings are null-terminated)
            }

            return builder.ToString().Substring(0, terminator);  //return the data up til the null terminator.
        }
Esempio n. 11
0
        private static int SearchExports(IntPtr hProcess, IntPtr hModule, byte[] exports, string name)
        {
            uint cntExports = BitConverter.ToUInt32(exports, 0x18); //number of named exported functions
            uint ptrNameTable = BitConverter.ToUInt32(exports, 0x20); //pointer to the export name table
            int rva = -1;

            if (cntExports > 0 && ptrNameTable > 0)
            {
                byte[] rawPtrs = ReadRemoteMemory(hProcess, hModule.Add(ptrNameTable), cntExports << 2); //be lazy and read all the name pointers at once.
                if (rawPtrs != null)
                {
                    //quickly convert that series of bytes into pointer values that make sense. 
                    uint[] namePtrs = new uint[cntExports];
                    for (int i = 0; i < namePtrs.Length; i++)
                        namePtrs[i] = BitConverter.ToUInt32(rawPtrs, i << 2);

                    //binary search, huzzah! Part of the PE specification is that all exported functions are ordered lexicographically in a PE file.
                    int start = 0, end = namePtrs.Length - 1, middle = 0;
                    string curvalue = string.Empty;
                    //basically just search through all the exports looking for the specified function
                    while (start >= 0 && start <= end && rva == -1)
                    {
                        middle = (start + end) / 2;
                        curvalue = ReadRemoteString(hProcess, hModule.Add(namePtrs[middle]));
                        if (curvalue.Equals(name))
                            rva = middle;
                        else if (string.CompareOrdinal(curvalue, name) < 0)
                            start = middle - 1;
                        else
                            end = middle + 1;
                    }
                }
            }
            return rva;
        }
Esempio n. 12
0
        /*
         * This is my GetProcAddressEx function. Basically, it does exactly what GetProcAddress does,
         * but for a module in a remote process. It looks up the module, and from there parses the lexicographically
         * ordered export function table (commonly known as the EAT). It calculates based on ordinal offset.
         * However, if you find this method doesn't work for you for whatever reason (i rushed the binary search algorithm)
         * i've provided another GetProcAddressEx method below with the same parameters which basically just calls the 'official'
         * GetProcAddress function from within the remote process and captures the return. Up to you -Jason
         */
        public static IntPtr GetProcAddressEx(IntPtr hProc, IntPtr hModule, object lpProcName)
        {
            IntPtr procAddress = IntPtr.Zero;
            byte[] pDosHd = ReadRemoteMemory(hProc, hModule, 0x40); //attempt to read the DOS header from memory
            if (pDosHd != null && BitConverter.ToUInt16(pDosHd, 0) == 0x5A4D) //compare the expected DOS "MZ" signature to whatever we just read
            {
                uint e_lfanew = BitConverter.ToUInt32(pDosHd, 0x3C); //read the e_lfanew number
                if (e_lfanew > 0)
                {
                    byte[] pNtHd = ReadRemoteMemory(hProc, hModule.Add(e_lfanew), 0x108); //read the NT_HEADERS.
                    if (pNtHd != null && BitConverter.ToUInt32(pNtHd, 0) == 0x4550) //check the NT_HEADERS signature (PE\0\0)
                    {
                        uint expDirPtr = BitConverter.ToUInt32(pNtHd, 0x78); //get the pointer to the export directory (first data directory)
                        uint expDirSize = BitConverter.ToUInt32(pNtHd, 0x7C);
                        if (expDirPtr > 0 && expDirSize > 0) //does this module even export functions?
                        {
                            byte[] pExpDir = ReadRemoteMemory(hProc, hModule.Add(expDirPtr), 0x28); //Read the export directory from the process
                            uint pEat = BitConverter.ToUInt32(pExpDir, 0x1C); //pointer to the export address table
                            uint pOrd = BitConverter.ToUInt32(pExpDir, 0x24); //pointer to the ordinal table.
                            uint nFunc = BitConverter.ToUInt32(pExpDir, 0x14);
                            int ord = -1;

                            if (pEat > 0 && pOrd > 0)
                            {
                                if (lpProcName.GetType().Equals(typeof(string)))
                                {
                                    int index = SearchExports(hProc, hModule, pExpDir, (string)lpProcName); //search the exported names table for the specified function
                                    if (index > -1) //check the function was found
                                    {
                                        byte[] bOrd = ReadRemoteMemory(hProc, hModule.Add(pOrd + (index << 1)), 0x2); //read the ordinal number for the function from the process
                                        ord = (int)(bOrd == null ? -1 : BitConverter.ToUInt16(bOrd, 0)); //get the ordinal number for this function
                                    }
                                }
                                else if (lpProcName.GetType().Equals(typeof(short)) || lpProcName.GetType().Equals(typeof(ushort)))
                                {
                                    ord = int.Parse(lpProcName.ToString());
                                }
                                if (ord > -1 && ord < nFunc) //just a final check to make sure we have a valid ordinal
                                {
                                    //reference the Export Address Table to find the function address for our ordinal (don't forget to factor in the ordinal base)
                                    //Unlike zero-based indexing, the 'ordinal number' indexing starts at 1, so subtract 1 from the ordbase to get zero-based index
                                    byte[] addr = ReadRemoteMemory(hProc, hModule.Add(pEat + (ord << 2)), 0x4);
                                    if (addr != null)
                                    {
                                        uint pFunction = BitConverter.ToUInt32(addr, 0);
                                        if (pFunction >= expDirPtr && pFunction < (expDirPtr + expDirSize)) //forwarded.
                                        {
                                            string forward = ReadRemoteString(hProc, hModule.Add(pFunction));
                                            if (!string.IsNullOrEmpty(forward) && forward.Contains("."))
                                                procAddress = GetProcAddressEx(hProc, GetModuleHandleEx(hProc, forward.Split('.')[0]), forward.Split('.')[1]);
                                        }
                                        else
                                        {
                                            procAddress = hModule.Add(pFunction);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return procAddress;
        }