private void CallEntryPoint(IntPtr baseAddress, IntPtr entryPoint) { // Initialize shellcode to call the entry of the dll in the remote process var shellcodeBytes = _properties.IsWow64 ? Shellcode.CallDllMainx86(baseAddress, entryPoint) : Shellcode.CallDllMainx64(baseAddress, entryPoint); // Allocate memory for the shellcode in the remote process var shellcodeAddress = IntPtr.Zero; try { shellcodeAddress = _properties.MemoryModule.AllocateMemory(_properties.ProcessId, shellcodeBytes.Length); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the shellcode in the remote process"); } // Write the shellcode into the memory of the remote process try { _properties.MemoryModule.WriteMemory(_properties.ProcessId, shellcodeAddress, shellcodeBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the remote process"); } // Create a remote thread to call the entry point in the remote process Native.NtCreateThreadEx(out var remoteThreadHandle, Native.AccessMask.SpecificRightsAll | Native.AccessMask.StandardRightsAll, IntPtr.Zero, _properties.ProcessHandle, shellcodeAddress, IntPtr.Zero, Native.CreationFlags.HideFromDebugger, 0, 0, 0, IntPtr.Zero); if (remoteThreadHandle is null) { ExceptionHandler.ThrowWin32Exception("Failed to create a remote thread to call the entry point in the remote process"); } // Wait for the remote thread to finish its task Native.WaitForSingleObject(remoteThreadHandle, int.MaxValue); // Free the memory previously allocated for the shellcode in the remote process try { _properties.MemoryModule.FreeMemory(_properties.ProcessId, shellcodeAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the shellcode in the remote process"); } // Close the handle opened to the remote thread remoteThreadHandle?.Close(); }
private void CallEntryPoint(IntPtr baseAddress, IntPtr entryPoint) { // Get the id of the process var processId = _process.Id; // Open a handle to the process var processHandle = _process.SafeHandle; // Determine if the process is running under WOW64 Native.IsWow64Process(processHandle, out var isWow64); // Create shellcode to call the entry of the dll in the process var shellcodeBytes = isWow64 ? Shellcode.CallDllMainx86(baseAddress, entryPoint) : Shellcode.CallDllMainx64(baseAddress, entryPoint); // Allocate memory for the shellcode in the process var shellcodeSize = shellcodeBytes.Length; var shellcodeAddress = IntPtr.Zero; try { shellcodeAddress = _memoryModule.AllocateMemory(processId, shellcodeSize); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to allocate memory for the shellcode in the process"); } // Write the shellcode into the memory of the process try { _memoryModule.WriteMemory(processId, shellcodeAddress, shellcodeBytes); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to write the shellcode into the memory of the process"); } // Create a remote thread to call the entry point in the process Native.RtlCreateUserThread(processHandle, IntPtr.Zero, false, 0, IntPtr.Zero, IntPtr.Zero, shellcodeAddress, IntPtr.Zero, out var remoteThreadHandle, 0); if (remoteThreadHandle is null) { ExceptionHandler.ThrowWin32Exception("Failed to create a remote thread to call the entry point in the process"); } // Wait for the remote thread to finish its task Native.WaitForSingleObject(remoteThreadHandle, int.MaxValue); // Free the memory previously allocated for the shellcode try { _memoryModule.FreeMemory(processId, shellcodeAddress); } catch (Win32Exception) { ExceptionHandler.ThrowWin32Exception("Failed to free the memory allocated for the shellcode in the process"); } // Close the handle opened to the process processHandle?.Close(); // Close the handle opened to the remote thread remoteThreadHandle?.Close(); }