Ejemplo n.º 1
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());
        }
Ejemplo n.º 2
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));
 }