Esempio n. 1
0
        internal static byte[] CreateThreadIntercept32(PointerEx jumpTo, PointerEx originalIP)
        {
            List <byte> data = new List <byte>
            {
                // pusha
                0x60,

                // pushf
                0x9c,

                // mov eax, jumpTo
                0xb8
            };

            data.AddRange(BitConverter.GetBytes((int)jumpTo));

            // call eax
            data.AddRange(new byte[] { 0xff, 0xd0 });

            // popf
            data.Add(0x9d);

            // popa
            data.Add(0x61);

            // push originalIP
            data.Add(0x68);
            data.AddRange(BitConverter.GetBytes((int)originalIP));

            // ret
            data.Add(0xC3);
            return(data.ToArray());
        }
Esempio n. 2
0
 public PointerEx this[PointerEx offset]
 {
     get
     {
         return(offset + BaseAddress);
     }
 }
Esempio n. 3
0
 public ProcessModuleExportEx(string name, PointerEx absoluteAddress, int ordinal, string forwarderString)
 {
     Ordinal         = ordinal;
     AbsoluteAddress = absoluteAddress;
     Name            = name;
     Forwarder       = forwarderString;
 }
Esempio n. 4
0
        public static ProcessModuleEx FromMappedModule(PointerEx moduleHandle, byte[] moduleData)
        {
            ProcessModuleEx pmx = new ProcessModuleEx(moduleHandle, null);

            pmx.CacheExports(moduleData);
            pmx.IsManualMapped = true;
            return(pmx);
        }
Esempio n. 5
0
 public static byte[] CreateRemoteCall(PointerEx jumpLocation, PointerEx[] args, int pointerSize, PointerEx raxStorAddress, PointerEx threadStateAddress, byte xmmMask_64 = 0, ExXMMReturnType xmmReturnType = ExXMMReturnType.XMMR_NONE)
 {
     if (pointerSize == 8)
     {
         return(CreateRemoteCall64(jumpLocation, args, raxStorAddress, threadStateAddress, xmmMask_64, xmmReturnType));
     }
     return(CreateRemoteCall32(jumpLocation, args, raxStorAddress, threadStateAddress));
 }
Esempio n. 6
0
        private void MMLoadDependencies(PEImage sModule, PointerEx hModule)
        {
            var activationContext = new PEActivationContext(sModule.Resources.GetManifest(), HostProcess);

            foreach (var dependency in sModule.Imports.GetImportDescriptors())
            {
                //var dependencyFilePath = ResolveFilePath(activationContext, _processContext.ResolveModuleName(dependency.Name));
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Converts a struct to a byte array
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="s"></param>
        /// <returns></returns>
        public static byte[] ToByteArray <T>(this T s) where T : struct
        {
            PointerEx size = Marshal.SizeOf(s);

            byte[]    data     = new byte[size];
            PointerEx dwStruct = Marshal.AllocHGlobal((int)size);

            Marshal.StructureToPtr(s, dwStruct, true);
            Marshal.Copy(dwStruct, data, 0, size);
            Marshal.FreeHGlobal(dwStruct);
            return(data);
        }
Esempio n. 8
0
        private static byte[] CreateRemoteCall32(PointerEx jumpLocation, PointerEx[] args, PointerEx eaxStorAddress, PointerEx threadStateAddress)
        {
            List <byte> data = new List <byte>();

            foreach (var arg in args.Reverse())
            {
                if (arg <= byte.MaxValue)
                {
                    // push byte
                    data.AddRange(new byte[] { 0x6A, arg });
                }
                else
                {
                    // push int32
                    data.Add(0x68);
                    data.AddRange(BitConverter.GetBytes((int)arg));
                }
            }

            // mov eax, jumpLoc
            data.Add(0xB8);
            data.AddRange(BitConverter.GetBytes((int)jumpLocation));

            // call eax
            data.AddRange(new byte[] { 0xFF, 0xD0 });

            if (eaxStorAddress)
            {
                // mov eaxStorAddress, eax
                data.Add(0xA3);
                data.AddRange(BitConverter.GetBytes((int)eaxStorAddress));
            }

            // mov eax, threadStateAddress
            data.Add(0xB8);
            data.AddRange(BitConverter.GetBytes((int)threadStateAddress));

            // change thread state to finished
            // mov DWORD PTR [eax], 0x1
            data.AddRange(new byte[] { 0xC7, 0x00, 0x01, 0x00, 0x00, 0x00 });

            // xor eax, eax
            data.AddRange(new byte[] { 0x33, 0xC0 });

            // ret
            data.Add(0xC3);
            return(data.ToArray());
        }
Esempio n. 9
0
        public PointerEx Size()
        {
            PointerEx n_size = InternalDataOffsetEnd;

            n_size = n_size.Align(ARG_ALIGN);
            foreach (var arg in Arguments)
            {
                if (!arg.IsReferenceType)
                {
                    continue;
                }
                n_size += arg.Data.Length;
                n_size  = n_size.Align(ARG_ALIGN);
            }
            return(n_size);
        }
Esempio n. 10
0
        public byte[] Build(PointerEx baseAddress)
        {
            byte[]    data  = new byte[Size()];
            PointerEx index = InternalDataOffsetEnd;

            index = index.Align(ARG_ALIGN);

            foreach (var arg in Arguments)
            {
                if (!arg.IsReferenceType)
                {
                    continue;
                }
                arg.Handle = index + baseAddress;
                arg.Data.CopyTo(data, index);
                index += arg.Data.Length;
                index  = index.Align(ARG_ALIGN);
            }

            return(data);
        }
Esempio n. 11
0
        /// <summary>
        /// Manually map module into remote process.
        /// </summary>
        /// <author>Ruben Boonen (@FuzzySec)</author> (modified for external ProcessEx)
        /// <param name="localModuleHandle">Pointer to the module base.</param>
        /// <returns>PE_MANUAL_MAP object</returns>
        private PE_MANUAL_MAP MapModuleToMemory(PointerEx localModuleHandle, byte[] moduleRaw)
        {
#if DEBUG
            DLog($"Attempting to map module of size {moduleRaw.Length}");
#endif
            // Fetch PE meta data
            PE_META_DATA PEINFO = GetPeMetaData(localModuleHandle);

            // Check module matches the process architecture
            if ((PEINFO.Is32Bit && IntPtr.Size == 8) || (!PEINFO.Is32Bit && IntPtr.Size == 4))
            {
                Marshal.FreeHGlobal(localModuleHandle);
                throw new InvalidOperationException(DSTR(DSTR_MOD_ARCHITECTURE_WRONG));
            }

            // Alloc PE image memory -> RW
            IntPtr RegionSize         = PEINFO.Is32Bit ? (IntPtr)PEINFO.OptHeader32.SizeOfImage : (IntPtr)PEINFO.OptHeader64.SizeOfImage;
            IntPtr remoteModuleHandle = QuickAlloc(RegionSize);

#if DEBUG
            DLog($"Module memory allocated at 0x{remoteModuleHandle.ToInt64():X16}");
#endif
            return(__MapModuleToMemory(localModuleHandle, remoteModuleHandle, moduleRaw, PEINFO));
        }
Esempio n. 12
0
        public bool TryMapModule(out PointerEx hModule)
        {
            var sModule = new PEImage(RawDLL);

            hModule = NativeStealth.VirtualAllocEx(HostProcess.Handle, 0, (uint)sModule.Headers.PEHeader.SizeOfImage, Native.AllocationType.Commit | Native.AllocationType.Reserve, Native.MemoryProtection.ReadOnly);
            if (!hModule)
            {
                throw new Exception("Unable to allocate enough memory to map the module");
            }
            try
            {
                MMLoadDependencies(sModule, hModule);
            }
            catch
            {
                if (HostProcess.Handle)
                {
                    ProcessEx.VirtualFreeEx(HostProcess.Handle, hModule, (uint)sModule.Headers.PEHeader.SizeOfImage, (int)FreeType.Release);
                }
                throw;
            }
            ModuleHandle = hModule;
            return(true);
        }
Esempio n. 13
0
 // credit: https://github.com/erfg12/memory.dll/blob/master/Memory/memory.cs
 public Task <IEnumerable <PointerEx> > Search(string query, PointerEx start, PointerEx end, MemorySearchFlags flags)
 {
     return(Task.Run(() =>
     {
         var Results = new List <SearcherResult>();
         string[] patterns = query.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
         byte[] finalPattern = new byte[patterns.Length];
         byte[] mask = new byte[patterns.Length];
         for (int i = 0; i < patterns.Length; i++)
         {
             string s = patterns[i];
             if (s == "?")
             {
                 mask[i] = 0;
             }
             else if (s.Length < 2)
             {
                 if (s.HexByte(out byte b))
                 {
                     finalPattern[i] = b;
                 }
                 mask[i] = 0xFF;
             }
             else
             {
                 mask[i] = (byte)((s[0].IsHex() ? 0xF0 : 0) + (s[1].IsHex() ? 0x0F : 0));
                 if ((mask[i] & 0xF0) > 0)
                 {
                     finalPattern[i] += (byte)(s[0].HexByte() * 0x10);
                 }
                 if ((mask[i] & 0xF) > 0)
                 {
                     finalPattern[i] += s[1].HexByte();
                 }
             }
         }
         var sysInfo = new ProcessEx.SYSTEM_INFO();
         ProcessEx.GetSystemInfo(out sysInfo);
         PointerEx proc_min_address = sysInfo.lpMinimumApplicationAddress;
         PointerEx proc_max_address = sysInfo.lpMaximumApplicationAddress;
         if (start < proc_min_address)
         {
             start = proc_min_address;
         }
         if (end > proc_max_address)
         {
             end = proc_max_address;
         }
         PointerEx cBase = start.Clone();
         var memInfo = new ProcessEx.MEMORY_BASIC_INFORMATION();
         while (ProcessEx.VirtualQueryEx(Proc.Handle, cBase, out memInfo, (uint)Marshal.SizeOf(memInfo)) &&
                cBase < end && cBase + memInfo.RegionSize > cBase)
         {
             bool isValid = memInfo.State == ProcessEx.MEM_COMMIT;
             isValid &= memInfo.BaseAddress < proc_max_address;
             isValid &= ((memInfo.Protect & Native.PAGE_GUARD) == 0);
             isValid &= ((memInfo.Protect & Native.PAGE_NOACCESS) == 0);
             isValid &= (memInfo.Type == ProcessEx.MEM_PRIVATE) || (memInfo.Type == ProcessEx.MEM_IMAGE);
             if (isValid)
             {
                 bool isReadable = (memInfo.Protect & Native.PAGE_READONLY) > 0;
                 bool isWritable = ((memInfo.Protect & Native.PAGE_READWRITE) > 0) ||
                                   ((memInfo.Protect & Native.PAGE_WRITECOPY) > 0) ||
                                   ((memInfo.Protect & Native.PAGE_EXECUTE_READWRITE) > 0) ||
                                   ((memInfo.Protect & Native.PAGE_EXECUTE_WRITECOPY) > 0);
                 bool isExecutable = ((memInfo.Protect & Native.PAGE_EXECUTE) > 0) ||
                                     ((memInfo.Protect & Native.PAGE_EXECUTE_READ) > 0) ||
                                     ((memInfo.Protect & Native.PAGE_EXECUTE_READWRITE) > 0) ||
                                     ((memInfo.Protect & Native.PAGE_EXECUTE_WRITECOPY) > 0);
                 isReadable &= ((byte)flags & (byte)MemorySearchFlags.Read) > 0;
                 isWritable &= ((byte)flags & (byte)MemorySearchFlags.Write) > 0;
                 isExecutable &= ((byte)flags & (byte)MemorySearchFlags.Execute) > 0;
                 isValid &= isReadable || isWritable || isExecutable;
             }
             cBase = memInfo.BaseAddress + memInfo.RegionSize;
             if (!isValid)
             {
                 continue;
             }
             SearcherResult result = new SearcherResult
             {
                 BaseAddress = cBase - memInfo.RegionSize,
                 RegionSize = memInfo.RegionSize,
                 RegionBase = memInfo.BaseAddress
             };
             if (Results.Count > 0)
             {
                 var previousRegion = Results[Results.Count - 1];
                 if ((previousRegion.RegionBase + previousRegion.RegionSize) == memInfo.BaseAddress)
                 {
                     Results[Results.Count - 1] = new SearcherResult
                     {
                         BaseAddress = previousRegion.BaseAddress,
                         RegionBase = previousRegion.RegionBase,
                         RegionSize = previousRegion.RegionSize + memInfo.RegionSize
                     };
                     continue;
                 }
             }
             Results.Add(result);
         } // end while
         ConcurrentBag <PointerEx> bagResult = new ConcurrentBag <PointerEx>();
         Parallel.ForEach(Results,
                          (item, parallelLoopState, index) =>
         {
             PointerEx[] compareResults = CompareScan(item, finalPattern, mask);
             foreach (PointerEx result in compareResults)
             {
                 bagResult.Add(result);
             }
         });
         return bagResult.ToList().OrderBy(c => c).AsEnumerable();
     }));
 }
Esempio n. 14
0
 public static PointerEx Align(this PointerEx value, uint alignment) => (value + (alignment - 1)) & ~(alignment - 1);
Esempio n. 15
0
 public static PointerEx Subtract(this PointerEx i, PointerEx offset)
 {
     return(i.IntPtr.Subtract(offset));
 }
Esempio n. 16
0
 public static PointerEx Add(this PointerEx i, PointerEx offset)
 {
     return(i.IntPtr.Add(offset));
 }
Esempio n. 17
0
 public static extern int NtCreateThreadEx(out SafeWaitHandle threadHandle, AccessMask accessMask, PointerEx objectAttributes, PointerEx processHandle, PointerEx startAddress, PointerEx argument, ThreadCreationFlags flags, PointerEx zeroBits, PointerEx stackSize, PointerEx maximumStackSize, IntPtr attributeList);
Esempio n. 18
0
 static EnvironmentEx()
 {
     if (Environment.Is64BitProcess)
     {
         APISetMapAddress = Marshal.PtrToStructure <Peb64>(RtlGetCurrentPeb()).APISetMap;
     }
     else
     {
         APISetMapAddress = Marshal.PtrToStructure <Peb32>(RtlGetCurrentPeb()).APISetMap;
     }
     #region DSTRINGS
     #if DEBUG
     DSTR_MODULE_EXPORT_NOT_FOUND    = CreateDebugString("Module '{0}' does not contain export '{1}'");
     DSTR_OS_VERSION_TOO_OLD         = CreateDebugString("OS Major Version must be >= 10");
     DSTR_MODULE_NAME_INVALID        = CreateDebugString("Failed to read imported DLL name.");
     DSTR_MODULE_FILE_NOT_FOUND      = CreateDebugString("{0}, unable to find the specified file.");
     DSTR_DINVOKE_MAIN_FAILED        = CreateDebugString("Failed to call DllMain -> DLL_PROCESS_ATTACH");
     DSTR_DINVOKE_MOD_CANNOT_BE_NULL = CreateDebugString("modulePath cannot be null.");
     DSTR_MOD_ARCHITECTURE_WRONG     = CreateDebugString("The module architecture does not match the process architecture.");
     DSTR_MOD_EXPORTS_BAD            = CreateDebugString("Failed to parse module exports.");
     DSTR_EXPORT_NOT_FOUND           = CreateDebugString("{0}, export not found.");
     DSTR_FAILED_MEMORY_WRITE        = CreateDebugString("Failed to write to memory.");
     DSTR_MEM_ACCESS_VIOLATION       = CreateDebugString("Memory access violation.");
     DSTR_API_DLL_UNRESOLVED         = CreateDebugString("api dll was not resolved ({0})");
     DSTR_UNK_SEC_FLAG               = CreateDebugString("Unknown section flag, {0}");
     DSTR_RAXSTOR_MISSING            = CreateDebugString("Unable to execute a 64 bit function without RAXStor");
     DSTR_ACCESS_DENIED              = CreateDebugString("Access is denied.");
     DSTR_ALREADY_COMMITTED          = CreateDebugString("The specified address range is already committed.");
     DSTR_LOW_ON_VMEM                = CreateDebugString("Your system is low on virtual memory.");
     DSTR_CONFLICTING_ADDRESS        = CreateDebugString("The specified address range conflicts with the address space.");
     DSTR_INSUFFICIENT_RESOURCES     = CreateDebugString("Insufficient system resources exist to complete the API call.");
     DSTR_INVALID_HANDLE             = CreateDebugString("Invalid handle");
     DSTR_INVALID_PAGE_PROTECT       = CreateDebugString("The specified page protection was not valid.");
     DSTR_OBJECT_TYPE_MISMATCH       = CreateDebugString("Object type mismatch");
     DSTR_PROC_EXITING               = CreateDebugString("An attempt was made to duplicate an object handle into or out of an exiting process.");
     DSTR_PROC_ADDRESS_LOOKUP_FAILED = CreateDebugString("Failed get procedure address, {0}");
     DSTR_INVALID_PROCINFOCLASS      = CreateDebugString("Invalid ProcessInfoClass {0}");
     DSTR_FAILED_MEMPROTECT          = CreateDebugString("Failed to change memory protection, {0}");
     DSTR_BUFFER_TOO_SMALL           = CreateDebugString("Destination buffer size is too small");
     DSTR_PTR_CAST_FAIL              = CreateDebugString("Cannot cast data of length {0} to a pointer of size {1}");
     DSTR_TARG_PROC_NULL             = CreateDebugString("Target process cannot be null");
     DSTR_READ_MISSING_HANDLE        = CreateDebugString("Tried to read from a memory region when a handle to the desired process doesn't exist");
     DSTR_INVALID_VALUETYPE          = CreateDebugString("Type {0} is not a valid value type");
     DSTR_WRITE_MISSING_HANDLE       = CreateDebugString("Tried to write to a memory region when a handle to the desired process doesn't exist");
     DSTR_FAILED_READFROM            = CreateDebugString("Failed to read data of size {0} from address 0x{1}");
     DSTR_FAILED_WRITETO             = CreateDebugString("Failed to write {0} bytes to region 0x{1}");
     DSTR_INJECT_DEAD_PROC           = CreateDebugString("Cannot inject a dll to a process which has exited");
     DSTR_INJECT_EMPTY_DLL           = CreateDebugString("DSTR_INJECT_EMPTY_DLL");
     DSTR_FAILED_LOAD_MODULE         = CreateDebugString("Failed to load an essential module at '{0}'");
     DSTR_CAST_SERIALIZE_FAILED      = CreateDebugString("Cannot cast type [{0}] to a serializable type for RPC returns");
     DSTR_RPC_INITIALIZED            = CreateDebugString("Cannot invoke rpc of type {0} because the rpc type has not been initialized.");
     DSTR_PROC_EXITED                = CreateDebugString("Process exited unexpectedly...");
     DSTR_FIND_THREAD_HIJACK         = CreateDebugString("Unable to find a thread which can be hijacked.");
     DSTR_OPEN_THREAD_FAILED         = CreateDebugString("Unable to open target thread for RPC...");
     DSTR_THREAD_CTX_FAILED          = CreateDebugString("Unable to get a thread context for the target process RPC.");
     DSTR_RPC_TIMEOUT                = CreateDebugString("Function call timed out");
     DSTR_ALLOC_NO_HANDLE            = CreateDebugString("Tried to allocate a memory region when a handle to the desired process doesn't exist");
     DSTR_THREAD_NO_HANDLE           = CreateDebugString("Tried to create a thread in a process which has no open handle!");
     DSTR_CALLTYPE_NOT_IMPLEMENTED   = CreateDebugString("Calltype {0} not implemented");
     DSTR_SERIALIZE_TYPE_INVALID     = CreateDebugString("Cannot cast type [{0}] to a serializable type for RPC. If this was an array, convert it to a byte array first.");
     DSTR_UNHANDLED_ARG_RPC          = CreateDebugString("Unhandled argument type for serialization: {0}");
     #endif
     #endregion
 }
Esempio n. 19
0
 internal ProcessModuleEx(PointerEx baseAddress, string modulePath)
 {
     __baseaddress = baseAddress;
     __modulepath  = modulePath;
 }
Esempio n. 20
0
        private static byte[] CreateRemoteCall64(PointerEx jumpLocation, PointerEx[] args, PointerEx raxStorAddress, PointerEx threadStateAddress, byte xmmMask, ExXMMReturnType xmmReturnType)
        {
            if (!raxStorAddress)
            {
                throw new Exception(DSTR(DSTR_RAXSTOR_MISSING));
            }

            List <byte> data = new List <byte>();

            // movabs rax, raxStorAddress
            data.AddRange(new byte[] { 0x48, 0xb8 });
            data.AddRange(BitConverter.GetBytes((long)raxStorAddress));

            // mov QWORD PTR [rax], rsp
            // mov rax, -16
            // and rsp, rax
            // sub rsp, 32
            data.AddRange(new byte[] { 0x48, 0x89, 0x20, 0x48, 0xC7, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0x48, 0x21, 0xC4, 0x48, 0x83, 0xEC, 0x20 });

            for (int i = args.Length - 1; i > -1; i--)
            {
                var arg = args[i];
                if (i < 4 && (PointerEx)(xmmMask & (1 << i)))
                {
                    bool is64xmm = (PointerEx)(xmmMask & (1 << i + 4));

                    // mov rax, arg
                    data.AddRange(new byte[] { 0x48, 0xb8 });
                    data.AddRange(BitConverter.GetBytes((long)arg));

                    if (is64xmm)
                    {
                        // movlpd xmm<?>, QWORD PTR [rax]
                        data.AddRange(new byte[] { 0x66, 0x0f, 0x12 });
                        data.Add((byte)(i * 8));
                    }
                    else
                    {
                        // movss xmm<?>, DWORD PTR [rax]
                        data.AddRange(new byte[] { 0xf3, 0x0f, 0x10 });
                        data.Add((byte)(i * 8));
                    }
                    continue;
                }

                switch (i)
                {
                case ARG_RCX:
                {
                    if (!arg)
                    {
                        // xor ecx, ecx
                        data.AddRange(new byte[] { 0x31, 0xC9 });
                        break;
                    }

                    if (arg <= (long)uint.MaxValue)
                    {
                        // mov ecx, arg
                        data.Add(0xB9);
                        data.AddRange(BitConverter.GetBytes((int)arg));
                        break;
                    }

                    // mov rcx, arg
                    data.AddRange(new byte[] { 0x48, 0xB9 });
                    data.AddRange(BitConverter.GetBytes((long)arg));
                }
                break;

                case ARG_RDX:
                {
                    if (!arg)
                    {
                        // xor edx, edx
                        data.AddRange(new byte[] { 0x31, 0xD2 });
                        break;
                    }

                    if (arg <= (long)uint.MaxValue)
                    {
                        // mov edx, arg
                        data.Add(0xBA);
                        data.AddRange(BitConverter.GetBytes((int)arg));
                        break;
                    }

                    // mov rdx, arg
                    data.AddRange(new byte[] { 0x48, 0xBA });
                    data.AddRange(BitConverter.GetBytes((long)arg));
                }
                break;

                case ARG_R8:
                {
                    if (!arg)
                    {
                        // xor r8d, r8d
                        data.AddRange(new byte[] { 0x45, 0x31, 0xC0 });
                        break;
                    }

                    if (arg <= (long)uint.MaxValue)
                    {
                        // mov r8d, arg
                        data.AddRange(new byte[] { 0x41, 0xB8 });
                        data.AddRange(BitConverter.GetBytes((int)arg));
                        break;
                    }

                    // mov r8, arg
                    data.AddRange(new byte[] { 0x49, 0xB8 });
                    data.AddRange(BitConverter.GetBytes((long)arg));
                }
                break;

                case ARG_R9:
                {
                    if (!arg)
                    {
                        // xor r9d, r8d
                        data.AddRange(new byte[] { 0x45, 0x31, 0xC9 });
                        break;
                    }

                    if (arg <= (long)uint.MaxValue)
                    {
                        // mov r9d, arg
                        data.AddRange(new byte[] { 0x41, 0xB9 });
                        data.AddRange(BitConverter.GetBytes((int)arg));
                        break;
                    }

                    // mov r9, arg
                    data.AddRange(new byte[] { 0x49, 0xB9 });
                    data.AddRange(BitConverter.GetBytes((long)arg));
                }
                break;

                default:
                {
                    if (!arg)
                    {
                        // push 0
                        data.AddRange(new byte[] { 0x6a, 0x00 });
                        break;
                    }

                    // mov rax, arg
                    data.AddRange(new byte[] { 0x48, 0xb8 });
                    data.AddRange(BitConverter.GetBytes((long)arg));

                    // push rax
                    data.Add(0x50);
                }
                break;
                }
            }

            // sub rsp, 0x20 for the shadow store
            data.AddRange(new byte[] { 0x48, 0x83, 0xEC, 0x20 });

            // mov rax, jumploc
            data.AddRange(new byte[] { 0x48, 0xB8 });
            data.AddRange(BitConverter.GetBytes((long)jumpLocation));

            // call rax
            data.AddRange(new byte[] { 0xFF, 0xD0 });

            // add rsp, 0x20 for removing shadow store
            data.AddRange(new byte[] { 0x48, 0x83, 0xC4, 0x20 });

            // movabs rbx, raxStorAddress
            data.AddRange(new byte[] { 0x48, 0xBB });
            data.AddRange(BitConverter.GetBytes((long)raxStorAddress));

            // mov rsp, QWORD PTR[rbx]
            data.AddRange(new byte[] { 0x48, 0x8B, 0x23 });

            if (xmmReturnType == ExXMMReturnType.XMMR_NONE)
            {
                // mov ReturnAddress, rax
                data.AddRange(new byte[] { 0x48, 0xA3 });
                data.AddRange(BitConverter.GetBytes((long)raxStorAddress));
            }
            else
            {
                // mov rax, ReturnAddress
                data.AddRange(new byte[] { 0x48, 0xB8 });
                data.AddRange(BitConverter.GetBytes((long)raxStorAddress));

                if (xmmReturnType == ExXMMReturnType.XMMR_SINGLE)
                {
                    // movss DWORD PTR [rax], xmm0
                    data.AddRange(new byte[] { 0xF3, 0x0F, 0x11, 0x00 });
                }
                else
                {
                    // movlpd QWORD PTR [rax],xmm0
                    data.AddRange(new byte[] { 0x66, 0x0F, 0x13, 0x00 });
                }
            }

            // mov rax, threadStateAddress
            data.AddRange(new byte[] { 0x48, 0xB8 });
            data.AddRange(BitConverter.GetBytes((long)threadStateAddress));

            // change thread state to finished
            // mov QWORD PTR [rax], 0x1
            data.AddRange(new byte[] { 0x48, 0xC7, 0x00, 0x01, 0x00, 0x00, 0x00 });

            // xor rax, rax
            data.AddRange(new byte[] { 0x31, 0xC0 });

            // ret
            data.Add(0xC3);
            return(data.ToArray());
        }
Esempio n. 21
0
        internal static byte[] CreateThreadIntercept64(PointerEx jumpTo, PointerEx originalIP, PointerEx xmmSpace)
        {
            List <byte> data = new List <byte>();

            // pushf TWICE
            // the reason is because we need padding space behind the saved flags so that we can place our fake return pointer back there
            data.AddRange(new byte[] { 0x9C, 0x9C });

            // push all the standard registers
            data.AddRange(new byte[] { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57 });

            // mov rax, xmmSpace
            data.AddRange(new byte[] { 0x48, 0xB8 });
            data.AddRange(BitConverter.GetBytes((long)xmmSpace));

            // save all the xmm registers to xmmSpace
            data.AddRange(new byte[] { 0x66, 0x0F, 0x29, 0x00, 0x66, 0x0F, 0x29, 0x48, 0x10, 0x66, 0x0F, 0x29, 0x50, 0x20, 0x66, 0x0F, 0x29, 0x58, 0x30,
                                       0x66, 0x0F, 0x29, 0x60, 0x40, 0x66, 0x0F, 0x29, 0x68, 0x50, 0x66, 0x0F, 0x29, 0x70, 0x60, 0x66, 0x0F, 0x29, 0x78,
                                       0x70, 0x66, 0x44, 0x0F, 0x29, 0x80, 0x80, 0x00, 0x00, 0x00, 0x66, 0x44, 0x0F, 0x29, 0x88, 0x90, 0x00, 0x00, 0x00,
                                       0x66, 0x44, 0x0F, 0x29, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x66, 0x44, 0x0F, 0x29, 0x98, 0xB0, 0x00, 0x00, 0x00, 0x66,
                                       0x44, 0x0F, 0x29, 0xA0, 0xC0, 0x00, 0x00, 0x00, 0x66, 0x44, 0x0F, 0x29, 0xA8, 0xD0, 0x00, 0x00, 0x00, 0x66, 0x44,
                                       0x0F, 0x29, 0xB0, 0xE0, 0x00, 0x00, 0x00, 0x66, 0x44, 0x0F, 0x29, 0xB8, 0xF0, 0x00, 0x00, 0x00 });

            // mov rax, jumpTo
            data.AddRange(new byte[] { 0x48, 0xB8 });
            data.AddRange(BitConverter.GetBytes((long)jumpTo));

            // call rax
            data.AddRange(new byte[] { 0xFF, 0xD0 });

            // mov rax, xmmSpace
            data.AddRange(new byte[] { 0x48, 0xB8 });
            data.AddRange(BitConverter.GetBytes((long)xmmSpace));

            // load all the xmm registers from xmmSpace
            data.AddRange(new byte[] { 0x66, 0x0F, 0x28, 0x00, 0x66, 0x0F, 0x28, 0x48, 0x10, 0x66, 0x0F, 0x28, 0x50, 0x20, 0x66, 0x0F, 0x28, 0x58, 0x30,
                                       0x66, 0x0F, 0x28, 0x60, 0x40, 0x66, 0x0F, 0x28, 0x68, 0x50, 0x66, 0x0F, 0x28, 0x70, 0x60, 0x66, 0x0F, 0x28, 0x78,
                                       0x70, 0x66, 0x44, 0x0F, 0x28, 0x80, 0x80, 0x00, 0x00, 0x00, 0x66, 0x44, 0x0F, 0x28, 0x88, 0x90, 0x00, 0x00, 0x00,
                                       0x66, 0x44, 0x0F, 0x28, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x66, 0x44, 0x0F, 0x28, 0x98, 0xB0, 0x00, 0x00, 0x00, 0x66,
                                       0x44, 0x0F, 0x28, 0xA0, 0xC0, 0x00, 0x00, 0x00, 0x66, 0x44, 0x0F, 0x28, 0xA8, 0xD0, 0x00, 0x00, 0x00, 0x66, 0x44,
                                       0x0F, 0x28, 0xB0, 0xE0, 0x00, 0x00, 0x00, 0x66, 0x44, 0x0F, 0x28, 0xB8, 0xF0, 0x00, 0x00, 0x00 });

            // pop all the standard registers
            data.AddRange(new byte[] { 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58 });

            // sub rsp, 0x8
            // data.AddRange(new byte[] { 0x48, 0x83, 0xEC, 0x08 });
            // no longer need to move rsp since we reserve space by flags push

            // mov DWORD PTR [rsp+8], originalIP_l
            data.AddRange(new byte[] { 0xC7, 0x44, 0x24, 0x08 });
            data.AddRange(BitConverter.GetBytes((int)originalIP));

            // mov DWORD PTR [rsp+0xC], originalIP_h
            data.AddRange(new byte[] { 0xC7, 0x44, 0x24, 0x0C });
            data.AddRange(BitConverter.GetBytes((int)((long)originalIP >> 32)));

            // popf here, so flags are 100% correct
            data.Add(0x9D);

            // ret
            data.Add(0xC3);
            return(data.ToArray());
        }