Пример #1
0
        private static byte[] AssembleShellcode(CallDescriptor callDescriptor, IntPtr completionFlagBuffer)
        {
            var shellcode = new List <byte>();

            if (callDescriptor.IsWow64Call)
            {
                // pushf

                shellcode.Add(0x9C);

                // pusha

                shellcode.Add(0x60);

                // Assemble the function parameters

                if (callDescriptor.CallingConvention == CallingConvention.FastCall)
                {
                    ParameterAssembler.AssembleFastCallParameters(callDescriptor, ref shellcode);
                }

                else
                {
                    ParameterAssembler.AssembleStdCallParameters(callDescriptor, ref shellcode);
                }

                // mov eax, functionAddress

                shellcode.Add(0xB8);

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

                // call eax

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

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

                    shellcode.Add(0xA3);

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

                // mov BYTE PTR [completionFlagBuffer], 0x01

                shellcode.AddRange(new byte[] { 0xC6, 0x05 });

                shellcode.AddRange(BitConverter.GetBytes((int)completionFlagBuffer));

                shellcode.Add(0x01);

                // 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 the function parameters

                ParameterAssembler.AssembleFastCallParameters(callDescriptor, ref shellcode);

                // mov rax, functionAddress

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

                shellcode.AddRange(BitConverter.GetBytes((long)callDescriptor.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 (callDescriptor.ReturnAddress != IntPtr.Zero)
                {
                    // mov [returnAddress], rax

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

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

                // mov rax, completionFlagBuffer

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

                shellcode.AddRange(BitConverter.GetBytes((long)completionFlagBuffer));

                // mov BYTE PTR [rax], 0x01

                shellcode.AddRange(new byte[] { 0xC6, 0x00, 0x01 });

                // 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());
        }
Пример #2
0
        private static byte[] AssembleShellcode(CallDescriptor callDescriptor)
        {
            var shellcode = new List <byte>();

            if (callDescriptor.IsWow64Call)
            {
                // Assemble the function parameters

                if (callDescriptor.CallingConvention == CallingConvention.FastCall)
                {
                    ParameterAssembler.AssembleFastCallParameters(callDescriptor, ref shellcode);
                }

                else
                {
                    ParameterAssembler.AssembleStdCallParameters(callDescriptor, ref shellcode);
                }

                // mov eax, functionAddress

                shellcode.Add(0xB8);

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

                // call eax

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

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

                    shellcode.Add(0xA3);

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

                // xor eax, eax

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

                // ret

                shellcode.Add(0xC3);
            }

            else
            {
                // Assemble the function parameters

                ParameterAssembler.AssembleFastCallParameters(callDescriptor, ref shellcode);

                // mov rax, functionAddress

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

                shellcode.AddRange(BitConverter.GetBytes((long)callDescriptor.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 (callDescriptor.ReturnAddress != IntPtr.Zero)
                {
                    // mov [returnAddress], rax

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

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

                // xor eax, eax

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

                // ret

                shellcode.Add(0xC3);
            }

            return(shellcode.ToArray());
        }