internal TDelegate CreateDelegateForSyscall <TDelegate>() where TDelegate : class { // Get the address of the function var functionAddress = _ntDllAddress + (int)_ntDllFunctions.Find(function => function.Name == typeof(TDelegate).Name.Replace("Definition", "")).Offset; // Copy the first 8 bytes of the function var functionBytes = new byte[8]; Marshal.Copy(functionAddress, functionBytes, 0, 8); // Retrieve the syscall index from the bytes var syscallIndexBytes = Environment.Is64BitProcess ? functionBytes.Skip(4).Take(4) : functionBytes.Skip(1).Take(4); var syscallIndex = BitConverter.ToUInt32(syscallIndexBytes.ToArray(), 0); // Create the shellcode used to perform the syscall var shellcode = Environment.Is64BitProcess ? SyscallX64.GetShellcode(syscallIndex) : SyscallX86.GetShellcode(syscallIndex); // Store the shellcode in a buffer var shellcodeBuffer = MemoryTools.AllocateMemoryForBuffer(shellcode.Length); _shellcodeAddresses.Add(shellcodeBuffer); Marshal.Copy(shellcode, 0, shellcodeBuffer, shellcode.Length); // Create a delegate to perform the syscall return(Marshal.GetDelegateForFunctionPointer <TDelegate>(shellcodeBuffer)); }
private void CreateSyscall <TSyscall>() where TSyscall : class { // Get the address of the function to syscall var functionAddress = PInvoke.GetProcAddress(_ntDllAddress, typeof(TSyscall).Name.Replace("Definition", "")); // Copy the first 8 bytes of the function var functionBytes = new byte[8]; Marshal.Copy(functionAddress, functionBytes, 0, 8); // Retrieve the syscall index from the bytes var syscallIndexBytes = Environment.Is64BitProcess ? functionBytes.Skip(4).Take(4) : functionBytes.Skip(1).Take(4); // Write the shellcode used to perform the syscall into the local process var shellcode = Environment.Is64BitProcess ? SyscallX64.GetShellcode(syscallIndexBytes.ToArray()) : SyscallX86.GetShellcode(syscallIndexBytes.ToArray()); var shellcodeBuffer = LocalMemoryTools.StoreBytesInBuffer(shellcode); // Create an instance of the syscall class var syscallInstance = Activator.CreateInstance(typeof(TSyscall), BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { shellcodeBuffer }, null); // Get the parameter and return types of the syscall method var methodInformation = typeof(TSyscall).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.NonPublic); var methodTypes = new List <Type>(methodInformation.GetParameters().Select(parameter => parameter.ParameterType)) { methodInformation.ReturnType }; // Create the delegate type to represent the syscall method Type delegateType; if (methodTypes.Last() == typeof(void)) { methodTypes.RemoveAt(methodTypes.Count - 1); delegateType = Expression.GetActionType(methodTypes.ToArray()); } else { delegateType = Expression.GetFuncType(methodTypes.ToArray()); } // Create a delegate for the syscall method var syscallDelegate = Delegate.CreateDelegate(delegateType, syscallInstance, "Invoke"); _syscallCache.Add(typeof(TSyscall).Name, new SyscallInstance(syscallDelegate, shellcodeBuffer)); }