main.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <sys/ioctl.h>
  5. #include <sys/mman.h>
  6. #include <fcntl.h>
  7. //#include <linux/kvm.h>
  8. typedef __signed__ char __s8;
  9. typedef unsigned char __u8;
  10. typedef __signed__ short __s16;
  11. typedef unsigned short __u16;
  12. typedef __signed__ int __s32;
  13. typedef unsigned int __u32;
  14. #ifdef __GNUC__
  15. __extension__ typedef __signed__ long long __s64;
  16. __extension__ typedef unsigned long long __u64;
  17. #else
  18. typedef __signed__ long long __s64;
  19. typedef unsigned long long __u64;
  20. #endif
  21. //from linux/kvm.h
  22. #define KVM_CREATE_VM _IO(KVMIO, 0x01) /* returns a VM fd */
  23. #define KVM_CREATE_VCPU _IO(KVMIO, 0x41)
  24. #define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */
  25. #define KVM_RUN _IO(KVMIO, 0x80)
  26. #define KVM_GET_REGS _IOR(KVMIO, 0x81, struct kvm_regs)
  27. #define KVM_SET_REGS _IOW(KVMIO, 0x82, struct kvm_regs)
  28. #define KVM_GET_SREGS _IOR(KVMIO, 0x83, struct kvm_sregs)
  29. #define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs)
  30. #define KVMIO 0xAE
  31. #define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46, \
  32. struct kvm_userspace_memory_region)
  33. /* Architectural interrupt line count. */
  34. #define KVM_NR_INTERRUPTS 256
  35. struct kvm_hyperv_exit {
  36. #define KVM_EXIT_HYPERV_SYNIC 1
  37. #define KVM_EXIT_HYPERV_HCALL 2
  38. #define KVM_EXIT_HYPERV_SYNDBG 3
  39. __u32 type;
  40. __u32 pad1;
  41. union {
  42. struct {
  43. __u32 msr;
  44. __u32 pad2;
  45. __u64 control;
  46. __u64 evt_page;
  47. __u64 msg_page;
  48. } synic;
  49. struct {
  50. __u64 input;
  51. __u64 result;
  52. __u64 params[2];
  53. } hcall;
  54. struct {
  55. __u32 msr;
  56. __u32 pad2;
  57. __u64 control;
  58. __u64 status;
  59. __u64 send_page;
  60. __u64 recv_page;
  61. __u64 pending_page;
  62. } syndbg;
  63. } u;
  64. };
  65. struct kvm_debug_exit_arch {
  66. __u32 exception;
  67. __u32 pad;
  68. __u64 pc;
  69. __u64 dr6;
  70. __u64 dr7;
  71. };
  72. /* for KVM_SET_USER_MEMORY_REGION */
  73. struct kvm_userspace_memory_region {
  74. __u32 slot;
  75. __u32 flags;
  76. __u64 guest_phys_addr;
  77. __u64 memory_size; /* bytes */
  78. __u64 userspace_addr; /* start of the userspace allocated memory */
  79. };
  80. struct kvm_xen_exit {
  81. #define KVM_EXIT_XEN_HCALL 1
  82. __u32 type;
  83. union {
  84. struct {
  85. __u32 longmode;
  86. __u32 cpl;
  87. __u64 input;
  88. __u64 result;
  89. __u64 params[6];
  90. } hcall;
  91. } u;
  92. };
  93. /* for KVM_GET_REGS and KVM_SET_REGS */
  94. struct kvm_regs {
  95. /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
  96. __u64 rax, rbx, rcx, rdx;
  97. __u64 rsi, rdi, rsp, rbp;
  98. __u64 r8, r9, r10, r11;
  99. __u64 r12, r13, r14, r15;
  100. __u64 rip, rflags;
  101. };
  102. struct my_kvm_segment {
  103. __u64 base;
  104. __u32 limit;
  105. __u16 selector;
  106. __u8 type;
  107. __u8 present, dpl, db, s, l, g, avl;
  108. __u8 unusable;
  109. __u8 padding;
  110. };
  111. struct kvm_dtable {
  112. __u64 base;
  113. __u16 limit;
  114. __u16 padding[3];
  115. };
  116. /* for KVM_GET_SREGS and KVM_SET_SREGS */
  117. struct kvm_sregs {
  118. /* out (KVM_GET_SREGS) / in (KVM_SET_SREGS) */
  119. struct my_kvm_segment cs, ds, es, fs, gs, ss;
  120. struct my_kvm_segment tr, ldt;
  121. struct kvm_dtable gdt, idt;
  122. __u64 cr0, cr2, cr3, cr4, cr8;
  123. __u64 efer;
  124. __u64 apic_base;
  125. __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
  126. };
  127. /* for KVM_GET/SET_VCPU_EVENTS */
  128. struct kvm_vcpu_events {
  129. struct {
  130. __u8 injected;
  131. __u8 nr;
  132. __u8 has_error_code;
  133. __u8 pending;
  134. __u32 error_code;
  135. } exception;
  136. struct {
  137. __u8 injected;
  138. __u8 nr;
  139. __u8 soft;
  140. __u8 shadow;
  141. } interrupt;
  142. struct {
  143. __u8 injected;
  144. __u8 pending;
  145. __u8 masked;
  146. __u8 pad;
  147. } nmi;
  148. __u32 sipi_vector;
  149. __u32 flags;
  150. struct {
  151. __u8 smm;
  152. __u8 pending;
  153. __u8 smm_inside_nmi;
  154. __u8 latched_init;
  155. } smi;
  156. __u8 reserved[27];
  157. __u8 exception_has_payload;
  158. __u64 exception_payload;
  159. };
  160. /* kvm_sync_regs struct included by kvm_run struct */
  161. struct kvm_sync_regs {
  162. /* Members of this structure are potentially malicious.
  163. * Care must be taken by code reading, esp. interpreting,
  164. * data fields from them inside KVM to prevent TOCTOU and
  165. * double-fetch types of vulnerabilities.
  166. */
  167. struct kvm_regs regs;
  168. struct kvm_sregs sregs;
  169. struct kvm_vcpu_events events;
  170. };
  171. /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
  172. struct kvm_run {
  173. /* in */
  174. __u8 request_interrupt_window;
  175. __u8 immediate_exit;
  176. __u8 padding1[6];
  177. /* out */
  178. __u32 exit_reason;
  179. __u8 ready_for_interrupt_injection;
  180. __u8 if_flag;
  181. __u16 flags;
  182. /* in (pre_kvm_run), out (post_kvm_run) */
  183. __u64 cr8;
  184. __u64 apic_base;
  185. #ifdef __KVM_S390
  186. /* the processor status word for s390 */
  187. __u64 psw_mask; /* psw upper half */
  188. __u64 psw_addr; /* psw lower half */
  189. #endif
  190. union {
  191. /* KVM_EXIT_UNKNOWN */
  192. struct {
  193. __u64 hardware_exit_reason;
  194. } hw;
  195. /* KVM_EXIT_FAIL_ENTRY */
  196. struct {
  197. __u64 hardware_entry_failure_reason;
  198. __u32 cpu;
  199. } fail_entry;
  200. /* KVM_EXIT_EXCEPTION */
  201. struct {
  202. __u32 exception;
  203. __u32 error_code;
  204. } ex;
  205. /* KVM_EXIT_IO */
  206. struct {
  207. #define KVM_EXIT_IO_IN 0
  208. #define KVM_EXIT_IO_OUT 1
  209. __u8 direction;
  210. __u8 size; /* bytes */
  211. __u16 port;
  212. __u32 count;
  213. __u64 data_offset; /* relative to kvm_run start */
  214. } io;
  215. /* KVM_EXIT_DEBUG */
  216. struct {
  217. struct kvm_debug_exit_arch arch;
  218. } debug;
  219. /* KVM_EXIT_MMIO */
  220. struct {
  221. __u64 phys_addr;
  222. __u8 data[8];
  223. __u32 len;
  224. __u8 is_write;
  225. } mmio;
  226. /* KVM_EXIT_HYPERCALL */
  227. struct {
  228. __u64 nr;
  229. __u64 args[6];
  230. __u64 ret;
  231. __u32 longmode;
  232. __u32 pad;
  233. } hypercall;
  234. /* KVM_EXIT_TPR_ACCESS */
  235. struct {
  236. __u64 rip;
  237. __u32 is_write;
  238. __u32 pad;
  239. } tpr_access;
  240. /* KVM_EXIT_S390_SIEIC */
  241. struct {
  242. __u8 icptcode;
  243. __u16 ipa;
  244. __u32 ipb;
  245. } s390_sieic;
  246. /* KVM_EXIT_S390_RESET */
  247. #define KVM_S390_RESET_POR 1
  248. #define KVM_S390_RESET_CLEAR 2
  249. #define KVM_S390_RESET_SUBSYSTEM 4
  250. #define KVM_S390_RESET_CPU_INIT 8
  251. #define KVM_S390_RESET_IPL 16
  252. __u64 s390_reset_flags;
  253. /* KVM_EXIT_S390_UCONTROL */
  254. struct {
  255. __u64 trans_exc_code;
  256. __u32 pgm_code;
  257. } s390_ucontrol;
  258. /* KVM_EXIT_DCR (deprecated) */
  259. struct {
  260. __u32 dcrn;
  261. __u32 data;
  262. __u8 is_write;
  263. } dcr;
  264. /* KVM_EXIT_INTERNAL_ERROR */
  265. struct {
  266. __u32 suberror;
  267. /* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
  268. __u32 ndata;
  269. __u64 data[16];
  270. } internal;
  271. /*
  272. * KVM_INTERNAL_ERROR_EMULATION
  273. *
  274. * "struct emulation_failure" is an overlay of "struct internal"
  275. * that is used for the KVM_INTERNAL_ERROR_EMULATION sub-type of
  276. * KVM_EXIT_INTERNAL_ERROR. Note, unlike other internal error
  277. * sub-types, this struct is ABI! It also needs to be backwards
  278. * compatible with "struct internal". Take special care that
  279. * "ndata" is correct, that new fields are enumerated in "flags",
  280. * and that each flag enumerates fields that are 64-bit aligned
  281. * and sized (so that ndata+internal.data[] is valid/accurate).
  282. */
  283. struct {
  284. __u32 suberror;
  285. __u32 ndata;
  286. __u64 flags;
  287. __u8 insn_size;
  288. __u8 insn_bytes[15];
  289. } emulation_failure;
  290. /* KVM_EXIT_OSI */
  291. struct {
  292. __u64 gprs[32];
  293. } osi;
  294. /* KVM_EXIT_PAPR_HCALL */
  295. struct {
  296. __u64 nr;
  297. __u64 ret;
  298. __u64 args[9];
  299. } papr_hcall;
  300. /* KVM_EXIT_S390_TSCH */
  301. struct {
  302. __u16 subchannel_id;
  303. __u16 subchannel_nr;
  304. __u32 io_int_parm;
  305. __u32 io_int_word;
  306. __u32 ipb;
  307. __u8 dequeued;
  308. } s390_tsch;
  309. /* KVM_EXIT_EPR */
  310. struct {
  311. __u32 epr;
  312. } epr;
  313. /* KVM_EXIT_SYSTEM_EVENT */
  314. struct {
  315. #define KVM_SYSTEM_EVENT_SHUTDOWN 1
  316. #define KVM_SYSTEM_EVENT_RESET 2
  317. #define KVM_SYSTEM_EVENT_CRASH 3
  318. __u32 type;
  319. __u64 flags;
  320. } system_event;
  321. /* KVM_EXIT_S390_STSI */
  322. struct {
  323. __u64 addr;
  324. __u8 ar;
  325. __u8 reserved;
  326. __u8 fc;
  327. __u8 sel1;
  328. __u16 sel2;
  329. } s390_stsi;
  330. /* KVM_EXIT_IOAPIC_EOI */
  331. struct {
  332. __u8 vector;
  333. } eoi;
  334. /* KVM_EXIT_HYPERV */
  335. struct kvm_hyperv_exit hyperv;
  336. /* KVM_EXIT_ARM_NISV */
  337. struct {
  338. __u64 esr_iss;
  339. __u64 fault_ipa;
  340. } arm_nisv;
  341. /* KVM_EXIT_X86_RDMSR / KVM_EXIT_X86_WRMSR */
  342. struct {
  343. __u8 error; /* user -> kernel */
  344. __u8 pad[7];
  345. #define KVM_MSR_EXIT_REASON_INVAL (1 << 0)
  346. #define KVM_MSR_EXIT_REASON_UNKNOWN (1 << 1)
  347. #define KVM_MSR_EXIT_REASON_FILTER (1 << 2)
  348. __u32 reason; /* kernel -> user */
  349. __u32 index; /* kernel -> user */
  350. __u64 data; /* kernel <-> user */
  351. } msr;
  352. /* KVM_EXIT_XEN */
  353. struct kvm_xen_exit xen;
  354. /* Fix the size of the union. */
  355. char padding[256];
  356. };
  357. /* 2048 is the size of the char array used to bound/pad the size
  358. * of the union that holds sync regs.
  359. */
  360. #define SYNC_REGS_SIZE_BYTES 2048
  361. /*
  362. * shared registers between kvm and userspace.
  363. * kvm_valid_regs specifies the register classes set by the host
  364. * kvm_dirty_regs specified the register classes dirtied by userspace
  365. * struct kvm_sync_regs is architecture specific, as well as the
  366. * bits for kvm_valid_regs and kvm_dirty_regs
  367. */
  368. __u64 kvm_valid_regs;
  369. __u64 kvm_dirty_regs;
  370. union {
  371. struct kvm_sync_regs regs;
  372. char padding[SYNC_REGS_SIZE_BYTES];
  373. } s;
  374. };
  375. int kvm(uint8_t code[], size_t code_len)
  376. {
  377. // step 1, open /dev/kvm
  378. int kvmfd = open("/dev/kvm", O_RDWR | O_CLOEXEC);
  379. if (kvmfd == -1)
  380. {
  381. printf("failed to open /dev/kvm\n");
  382. return 0;
  383. }
  384. // step 2, create VM
  385. int vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
  386. printf("vmfd %d\n", vmfd);
  387. // step 3, set up user memory region
  388. size_t mem_size = 0x100000; // size of user memory you want to assign
  389. void *mem = mmap(0, mem_size, PROT_READ | PROT_WRITE,
  390. MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  391. printf("map mem %p\n", mem);
  392. int user_entry = 0x0;
  393. memcpy((void *)((size_t)mem + user_entry), code, code_len);
  394. struct kvm_userspace_memory_region region = {
  395. .slot = 0,
  396. .flags = 0,
  397. .guest_phys_addr = 0,
  398. .memory_size = mem_size,
  399. .userspace_addr = (size_t)mem};
  400. ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &region);
  401. /* end of step 3 */
  402. // step 4, create vCPU
  403. int vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
  404. printf("create vcpu,fd: %p\n", vcpufd);
  405. // step 5, set up memory for vCPU
  406. size_t vcpu_mmap_size = ioctl(kvmfd, KVM_GET_VCPU_MMAP_SIZE, NULL);
  407. struct kvm_run *run = (struct kvm_run *)mmap(0, vcpu_mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0);
  408. // step 6, set up vCPU's registers
  409. /* standard registers include general-purpose registers and flags */
  410. struct kvm_regs regs;
  411. ioctl(vcpufd, KVM_GET_REGS, &regs);
  412. regs.rip = user_entry;
  413. regs.rsp = 0x200000; // stack address
  414. regs.rflags = 0x2; // in x86 the 0x2 bit should always be set
  415. ioctl(vcpufd, KVM_SET_REGS, &regs); // set registers
  416. /* special registers include segment registers */
  417. struct kvm_sregs sregs;
  418. ioctl(vcpufd, KVM_GET_SREGS, &sregs);
  419. sregs.cs.base = sregs.cs.selector = 0; // let base of code segment equal to zero
  420. ioctl(vcpufd, KVM_SET_SREGS, &sregs);
  421. ioctl(vcpufd, KVM_GET_SREGS, &sregs);
  422. // step 7, execute vm and handle exit reason
  423. #define KVM_EXIT_UNKNOWN 0
  424. #define KVM_EXIT_EXCEPTION 1
  425. #define KVM_EXIT_IO 2
  426. #define KVM_EXIT_HYPERCALL 3
  427. #define KVM_EXIT_DEBUG 4
  428. #define KVM_EXIT_HLT 5
  429. #define KVM_EXIT_MMIO 6
  430. #define KVM_EXIT_IRQ_WINDOW_OPEN 7
  431. #define KVM_EXIT_SHUTDOWN 8
  432. #define KVM_EXIT_FAIL_ENTRY 9
  433. #define KVM_EXIT_INTR 10
  434. #define KVM_EXIT_SET_TPR 11
  435. #define KVM_EXIT_TPR_ACCESS 12
  436. #define KVM_EXIT_S390_SIEIC 13
  437. #define KVM_EXIT_S390_RESET 14
  438. #define KVM_EXIT_DCR 15 /* deprecated */
  439. #define KVM_EXIT_NMI 16
  440. #define KVM_EXIT_INTERNAL_ERROR 17
  441. #define KVM_EXIT_OSI 18
  442. #define KVM_EXIT_PAPR_HCALL 19
  443. #define KVM_EXIT_S390_UCONTROL 20
  444. #define KVM_EXIT_WATCHDOG 21
  445. #define KVM_EXIT_S390_TSCH 22
  446. #define KVM_EXIT_EPR 23
  447. #define KVM_EXIT_SYSTEM_EVENT 24
  448. #define KVM_EXIT_S390_STSI 25
  449. #define KVM_EXIT_IOAPIC_EOI 26
  450. #define KVM_EXIT_HYPERV 27
  451. #define KVM_EXIT_ARM_NISV 28
  452. #define KVM_EXIT_X86_RDMSR 29
  453. #define KVM_EXIT_X86_WRMSR 30
  454. #define KVM_EXIT_DIRTY_RING_FULL 31
  455. #define KVM_EXIT_AP_RESET_HOLD 32
  456. #define KVM_EXIT_X86_BUS_LOCK 33
  457. #define KVM_EXIT_XEN 34
  458. while (1)
  459. {
  460. ioctl(vcpufd, KVM_RUN, NULL);
  461. ioctl(vcpufd, KVM_GET_SREGS, &sregs);
  462. printf("Guest CR3: 0x%llx\n", sregs.cr3);
  463. switch (run->exit_reason)
  464. {
  465. case KVM_EXIT_HLT:
  466. fputs("KVM_EXIT_HLT \n", stderr);
  467. return 0;
  468. case KVM_EXIT_IO:
  469. /* TODO: check port and direction here */
  470. putchar(*(((char *)run) + run->io.data_offset));
  471. printf("KVM_EXIT_IO: run->io.port = %lx \n",
  472. run->io.port);
  473. break;
  474. case KVM_EXIT_FAIL_ENTRY:
  475. printf("KVM_EXIT_FAIL_ENTRY: hardware_entry_failure_reason = 0x%lx",
  476. run->fail_entry.hardware_entry_failure_reason);
  477. return 0;
  478. case KVM_EXIT_INTERNAL_ERROR:
  479. printf("KVM_EXIT_INTERNAL_ERROR: suberror = 0x%x",
  480. run->internal.suberror);
  481. return 0;
  482. case KVM_EXIT_SHUTDOWN:
  483. printf("KVM_EXIT_SHUTDOWN");
  484. return 0;
  485. default:
  486. printf("Unhandled reason: %d", run->exit_reason);
  487. return 0;
  488. }
  489. }
  490. }
  491. /*汇编指令解释
  492. 0xB0 0x61 (mov al, 0x61)
  493. 解释:将立即数 0x61(ASCII 字符 'a')加载到 AL 寄存器中。
  494. 0xBA 0x17 0x02 (mov dx, 0x0217)
  495. Linux: ilen = 3 外中断和EPT_VIOLATION
  496. 解释:将立即数 0x0217 加载到 DX 寄存器中。
  497. 0xEE (out dx, al)
  498. 解释:将 AL 寄存器的值输出到 DX 寄存器指定的端口。
  499. 0xB0 0x0A (mov al, 0x0A)
  500. 解释:将立即数 0x0A(换行符)加载到 AL 寄存器中。
  501. 0xEE (out dx, al)
  502. 解释:将 AL 寄存器的值输出到 DX 寄存器指定的端口。
  503. 0xF4 (hlt)
  504. 解释:执行 hlt 指令,使处理器进入休眠状态,直到下一个外部中断到来。*/
  505. int main()
  506. {
  507. //uint8_t code[] = "\xB0\x61\xBA\x17\x02\xEE\xB0\n\xEE\xF4";
  508. //uint8_t code[] = "\xB0\x61\xBA\x17\x02\xEE\xF4";
  509. uint8_t code[] = "\xB0\x61\xF4";
  510. kvm(code, sizeof(code));
  511. return 0;
  512. }