Example #1
0
        internal byte[] AssembleFunctionCall(FunctionCall functionCall)
        {
            var shellcode = new List <byte>();

            if (_isWow64)
            {
                // Assemble parameters

                switch (functionCall.CallingConvention)
                {
                case CallingConvention.FastCall:
                {
                    shellcode.AddRange(AssembleFastCallParameters(functionCall.Parameters));

                    break;
                }

                case CallingConvention.StdCall:
                {
                    shellcode.AddRange(AssembleStdCallParameters(Array.ConvertAll(functionCall.Parameters, item => (int)item)));

                    break;
                }
                }

                // mov eax, functionAddress

                shellcode.Add(0xB8);

                shellcode.AddRange(BitConverter.GetBytes((int)functionCall.FunctionAddress));

                // call eax

                shellcode.AddRange(new byte[] { 0xFF, 0xD0 });

                if (functionCall.ReturnAddress != IntPtr.Zero)
                {
                    // mov [returnAddress], eax

                    shellcode.Add(0xA3);

                    shellcode.AddRange(BitConverter.GetBytes((int)functionCall.ReturnAddress));
                }

                // xor eax, eax

                shellcode.AddRange(new byte[] { 0x33, 0xC0 });

                // ret

                shellcode.Add(0xC3);
            }

            else
            {
                // Assemble parameters

                shellcode.AddRange(AssembleFastCallParameters(functionCall.Parameters));

                // mov rax, functionAddress

                shellcode.AddRange(new byte[] { 0x48, 0xB8 });

                shellcode.AddRange(BitConverter.GetBytes((long)functionCall.FunctionAddress));

                // sub rsp, 0x28

                shellcode.AddRange(new byte[] { 0x48, 0x83, 0xEC, 0x28 });

                // call rax

                shellcode.AddRange(new byte[] { 0xFF, 0xD0 });

                // add rsp, 0x28

                shellcode.AddRange(new byte[] { 0x48, 0x83, 0xC4, 0x28 });

                if (functionCall.ReturnAddress != IntPtr.Zero)
                {
                    // mov [returnAddress], rax

                    shellcode.AddRange(new byte[] { 0x48, 0xA3 });

                    shellcode.AddRange(BitConverter.GetBytes((long)functionCall.ReturnAddress));
                }

                // xor eax, eax

                shellcode.AddRange(new byte[] { 0x31, 0xC0 });

                // ret

                shellcode.Add(0xC3);
            }

            return(shellcode.ToArray());
        }
Example #2
0
        internal byte[] AssembleThreadFunctionCall(FunctionCall functionCall)
        {
            var shellcode = new List <byte>();

            if (_isWow64)
            {
                // pushf

                shellcode.Add(0x9C);

                // pusha

                shellcode.Add(0x60);

                // Assemble parameters

                switch (functionCall.CallingConvention)
                {
                case CallingConvention.FastCall:
                {
                    shellcode.AddRange(AssembleFastCallParameters(functionCall.Parameters));

                    break;
                }

                case CallingConvention.StdCall:
                {
                    shellcode.AddRange(AssembleStdCallParameters(Array.ConvertAll(functionCall.Parameters, item => (int)item)));

                    break;
                }
                }

                // mov eax, functionAddress

                shellcode.Add(0xB8);

                shellcode.AddRange(BitConverter.GetBytes((int)functionCall.FunctionAddress));

                // call eax

                shellcode.AddRange(new byte[] { 0xFF, 0xD0 });

                if (functionCall.ReturnAddress != IntPtr.Zero)
                {
                    // mov [returnAddress], eax

                    shellcode.Add(0xA3);

                    shellcode.AddRange(BitConverter.GetBytes((int)functionCall.ReturnAddress));
                }

                // popa

                shellcode.Add(0x61);

                // popf

                shellcode.Add(0x9D);

                // ret

                shellcode.Add(0xC3);
            }

            else
            {
                // pushf

                shellcode.Add(0x9C);

                // push rax

                shellcode.Add(0x50);

                // push rbx

                shellcode.Add(0x53);

                // push rcx

                shellcode.Add(0x51);

                // push rdx

                shellcode.Add(0x52);

                // push r8

                shellcode.AddRange(new byte[] { 0x41, 0x50 });

                // push r9

                shellcode.AddRange(new byte[] { 0x41, 0x51 });

                // push r10

                shellcode.AddRange(new byte[] { 0x41, 0x52 });

                // push r11

                shellcode.AddRange(new byte[] { 0x41, 0x53 });

                // Assemble parameters

                shellcode.AddRange(AssembleFastCallParameters(functionCall.Parameters));

                // mov rax, functionAddress

                shellcode.AddRange(new byte[] { 0x48, 0xB8 });

                shellcode.AddRange(BitConverter.GetBytes((long)functionCall.FunctionAddress));

                // sub rsp, 0x28

                shellcode.AddRange(new byte[] { 0x48, 0x83, 0xEC, 0x28 });

                // call rax

                shellcode.AddRange(new byte[] { 0xFF, 0xD0 });

                // add rsp, 0x28

                shellcode.AddRange(new byte[] { 0x48, 0x83, 0xC4, 0x28 });

                if (functionCall.ReturnAddress != IntPtr.Zero)
                {
                    // mov [returnAddress], rax

                    shellcode.AddRange(new byte[] { 0x48, 0xA3 });

                    shellcode.AddRange(BitConverter.GetBytes((long)functionCall.ReturnAddress));
                }

                // pop r11

                shellcode.AddRange(new byte[] { 0x41, 0x5B });

                // pop r10

                shellcode.AddRange(new byte[] { 0x41, 0x5A });

                // pop r9

                shellcode.AddRange(new byte[] { 0x41, 0x59 });

                // pop r8

                shellcode.AddRange(new byte[] { 0x41, 0x58 });

                // pop rdx

                shellcode.Add(0x5A);

                // pop rcx

                shellcode.Add(0x59);

                // pop rbx

                shellcode.Add(0x5B);

                // pop rax

                shellcode.Add(0x58);

                // popf

                shellcode.Add(0x9D);

                // ret

                shellcode.Add(0xC3);
            }

            return(shellcode.ToArray());
        }