totally_safe_transmute/
lib.rs1#![forbid(unsafe_code)]
2
3pub fn totally_safe_transmute<T, U>(v: T) -> U {
4 #[repr(C)]
5 enum E<T, U> {
6 T(T),
7 #[allow(dead_code)] U(U),
8 }
9 let v = E::T(v);
10
11 #[cfg(target_os = "linux")]
12 {
13 use std::{io::{self, Write, Seek}, fs};
14
15 let mut f = fs::OpenOptions::new()
16 .write(true)
17 .open("/proc/self/mem").expect("welp");
18
19 f.seek(io::SeekFrom::Start(&v as *const _ as u64)).expect("oof");
20 f.write(&[1]).expect("darn");
21 }
22
23 #[cfg(target_os = "windows")]
24 {
25 use std::{env, process, fs};
26 let p = env::temp_dir().join("random-collision-free-name-I1G3qPvXTU4RvRML.ps1");
27 fs::write(&p, r#"
28 Param (
29 [int]$parentPid,
30 [UInt64]$tagAddress
31 )
32
33 Add-Type -TypeDefinition @"
34 using System;
35 using System.Runtime.InteropServices;
36
37 public static class Helper {
38 const int PROCESS_VM_WRITE = 0x0020;
39 const int PROCESS_VM_OPERATION = 0x0008;
40
41 [DllImport("kernel32.dll")]
42 public static extern IntPtr OpenProcess(int dwDesiredAccess,
43 bool bInheritHandle, int dwProcessId);
44
45 [DllImport("kernel32.dll", SetLastError = true)]
46 public static extern bool WriteProcessMemory(IntPtr hProcess, ulong lpBaseAddress,
47 byte[] lpBuffer, int dwSize, IntPtr lpNumberOfBytesWritten);
48
49 public static void Run(int parentPid, ulong tagAddress) {
50 IntPtr handle = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, parentPid);
51 WriteProcessMemory(handle, tagAddress, new byte[]{1}, 1, (IntPtr) 0);
52 }
53 }
54 "@
55
56 [Helper]::Run($parentPid, $tagAddress)
57 "#.replace("\n ", "\n")).unwrap();
58 let i = process::id();
59 if !process::Command::new("powershell")
60 .args(&[&p.to_str().unwrap(), &i.to_string()[..], &(&v as *const _ as u64).to_string()])
61 .spawn()
62 .unwrap()
63 .wait()
64 .unwrap()
65 .success() { panic!("install linux lol"); }
66 fs::remove_file(&p).unwrap();
67 }
68
69 if let E::U(v) = v {
70 return v;
71 }
72
73 panic!("rip");
74}
75
76#[test]
77fn main() {
78 let v: Vec<u8> = b"foo".to_vec();
79 let v: String = totally_safe_transmute(v);
80 assert_eq!(&v, "foo");
81}