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()); }
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()); }