├── .gitignore ├── Boot ├── boot.asm ├── boot.vcxproj └── main.cpp ├── GuestOS ├── GuestOS.vcxproj ├── GuestOS.vcxproj.filters ├── Shellcode.cpp ├── Shellcode.h ├── boot.asm ├── cpu.cpp ├── cpu.h ├── gdt.cpp ├── gdt.h ├── idt.cpp ├── idt.h ├── kernel.cpp ├── msr-index.h ├── os.h ├── paging.cpp ├── paging.h ├── trap.cpp ├── trap.h ├── tss.cpp ├── tss.h ├── video.cpp └── video.h ├── README.md ├── ShellcodeVM.VC.db ├── ShellcodeVM.sln ├── ShellcodeVM ├── HAXM.h ├── HAXM_CPU.h ├── HAXM_VM.h ├── HaxVM.cpp ├── HaxVM.h ├── HaxmTest.cpp ├── HaxmTest.vcxproj ├── HaxmTest.vcxproj.filters ├── ShellcodeVM.vcxproj ├── ShellcodeVM.vcxproj.filters ├── VM.cpp ├── VM.h ├── VM │ ├── page_frame.cpp │ ├── page_frame.h │ ├── paging.cpp │ └── paging.h ├── VMCS.h ├── VirtualCPU.cpp ├── VirtualCPU.h ├── VirtualContext.cpp ├── VirtualContext.h ├── VirtualIO.cpp ├── WinMiniDump.cpp ├── WinMiniDump.h ├── config.h ├── hax-all.h ├── hax-i386.h ├── hax-interface.h ├── hax-windows.c ├── hax-windows.h ├── main.cpp ├── msr.h ├── stdafx.cpp ├── stdafx.h ├── target-i386 │ ├── TODO │ ├── cc_helper.c │ ├── cc_helper_template.h │ ├── cpu-qom.h │ ├── cpu.h │ ├── excp_helper.c │ ├── fpu_helper.c │ ├── hax-all.c │ ├── hax-darwin.c │ ├── hax-darwin.h │ ├── hax-i386.h │ ├── hax-interface.h │ ├── hax-windows.c │ ├── hax-windows.h │ ├── helper.c │ ├── helper.h │ ├── int_helper.c │ ├── kvm-gs-restore.c │ ├── kvm-gs-restore.h │ ├── kvm.c │ ├── machine.c │ ├── mem_helper.c │ ├── misc_helper.c │ ├── ops_sse.h │ ├── ops_sse_header.h │ ├── seg_helper.c │ ├── shift_helper_template.h │ ├── smm_helper.c │ ├── svm.h │ ├── svm_helper.c │ └── translate.c └── vcpu.h ├── nasm ├── nasm.exe └── ndisasm.exe └── 同步文档.docx /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studo 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | *_i.c 42 | *_p.c 43 | *_i.h 44 | *.ilk 45 | *.meta 46 | *.obj 47 | *.pch 48 | *.pdb 49 | *.pgc 50 | *.pgd 51 | *.rsp 52 | *.sbr 53 | *.tlb 54 | *.tli 55 | *.tlh 56 | *.tmp 57 | *.tmp_proj 58 | *.log 59 | *.vspscc 60 | *.vssscc 61 | .builds 62 | *.pidb 63 | *.svclog 64 | *.scc 65 | 66 | # Chutzpah Test files 67 | _Chutzpah* 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | *.cachefile 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | *.vspx 81 | 82 | # TFS 2012 Local Workspace 83 | $tf/ 84 | 85 | # Guidance Automation Toolkit 86 | *.gpState 87 | 88 | # ReSharper is a .NET coding add-in 89 | _ReSharper*/ 90 | *.[Rr]e[Ss]harper 91 | *.DotSettings.user 92 | 93 | # JustCode is a .NET coding addin-in 94 | .JustCode 95 | 96 | # TeamCity is a build add-in 97 | _TeamCity* 98 | 99 | # DotCover is a Code Coverage Tool 100 | *.dotCover 101 | 102 | # NCrunch 103 | _NCrunch_* 104 | .*crunch*.local.xml 105 | 106 | # MightyMoose 107 | *.mm.* 108 | AutoTest.Net/ 109 | 110 | # Web workbench (sass) 111 | .sass-cache/ 112 | 113 | # Installshield output folder 114 | [Ee]xpress/ 115 | 116 | # DocProject is a documentation generator add-in 117 | DocProject/buildhelp/ 118 | DocProject/Help/*.HxT 119 | DocProject/Help/*.HxC 120 | DocProject/Help/*.hhc 121 | DocProject/Help/*.hhk 122 | DocProject/Help/*.hhp 123 | DocProject/Help/Html2 124 | DocProject/Help/html 125 | 126 | # Click-Once directory 127 | publish/ 128 | 129 | # Publish Web Output 130 | *.[Pp]ublish.xml 131 | *.azurePubxml 132 | # TODO: Comment the next line if you want to checkin your web deploy settings 133 | # but database connection strings (with potential passwords) will be unencrypted 134 | *.pubxml 135 | *.publishproj 136 | 137 | # NuGet Packages 138 | *.nupkg 139 | # The packages folder can be ignored because of Package Restore 140 | **/packages/* 141 | # except build/, which is used as an MSBuild target. 142 | !**/packages/build/ 143 | # Uncomment if necessary however generally it will be regenerated when needed 144 | #!**/packages/repositories.config 145 | 146 | # Windows Azure Build Output 147 | csx/ 148 | *.build.csdef 149 | 150 | # Windows Store app package directory 151 | AppPackages/ 152 | 153 | # Others 154 | *.[Cc]ache 155 | ClientBin/ 156 | [Ss]tyle[Cc]op.* 157 | ~$* 158 | *~ 159 | *.dbmdl 160 | *.dbproj.schemaview 161 | *.pfx 162 | *.publishsettings 163 | node_modules/ 164 | bower_components/ 165 | 166 | # RIA/Silverlight projects 167 | Generated_Code/ 168 | 169 | # Backup & report files from converting an old project file 170 | # to a newer Visual Studio version. Backup files are not needed, 171 | # because we have git ;-) 172 | _UpgradeReport_Files/ 173 | Backup*/ 174 | UpgradeLog*.XML 175 | UpgradeLog*.htm 176 | 177 | # SQL Server files 178 | *.mdf 179 | *.ldf 180 | 181 | # Business Intelligence projects 182 | *.rdl.data 183 | *.bim.layout 184 | *.bim_*.settings 185 | 186 | # Microsoft Fakes 187 | FakesAssemblies/ 188 | 189 | # Node.js Tools for Visual Studio 190 | .ntvs_analysis.dat 191 | 192 | # Visual Studio 6 build log 193 | *.plg 194 | 195 | # Visual Studio 6 workspace options file 196 | *.opt 197 | /ShellcodeVM/MiniDump.Dmp 198 | -------------------------------------------------------------------------------- /Boot/boot.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/Boot/boot.asm -------------------------------------------------------------------------------- /Boot/boot.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D} 23 | GuestOS 24 | 8.1 25 | 26 | 27 | 28 | Application 29 | true 30 | v140 31 | MultiByte 32 | 33 | 34 | Application 35 | false 36 | v140 37 | true 38 | MultiByte 39 | 40 | 41 | Application 42 | true 43 | v140 44 | MultiByte 45 | 46 | 47 | Application 48 | false 49 | v140 50 | true 51 | MultiByte 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | false 73 | 74 | 75 | false 76 | 77 | 78 | 79 | Level3 80 | Disabled 81 | true 82 | false 83 | false 84 | false 85 | NoExtensions 86 | Default 87 | E:\GitHub\ShellcodeOS\libc;E:\GitHub\ShellcodeVM\GuestOS; 88 | 89 | 90 | true 91 | Native 92 | boot_code16 93 | 0x0010000 94 | true 95 | Driver 96 | E:\GitHub\ShellcodeOS\Release\oslibc.lib 97 | true 98 | /filealign:0x1000 %(AdditionalOptions) 99 | 100 | 101 | 102 | 103 | Level3 104 | Disabled 105 | true 106 | 107 | 108 | true 109 | 110 | 111 | 112 | 113 | Level3 114 | MaxSpeed 115 | true 116 | true 117 | true 118 | false 119 | false 120 | E:\GitHub\ShellcodeOS\libc;E:\GitHub\ShellcodeVM\GuestOS; 121 | NoExtensions 122 | 123 | 124 | true 125 | true 126 | true 127 | E:\GitHub\ShellcodeOS\Release\oslibc.lib 128 | true 129 | boot_code16 130 | 0x0010000 131 | true 132 | false 133 | Native 134 | Driver 135 | /filealign:0x1000 %(AdditionalOptions) 136 | 137 | 138 | 139 | 140 | Level3 141 | MaxSpeed 142 | true 143 | true 144 | true 145 | 146 | 147 | true 148 | true 149 | true 150 | 151 | 152 | 153 | 154 | Document 155 | ..\nasm\nasm.exe -f win32 ./boot.asm -o $(Configuration)\boot.obj 156 | $(Configuration)\boot.obj 157 | ..\nasm\nasm.exe -f win64 ./boot.asm -o $(Configuration)\boot.obj 158 | $(Configuration)\boot.obj 159 | $(Configuration)\boot.obj 160 | ..\nasm\nasm.exe -f win64 ./boot.asm -o $(Configuration)\boot.obj 161 | $(Configuration)\boot.obj 162 | ..\nasm\nasm.exe -f win32 ./boot.asm -o $(Configuration)\boot.obj 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /Boot/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/Boot/main.cpp -------------------------------------------------------------------------------- /GuestOS/GuestOS.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {70B6C809-92DB-4C09-8E45-C6ED3256412B} 23 | GuestOS 24 | 8.1 25 | 26 | 27 | 28 | Application 29 | true 30 | v140 31 | MultiByte 32 | 33 | 34 | Application 35 | false 36 | v140 37 | true 38 | MultiByte 39 | 40 | 41 | Application 42 | true 43 | v140 44 | MultiByte 45 | 46 | 47 | Application 48 | false 49 | v140 50 | true 51 | MultiByte 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | false 73 | 74 | 75 | false 76 | 77 | 78 | 79 | Level3 80 | Disabled 81 | true 82 | false 83 | false 84 | false 85 | NoExtensions 86 | Default 87 | E:\GitHub\ShellcodeOS\libc;E:\GitHub\ShellcodeVM\GuestOS; 88 | 89 | 90 | true 91 | Native 92 | main 93 | 0x80000000 94 | true 95 | Driver 96 | E:\GitHub\ShellcodeOS\Release\oslibc.lib 97 | true 98 | /filealign:0x1000 %(AdditionalOptions) 99 | 100 | 101 | 102 | 103 | Level3 104 | Disabled 105 | true 106 | 107 | 108 | true 109 | 110 | 111 | 112 | 113 | Level3 114 | MaxSpeed 115 | true 116 | true 117 | true 118 | false 119 | false 120 | E:\GitHub\ShellcodeOS\libc;E:\GitHub\ShellcodeVM\GuestOS; 121 | 122 | 123 | true 124 | true 125 | true 126 | E:\GitHub\ShellcodeOS\Release\oslibc.lib 127 | true 128 | main 129 | 0x80000000 130 | true 131 | false 132 | Native 133 | Driver 134 | /filealign:0x1000 %(AdditionalOptions) 135 | false 136 | true 137 | 138 | 139 | 140 | 141 | Level3 142 | MaxSpeed 143 | true 144 | true 145 | true 146 | 147 | 148 | true 149 | true 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /GuestOS/GuestOS.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 源文件 29 | 30 | 31 | 源文件 32 | 33 | 34 | 源文件 35 | 36 | 37 | 源文件 38 | 39 | 40 | 源文件 41 | 42 | 43 | 44 | 45 | 头文件 46 | 47 | 48 | 头文件 49 | 50 | 51 | 头文件 52 | 53 | 54 | 头文件 55 | 56 | 57 | 头文件 58 | 59 | 60 | 头文件 61 | 62 | 63 | 头文件 64 | 65 | 66 | 头文件 67 | 68 | 69 | -------------------------------------------------------------------------------- /GuestOS/Shellcode.cpp: -------------------------------------------------------------------------------- 1 | #include "Shellcode.h" 2 | 3 | Shellcode::Shellcode() 4 | { 5 | } 6 | 7 | Shellcode::~Shellcode() 8 | { 9 | } 10 | -------------------------------------------------------------------------------- /GuestOS/Shellcode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/Shellcode.h -------------------------------------------------------------------------------- /GuestOS/boot.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/boot.asm -------------------------------------------------------------------------------- /GuestOS/cpu.cpp: -------------------------------------------------------------------------------- 1 | #include "cpu.h" 2 | #include "vga.h" 3 | #include "stdio.h" 4 | #include 5 | 6 | char *CPU::table_lookup_model() 7 | { 8 | struct cpu_model_info 9 | { 10 | int vendor; 11 | int family; 12 | char *model_names[16]; 13 | }; 14 | 15 | static struct cpu_model_info cpu_models[] = 16 | { 17 | { CPU_VENDOR_INTEL, 4,{ "486 DX-25/33", "486 DX-50", "486 SX", "486 DX/2", "486 SL", "486 SX/2", NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL, NULL, NULL } }, 18 | { CPU_VENDOR_INTEL, 5,{ "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75 - 200", "OverDrive PODP5V83", "Pentium MMX", NULL, NULL, "Mobile Pentium 75 - 200", "Mobile Pentium MMX", NULL, NULL, NULL, NULL, NULL, NULL, NULL } }, 19 | { CPU_VENDOR_INTEL, 6,{ "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)", NULL, "Pentium II (Deschutes)", "Mobile Pentium II", "Pentium III (Katmai)", "Pentium III (Coppermine)", NULL, "Pentium III (Cascades)", NULL, NULL, NULL, NULL } }, 20 | { CPU_VENDOR_AMD, 4,{ NULL, NULL, NULL, "486 DX/2", NULL, NULL, NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT", "Am5x86-WB" } }, 21 | { CPU_VENDOR_AMD, 5,{ "K5/SSA5", "K5", "K5", "K5", NULL, NULL, "K6", "K6", "K6-2", "K6-3", NULL, NULL, NULL, NULL, NULL, NULL } }, 22 | { CPU_VENDOR_AMD, 6,{ "Athlon", "Athlon", "Athlon", NULL, "Athlon", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }, 23 | { CPU_VENDOR_UMC, 4,{ NULL, "U5D", "U5S", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }, 24 | { CPU_VENDOR_NEXGEN, 5,{ "Nx586", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }, 25 | { CPU_VENDOR_RISE, 5,{ "iDragon", NULL, "iDragon", NULL, NULL, NULL, NULL, NULL, "iDragon II", "iDragon II", NULL, NULL, NULL, NULL, NULL, NULL } } 26 | }; 27 | struct cpu_model_info *info = cpu_models; 28 | 29 | if (m_model >= 16) return NULL; 30 | 31 | for (int i = 0; i < sizeof(cpu_models) / sizeof(struct cpu_model_info); i++) 32 | { 33 | if (info->vendor == m_vendor && info->family == m_family) 34 | { 35 | return info->model_names[m_model]; 36 | } 37 | info++; 38 | } 39 | 40 | return NULL; 41 | } 42 | 43 | CPU::CPU() 44 | { 45 | CPUID_INFO cpuid_info; 46 | // Get vendor ID 47 | 48 | cpuid(0x00000000, &cpuid_info); 49 | 50 | m_cpuid_level = cpuid_info.eax; 51 | *(uint32*)(m_vendorid + 0)= cpuid_info.ebx; 52 | *(uint32*)(m_vendorid + 4)= cpuid_info.edx; 53 | *(uint32*)(m_vendorid + 8)= cpuid_info.ecx; 54 | *(uint32*)(m_vendorid + 12) = 0; 55 | 56 | if (strcmp(m_vendorid, "GenuineIntel") == 0) 57 | { 58 | m_vendor = CPU_VENDOR_INTEL; 59 | strcpy(m_vendorname,"Intel"); 60 | } 61 | else if (strcmp(m_vendorid, "AuthenticAMD") == 0) 62 | { 63 | m_vendor = CPU_VENDOR_AMD; 64 | strcpy(m_vendorname , "AMD"); 65 | } 66 | else if (strcmp(m_vendorid, "CyrixInstead") == 0) 67 | { 68 | m_vendor = CPU_VENDOR_CYRIX; 69 | strcpy(m_vendorname , "Cyrix"); 70 | } 71 | else if (strcmp(m_vendorid, "UMC UMC UMC ") == 0) 72 | { 73 | m_vendor = CPU_VENDOR_UMC; 74 | strcpy(m_vendorname , "UMC"); 75 | } 76 | else if (strcmp(m_vendorid, "CentaurHauls") == 0) 77 | { 78 | m_vendor = CPU_VENDOR_CENTAUR; 79 | strcpy(m_vendorname , "Centaur"); 80 | } 81 | else if (strcmp(m_vendorid, "NexGenDriven") == 0) 82 | { 83 | m_vendor = CPU_VENDOR_NEXGEN; 84 | strcpy(m_vendorname , "NexGen"); 85 | } 86 | else if (strcmp(m_vendorid, "GenuineTMx86") == 0 || strcmp(m_vendorid, "TransmetaCPU") == 0) 87 | { 88 | m_vendor = CPU_VENDOR_TRANSMETA; 89 | strcpy(m_vendorname , "Transmeta"); 90 | } 91 | else 92 | { 93 | m_vendor = CPU_VENDOR_UNKNOWN; 94 | strcpy(m_vendorname , m_vendorid); 95 | } 96 | 97 | // Get model and features 98 | if (m_cpuid_level >= 0x00000001) 99 | { 100 | cpuid(0x00000001, &cpuid_info); 101 | m_family = (cpuid_info.eax >> 8) & 15; 102 | m_model = (cpuid_info.eax >> 4) & 15; 103 | m_stepping = cpuid_info.eax & 15; 104 | m_features = cpuid_info.edx; 105 | } 106 | 107 | // SEP CPUID bug: Pentium Pro reports SEP but doesn't have it 108 | if (m_family == 6 && m_model < 3 && m_stepping < 3) m_features &= ~CPU_FEATURE_SEP; 109 | 110 | // Get brand string 111 | cpuid(0x80000000, &cpuid_info); 112 | if (cpuid_info.eax > 0x80000000) 113 | { 114 | char model[64]; 115 | char *p, *q; 116 | int space; 117 | 118 | memset(model, 0, 64); 119 | cpuid(0x80000002, (CPUID_INFO*)model); 120 | cpuid(0x80000003, (CPUID_INFO*)(model + 16)); 121 | cpuid(0x80000004, (CPUID_INFO*)(model + 32)); 122 | 123 | // Trim brand string 124 | p = model; 125 | q = m_modelid; 126 | space = 0; 127 | while (*p == ' ') p++; 128 | while (*p) 129 | { 130 | if (*p == ' ') 131 | { 132 | space = 1; 133 | } 134 | else 135 | { 136 | if (space) *q++ = ' '; 137 | space = 0; 138 | *q++ = *p; 139 | } 140 | p++; 141 | } 142 | *q = 0; 143 | } 144 | else 145 | { 146 | char *modelid = table_lookup_model(); 147 | if (modelid) 148 | { 149 | sprintf(m_modelid, "%s %s", m_vendorname, modelid); 150 | } 151 | else 152 | { 153 | sprintf(m_modelid, "%s %d86", m_vendorname, m_family); 154 | } 155 | } 156 | printf("cpu: %s family %d model %d stepping %d\n", m_modelid, m_family, m_model, m_stepping); 157 | } 158 | 159 | 160 | CPU::~CPU() 161 | { 162 | } 163 | 164 | 165 | void CPU::cpuid(uint32 id, CPUID_INFO* cpuid_info) 166 | { 167 | __asm 168 | { 169 | mov eax, id 170 | cpuid 171 | push esi 172 | mov esi, [cpuid_info] 173 | mov [esi]CPUID_INFO.eax, eax 174 | mov [esi]CPUID_INFO.ebx, ebx 175 | mov [esi]CPUID_INFO.ecx, ecx 176 | mov [esi]CPUID_INFO.edx, edx 177 | pop esi 178 | } 179 | } -------------------------------------------------------------------------------- /GuestOS/cpu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "typedef.h" 3 | // 4 | // ASM instructions 5 | // 6 | 7 | #define sysenter __asm _emit 0x0F __asm _emit 0x34 8 | #define sysexit __asm _emit 0x0F __asm _emit 0x35 9 | 10 | // 11 | // x86 EFLAGS 12 | // 13 | 14 | #define EFLAG_CF 0x00000001 // Carry 15 | #define EFLAG_PF 0x00000004 // Parity 16 | #define EFLAG_AF 0x00000010 // BCD stuff 17 | #define EFLAG_ZF 0x00000040 // Zero 18 | #define EFLAG_SF 0x00000080 // Sign 19 | #define EFLAG_TF 0x00000100 // Single step 20 | #define EFLAG_IF 0x00000200 // Interrupts 21 | #define EFLAG_DF 0x00000400 // Direction 22 | #define EFLAG_OF 0x00000800 // Overflow 23 | #define EFLAG_IOPL 0x00003000 // I/O privilege level 24 | #define EFLAG_NT 0x00004000 // Nested task 25 | #define EFLAG_RF 0x00010000 // Resume flag 26 | #define EFLAG_VM 0x00020000 // Virtual 8086 27 | #define EFLAGS_AC 0x00040000 // Alignment Check 28 | #define EFLAGS_VIF 0x00080000 // Virtual Interrupt Flag 29 | #define EFLAGS_VIP 0x00100000 // Virtual Interrupt Pending 30 | #define EFLAGS_ID 0x00200000 // CPUID detection flag 31 | 32 | // 33 | // x86 CR0 flags 34 | // 35 | 36 | #define CR0_PE (1 << 0) // Protection enable 37 | #define CR0_MP (1 << 1) // Math processor present 38 | #define CR0_EM (1 << 2) // Emulate FP - trap on FP instruction 39 | #define CR0_TS (1 << 3) // Task switched flag 40 | #define CR0_ET (1 << 4) // Extension type - 387 DX presence 41 | #define CR0_NE (1 << 5) // Numeric Error - allow traps on numeric errors 42 | #define CR0_WP (1 << 16) // Write protect - ring 0 honors RO PTE's 43 | #define CR0_AM (1 << 18) // Alignment - trap on unaligned refs 44 | #define CR0_NW (1 << 29) // Not write-through - inhibit write-through 45 | #define CR0_CD (1 << 30) // Cache disable 46 | #define CR0_PG (1 << 31) // Paging - use PTEs/CR3 47 | 48 | // 49 | // x86 CR4 feature flags 50 | // 51 | #define CR4_VME 0x0001 // Enable vm86 extensions 52 | #define CR4_PVI 0x0002 // Virtual interrupts flag enable 53 | #define CR4_TSD 0x0004 // Disable time stamp at ipl 3 54 | #define CR4_DE 0x0008 // Enable debugging extensions 55 | #define CR4_PSE 0x0010 // Enable page size extensions 56 | #define CR4_PAE 0x0020 // Enable physical address extensions 57 | #define CR4_MCE 0x0040 // Machine check enable 58 | #define CR4_PGE 0x0080 // Enable global pages 59 | #define CR4_PCE 0x0100 // Enable performance counters at ipl 3 60 | #define CR4_OSFXSR 0x0200 // Enable fast FPU save and restore 61 | #define CR4_OSXMMEXCPT 0x0400 // Enable unmasked SSE exceptions 62 | 63 | // 64 | // CPU feature flags (CPUID level 0x00000001, edx) 65 | // 66 | 67 | #define CPU_FEATURE_FPU (1 << 0) // Onboard FPU 68 | #define CPU_FEATURE_VME (1 << 1) // Virtual Mode Extensions 69 | #define CPU_FEATURE_DE (1 << 2) // Debugging Extensions 70 | #define CPU_FEATURE_PSE (1 << 3) // Page Size Extensions 71 | #define CPU_FEATURE_TSC (1 << 4) // Time Stamp Counter 72 | #define CPU_FEATURE_MSR (1 << 5) // Model-Specific Registers, RDMSR, WRMSR 73 | #define CPU_FEATURE_PAE (1 << 6) // Physical Address Extensions 74 | #define CPU_FEATURE_MCE (1 << 7) // Machine Check Architecture 75 | #define CPU_FEATURE_CX8 (1 << 8) // CMPXCHG8 instruction 76 | #define CPU_FEATURE_APIC (1 << 9) // Onboard APIC 77 | #define CPU_FEATURE_SEP (1 << 11) // SYSENTER/SYSEXIT 78 | #define CPU_FEATURE_MTRR (1 << 12) // Memory Type Range Registers 79 | #define CPU_FEATURE_PGE (1 << 13) // Page Global Enable 80 | #define CPU_FEATURE_MCA (1 << 14) // Machine Check Architecture 81 | #define CPU_FEATURE_CMOV (1 << 15) // CMOV instruction 82 | #define CPU_FEATURE_PAT (1 << 16) // Page Attribute Table 83 | #define CPU_FEATURE_PSE36 (1 << 17) // 36-bit PSEs 84 | #define CPU_FEATURE_PN (1 << 18) // Processor serial number 85 | #define CPU_FEATURE_CLFLSH (1 << 19) // Supports the CLFLUSH instruction 86 | #define CPU_FEATURE_DTES (1 << 21) // Debug Trace Store 87 | #define CPU_FEATURE_ACPI (1 << 22) // ACPI via MSR 88 | #define CPU_FEATURE_MMX (1 << 23) // Multimedia Extensions 89 | #define CPU_FEATURE_FXSR (1 << 24) // FXSAVE and FXRSTOR instructions 90 | #define CPU_FEATURE_XMM (1 << 25) // Streaming SIMD Extensions 91 | #define CPU_FEATURE_XMM2 (1 << 26) // Streaming SIMD Extensions-2 92 | #define CPU_FEATURE_SELFSNOOP (1 << 27) // CPU self snoop 93 | #define CPU_FEATURE_ACC (1 << 29) // Automatic clock control 94 | #define CPU_FEATURE_IA64 (1 << 30) // IA-64 processor 95 | 96 | // 97 | // Model Specific Registers 98 | // 99 | 100 | #define MSR_SYSENTER_CS 0x174 // CS register target for CPL 0 code 101 | #define MSR_SYSENTER_ESP 0x175 // Stack pointer for CPL 0 code 102 | #define MSR_SYSENTER_EIP 0x176 // CPL 0 code entry point 103 | 104 | // 105 | // CPU vendors 106 | // 107 | 108 | #define CPU_VENDOR_UNKNOWN 0 109 | #define CPU_VENDOR_INTEL 1 110 | #define CPU_VENDOR_CYRIX 2 111 | #define CPU_VENDOR_AMD 3 112 | #define CPU_VENDOR_UMC 4 113 | #define CPU_VENDOR_NEXGEN 5 114 | #define CPU_VENDOR_CENTAUR 6 115 | #define CPU_VENDOR_RISE 7 116 | #define CPU_VENDOR_TRANSMETA 8 117 | 118 | // CPU family 119 | 120 | #define CPU_FAMILY_386 3 121 | #define CPU_FAMILY_486 4 122 | #define CPU_FAMILY_P5 5 123 | #define CPU_FAMILY_P6 6 124 | 125 | // 126 | // CPU information 127 | // 128 | 129 | struct CPUID_INFO 130 | { 131 | uint32 eax; 132 | uint32 ebx; 133 | uint32 ecx; 134 | uint32 edx; 135 | }; 136 | 137 | class CPU 138 | { 139 | private: 140 | int m_family; 141 | int m_vendor; 142 | int m_model; 143 | int m_stepping; 144 | int m_mhz; 145 | unsigned long m_features; 146 | unsigned long m_cpuid_level; 147 | char m_vendorid[16]; 148 | char m_modelid[64]; 149 | char m_vendorname[16]; 150 | //PROCESS 151 | //GDT 152 | //IDT 153 | //TSS 154 | public: 155 | CPU(); 156 | ~CPU(); 157 | char *table_lookup_model(); 158 | void cpuid(uint32 id, CPUID_INFO* cpuid_info); 159 | }; 160 | 161 | -------------------------------------------------------------------------------- /GuestOS/gdt.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/gdt.cpp -------------------------------------------------------------------------------- /GuestOS/gdt.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/gdt.h -------------------------------------------------------------------------------- /GuestOS/idt.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/idt.cpp -------------------------------------------------------------------------------- /GuestOS/idt.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/idt.h -------------------------------------------------------------------------------- /GuestOS/kernel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "c++.h" 4 | #include "os.h" 5 | #include "gdt.h" 6 | #include "idt.h" 7 | #include "tss.h" 8 | #include "trap.h" 9 | #include "paging.h" 10 | #include "video.h" 11 | #include "Shellcode.h" 12 | #include "msr-index.h" 13 | 14 | GDT gdt; 15 | IDT idt; 16 | TSS tss; 17 | VIDEO video; 18 | PAGER pager; 19 | Shellcode shellcode; 20 | 21 | extern "C" int liballoc_lock() { return 0; } 22 | extern "C" int liballoc_unlock() { return 0; } 23 | extern "C" void* liballoc_alloc(int pages) { return 0; } 24 | extern "C" int liballoc_free(void*ptr, int size) { return 0; } 25 | 26 | void return_to_user_mode() 27 | { 28 | __asm cli 29 | __asm xor eax,eax 30 | __asm mov ax, SEL_USER_DATA 31 | __asm mov ds, ax 32 | __asm mov es, ax 33 | __asm mov gs, ax 34 | 35 | __asm mov ax, SEL_USER_FS 36 | __asm mov fs, ax 37 | 38 | __asm push SEL_USER_DATA //Ring3_SS 39 | __asm push SHELLCODE_STACK_VIRTUAL_ADDR//Ring3_ESP 40 | __asm pushfd 41 | __asm push SEL_USER_CODE //Ring3_CS 42 | __asm push SHELLCODE_BUF_VIRTUAL_ADDR//Ring3_EIP 43 | __asm iretd 44 | } 45 | 46 | int main() 47 | { 48 | CppInit(); 49 | video.Init(VIDEO_BUF_VIRTUAL_ADDR, MB(2), 100, 100); 50 | gdt.Init(); 51 | idt.Init(); 52 | tss.Init(&gdt); 53 | TRAP::Init(&idt); 54 | tss.active(); 55 | __asm mov esp, KERNEL_STACK_TOP_VIRTUAL_ADDR 56 | pager.unmap_pages(0, FRAME_DB_PHYSICAL_ADDR); 57 | //pager.map_pages(SHELLCODE_TEB_PHYSICAL_ADDR, SHELLCODE_TEB_VIRTUAL_ADDR, SHELLCODE_TEB_SIZE, PT_READONLY | PT_USER); 58 | //pager.map_pages(DUMMY_PEB_PHYSICAL_ADDR, DUMMY_PEB_VIRTUAL_ADDR, DUMMY_PEB_SIZE,PT_READONLY | PT_USER); 59 | //pager.map_pages(KERNEL32_PHYSICAL_ADDR, KERNEL32_VIRTUAL_ADDR, KERNEL32_SIZE, PT_READONLY | PT_USER); 60 | pager.map_pages(SHELLCODE_BUF_PHYSICAL_ADDR, SHELLCODE_BUF_VIRTUAL_ADDR, SHELLCODE_BUF_SIZE, PT_PRESENT | PT_READONLY | PT_USER); 61 | 62 | UINT32 test_code_buf = 0; 63 | UINT32 test_code_len = 0; 64 | __asm jmp test_code_end 65 | { 66 | __asm test_code_start: 67 | { 68 | __asm MOV EAX, 0x11111111 69 | __asm MOV EBX, 0x22222222 70 | __asm MOV ECX, 0x33333333 71 | __asm MOV EDX, 0x44444444 72 | __asm INT 0 73 | __asm MOV EDI, SHELLCODE_BUF_VIRTUAL_ADDR 74 | __asm MOV [EDI],EDI 75 | __asm MOV EDI, 0x12345678 76 | __asm MOV EDX, [EDI] 77 | __asm hlt 78 | } 79 | __asm test_code_end: 80 | } 81 | __asm mov eax, test_code_start 82 | __asm mov test_code_buf, eax 83 | __asm mov eax, test_code_end 84 | __asm SUB eax, test_code_start 85 | __asm mov test_code_len, eax 86 | 87 | memcpy((byte*)SHELLCODE_BUF_VIRTUAL_ADDR, (void*)test_code_buf, test_code_len); 88 | 89 | __asm MOV ECX, IA32_DEBUGCTL 90 | __asm rdmsr 91 | __asm OR EAX, 0x02 92 | __asm wrmsr 93 | __asm XOR EAX,EAX 94 | __asm rdmsr 95 | return_to_user_mode(); 96 | __asm hlt 97 | //video.puts("Hello world\n"); 98 | __asm mov edx,0x44444444 99 | __asm mov ecx,0 100 | __asm div ecx 101 | 102 | __asm jmp $ 103 | return 0; 104 | } -------------------------------------------------------------------------------- /GuestOS/os.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/os.h -------------------------------------------------------------------------------- /GuestOS/paging.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/paging.cpp -------------------------------------------------------------------------------- /GuestOS/paging.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define PAGE_SIZE 0x1000 5 | #define PAGE_SIZE_BITS 12 6 | #define PDE_INDEX(virtual_addr) ((virtual_addr>>22)) 7 | #define PTE_INDEX(virtual_addr) ((virtual_addr>>12)&0x3FF) 8 | 9 | #define KERNEL_BASE 0x80000000 10 | #define PAGE_DIR_BASE 0xC0300000 11 | #define PAGE_TABLE_BASE 0xC0000000 12 | #define PAGE_FRAME_BASE 0xC0400000 13 | 14 | #define GET_PDE(addr) ((uint32_t*)PAGE_DIR_BASE)[(uint32_t)(addr)>>22] 15 | #define GET_PTE(addr) ((uint32_t*)PAGE_TABLE_BASE)[(uint32_t)(addr)>>12] 16 | #define GET_PAGE_TABLE(addr) (PAGE_TABLE_BASE + ((uint32_t)(addr)>>22)* PAGE_SIZE) 17 | 18 | #define SET_PDE(addr, val) ((uint32_t*)PAGE_DIR_BASE)[(uint32_t)(addr)>>22] = val; 19 | #define SET_PTE(addr, val) ((uint32_t*)PAGE_TABLE_BASE)[(uint32_t)(addr)>>12]=val; 20 | 21 | #define PAGE_ALGINED(addr) ((((uint32_t)addr) & 0x00000FFF) ==0) 22 | #define CHECK_PAGE_ALGINED(addr) //if ((((uint32_t)addr) & 0x00000FFF) !=0) panic("CHECK_PAGE_ALGINED(%08X)",addr); 23 | 24 | #define PT_PRESENT 0x001 25 | 26 | #define PT_WRITABLE 0x002 27 | #define PT_READONLY 0x000 28 | 29 | #define PT_USER 0x004 30 | #define PT_KERNEL 0x000 31 | 32 | #define PT_ACCESSED 0x020 33 | #define PT_DIRTY 0x040 34 | 35 | #define PAGE_FREE 0x00 36 | #define PAGE_USED 0x01 37 | #define PAGE_RESERVED 0xff 38 | 39 | 40 | #define KB(x) ((uint32_t)x<<10) 41 | #define MB(x) ((uint32_t)x<<20) 42 | #define GB(x) ((uint32_t)x<<30) 43 | 44 | #define USER_SPACE(addr) (((uint32_t)addr) < KERNEL_BASE) 45 | #define KERNEL_SPACE(addr) (((uint32_t)addr) >= KERNEL_BASE) 46 | 47 | #define PAGES_TO_SIZE(pages) ((uint32_t)(pages)<<12) 48 | #define SIZE_TO_PAGES(size) (((uint32_t)(size) + PAGE_SIZE -1)>>12) 49 | #define PAGE_ALGIN_SIZE(size) ((uint32_t)(size + 4095)&0xFFFFF000) 50 | 51 | class PAGER 52 | { 53 | private: 54 | uint32_t m_page_dir; 55 | uint32_t m_page_table_base; 56 | 57 | uint32_t m_page_frame_min; 58 | uint32_t m_page_frame_max; 59 | uint32_t m_next_free_page_frame; 60 | uint8_t* m_page_frame_database; 61 | bool m_database_usable; 62 | 63 | public: 64 | PAGER(); 65 | ~PAGER(); 66 | public: 67 | bool Init(uint32_t page_frame_min, uint32_t page_frame_max); 68 | 69 | void map_pages(uint32_t physical_address, uint32_t virtual_address, uint32_t size, uint32_t protect = (PT_PRESENT | PT_WRITABLE)); 70 | void unmap_pages(uint32_t virtual_address, uint32_t size); 71 | 72 | bool create_database(); 73 | uint32_t alloc_physical_page(); 74 | uint32_t alloc_physical_pages(uint32_t pages); 75 | void free_physical_page(uint32_t page); 76 | void free_physical_pages(uint32_t start_page, uint32_t pages); 77 | 78 | private: 79 | void startup_page_mode(); 80 | uint32_t new_page_dir(); 81 | uint32_t new_page_table(uint32_t virtual_address); 82 | bool identity_paging_lowest_4M(); 83 | }; 84 | 85 | -------------------------------------------------------------------------------- /GuestOS/trap.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/trap.cpp -------------------------------------------------------------------------------- /GuestOS/trap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "typedef.h" 3 | #include "idt.h" 4 | #include "gdt.h" 5 | 6 | 7 | #pragma pack(push, 1) 8 | struct TRAP_CONTEXT 9 | { 10 | uint32 gs, fs, es, ds; 11 | uint32 edi, esi, ebp, tmp, ebx, edx, ecx, eax; 12 | uint32 irq_no, err_code; 13 | uint32 eip, cs, eflags, esp, ss; 14 | }; //19*4=76 Bytes 15 | #pragma pack(pop) 16 | 17 | #define MAX_TRAP_ENTRIES 19 18 | 19 | typedef void (*TRAP_HANDLER)(TRAP_CONTEXT* context); 20 | 21 | class TRAP 22 | { 23 | private: 24 | static TRAP_HANDLER m_handlers[MAX_TRAP_ENTRIES]; 25 | public: 26 | static void Init(IDT* idt); 27 | static void register_handler(int irq_no, TRAP_HANDLER handler); 28 | static void dispatch(TRAP_CONTEXT* context); 29 | static void handler0(TRAP_CONTEXT* context); 30 | static void handler1(TRAP_CONTEXT* context); 31 | static void handler2(TRAP_CONTEXT* context); 32 | static void handler3(TRAP_CONTEXT* context); 33 | static void handler4(TRAP_CONTEXT* context); 34 | static void handler5(TRAP_CONTEXT* context); 35 | static void handler6(TRAP_CONTEXT* context); 36 | static void handler7(TRAP_CONTEXT* context); 37 | static void handler8(TRAP_CONTEXT* context); 38 | static void handler9(TRAP_CONTEXT* context); 39 | static void handler10(TRAP_CONTEXT* context); 40 | static void handler11(TRAP_CONTEXT* context); 41 | static void handler12(TRAP_CONTEXT* context); 42 | static void handler13(TRAP_CONTEXT* context); 43 | static void handler14(TRAP_CONTEXT* context); 44 | static void handler15(TRAP_CONTEXT* context); 45 | static void handler16(TRAP_CONTEXT* context); 46 | static void handler17(TRAP_CONTEXT* context); 47 | static void handler18(TRAP_CONTEXT* context); 48 | static void handler19(TRAP_CONTEXT* context); 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /GuestOS/tss.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/tss.cpp -------------------------------------------------------------------------------- /GuestOS/tss.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/GuestOS/tss.h -------------------------------------------------------------------------------- /GuestOS/video.cpp: -------------------------------------------------------------------------------- 1 | #include "VIDEO.h" 2 | #include 3 | 4 | VIDEO::VIDEO() 5 | { 6 | m_video_buf=0; 7 | m_video_buf_size = 0; 8 | m_screen_width = 25; 9 | m_screen_height = 80; 10 | m_cursor_x = 0; 11 | m_cursor_y = 0; 12 | } 13 | 14 | VIDEO::~VIDEO() 15 | { 16 | } 17 | 18 | bool VIDEO::Init(uint32_t video_buf, uint32_t buf_size, uint32_t width, uint32_t height) 19 | { 20 | m_video_buf = video_buf; 21 | m_video_buf_size = buf_size; 22 | m_screen_width = width <= MAX_SCREEN_WIDTH ? width-1 : MAX_SCREEN_WIDTH; 23 | m_screen_height = height<= MAX_SCREEN_HEIGHT? height-1: MAX_SCREEN_HEIGHT; 24 | m_cursor_x = 0; 25 | m_cursor_y = 0; 26 | 27 | return true; 28 | } 29 | 30 | void VIDEO::putc(char ch) 31 | { 32 | if (ch == '\r') 33 | { 34 | m_cursor_x = 0; 35 | return; 36 | } 37 | if (ch == '\n') 38 | { 39 | if (m_cursor_y < m_screen_height) m_cursor_y++; 40 | else scroll(1); 41 | return; 42 | } 43 | if (m_cursor_x >= m_screen_width) 44 | { 45 | m_cursor_x = 0; 46 | if (m_cursor_y < m_screen_height) m_cursor_y++; 47 | else scroll(1); 48 | } 49 | char* addr = (char*)(m_video_buf + m_cursor_y*LINE_BUF_WIDTH + m_cursor_x++); 50 | *addr++ = ch; 51 | *addr = 0; 52 | } 53 | 54 | void VIDEO::puts(char* str) 55 | { 56 | int len = strlen(str); 57 | for (int i = 0; i < len; i++) putc(str[i]); 58 | } 59 | 60 | 61 | void VIDEO::clear() 62 | { 63 | char* line_buf = (char*)m_video_buf; 64 | for (int i = 0; i <= m_screen_height;i++) 65 | { 66 | line_buf[0] = 0; 67 | line_buf += LINE_BUF_WIDTH; 68 | } 69 | } 70 | 71 | void VIDEO::scroll(int lines) 72 | { 73 | char* line_buf = (char*)m_video_buf; 74 | memcpy(line_buf, line_buf + lines*LINE_BUF_WIDTH, (m_screen_height - lines)*LINE_BUF_WIDTH); 75 | } 76 | 77 | void VIDEO::gotoxy(int x, int y) 78 | { 79 | m_cursor_x = x; 80 | m_cursor_y = y; 81 | } 82 | 83 | int VIDEO::getx() 84 | { 85 | return m_cursor_x; 86 | } 87 | 88 | int VIDEO::gety() 89 | { 90 | return m_cursor_y; 91 | } 92 | 93 | -------------------------------------------------------------------------------- /GuestOS/video.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define MAX_VIDEO_BUF_SIZE 0x10000 5 | #define MAX_SCREEN_WIDTH 255 6 | #define MAX_SCREEN_HEIGHT 255 7 | #define LINE_BUF_WIDTH 256 8 | 9 | class VIDEO 10 | { 11 | private: 12 | uint32_t m_video_buf; 13 | uint32_t m_video_buf_size; 14 | uint32_t m_screen_width; 15 | uint32_t m_screen_height; 16 | uint32_t m_cursor_x; 17 | uint32_t m_cursor_y; 18 | public: 19 | VIDEO(); 20 | ~VIDEO(); 21 | bool Init(uint32_t video_buf, uint32_t buf_size, uint32_t width, uint32_t height); 22 | void putc(char ch); 23 | void puts(char* str); 24 | void clear(); 25 | void scroll(int lines); 26 | void gotoxy(int x, int y); 27 | int getx(); 28 | int gety(); 29 | }; 30 | 31 | extern VIDEO video; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ShellcodeVM 2 | ShellcodeVM 3 | -------------------------------------------------------------------------------- /ShellcodeVM.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/ShellcodeVM.VC.db -------------------------------------------------------------------------------- /ShellcodeVM.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellcodeVM", "ShellcodeVM\ShellcodeVM.vcxproj", "{C27C6721-3007-443E-B095-51024C1B8236}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GuestOS", "GuestOS\GuestOS.vcxproj", "{70B6C809-92DB-4C09-8E45-C6ED3256412B}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Boot", "Boot\Boot.vcxproj", "{77EB0E19-AA23-415C-B34B-8BDCD4CD495D}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {C27C6721-3007-443E-B095-51024C1B8236}.Debug|x64.ActiveCfg = Debug|x64 21 | {C27C6721-3007-443E-B095-51024C1B8236}.Debug|x64.Build.0 = Debug|x64 22 | {C27C6721-3007-443E-B095-51024C1B8236}.Debug|x86.ActiveCfg = Debug|Win32 23 | {C27C6721-3007-443E-B095-51024C1B8236}.Debug|x86.Build.0 = Debug|Win32 24 | {C27C6721-3007-443E-B095-51024C1B8236}.Release|x64.ActiveCfg = Release|x64 25 | {C27C6721-3007-443E-B095-51024C1B8236}.Release|x64.Build.0 = Release|x64 26 | {C27C6721-3007-443E-B095-51024C1B8236}.Release|x86.ActiveCfg = Release|Win32 27 | {C27C6721-3007-443E-B095-51024C1B8236}.Release|x86.Build.0 = Release|Win32 28 | {70B6C809-92DB-4C09-8E45-C6ED3256412B}.Debug|x64.ActiveCfg = Debug|x64 29 | {70B6C809-92DB-4C09-8E45-C6ED3256412B}.Debug|x64.Build.0 = Debug|x64 30 | {70B6C809-92DB-4C09-8E45-C6ED3256412B}.Debug|x86.ActiveCfg = Debug|Win32 31 | {70B6C809-92DB-4C09-8E45-C6ED3256412B}.Debug|x86.Build.0 = Debug|Win32 32 | {70B6C809-92DB-4C09-8E45-C6ED3256412B}.Release|x64.ActiveCfg = Release|x64 33 | {70B6C809-92DB-4C09-8E45-C6ED3256412B}.Release|x64.Build.0 = Release|x64 34 | {70B6C809-92DB-4C09-8E45-C6ED3256412B}.Release|x86.ActiveCfg = Release|Win32 35 | {70B6C809-92DB-4C09-8E45-C6ED3256412B}.Release|x86.Build.0 = Release|Win32 36 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D}.Debug|x64.ActiveCfg = Debug|x64 37 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D}.Debug|x64.Build.0 = Debug|x64 38 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D}.Debug|x86.ActiveCfg = Debug|Win32 39 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D}.Debug|x86.Build.0 = Debug|Win32 40 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D}.Release|x64.ActiveCfg = Release|x64 41 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D}.Release|x64.Build.0 = Release|x64 42 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D}.Release|x86.ActiveCfg = Release|Win32 43 | {77EB0E19-AA23-415C-B34B-8BDCD4CD495D}.Release|x86.Build.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | EndGlobal 49 | -------------------------------------------------------------------------------- /ShellcodeVM/HAXM.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "hax-interface.h" 7 | #include "hax-windows.h" 8 | #include "HAXM_VM.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | typedef map HAXM_VM_MAP; 17 | 18 | class HAXM 19 | { 20 | private: 21 | HANDLE m_hDevice; 22 | HAXM_VM_MAP m_vm_list; 23 | public: 24 | 25 | HAXM() 26 | { 27 | m_hDevice = INVALID_HANDLE_VALUE; 28 | } 29 | 30 | ~HAXM() 31 | { 32 | close_device(); 33 | } 34 | 35 | /* 36 | * return 0 upon success, -1 when the driver is not loaded, 37 | * other negative value for other failures 38 | */ 39 | bool open_device() 40 | { 41 | if (m_hDevice != INVALID_HANDLE_VALUE) 42 | { 43 | return true; 44 | } 45 | 46 | m_hDevice = CreateFile("\\\\.\\HAX", 47 | GENERIC_READ | GENERIC_WRITE, 48 | 0, 49 | NULL, 50 | CREATE_ALWAYS, 51 | FILE_ATTRIBUTE_NORMAL, 52 | NULL); 53 | 54 | if (m_hDevice == INVALID_HANDLE_VALUE) 55 | { 56 | printf("Failed to open the HAX device!\n"); 57 | //uint32_t errNum = GetLastError(); 58 | //if (errNum == ERROR_FILE_NOT_FOUND) return -1; 59 | return false; 60 | } 61 | printf("open the HAX device OK\n"); 62 | return true; 63 | } 64 | 65 | bool close_device() 66 | { 67 | if (m_hDevice != INVALID_HANDLE_VALUE) 68 | { 69 | HAXM_VM_MAP::iterator it = m_vm_list.begin(); 70 | for (; it != m_vm_list.end(); it++) 71 | { 72 | delete it->second; 73 | } 74 | m_vm_list.clear(); 75 | if (!CloseHandle(m_hDevice)) return false; 76 | m_hDevice = INVALID_HANDLE_VALUE; 77 | } 78 | 79 | return true; 80 | } 81 | 82 | //bool get_device_version(struct hax_module_version *version) 83 | bool is_supported() 84 | { 85 | // Current version 86 | static UINT32 HaxCurrentVersion = 0x2; 87 | 88 | // Minimum HAX kernel version 89 | static UINT32 HaxMinVersion = 0x1; 90 | 91 | if (m_hDevice == INVALID_HANDLE_VALUE) 92 | { 93 | printf("Invalid HANDLE for hax device!\n"); 94 | return false; 95 | } 96 | 97 | int ret; 98 | DWORD dSize = 0; 99 | hax_module_version version; 100 | ret = DeviceIoControl(m_hDevice, 101 | HAX_IOCTL_VERSION, 102 | NULL, 0, 103 | &version, sizeof(version), 104 | &dSize, 105 | (LPOVERLAPPED)NULL); 106 | if (!ret) 107 | { 108 | DWORD err = GetLastError(); 109 | if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_MORE_DATA) 110 | { 111 | printf("HAX module is too large.\n"); 112 | } 113 | printf("Failed to get Hax module version:%d\n", err); 114 | return false; 115 | } 116 | printf("haxm compat_version:%08X cur_version=%08X\n", 117 | version.compat_version, version.cur_version); 118 | 119 | if ((HaxMinVersion > version.cur_version) || (HaxCurrentVersion < version.compat_version)) 120 | return false; 121 | return true; 122 | } 123 | 124 | //bool get_capability() 125 | bool is_available() 126 | { 127 | if (m_hDevice == INVALID_HANDLE_VALUE) 128 | { 129 | printf("Invalid HANDLE for hax device!\n"); 130 | return false; 131 | } 132 | 133 | int ret; 134 | DWORD dSize = 0; 135 | DWORD err = 0; 136 | hax_capabilityinfo cap; 137 | ret = DeviceIoControl(m_hDevice, 138 | HAX_IOCTL_CAPABILITY, 139 | NULL, 0, 140 | &cap, sizeof(cap), 141 | &dSize, 142 | (LPOVERLAPPED)NULL); 143 | 144 | if (!ret) 145 | { 146 | err = GetLastError(); 147 | if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_MORE_DATA) 148 | { 149 | printf("hax capability is too long to hold.\n"); 150 | } 151 | printf("Failed to get Hax capability:%d\n", err); 152 | return false; 153 | } 154 | if (cap.wstatus & HAX_CAP_STATUS_WORKING) printf("HAXM is working\n"); 155 | else 156 | { 157 | printf("HAXM is not working possibly because VT/NX is disabled\n"); 158 | if (cap.winfo & HAX_CAP_FAILREASON_VT) printf("HAXM is not working because VT is not enabeld\n"); 159 | else if (cap.winfo & HAX_CAP_FAILREASON_NX) printf("HAXM is not working because NX not enabled\n"); 160 | } 161 | if (cap.wstatus & HAX_CAP_MEMQUOTA) 162 | { 163 | printf("HAXM has hard limit on how many RAM can be used as guest RAM\n"); 164 | printf("mem_quota:%I64d\n", cap.mem_quota); 165 | } 166 | else printf("HAXM has no memory limitation\n"); 167 | return true; 168 | } 169 | 170 | HAXM_VM* create_vm() 171 | { 172 | int ret; 173 | int vmid = 0; 174 | DWORD dSize = 0; 175 | 176 | ret = DeviceIoControl( 177 | m_hDevice, 178 | HAX_IOCTL_CREATE_VM, 179 | NULL, 0, 180 | &vmid, sizeof(vmid), 181 | &dSize, 182 | (LPOVERLAPPED) NULL); 183 | if (!ret) 184 | { 185 | printf("error code:%d", GetLastError()); 186 | return 0; 187 | } 188 | printf("vm_id=%08X\n", vmid); 189 | HAXM_VM* vm = new HAXM_VM(vmid); 190 | if (!vm->open_vm()) 191 | { 192 | delete vm; 193 | return NULL; 194 | } 195 | m_vm_list[vmid] = vm; 196 | return vm; 197 | } 198 | 199 | }; 200 | 201 | -------------------------------------------------------------------------------- /ShellcodeVM/HAXM_CPU.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/ShellcodeVM/HAXM_CPU.h -------------------------------------------------------------------------------- /ShellcodeVM/HAXM_VM.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/ShellcodeVM/HAXM_VM.h -------------------------------------------------------------------------------- /ShellcodeVM/HaxVM.cpp: -------------------------------------------------------------------------------- 1 | #include "HaxVM.h" 2 | 3 | // Current version 4 | UINT32 HaxCurrentVersion = 0x2; 5 | 6 | // Minimum HAX kernel version 7 | UINT32 HaxMinVersion = 0x1; 8 | 9 | bool HaxIsSupported(hax_state *Hax) 10 | { 11 | hax_module_version version; 12 | if (hax_mod_version(Hax, &version) < 0) 13 | return false; 14 | 15 | if ((HaxMinVersion > version.cur_version) || (HaxCurrentVersion < version.compat_version)) 16 | return false; 17 | 18 | return true; 19 | } 20 | 21 | bool HaxIsAvailable(hax_state *Hax) 22 | { 23 | hax_capabilityinfo capinfo; 24 | if (!HaxGetCapability(Hax, &capinfo)) 25 | return false; 26 | 27 | if ((capinfo.wstatus & HAX_CAP_WORKSTATUS_MASK) == HAX_CAP_STATUS_NOTWORKING) 28 | { 29 | if (capinfo.winfo & HAX_CAP_FAILREASON_VT) 30 | printf("VT feature is not enabled, HAXM not working.\n"); 31 | else if (capinfo.winfo & HAX_CAP_FAILREASON_NX) 32 | printf("NX feature is not enabled, HAXM not working.\n"); 33 | 34 | return false; 35 | } 36 | 37 | if (capinfo.wstatus & HAX_CAP_MEMQUOTA) 38 | { 39 | if (capinfo.mem_quota < Hax->mem_quota) 40 | { 41 | printf("The memory needed by this VM exceeds the driver limit.\n"); 42 | return false; 43 | } 44 | } 45 | 46 | return true; 47 | } 48 | 49 | bool HaxGetCapability(hax_state *Hax, hax_capabilityinfo *Caps) 50 | { 51 | if (hax_invalid_fd(Hax->fd)) 52 | { 53 | printf("Invalid handle for Hax device!\n"); 54 | return false; 55 | } 56 | 57 | DWORD bytesReturned; 58 | if (!DeviceIoControl(Hax->fd, HAX_IOCTL_CAPABILITY, nullptr, 0, Caps, sizeof(*Caps), &bytesReturned, nullptr)) 59 | { 60 | DWORD err = GetLastError(); 61 | 62 | if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_MORE_DATA) 63 | printf("Hax capability is too long to hold.\n"); 64 | 65 | printf("Failed to get Hax capability: %d\n", err); 66 | return false; 67 | } 68 | 69 | return true; 70 | } 71 | 72 | hax_vm *HaxVmCreate(hax_state *Hax) 73 | { 74 | // Handle validate 75 | if (hax_invalid_fd(Hax->fd)) 76 | return nullptr; 77 | 78 | // Skip this if a VM is already allocated 79 | if (Hax->vm) 80 | return Hax->vm; 81 | 82 | // Allocate memory for the virtual machine structure 83 | // and zero the memory 84 | auto vm = (hax_vm *)malloc(sizeof(hax_vm)); 85 | 86 | if (!vm) 87 | return nullptr; 88 | 89 | memset(vm, 0, sizeof(struct hax_vm)); 90 | 91 | // Ask the driver for a VM instance and ID 92 | int vmId = 0; 93 | 94 | if (hax_host_create_vm(Hax, &vmId) < 0) 95 | { 96 | printf("Failed to create vm\n"); 97 | 98 | free(vm); 99 | return nullptr; 100 | } 101 | 102 | vm->id = vmId; 103 | vm->fd = hax_host_open_vm(Hax, vmId); 104 | 105 | // Validate the VM's handle 106 | if (hax_invalid_fd(vm->fd)) 107 | { 108 | printf("Open vm device error\n"); 109 | 110 | free(vm); 111 | return nullptr; 112 | } 113 | 114 | // Notify the driver which version we are using 115 | hax_qemu_version qversion; 116 | qversion.cur_version = HaxCurrentVersion; 117 | qversion.least_version = HaxMinVersion; 118 | hax_notify_qemu_version(vm->fd, &qversion); 119 | 120 | Hax->vm = vm; 121 | return vm; 122 | } 123 | 124 | bool HaxVmDestroy(hax_vm *Vm) 125 | { 126 | if (!Vm) 127 | return false; 128 | 129 | // Enumerate all vCPUs linked to the VM 130 | // and check if they are deleted 131 | for (int i = 0; i < HAX_MAX_VCPU; i++) 132 | { 133 | if (Vm->vcpus[i]) 134 | { 135 | printf("vCPU should be cleaned before vm clean\n"); 136 | return false; 137 | } 138 | } 139 | 140 | // Tell the driver to kill the instance 141 | hax_close_fd(Vm->fd); 142 | 143 | // Free the struct 144 | free(Vm); 145 | return true; 146 | } -------------------------------------------------------------------------------- /ShellcodeVM/HaxVM.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hax-all.h" 4 | 5 | bool HaxIsSupported(hax_state *Hax); 6 | bool HaxIsAvailable(hax_state *Hax); 7 | bool HaxGetCapability(hax_state *Hax, hax_capabilityinfo *Caps); 8 | 9 | hax_vm *HaxVmCreate(hax_state *Hax); 10 | bool HaxVmDestroy(hax_vm *Vm); -------------------------------------------------------------------------------- /ShellcodeVM/HaxmTest.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "WinMiniDump.h" 3 | 4 | void TestDOS(hax_state *State, hax_vcpu_state *Cpu) 5 | { 6 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_CS_SELECTOR, 0); 7 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_CS_LIMIT, 0xffff); 8 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_CS_ACCESS_RIGHTS, 0x9b); 9 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_CS_BASE, 0); 10 | 11 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_DS_SELECTOR, 0); 12 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_DS_LIMIT, 0xffff); 13 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_DS_ACCESS_RIGHTS, 0x93); 14 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_DS_BASE, 0); 15 | 16 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_ES_SELECTOR, 0); 17 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_ES_LIMIT, 0xffff); 18 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_ES_ACCESS_RIGHTS, 0x93); 19 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_ES_BASE, 0); 20 | 21 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_FS_SELECTOR, 0); 22 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_FS_LIMIT, 0xffff); 23 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_FS_ACCESS_RIGHTS, 0x93); 24 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_FS_BASE, 0); 25 | 26 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_GS_SELECTOR, 0); 27 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_GS_LIMIT, 0xffff); 28 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_GS_ACCESS_RIGHTS, 0x93); 29 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_GS_BASE, 0); 30 | 31 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_SS_SELECTOR, 0); 32 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_SS_LIMIT, 0xffff); 33 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_SS_ACCESS_RIGHTS, 0x93); 34 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_SS_BASE, 0); 35 | 36 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_LDTR_SELECTOR, 0); 37 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_LDTR_LIMIT, 0); 38 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_LDTR_ACCESS_RIGHTS, 0x10000); 39 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_LDTR_BASE, 0); 40 | 41 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_TR_SELECTOR, 0); 42 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_TR_LIMIT, 0); 43 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_TR_ACCESS_RIGHTS, 0x83); 44 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_TR_BASE, 0); 45 | 46 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_GDTR_LIMIT, 0); 47 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_GDTR_BASE, 0); 48 | 49 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_IDTR_LIMIT, 0); 50 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_IDTR_BASE, 0); 51 | 52 | //VCpu_WriteVMCS(Cpu, VMCS_GUEST_CR0, 0x20 | 1); 53 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_CR3, 0x0); 54 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_CR4, 0x2000); 55 | 56 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_RSP, 0x100); 57 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_RIP, 0x0); 58 | VCpu_WriteVMCS(Cpu, VMCS_GUEST_RFLAGS, 0x200 | 0x2); 59 | 60 | LPVOID mem = VirtualAlloc(nullptr, 16384, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 61 | memset(mem, 0x90, 16384); 62 | //uint32 code_start = (uint32)boot_code_start; 63 | //uint32 code_end = (uint32)boot_code_end; 64 | //uint32 code_size = code_end - code_start; 65 | //memcpy(mem, boot_code_start, code_size); 66 | 67 | *(uint64*)((uint64)mem + 0x1000) = 0; //null 68 | *(uint64*)((uint64)mem + 0x1008) = 0x00cf9A000000ffff;//code32 69 | *(uint64*)((uint64)mem + 0x1010) = 0x00cf92000000ffff;//data32 70 | 71 | *(uint16*)((uint64)mem + 0x1020) = 3*8-1;//GDTR.limit 72 | *(uint32*)((uint64)mem + 0x1022) = 0x1000;//GDTR.base 73 | 74 | *(uint16*)((uint64)mem + 0x1030) = 0;//IDTR.limit 75 | *(uint32*)((uint64)mem + 0x1032) = 0;//IDTR.base 76 | 77 | hax_populate_ram(State->vm, (uint64)mem, 16384); 78 | hax_set_phys_mem(State, 0, 16384, (uint64)mem); 79 | 80 | VCpu_Run(Cpu); 81 | 82 | vcpu_state_t state; 83 | memset(&state, 0, sizeof(vcpu_state_t)); 84 | 85 | if (hax_sync_vcpu_state(Cpu, &state, 0) < 0) 86 | __debugbreak(); 87 | } 88 | 89 | void dump_vcpu_state(hax_vcpu_state *CPU); 90 | int main1(int argc, char *argv[]) 91 | { 92 | WinMiniDump MiniDump; 93 | MiniDump.Create("MiniDump.Dmp", NULL,0, 94 | (MINIDUMP_TYPE)( 95 | //(UINT32)MiniDumpWithDataSegs 96 | //| (UINT32)MiniDumpWithCodeSegs 97 | //| 98 | //(UINT32)MiniDumpWithFullMemory 99 | //| (UINT32)MiniDumpWithFullMemoryInfo 100 | (UINT32)MiniDumpWithFullMemory | 101 | (UINT32)MiniDumpWithFullMemoryInfo | 102 | (UINT32)MiniDumpWithHandleData | 103 | (UINT32)MiniDumpWithThreadInfo | 104 | (UINT32)MiniDumpWithUnloadedModules 105 | ) 106 | ); 107 | MiniDump.Open("MiniDump.Dmp"); 108 | MiniDump.DumpHeader(); 109 | MiniDump.DumpDirectory(); 110 | 111 | // Is everything loaded and compatible? 112 | if (!VM_HaxEnabled()) 113 | return 1; 114 | 115 | // Create the VM instance with 16kb RAM 116 | auto state = VM_CreateInstance(16384); 117 | 118 | if (!state) 119 | return 1; 120 | 121 | // Set up the virtual processor 122 | auto cpu = VCpu_Create(state); 123 | 124 | if (!cpu) 125 | return 1; 126 | 127 | VCpu_Init(cpu); 128 | dump_vcpu_state(cpu); 129 | TestDOS(state, cpu); 130 | 131 | getchar(); 132 | VCpu_Destroy(state, cpu); 133 | VM_DestroyInstance(state); 134 | 135 | return 0; 136 | } -------------------------------------------------------------------------------- /ShellcodeVM/HaxmTest.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {008C18FA-6BEC-4D53-B7EC-7E30826CB389} 23 | Win32Proj 24 | HaxmTest 25 | 26 | 27 | 28 | Application 29 | true 30 | v120 31 | MultiByte 32 | 33 | 34 | Application 35 | true 36 | v120 37 | MultiByte 38 | 39 | 40 | Application 41 | false 42 | v120 43 | true 44 | MultiByte 45 | 46 | 47 | Application 48 | false 49 | v120 50 | true 51 | MultiByte 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | 72 | 73 | true 74 | 75 | 76 | false 77 | 78 | 79 | false 80 | 81 | 82 | 83 | 84 | 85 | Level3 86 | Disabled 87 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 88 | 89 | 90 | Console 91 | true 92 | 93 | 94 | 95 | 96 | 97 | 98 | Level3 99 | Disabled 100 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 101 | 102 | 103 | Console 104 | true 105 | 106 | 107 | 108 | 109 | Level3 110 | 111 | 112 | MaxSpeed 113 | true 114 | true 115 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 116 | 117 | 118 | Console 119 | true 120 | true 121 | true 122 | 123 | 124 | 125 | 126 | Level3 127 | 128 | 129 | MaxSpeed 130 | true 131 | true 132 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 133 | 134 | 135 | Console 136 | true 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /ShellcodeVM/HaxmTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {caf558be-0c80-459a-8c32-f2af65216e12} 14 | 15 | 16 | 17 | 18 | Header Files 19 | 20 | 21 | Header Files 22 | 23 | 24 | hax 25 | 26 | 27 | hax 28 | 29 | 30 | hax 31 | 32 | 33 | hax 34 | 35 | 36 | hax 37 | 38 | 39 | Header Files 40 | 41 | 42 | hax 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | 55 | 56 | Source Files 57 | 58 | 59 | Source Files 60 | 61 | 62 | Source Files 63 | 64 | 65 | Source Files 66 | 67 | 68 | Source Files 69 | 70 | 71 | Source Files 72 | 73 | 74 | Source Files 75 | 76 | 77 | hax 78 | 79 | 80 | -------------------------------------------------------------------------------- /ShellcodeVM/ShellcodeVM.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {C27C6721-3007-443E-B095-51024C1B8236} 23 | ShellcodeVM 24 | 8.1 25 | 26 | 27 | 28 | Application 29 | true 30 | v140 31 | MultiByte 32 | 33 | 34 | Application 35 | false 36 | v140 37 | true 38 | MultiByte 39 | 40 | 41 | Application 42 | true 43 | v140 44 | MultiByte 45 | 46 | 47 | Application 48 | false 49 | v140 50 | true 51 | MultiByte 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Level3 75 | Disabled 76 | true 77 | _CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) 78 | 4005;4477 79 | vm;../GuestOS; 80 | 81 | 82 | true 83 | 84 | 85 | %(Inputs) 86 | 87 | 88 | 89 | 90 | Level3 91 | Disabled 92 | true 93 | _CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) 94 | 4005 95 | 96 | 97 | true 98 | 99 | 100 | 101 | 102 | Level3 103 | MaxSpeed 104 | true 105 | true 106 | true 107 | _CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) 108 | 4005 109 | vm;../GuestOS; 110 | 111 | 112 | true 113 | true 114 | true 115 | 116 | 117 | 118 | 119 | Level3 120 | MaxSpeed 121 | true 122 | true 123 | true 124 | _CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) 125 | 4005 126 | vm; 127 | 128 | 129 | true 130 | true 131 | true 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /ShellcodeVM/ShellcodeVM.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 头文件 26 | 27 | 28 | 头文件 29 | 30 | 31 | 头文件 32 | 33 | 34 | 头文件 35 | 36 | 37 | 头文件 38 | 39 | 40 | 头文件 41 | 42 | 43 | 头文件 44 | 45 | 46 | 头文件 47 | 48 | 49 | 头文件 50 | 51 | 52 | 头文件 53 | 54 | 55 | 头文件 56 | 57 | 58 | 头文件 59 | 60 | 61 | 头文件 62 | 63 | 64 | 65 | 66 | 源文件 67 | 68 | 69 | 源文件 70 | 71 | 72 | 源文件 73 | 74 | 75 | 源文件 76 | 77 | 78 | 源文件 79 | 80 | 81 | 源文件 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /ShellcodeVM/VM.cpp: -------------------------------------------------------------------------------- 1 | #include "VM.h" 2 | #include "HaxVM.h" 3 | 4 | bool VM_HaxEnabled() 5 | { 6 | // This function only creates a temporary state for the driver handle 7 | hax_state hax; 8 | memset(&hax, 0, sizeof(hax_state)); 9 | 10 | hax.fd = hax_mod_open(); 11 | 12 | // Is the returned handle valid? 13 | if (hax_invalid_fd(hax.fd)) 14 | return false; 15 | 16 | // Determine the capabilities from the driver 17 | if (!HaxIsAvailable(&hax)) 18 | { 19 | hax_mod_close(&hax); 20 | return false; 21 | } 22 | 23 | // Check if the version is supported 24 | if (!HaxIsSupported(&hax)) 25 | { 26 | printf("Incompatible HAX version\n"); 27 | hax_mod_close(&hax); 28 | return false; 29 | } 30 | 31 | hax_mod_close(&hax); 32 | return true; 33 | } 34 | 35 | hax_state *VM_CreateInstance(UINT RAMSize) 36 | { 37 | // Allocate a state structure and zero it 38 | auto instance = (hax_state *)malloc(sizeof(hax_state)); 39 | 40 | if (!instance) 41 | return nullptr; 42 | 43 | memset(instance, 0, sizeof(hax_state)); 44 | 45 | // Set device handle and RAM size 46 | instance->fd = hax_mod_open(); 47 | instance->mem_quota = RAMSize; 48 | 49 | // Link a VM handle to the state 50 | if (!HaxVmCreate(instance)) 51 | { 52 | free(instance); 53 | return nullptr; 54 | } 55 | 56 | return instance; 57 | } 58 | 59 | bool VM_DestroyInstance(hax_state *Hax) 60 | { 61 | if (HaxVmDestroy(Hax->vm)) 62 | { 63 | // Free state 64 | free(Hax); 65 | return true; 66 | } 67 | 68 | return false; 69 | } 70 | 71 | bool VM_SetRAMSize(hax_state *Hax, UINT Size) 72 | { 73 | uint64_t oldQuota = Hax->mem_quota; 74 | Hax->mem_quota = Size; 75 | 76 | // Check if the memory size is allowed 77 | if (HaxIsAvailable(Hax)) 78 | return true; 79 | 80 | // Otherwise reset and return false 81 | Hax->mem_quota = oldQuota; 82 | return false; 83 | } -------------------------------------------------------------------------------- /ShellcodeVM/VM.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hax-all.h" 4 | 5 | bool VM_HaxEnabled(); 6 | hax_state *VM_CreateInstance(UINT RAMSize); 7 | bool VM_DestroyInstance(hax_state *Hax); 8 | bool VM_SetRAMSize(hax_state *Hax, UINT Size); -------------------------------------------------------------------------------- /ShellcodeVM/VM/page_frame.cpp: -------------------------------------------------------------------------------- 1 | #include "page_frame.h" 2 | #include "paging.h" 3 | #include 4 | 5 | page_frame_database::page_frame_database() 6 | { 7 | m_mem_size = 0; 8 | m_page_frame_min = 0; 9 | m_page_frame_max = 0; 10 | m_next_free_page_frame = 0; 11 | m_page_frame_map = NULL; 12 | } 13 | 14 | page_frame_database::~page_frame_database() 15 | { 16 | if (m_page_frame_map != NULL) 17 | { 18 | delete m_page_frame_map; 19 | m_page_frame_map = NULL; 20 | } 21 | } 22 | 23 | bool page_frame_database::Init(pager* pager, uint64_t mem_size) 24 | { 25 | m_pager = pager; 26 | m_mem_size = mem_size; 27 | m_page_frame_min = SIZE_TO_PAGES(MB(4)); 28 | m_page_frame_max = SIZE_TO_PAGES(mem_size); 29 | m_next_free_page_frame = 0; 30 | m_page_frame_map = new uint8_t(m_page_frame_max); 31 | memset(m_page_frame_map, 0, m_page_frame_max); 32 | uint64_t m_page_dir = pager->new_page_dir(); 33 | return true; 34 | } 35 | 36 | uint64_t page_frame_database::alloc_physical_page() 37 | { 38 | for (int i = m_next_free_page_frame; i < m_page_frame_max; i++) 39 | { 40 | if (m_page_frame_map[i] == PAGE_FRAME_FREE) 41 | { 42 | m_next_free_page_frame = i + 1; 43 | return i*PAGE_SIZE; 44 | } 45 | } 46 | return 0; 47 | } 48 | 49 | uint64_t page_frame_database::alloc_physical_pages(uint64_t pages) 50 | { 51 | for (int i = m_next_free_page_frame; i < m_page_frame_max - pages; i++) 52 | { 53 | if (m_page_frame_map[i] == PAGE_FRAME_FREE) 54 | { 55 | int j = i; 56 | for (j++; j < i + pages && j < m_page_frame_max; j++) 57 | { 58 | if (m_page_frame_map[j] != PAGE_FRAME_FREE) break; 59 | } 60 | if (j = i + pages) 61 | { 62 | m_next_free_page_frame = j; 63 | return i*PAGE_SIZE; 64 | } 65 | } 66 | } 67 | return 0; 68 | } 69 | 70 | void page_frame_database::free_physical_page(uint64_t page) 71 | { 72 | m_page_frame_map[page] = PAGE_FRAME_FREE; 73 | if (page < m_next_free_page_frame) 74 | { 75 | m_next_free_page_frame = page; 76 | } 77 | } 78 | 79 | void page_frame_database::free_physical_pages(uint64_t start_page, uint64_t pages) 80 | { 81 | for (uint64_t i = start_page; i < start_page + pages; i++) 82 | { 83 | m_page_frame_map[i] = PAGE_FRAME_FREE; 84 | } 85 | if (m_next_free_page_frame > start_page) 86 | { 87 | m_next_free_page_frame = start_page; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /ShellcodeVM/VM/page_frame.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define PAGE_FRAME_FREE 0 5 | #define PAGE_FRAME_USED 1 6 | 7 | class pager; 8 | class page_frame_database 9 | { 10 | private: 11 | pager* m_pager; 12 | uint64_t m_mem_size; 13 | uint64_t m_page_frame_min; 14 | uint64_t m_page_frame_max; 15 | uint64_t m_next_free_page_frame; 16 | uint8_t* m_page_frame_map; 17 | public: 18 | page_frame_database(); 19 | ~page_frame_database(); 20 | bool Init(pager* pager, uint64_t mem_size); 21 | uint64_t alloc_physical_page(); 22 | uint64_t alloc_physical_pages(uint64_t pages); 23 | void free_physical_page(uint64_t page); 24 | void free_physical_pages(uint64_t start_page, uint64_t pages); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /ShellcodeVM/VM/paging.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/ShellcodeVM/VM/paging.cpp -------------------------------------------------------------------------------- /ShellcodeVM/VM/paging.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define PAGE_SIZE 0x1000 5 | #define PAGE_SIZE_BITS 12 6 | #define PD_INDEX(virtual_addr) ((virtual_addr>>22)) 7 | #define PT_INDEX(virtual_addr) ((virtual_addr>>12)&0x3FF) 8 | 9 | #define KERNEL_BASE 0x80000000 10 | #define PAGE_DIR_BASE m_page_dir //host va 11 | #define PAGE_TABLE_BASE m_page_table_base //host va 12 | 13 | #define GET_PDE(addr) ((uint32_t*)PAGE_DIR_BASE)[(uint32_t)(addr)>>22] 14 | #define GET_PTE(addr) ((uint32_t*)PAGE_TABLE_BASE)[(uint32_t)(addr)>>12] 15 | #define GET_PAGE_TABLE(addr) (PAGE_TABLE_BASE + ((uint32_t)(addr)>>22)* PAGE_SIZE) 16 | 17 | #define SET_PDE(addr, val) ((uint32_t*)PAGE_DIR_BASE)[(uint32_t)(addr)>>22] = val; 18 | #define SET_PTE(addr, val) ((uint32_t*)PAGE_TABLE_BASE)[(uint32_t)(addr)>>12]=val; 19 | 20 | #define PAGE_ALGINED(addr) ((((uint32_t)addr) & 0x00000FFF) ==0) 21 | #define CHECK_PAGE_ALGINED(addr) if ((((uint32_t)addr) & 0x00000FFF) !=0) panic("CHECK_PAGE_ALGINED(%08X)",addr); 22 | 23 | #define PT_PRESENT 0x001 24 | 25 | #define PT_WRITABLE 0x002 26 | #define PT_READONLY 0x000 27 | 28 | #define PT_USER 0x004 29 | #define PT_KERNEL 0x000 30 | 31 | #define PT_ACCESSED 0x020 32 | #define PT_DIRTY 0x040 33 | 34 | #define KB(x) ((uint64_t)x<<10) 35 | #define MB(x) ((uint64_t)x<<20) 36 | #define GB(x) ((uint64_t)x<<30) 37 | 38 | #define USER_SPACE(addr) (((uint32_t)addr) < KERNEL_BASE) 39 | #define KERNEL_SPACE(addr) (((uint32_t)addr) >= KERNEL_BASE) 40 | 41 | #define PAGES_TO_SIZE(pages) ((uint64_t)(pages)<<12) 42 | #define SIZE_TO_PAGES(size) (((uint64_t)(size) + PAGE_SIZE -1)>>12) 43 | #define GPA_TO_HVA(gpa) (m_host_mem + gpa) 44 | 45 | #define CHECK_PAGE_ALGINED(addr) if ((((uint64_t)addr) & 0x00000FFF) !=0) printf("CHECK_PAGE_ALGINED(%08X)",addr); 46 | 47 | class page_frame_database; 48 | class pager 49 | { 50 | private: 51 | uint64_t m_page_dir; 52 | uint64_t m_host_mem; 53 | uint64_t m_page_table_base; 54 | page_frame_database* m_page_frame_db; 55 | public: 56 | pager(); 57 | ~pager(); 58 | public: 59 | bool Init(page_frame_database* page_frame_db, uint64_t host_mem, uint64_t page_table_base); 60 | uint64_t new_page_dir(); 61 | uint64_t new_page_table(uint64_t virtual_address); 62 | uint64_t map_pages(uint64_t physical_address, uint64_t virtual_address, uint64_t size, uint64_t protect = (PT_PRESENT | PT_WRITABLE)); 63 | void unmap_pages(uint64_t virtual_address, uint64_t size); 64 | }; 65 | 66 | -------------------------------------------------------------------------------- /ShellcodeVM/VirtualCPU.cpp: -------------------------------------------------------------------------------- 1 | #include "VirtualCPU.h" 2 | #include "VirtualContext.h" 3 | #include "VMCS.h" 4 | 5 | #define HAX_EMULATE_STATE_MMIO 0x1 6 | #define HAX_EMULATE_STATE_REAL 0x2 7 | #define HAX_EMULATE_STATE_NONE 0x3 8 | #define HAX_EMULATE_STATE_INITIAL 0x4 9 | 10 | #define SET_SEGMENT_ACCESS(seg, value) \ 11 | (seg).available = ((value) >> 12) & 1; \ 12 | (seg).present = ((value) >> 7) & 1; \ 13 | (seg).dpl = ((value) >> 5) & ~(~0 << (6-5+1)); \ 14 | (seg).desc = ((value) >> 4) & 1; \ 15 | (seg).type = ((value) >> 0) & ~(~0 << (3-0+1)); 16 | 17 | hax_vcpu_state *VCpu_Create(hax_state *Hax) 18 | { 19 | if (!Hax->vm) 20 | { 21 | printf("vCPU created failed, vm is null\n"); 22 | return nullptr; 23 | } 24 | 25 | // Find the next free vCPU index 26 | int cpuId = -1; 27 | 28 | for (int i = 0; i < ARRAYSIZE(Hax->vm->vcpus); i++) 29 | { 30 | if (Hax->vm->vcpus[i]) 31 | continue; 32 | 33 | cpuId = i; 34 | break; 35 | } 36 | 37 | if (cpuId == -1) 38 | { 39 | printf("Maximum number of vCPUs have been allocated for this VM!\n"); 40 | return nullptr; 41 | } 42 | 43 | // Allocate the virtual CPU instance structure and 44 | // zero memory 45 | auto vCPU = (hax_vcpu_state *)malloc(sizeof(hax_vcpu_state)); 46 | 47 | if (!vCPU) 48 | { 49 | printf("Failed to alloc vCPU state\n"); 50 | return nullptr; 51 | } 52 | 53 | memset(vCPU, 0, sizeof(hax_vcpu_state)); 54 | 55 | // Tell the driver to create the vCPU instance 56 | vCPU->vcpu_id = cpuId; 57 | 58 | if (hax_host_create_vcpu(Hax->vm->fd, cpuId) < 0) 59 | { 60 | printf("Failed to create vCPU %x\n", cpuId); 61 | goto error; 62 | } 63 | 64 | // Grab a handle to the driver's instance 65 | vCPU->fd = hax_host_open_vcpu(Hax->vm->id, cpuId); 66 | 67 | if (hax_invalid_fd(vCPU->fd)) 68 | { 69 | printf("Failed to open the vCPU handle\n"); 70 | goto error; 71 | } 72 | 73 | // Mark the CPU index as used with a pointer 74 | Hax->vm->vcpus[cpuId] = vCPU; 75 | 76 | // Create the tunnel to kernel data 77 | if (hax_host_setup_vcpu_channel(vCPU) < 0) 78 | { 79 | printf("Invalid HAX tunnel size \n"); 80 | goto error; 81 | } 82 | 83 | return vCPU; 84 | 85 | error: 86 | // vCPU and tunnel will be closed automatically 87 | if (vCPU && !hax_invalid_fd(vCPU->fd)) 88 | hax_close_fd(vCPU->fd); 89 | 90 | Hax->vm->vcpus[cpuId] = nullptr; 91 | free(vCPU); 92 | return nullptr; 93 | } 94 | 95 | bool VCpu_Destroy(hax_state *Hax, hax_vcpu_state *CPU) 96 | { 97 | if (!Hax->vm) 98 | { 99 | printf("vCPU %x destroy failed, vm is null\n", CPU->vcpu_id); 100 | return false; 101 | } 102 | 103 | // Get a direct pointer to the index 104 | auto vCPU = Hax->vm->vcpus[CPU->vcpu_id]; 105 | 106 | // Check if valid 107 | if (!vCPU) 108 | return false; 109 | 110 | // 1. The hax_tunnel is also destroyed at vcpu_destroy 111 | // 2. hax_close_fd will require the HAX kernel module to free vCPU 112 | Hax->vm->vcpus[CPU->vcpu_id] = nullptr; 113 | 114 | hax_close_fd(vCPU->fd); 115 | free(vCPU); 116 | return true; 117 | } 118 | 119 | void VCpu_Init(hax_vcpu_state *CPU) 120 | { 121 | VCpu_ResetState(CPU); 122 | } 123 | 124 | void VCpu_ResetState(hax_vcpu_state *CPU) 125 | { 126 | CPU->emulation_state = HAX_EMULATE_STATE_INITIAL; 127 | CPU->tunnel->user_event_pending = 0; 128 | CPU->tunnel->ready_for_interrupt_injection = 0; 129 | } 130 | 131 | 132 | void VCpu_WriteVMCS(hax_vcpu_state *CPU, UINT Field, UINT64 Value) 133 | { 134 | // Query the CPU state 135 | vcpu_state_t state; 136 | 137 | if (hax_sync_vcpu_state(CPU, &state, 0) < 0) 138 | __debugbreak(); 139 | 140 | // Set the required field 141 | switch (Field) 142 | { 143 | case VMCS_GUEST_ES_SELECTOR: state._es.selector = (uint16_t)Value; break; 144 | case VMCS_GUEST_ES_LIMIT: state._es.limit = (uint32)Value; break; 145 | case VMCS_GUEST_ES_ACCESS_RIGHTS: SET_SEGMENT_ACCESS(state._es, Value) break; 146 | case VMCS_GUEST_ES_BASE: state._es.base = (uint64)Value; break; 147 | 148 | case VMCS_GUEST_CS_SELECTOR: state._cs.selector = (uint16_t)Value; break; 149 | case VMCS_GUEST_CS_LIMIT: state._cs.limit = (uint32)Value; break; 150 | case VMCS_GUEST_CS_ACCESS_RIGHTS: SET_SEGMENT_ACCESS(state._cs, Value) break; 151 | case VMCS_GUEST_CS_BASE: state._cs.base = (uint64)Value; break; 152 | 153 | case VMCS_GUEST_SS_SELECTOR: state._ss.selector = (uint16_t)Value; break; 154 | case VMCS_GUEST_SS_LIMIT: state._ss.limit = (uint32)Value; break; 155 | case VMCS_GUEST_SS_ACCESS_RIGHTS: SET_SEGMENT_ACCESS(state._ss, Value) break; 156 | case VMCS_GUEST_SS_BASE: state._ss.base = (uint64)Value; break; 157 | 158 | case VMCS_GUEST_DS_SELECTOR: state._ds.selector = (uint16_t)Value; break; 159 | case VMCS_GUEST_DS_LIMIT: state._ds.limit = (uint32)Value; break; 160 | case VMCS_GUEST_DS_ACCESS_RIGHTS: SET_SEGMENT_ACCESS(state._ds, Value) break; 161 | case VMCS_GUEST_DS_BASE: state._ds.base = (uint64)Value; break; 162 | 163 | case VMCS_GUEST_FS_SELECTOR: state._fs.selector = (uint16_t)Value; break; 164 | case VMCS_GUEST_FS_LIMIT: state._fs.limit = (uint32)Value; break; 165 | case VMCS_GUEST_FS_ACCESS_RIGHTS: SET_SEGMENT_ACCESS(state._fs, Value) break; 166 | case VMCS_GUEST_FS_BASE: state._fs.base = (uint64)Value; break; 167 | 168 | case VMCS_GUEST_GS_SELECTOR: state._gs.selector = (uint16_t)Value; break; 169 | case VMCS_GUEST_GS_LIMIT: state._gs.limit = (uint32)Value; break; 170 | case VMCS_GUEST_GS_ACCESS_RIGHTS: SET_SEGMENT_ACCESS(state._gs, Value) break; 171 | case VMCS_GUEST_GS_BASE: state._gs.base = (uint64)Value; break; 172 | 173 | case VMCS_GUEST_LDTR_SELECTOR: state._ldt.selector = (uint16_t)Value; break; 174 | case VMCS_GUEST_LDTR_LIMIT: state._ldt.limit = (uint32)Value; break; 175 | case VMCS_GUEST_LDTR_ACCESS_RIGHTS: SET_SEGMENT_ACCESS(state._ldt, Value) break; 176 | case VMCS_GUEST_LDTR_BASE: state._ldt.base = (uint64)Value; break; 177 | 178 | case VMCS_GUEST_TR_SELECTOR: state._tr.selector = (uint16_t)Value; break; 179 | case VMCS_GUEST_TR_LIMIT: state._tr.limit = (uint32)Value; break; 180 | case VMCS_GUEST_TR_ACCESS_RIGHTS: SET_SEGMENT_ACCESS(state._tr, Value) break; 181 | case VMCS_GUEST_TR_BASE: state._tr.base = (uint64)Value; break; 182 | 183 | case VMCS_GUEST_GDTR_LIMIT: state._gdt.limit = (uint32)Value; break; 184 | case VMCS_GUEST_GDTR_BASE: state._gdt.base = (uint64)Value; break; 185 | 186 | case VMCS_GUEST_IDTR_LIMIT: state._idt.limit = (uint32)Value; break; 187 | case VMCS_GUEST_IDTR_BASE: state._idt.base = (uint64)Value; break; 188 | 189 | case VMCS_GUEST_CR0: state._cr0 = (uint64)Value; break; 190 | case VMCS_GUEST_CR3: state._cr3 = (uint64)Value; break; 191 | case VMCS_GUEST_CR4: state._cr4 = (uint64)Value; break; 192 | 193 | case VMCS_GUEST_DR7: state._dr7 = (uint64)Value; break; 194 | case VMCS_GUEST_RSP: state._rsp = (uint64)Value; break; 195 | case VMCS_GUEST_RIP: state._rip = (uint64)Value; break; 196 | case VMCS_GUEST_RFLAGS: state._rflags = (uint64)Value; break; 197 | 198 | case VMCS_GUEST_IA32_SYSENTER_CS: state._sysenter_cs = (uint32)Value; break; 199 | case VMCS_GUEST_IA32_SYSENTER_ESP: state._sysenter_esp = (uint64)Value; break; 200 | case VMCS_GUEST_IA32_SYSENTER_EIP: state._sysenter_eip = (uint64)Value; break; 201 | 202 | default: 203 | __debugbreak(); 204 | } 205 | 206 | // Set the new CPU state 207 | if (hax_sync_vcpu_state(CPU, &state, 1) < 0) 208 | __debugbreak(); 209 | } 210 | 211 | bool VCpu_Run(hax_vcpu_state *CPU) 212 | { 213 | return VCpu_Exec(CPU); 214 | } -------------------------------------------------------------------------------- /ShellcodeVM/VirtualCPU.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hax-all.h" 4 | 5 | hax_vcpu_state *VCpu_Create(hax_state *Hax); 6 | bool VCpu_Destroy(hax_state *Hax, hax_vcpu_state *CPU); 7 | void VCpu_Init(hax_vcpu_state *CPU); 8 | void VCpu_ResetState(hax_vcpu_state *CPU); 9 | void VCpu_WriteVMCS(hax_vcpu_state *CPU, UINT Field, UINT64 Value); 10 | bool VCpu_Run(hax_vcpu_state *CPU); 11 | -------------------------------------------------------------------------------- /ShellcodeVM/VirtualContext.cpp: -------------------------------------------------------------------------------- 1 | #include "VirtualContext.h" 2 | 3 | #define HAX_EMUL_ONE 0x1 4 | #define HAX_EMUL_REAL 0x2 5 | #define HAX_EMUL_HLT 0x4 6 | #define HAX_EMUL_EXITLOOP 0x5 7 | 8 | void dump_vcpu_state(hax_vcpu_state *CPU) 9 | { 10 | vcpu_state_t state, *cpu=&state; 11 | 12 | memset(&state, 0, sizeof(vcpu_state_t)); 13 | if (hax_sync_vcpu_state(CPU, &state, 0) < 0) 14 | __debugbreak(); 15 | 16 | printf("eax=%08X ebx=%08X ecx=%08X edx=%08X\n", cpu->_eax, cpu->_ebx, cpu->_ecx, cpu->_edx); 17 | printf("esp=%08X ebp=%08X esi=%08X edi=%08X\n", cpu->_esp, cpu->_ebp, cpu->_esi, cpu->_edi); 18 | printf("eip=%08X elfags=%08X\n", cpu->_eip, cpu->_eflags); 19 | printf("cr0=%08X cr2=%08X cr3=%08X cr4=%08X\n", cpu->_cr0, cpu->_cr2, cpu->_cr3, cpu->_cr4); 20 | printf("dr0=%08X dr1=%08X dr2=%08X dr3=%08X\n", cpu->_dr0, cpu->_dr1, cpu->_dr2, cpu->_dr3); 21 | printf("dr6=%08X dr7=%08X\n", cpu->_dr6, cpu->_dr7); 22 | printf("\n"); 23 | } 24 | 25 | /* 26 | * Request the HAX kernel module to run the CPU for us until one of 27 | * the following occurs: 28 | * 1. Guest crashes or is shut down 29 | * 2. We need QEMU's emulation like when the guest executes a MMIO 30 | * instruction or guest enters emulation mode (non-PG mode) 31 | * 3. Guest executes HLT 32 | * 4. Qemu has Signal/event pending 33 | * 5. An unknown VMX-exit happens 34 | */ 35 | int hax_vcpu_interrupt(hax_vcpu_state *CPU); 36 | int VCpu_Exec(hax_vcpu_state *CPU) 37 | { 38 | int ret = 0; 39 | hax_tunnel *ht = CPU->tunnel; 40 | dump_vcpu_state(CPU); 41 | do 42 | { 43 | hax_vcpu_interrupt(CPU); 44 | 45 | int haxResult = hax_vcpu_run(CPU); 46 | 47 | dump_vcpu_state(CPU); 48 | 49 | // Simply continue the vcpu_run if system call interrupted 50 | if (haxResult == -EINTR || haxResult == -EAGAIN) 51 | { 52 | printf("IO window interrupted\n"); 53 | continue; 54 | } 55 | 56 | // Fail if system call failed 57 | if (haxResult < 0) 58 | { 59 | printf("vCPU run failed for vCPU %x\n", CPU->vcpu_id); 60 | abort(); 61 | } 62 | 63 | switch (ht->_exit_status) 64 | { 65 | // Regular I/O 66 | case HAX_EXIT_IO: 67 | /* 68 | { 69 | ret = hax_handle_io(env, ht->pio._df, ht->pio._port, 70 | ht->pio._direction, 71 | ht->pio._size, ht->pio._count, vcpu->iobuf); 72 | } 73 | */ 74 | break; 75 | 76 | // Memory-mapped I/O 77 | case HAX_EXIT_MMIO: 78 | ret = HAX_EMUL_ONE; 79 | break; 80 | 81 | // Fast memory-mapped I/O 82 | case HAX_EXIT_FAST_MMIO: 83 | //ret = hax_handle_fastmmio(env, (hax_fastmmio *)vcpu->iobuf); 84 | break; 85 | 86 | // Guest running in real mode 87 | case HAX_EXIT_REAL: 88 | ret = HAX_EMUL_REAL; 89 | break; 90 | 91 | // Guest state changed, currently only for shutdown 92 | case HAX_EXIT_STATECHANGE: 93 | printf("VCPU shutdown request\n"); 94 | ret = HAX_EMUL_EXITLOOP; 95 | break; 96 | 97 | case HAX_EXIT_UNKNOWN_VMEXIT: 98 | dprint("Unknown VMX exit %x from guest\n", ht->_exit_reason); 99 | //qemu_system_reset_request(); 100 | //hax_prepare_emulation(env); 101 | //cpu_dump_state(env, stderr, fprintf, 0); 102 | ret = HAX_EMUL_EXITLOOP; 103 | break; 104 | 105 | // HLT instruction executed 106 | case HAX_EXIT_HLT: 107 | /* 108 | if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && 109 | !(env->interrupt_request & CPU_INTERRUPT_NMI)) { 110 | // hlt instruction with interrupt disabled is shutdown 111 | env->eflags |= IF_MASK; 112 | env->halted = 1; 113 | env->exception_index = EXCP_HLT; 114 | ret = HAX_EMUL_HLT; 115 | } 116 | */ 117 | break; 118 | 119 | // these situations will continue to the Hax module 120 | case HAX_EXIT_INTERRUPT: 121 | case HAX_EXIT_PAUSED: 122 | break; 123 | 124 | default: 125 | printf("Unknown exit %x from Hax driver\n", ht->_exit_status); 126 | ret = HAX_EMUL_EXITLOOP; 127 | break; 128 | } 129 | }while (!ret); 130 | 131 | return ret; 132 | } 133 | 134 | #define HAX_RAM_INFO_ROM 0x1 135 | 136 | /* 137 | static void set_v8086_seg(struct segment_desc_t *lhs, const SegmentCache *rhs) 138 | { 139 | memset(lhs, 0, sizeof(struct segment_desc_t )); 140 | lhs->selector = rhs->selector; 141 | lhs->base = rhs->base; 142 | lhs->limit = rhs->limit; 143 | lhs->type = 3; 144 | lhs->present = 1; 145 | lhs->dpl = 3; 146 | lhs->operand_size = 0; 147 | lhs->desc = 1; 148 | lhs->long_mode = 0; 149 | lhs->granularity = 0; 150 | lhs->available = 0; 151 | } 152 | */ 153 | 154 | void hax_msr_entry_set(struct vmx_msr *item, uint32_t index, uint64_t value) 155 | { 156 | item->entry = index; 157 | item->value = value; 158 | } 159 | 160 | bool hax_get_fpu(hax_vcpu_state *CPU, fx_layout *FPU) 161 | { 162 | return hax_sync_fpu(CPU, FPU, 0) >= 0; 163 | } 164 | 165 | bool hax_set_fpu(hax_vcpu_state *CPU, fx_layout *FPU) 166 | { 167 | return hax_sync_fpu(CPU, FPU, 1) >= 0; 168 | } -------------------------------------------------------------------------------- /ShellcodeVM/VirtualContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hax-all.h" 4 | 5 | int VCpu_Exec(hax_vcpu_state *CPU); -------------------------------------------------------------------------------- /ShellcodeVM/VirtualIO.cpp: -------------------------------------------------------------------------------- 1 | #include "hax-all.h" 2 | 3 | int hax_handle_fastmmio(hax_vcpu_state *env, struct hax_fastmmio *hft) 4 | { 5 | uint64_t buf = 0; 6 | 7 | /* 8 | * With fast MMIO, QEMU need not sync vCPU state with HAXM 9 | * driver because it will only invoke MMIO handler 10 | * However, some MMIO operations utilize virtual address like qemu_pipe 11 | * Thus we need to sync the CR0, CR3 and CR4 so that QEMU 12 | * can translate the guest virtual address to guest physical 13 | * address 14 | */ 15 | buf = hft->value; 16 | //cpu_physical_memory_rw(hft->gpa, &buf, hft->size, hft->direction); 17 | if (hft->direction == 0) 18 | hft->value = buf; 19 | 20 | return 0; 21 | } 22 | 23 | int hax_handle_io(hax_vcpu_state *env, uint32_t df, uint16_t port, int direction, 24 | int size, int count, void *buffer) 25 | { 26 | /* 27 | uint8_t *ptr; 28 | int i; 29 | 30 | if (!df) 31 | ptr = (uint8_t *)buffer; 32 | else 33 | ptr = buffer + size * count - size; 34 | for (i = 0; i < count; i++) 35 | { 36 | if (direction == HAX_EXIT_IO_IN) { 37 | switch (size) { 38 | case 1: 39 | stb_p(ptr, cpu_inb(port)); 40 | break; 41 | case 2: 42 | stw_p(ptr, cpu_inw(port)); 43 | break; 44 | case 4: 45 | stl_p(ptr, cpu_inl(port)); 46 | break; 47 | } 48 | } else { 49 | switch (size) { 50 | case 1: 51 | cpu_outb(port, ldub_p(ptr)); 52 | break; 53 | case 2: 54 | cpu_outw(port, lduw_p(ptr)); 55 | break; 56 | case 4: 57 | cpu_outl(port, ldl_p(ptr)); 58 | break; 59 | } 60 | } 61 | if (!df) 62 | ptr += size; 63 | else 64 | ptr -= size; 65 | } 66 | */ 67 | return 0; 68 | } 69 | 70 | int hax_vcpu_interrupt(hax_vcpu_state *CPU) 71 | { 72 | #if 0 73 | struct hax_tunnel *ht = CPU->tunnel; 74 | 75 | /* 76 | * Try to inject an interrupt if the guest can accept it 77 | * Unlike KVM, the HAX kernel module checks the eflags, instead. 78 | */ 79 | if (ht->ready_for_interrupt_injection && 80 | (env->interrupt_request & CPU_INTERRUPT_HARD)) 81 | { 82 | int irq; 83 | 84 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; 85 | irq = -1;//cpu_get_pic_interrupt(env); 86 | if (irq >= 0) { 87 | hax_inject_interrupt(env, irq); 88 | } 89 | } 90 | 91 | /* 92 | * If we have an interrupt pending but the guest is not ready to 93 | * receive it, request an interrupt window exit. This will cause 94 | * a return to userspace as soon as the guest is ready to receive 95 | * an interrupt. 96 | */ 97 | if ((env->interrupt_request & CPU_INTERRUPT_HARD)) 98 | ht->request_interrupt_window = 1; 99 | else 100 | ht->request_interrupt_window = 0; 101 | #endif 102 | return 0; 103 | } 104 | 105 | void hax_raise_event(hax_vcpu_state *CPU) 106 | { 107 | CPU->tunnel->user_event_pending = 1; 108 | } -------------------------------------------------------------------------------- /ShellcodeVM/WinMiniDump.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/ShellcodeVM/WinMiniDump.cpp -------------------------------------------------------------------------------- /ShellcodeVM/WinMiniDump.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | #pragma comment(lib,"DbgHelp.lib") 10 | 11 | class WinMiniDump 12 | { 13 | private: 14 | HANDLE m_hFile; 15 | HANDLE m_hMapFile; 16 | char* m_MapBuf; 17 | HANDLE m_hProcess; 18 | DWORD m_ProcessId; 19 | MINIDUMP_TYPE m_DumpType; 20 | 21 | public: 22 | WinMiniDump(); 23 | ~WinMiniDump(); 24 | bool Create(char* Filename, HANDLE hProcess=NULL, DWORD ProcessId=0, MINIDUMP_TYPE DumpType= MiniDumpWithFullMemory); 25 | bool Open(char* Filename); 26 | bool Close(); 27 | bool DumpHeader(); 28 | bool DumpDirectory(); 29 | void* RvaToAddress(uint32_t rva); 30 | void* GetStream(MINIDUMP_STREAM_TYPE type); 31 | bool DumpThreadList(PMINIDUMP_DIRECTORY dir); 32 | bool DumpModuleList(PMINIDUMP_DIRECTORY dir); 33 | bool DumpMemoryList(PMINIDUMP_DIRECTORY dir); 34 | bool DumpMemory64List(PMINIDUMP_DIRECTORY dir); 35 | bool DumpMemoryInfoList(PMINIDUMP_DIRECTORY dir); 36 | 37 | private: 38 | void ShowError(char* Note=NULL, DWORD Error=0); 39 | 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /ShellcodeVM/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define EINVAL 1 7 | #define EFAULT 2 8 | #define ENOSYS 3 9 | #define ENODEV 4 10 | #define ENXIO 5 11 | #define ENOSPC 6 12 | #define ENOMEM 7 13 | #define EINTR 8 14 | #define EAGAIN 9 15 | 16 | #define assert 17 | #define dprint printf 18 | 19 | #define CONFIG_WIN32 20 | #define CONFIG_SOFTFLOAT 21 | #define TARGET_X86_64 22 | 23 | typedef unsigned long long target_ulong; 24 | 25 | typedef unsigned long long target_phys_addr_t; 26 | typedef unsigned long long ram_addr_t; 27 | 28 | typedef uint8_t byte; 29 | typedef uint8_t uint8; 30 | typedef uint16_t uint16; 31 | typedef uint32_t uint32; 32 | typedef uint64_t uint64; 33 | 34 | typedef float float32; 35 | typedef double float64; -------------------------------------------------------------------------------- /ShellcodeVM/hax-all.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern "C" 4 | { 5 | #include "config.h" 6 | #include "hax-i386.h" 7 | } -------------------------------------------------------------------------------- /ShellcodeVM/hax-i386.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2011, Intel Corporation 3 | ** 4 | ** This software is licensed under the terms of the GNU General Public 5 | ** License version 2, as published by the Free Software Foundation, and 6 | ** may be copied, distributed, and modified under those terms. 7 | ** 8 | ** This program is distributed in the hope that it will be useful, 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ** GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef _HAX_I386_H 15 | #define _HAX_I386_H 16 | 17 | #include "config.h" 18 | 19 | typedef HANDLE hax_fd; 20 | 21 | struct hax_vcpu_state 22 | { 23 | hax_fd fd; 24 | int vcpu_id; 25 | int emulation_state; 26 | struct hax_tunnel *tunnel; 27 | unsigned char *iobuf; 28 | }; 29 | 30 | struct hax_state 31 | { 32 | hax_fd fd; /* the global hax device interface */ 33 | uint32_t version; 34 | struct hax_vm *vm; 35 | uint64_t mem_quota; 36 | }; 37 | 38 | #define HAX_MAX_VCPU 0x10 39 | #define MAX_VM_ID 0x40 40 | #define MAX_VCPU_ID 0x40 41 | 42 | struct hax_vm 43 | { 44 | hax_fd fd; 45 | int id; 46 | struct hax_vcpu_state *vcpus[HAX_MAX_VCPU]; 47 | }; 48 | 49 | /* Functions exported to host specific mode */ 50 | int valid_hax_tunnel_size(uint32_t size); 51 | int hax_open_device(hax_fd *fd); 52 | hax_fd hax_mod_open(void); 53 | int hax_populate_ram(struct hax_vm *vm, uint64_t va, uint32_t size); 54 | int hax_set_phys_mem(struct hax_state *hax, target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset); 55 | int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap); 56 | int hax_mod_version(struct hax_state *hax, struct hax_module_version *version); 57 | char *hax_vm_devfs_string(int vm_id); 58 | char *hax_vcpu_devfs_string(int vm_id, int vcpu_id); 59 | int hax_host_create_vm(struct hax_state *hax, int *vmid); 60 | hax_fd hax_host_open_vm(struct hax_state *hax, int vm_id); 61 | int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion); 62 | int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid); 63 | hax_fd hax_host_open_vcpu(int vmid, int vcpuid); 64 | int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu); 65 | int hax_vcpu_run(struct hax_vcpu_state* vcpu); 66 | int hax_sync_fpu(struct hax_vcpu_state *env, struct fx_layout *fl, int set); 67 | int hax_sync_msr(struct hax_vcpu_state *env, struct hax_msr_data *msrs, int set); 68 | int hax_sync_vcpu_state(struct hax_vcpu_state *env, struct vcpu_state_t *state, int set); 69 | int hax_inject_interrupt(struct hax_vcpu_state *env, int vector); 70 | 71 | #include "hax-windows.h" 72 | #include "hax-interface.h" 73 | 74 | #endif -------------------------------------------------------------------------------- /ShellcodeVM/hax-interface.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/ShellcodeVM/hax-interface.h -------------------------------------------------------------------------------- /ShellcodeVM/hax-windows.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2011, Intel Corporation 3 | ** 4 | ** This software is licensed under the terms of the GNU General Public 5 | ** License version 2, as published by the Free Software Foundation, and 6 | ** may be copied, distributed, and modified under those terms. 7 | ** 8 | ** This program is distributed in the hope that it will be useful, 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ** GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef __HAX_WINDOWS_H 15 | #define __HAX_WINDOWS_H 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #define HAX_INVALID_FD INVALID_HANDLE_VALUE 22 | 23 | static void hax_mod_close(struct hax_state *hax) 24 | { 25 | CloseHandle(hax->fd); 26 | } 27 | 28 | static void hax_close_fd(hax_fd fd) 29 | { 30 | CloseHandle(fd); 31 | } 32 | 33 | static int hax_invalid_fd(hax_fd fd) 34 | { 35 | return (fd == INVALID_HANDLE_VALUE) || (fd == NULL); 36 | } 37 | 38 | #define HAX_DEVICE_TYPE 0x4000 39 | 40 | /* See comments for the ioctl in hax-darwin.h */ 41 | #define HAX_IOCTL_VERSION CTL_CODE(HAX_DEVICE_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS) 42 | #define HAX_IOCTL_CREATE_VM CTL_CODE(HAX_DEVICE_TYPE, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS) 43 | #define HAX_IOCTL_CAPABILITY CTL_CODE(HAX_DEVICE_TYPE, 0x910, METHOD_BUFFERED, FILE_ANY_ACCESS) 44 | 45 | #define HAX_VM_IOCTL_VCPU_CREATE CTL_CODE(HAX_DEVICE_TYPE, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS) 46 | #define HAX_VM_IOCTL_ALLOC_RAM CTL_CODE(HAX_DEVICE_TYPE, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS) 47 | #define HAX_VM_IOCTL_SET_RAM CTL_CODE(HAX_DEVICE_TYPE, 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS) 48 | 49 | #define HAX_VCPU_IOCTL_RUN CTL_CODE(HAX_DEVICE_TYPE, 0x906, METHOD_BUFFERED, FILE_ANY_ACCESS) 50 | #define HAX_VCPU_IOCTL_SET_MSRS CTL_CODE(HAX_DEVICE_TYPE, 0x907, METHOD_BUFFERED, FILE_ANY_ACCESS) 51 | #define HAX_VCPU_IOCTL_GET_MSRS CTL_CODE(HAX_DEVICE_TYPE, 0x908, METHOD_BUFFERED, FILE_ANY_ACCESS) 52 | 53 | #define HAX_VCPU_IOCTL_SET_FPU CTL_CODE(HAX_DEVICE_TYPE, 0x909, METHOD_BUFFERED, FILE_ANY_ACCESS) 54 | #define HAX_VCPU_IOCTL_GET_FPU CTL_CODE(HAX_DEVICE_TYPE, 0x90a, METHOD_BUFFERED, FILE_ANY_ACCESS) 55 | 56 | #define HAX_VCPU_IOCTL_SETUP_TUNNEL CTL_CODE(HAX_DEVICE_TYPE, 0x90b, METHOD_BUFFERED, FILE_ANY_ACCESS) 57 | #define HAX_VCPU_IOCTL_INTERRUPT CTL_CODE(HAX_DEVICE_TYPE, 0x90c, METHOD_BUFFERED, FILE_ANY_ACCESS) 58 | #define HAX_VCPU_SET_REGS CTL_CODE(HAX_DEVICE_TYPE, 0x90d, METHOD_BUFFERED, FILE_ANY_ACCESS) 59 | #define HAX_VCPU_GET_REGS CTL_CODE(HAX_DEVICE_TYPE, 0x90e, METHOD_BUFFERED, FILE_ANY_ACCESS) 60 | 61 | #define HAX_VM_IOCTL_NOTIFY_QEMU_VERSION CTL_CODE(HAX_DEVICE_TYPE, 0x910, METHOD_BUFFERED, FILE_ANY_ACCESS) 62 | 63 | #endif -------------------------------------------------------------------------------- /ShellcodeVM/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/ShellcodeVM/main.cpp -------------------------------------------------------------------------------- /ShellcodeVM/msr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* MSRs */ 3 | #define IA32_FEATURE_CONTROL_CODE 0x03A 4 | #define IA32_SYSENTER_CS 0x174 5 | #define IA32_SYSENTER_ESP 0x175 6 | #define IA32_SYSENTER_EIP 0x176 7 | #define IA32_DEBUGCTL 0x1D9 8 | #define IA32_VMX_BASIC_MSR_CODE 0x480 9 | #define IA32_VMX_PINBASED_CTLS 0x481 10 | #define IA32_VMX_PROCBASED_CTLS 0x482 11 | #define IA32_VMX_EXIT_CTLS 0x483 12 | #define IA32_VMX_ENTRY_CTLS 0x484 13 | #define IA32_VMX_MISC 0x485 14 | #define IA32_VMX_CR0_FIXED0 0x486 15 | #define IA32_VMX_CR0_FIXED1 0x487 16 | #define IA32_VMX_CR4_FIXED0 0x488 17 | #define IA32_VMX_CR4_FIXED1 0x489 18 | #define IA32_FS_BASE 0xc0000100 19 | #define IA32_GS_BASE 0xc0000101 20 | #define IA64_SYSENTER_EIP 0xC0000082 21 | 22 | #define MSR_IA32_MTRRCAP 0xfe 23 | #define MSR_IA32_MTRR_DEF_TYPE 0x2ff 24 | #define MSR_IA32_MTRR_PHYSBASE(n) (0x200 + 2*(n)) 25 | #define MSR_IA32_MTRR_PHYSMASK(n) (0x200 + 2*(n) + 1) 26 | #define MSR_IA32_MTRR_FIX64K_00000 0x250 27 | #define MSR_IA32_MTRR_FIX16K_80000 0x258 28 | #define MSR_IA32_MTRR_FIX16K_A0000 0x259 29 | #define MSR_IA32_MTRR_FIX4K_C0000 0x268 30 | #define MSR_IA32_MTRR_FIX4K_C8000 0x269 31 | #define MSR_IA32_MTRR_FIX4K_D0000 0x26a 32 | #define MSR_IA32_MTRR_FIX4K_D8000 0x26b 33 | #define MSR_IA32_MTRR_FIX4K_E0000 0x26c 34 | #define MSR_IA32_MTRR_FIX4K_E8000 0x26d 35 | #define MSR_IA32_MTRR_FIX4K_F0000 0x26e 36 | #define MSR_IA32_MTRR_FIX4K_F8000 0x26f 37 | 38 | 39 | 40 | 41 | #define MSR_LASTBRANCH_0_FROM_IP 0x40 42 | #define MSR_LASTBRANCH_0_TO_IP 0x60 43 | #define MSR_LASTBRANCH_TOS 0x1C9 -------------------------------------------------------------------------------- /ShellcodeVM/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // HaxmTest.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /ShellcodeVM/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | #include 6 | #include 7 | 8 | #include "hax-all.h" 9 | #include "VirtualCPU.h" 10 | #include "VMCS.h" 11 | #include "VM.h" -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/TODO: -------------------------------------------------------------------------------- 1 | Correctness issues: 2 | 3 | - some eflags manipulation incorrectly reset the bit 0x2. 4 | - SVM: test, cpu save/restore, SMM save/restore. 5 | - x86_64: lcall/ljmp intel/amd differences ? 6 | - better code fetch (different exception handling + CS.limit support) 7 | - user/kernel PUSHL/POPL in helper.c 8 | - add missing cpuid tests 9 | - return UD exception if LOCK prefix incorrectly used 10 | - test ldt limit < 7 ? 11 | - fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret) 12 | - full support of segment limit/rights 13 | - full x87 exception support 14 | - improve x87 bit exactness (use bochs code ?) 15 | - DRx register support 16 | - CR0.AC emulation 17 | - SSE alignment checks 18 | - fix SSE min/max with nans 19 | 20 | Optimizations/Features: 21 | 22 | - add SVM nested paging support 23 | - add VMX support 24 | - add AVX support 25 | - add SSE5 support 26 | - fxsave/fxrstor AMD extensions 27 | - improve monitor/mwait support 28 | - faster EFLAGS update: consider SZAP, C, O can be updated separately 29 | with a bit field in CC_OP and more state variables. 30 | - evaluate x87 stack pointer statically 31 | - find a way to avoid translating several time the same TB if CR0.TS 32 | is set or not. 33 | - move kqemu support outside target-i386. 34 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/cc_helper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * x86 condition code helpers 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 19 | */ 20 | 21 | #include "cpu.h" 22 | #include "helper.h" 23 | 24 | const uint8_t parity_table[256] = { 25 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 26 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 27 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 28 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 29 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 30 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 31 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 32 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 33 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 34 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 35 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 36 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 37 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 38 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 39 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 40 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 41 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 42 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 43 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 44 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 45 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 46 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 47 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 48 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 49 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 50 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 51 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 52 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 53 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 54 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 55 | CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 56 | 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, 57 | }; 58 | 59 | #define SHIFT 0 60 | #include "cc_helper_template.h" 61 | #undef SHIFT 62 | 63 | #define SHIFT 1 64 | #include "cc_helper_template.h" 65 | #undef SHIFT 66 | 67 | #define SHIFT 2 68 | #include "cc_helper_template.h" 69 | #undef SHIFT 70 | 71 | #ifdef TARGET_X86_64 72 | #define SHIFT 3 73 | #include "cc_helper_template.h" 74 | #undef SHIFT 75 | #endif 76 | 77 | static int compute_all_eflags(CPUX86State *env) 78 | { 79 | return CC_SRC; 80 | } 81 | 82 | static int compute_c_eflags(CPUX86State *env) 83 | { 84 | return CC_SRC & CC_C; 85 | } 86 | 87 | uint32_t helper_cc_compute_all(CPUX86State *env, int op) 88 | { 89 | switch (op) { 90 | default: /* should never happen */ return 0; 91 | 92 | case CC_OP_EFLAGS: return compute_all_eflags(env); 93 | 94 | case CC_OP_MULB: return compute_all_mulb(env); 95 | case CC_OP_MULW: return compute_all_mulw(env); 96 | case CC_OP_MULL: return compute_all_mull(env); 97 | 98 | case CC_OP_ADDB: return compute_all_addb(env); 99 | case CC_OP_ADDW: return compute_all_addw(env); 100 | case CC_OP_ADDL: return compute_all_addl(env); 101 | 102 | case CC_OP_ADCB: return compute_all_adcb(env); 103 | case CC_OP_ADCW: return compute_all_adcw(env); 104 | case CC_OP_ADCL: return compute_all_adcl(env); 105 | 106 | case CC_OP_SUBB: return compute_all_subb(env); 107 | case CC_OP_SUBW: return compute_all_subw(env); 108 | case CC_OP_SUBL: return compute_all_subl(env); 109 | 110 | case CC_OP_SBBB: return compute_all_sbbb(env); 111 | case CC_OP_SBBW: return compute_all_sbbw(env); 112 | case CC_OP_SBBL: return compute_all_sbbl(env); 113 | 114 | case CC_OP_LOGICB: return compute_all_logicb(env); 115 | case CC_OP_LOGICW: return compute_all_logicw(env); 116 | case CC_OP_LOGICL: return compute_all_logicl(env); 117 | 118 | case CC_OP_INCB: return compute_all_incb(env); 119 | case CC_OP_INCW: return compute_all_incw(env); 120 | case CC_OP_INCL: return compute_all_incl(env); 121 | 122 | case CC_OP_DECB: return compute_all_decb(env); 123 | case CC_OP_DECW: return compute_all_decw(env); 124 | case CC_OP_DECL: return compute_all_decl(env); 125 | 126 | case CC_OP_SHLB: return compute_all_shlb(env); 127 | case CC_OP_SHLW: return compute_all_shlw(env); 128 | case CC_OP_SHLL: return compute_all_shll(env); 129 | 130 | case CC_OP_SARB: return compute_all_sarb(env); 131 | case CC_OP_SARW: return compute_all_sarw(env); 132 | case CC_OP_SARL: return compute_all_sarl(env); 133 | 134 | #ifdef TARGET_X86_64 135 | case CC_OP_MULQ: return compute_all_mulq(env); 136 | 137 | case CC_OP_ADDQ: return compute_all_addq(env); 138 | 139 | case CC_OP_ADCQ: return compute_all_adcq(env); 140 | 141 | case CC_OP_SUBQ: return compute_all_subq(env); 142 | 143 | case CC_OP_SBBQ: return compute_all_sbbq(env); 144 | 145 | case CC_OP_LOGICQ: return compute_all_logicq(env); 146 | 147 | case CC_OP_INCQ: return compute_all_incq(env); 148 | 149 | case CC_OP_DECQ: return compute_all_decq(env); 150 | 151 | case CC_OP_SHLQ: return compute_all_shlq(env); 152 | 153 | case CC_OP_SARQ: return compute_all_sarq(env); 154 | #endif 155 | } 156 | } 157 | 158 | uint32_t cpu_cc_compute_all(CPUArchState *env1, int op) 159 | { 160 | return helper_cc_compute_all(env1, op); 161 | } 162 | 163 | uint32_t helper_cc_compute_c(CPUX86State *env, int op) 164 | { 165 | switch (op) { 166 | default: /* should never happen */ return 0; 167 | 168 | case CC_OP_EFLAGS: return compute_c_eflags(env); 169 | 170 | case CC_OP_MULB: return compute_c_mull(env); 171 | case CC_OP_MULW: return compute_c_mull(env); 172 | case CC_OP_MULL: return compute_c_mull(env); 173 | 174 | case CC_OP_ADDB: return compute_c_addb(env); 175 | case CC_OP_ADDW: return compute_c_addw(env); 176 | case CC_OP_ADDL: return compute_c_addl(env); 177 | 178 | case CC_OP_ADCB: return compute_c_adcb(env); 179 | case CC_OP_ADCW: return compute_c_adcw(env); 180 | case CC_OP_ADCL: return compute_c_adcl(env); 181 | 182 | case CC_OP_SUBB: return compute_c_subb(env); 183 | case CC_OP_SUBW: return compute_c_subw(env); 184 | case CC_OP_SUBL: return compute_c_subl(env); 185 | 186 | case CC_OP_SBBB: return compute_c_sbbb(env); 187 | case CC_OP_SBBW: return compute_c_sbbw(env); 188 | case CC_OP_SBBL: return compute_c_sbbl(env); 189 | 190 | case CC_OP_LOGICB: return compute_c_logicb(env); 191 | case CC_OP_LOGICW: return compute_c_logicw(env); 192 | case CC_OP_LOGICL: return compute_c_logicl(env); 193 | 194 | case CC_OP_INCB: return compute_c_incl(env); 195 | case CC_OP_INCW: return compute_c_incl(env); 196 | case CC_OP_INCL: return compute_c_incl(env); 197 | 198 | case CC_OP_DECB: return compute_c_incl(env); 199 | case CC_OP_DECW: return compute_c_incl(env); 200 | case CC_OP_DECL: return compute_c_incl(env); 201 | 202 | case CC_OP_SHLB: return compute_c_shlb(env); 203 | case CC_OP_SHLW: return compute_c_shlw(env); 204 | case CC_OP_SHLL: return compute_c_shll(env); 205 | 206 | case CC_OP_SARB: return compute_c_sarl(env); 207 | case CC_OP_SARW: return compute_c_sarl(env); 208 | case CC_OP_SARL: return compute_c_sarl(env); 209 | 210 | #ifdef TARGET_X86_64 211 | case CC_OP_MULQ: return compute_c_mull(env); 212 | 213 | case CC_OP_ADDQ: return compute_c_addq(env); 214 | 215 | case CC_OP_ADCQ: return compute_c_adcq(env); 216 | 217 | case CC_OP_SUBQ: return compute_c_subq(env); 218 | 219 | case CC_OP_SBBQ: return compute_c_sbbq(env); 220 | 221 | case CC_OP_LOGICQ: return compute_c_logicq(env); 222 | 223 | case CC_OP_INCQ: return compute_c_incl(env); 224 | 225 | case CC_OP_DECQ: return compute_c_incl(env); 226 | 227 | case CC_OP_SHLQ: return compute_c_shlq(env); 228 | 229 | case CC_OP_SARQ: return compute_c_sarl(env); 230 | #endif 231 | } 232 | } 233 | 234 | void helper_write_eflags(CPUX86State *env, 235 | target_ulong t0, uint32_t update_mask) 236 | { 237 | cpu_load_eflags(env, t0, update_mask); 238 | } 239 | 240 | target_ulong helper_read_eflags(CPUX86State *env) 241 | { 242 | uint32_t eflags; 243 | eflags = helper_cc_compute_all(env, CC_OP); 244 | eflags |= (DF & DF_MASK); 245 | eflags |= env->eflags & ~(VM_MASK | RF_MASK); 246 | return eflags; 247 | } 248 | 249 | void helper_clts(CPUX86State *env) 250 | { 251 | env->cr[0] &= ~CR0_TS_MASK; 252 | env->hflags &= ~HF_TS_MASK; 253 | } 254 | 255 | void helper_reset_rf(CPUX86State *env) 256 | { 257 | env->eflags &= ~RF_MASK; 258 | } 259 | 260 | void helper_cli(CPUX86State *env) 261 | { 262 | env->eflags &= ~IF_MASK; 263 | } 264 | 265 | void helper_sti(CPUX86State *env) 266 | { 267 | env->eflags |= IF_MASK; 268 | } 269 | 270 | void helper_set_inhibit_irq(CPUX86State *env) 271 | { 272 | env->hflags |= HF_INHIBIT_IRQ_MASK; 273 | } 274 | 275 | void helper_reset_inhibit_irq(CPUX86State *env) 276 | { 277 | env->hflags &= ~HF_INHIBIT_IRQ_MASK; 278 | } 279 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/cc_helper_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i386 helpers 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 19 | */ 20 | #define DATA_BITS (1 << (3 + SHIFT)) 21 | #define SHIFT_MASK (DATA_BITS - 1) 22 | #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1)) 23 | #if DATA_BITS <= 32 24 | #define SHIFT1_MASK 0x1f 25 | #else 26 | #define SHIFT1_MASK 0x3f 27 | #endif 28 | 29 | #if DATA_BITS == 8 30 | #define SUFFIX b 31 | #define DATA_TYPE uint8_t 32 | #define DATA_STYPE int8_t 33 | #define DATA_MASK 0xff 34 | #elif DATA_BITS == 16 35 | #define SUFFIX w 36 | #define DATA_TYPE uint16_t 37 | #define DATA_STYPE int16_t 38 | #define DATA_MASK 0xffff 39 | #elif DATA_BITS == 32 40 | #define SUFFIX l 41 | #define DATA_TYPE uint32_t 42 | #define DATA_STYPE int32_t 43 | #define DATA_MASK 0xffffffff 44 | #elif DATA_BITS == 64 45 | #define SUFFIX q 46 | #define DATA_TYPE uint64_t 47 | #define DATA_STYPE int64_t 48 | #define DATA_MASK 0xffffffffffffffffULL 49 | #else 50 | #error unhandled operand size 51 | #endif 52 | 53 | /* dynamic flags computation */ 54 | 55 | static int glue(compute_all_add, SUFFIX)(CPUX86State *env) 56 | { 57 | int cf, pf, af, zf, sf, of; 58 | target_long src1, src2; 59 | src1 = CC_SRC; 60 | src2 = CC_DST - CC_SRC; 61 | cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1; 62 | pf = parity_table[(uint8_t)CC_DST]; 63 | af = (CC_DST ^ src1 ^ src2) & 0x10; 64 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 65 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 66 | of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; 67 | return cf | pf | af | zf | sf | of; 68 | } 69 | 70 | static int glue(compute_c_add, SUFFIX)(CPUX86State *env) 71 | { 72 | int cf; 73 | target_long src1; 74 | src1 = CC_SRC; 75 | cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1; 76 | return cf; 77 | } 78 | 79 | static int glue(compute_all_adc, SUFFIX)(CPUX86State *env) 80 | { 81 | int cf, pf, af, zf, sf, of; 82 | target_long src1, src2; 83 | src1 = CC_SRC; 84 | src2 = CC_DST - CC_SRC - 1; 85 | cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1; 86 | pf = parity_table[(uint8_t)CC_DST]; 87 | af = (CC_DST ^ src1 ^ src2) & 0x10; 88 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 89 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 90 | of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; 91 | return cf | pf | af | zf | sf | of; 92 | } 93 | 94 | static int glue(compute_c_adc, SUFFIX)(CPUX86State *env) 95 | { 96 | int cf; 97 | target_long src1; 98 | src1 = CC_SRC; 99 | cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1; 100 | return cf; 101 | } 102 | 103 | static int glue(compute_all_sub, SUFFIX)(CPUX86State *env) 104 | { 105 | int cf, pf, af, zf, sf, of; 106 | target_long src1, src2; 107 | src1 = CC_DST + CC_SRC; 108 | src2 = CC_SRC; 109 | cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; 110 | pf = parity_table[(uint8_t)CC_DST]; 111 | af = (CC_DST ^ src1 ^ src2) & 0x10; 112 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 113 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 114 | of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; 115 | return cf | pf | af | zf | sf | of; 116 | } 117 | 118 | static int glue(compute_c_sub, SUFFIX)(CPUX86State *env) 119 | { 120 | int cf; 121 | target_long src1, src2; 122 | src1 = CC_DST + CC_SRC; 123 | src2 = CC_SRC; 124 | cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; 125 | return cf; 126 | } 127 | 128 | static int glue(compute_all_sbb, SUFFIX)(CPUX86State *env) 129 | { 130 | int cf, pf, af, zf, sf, of; 131 | target_long src1, src2; 132 | src1 = CC_DST + CC_SRC + 1; 133 | src2 = CC_SRC; 134 | cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; 135 | pf = parity_table[(uint8_t)CC_DST]; 136 | af = (CC_DST ^ src1 ^ src2) & 0x10; 137 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 138 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 139 | of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; 140 | return cf | pf | af | zf | sf | of; 141 | } 142 | 143 | static int glue(compute_c_sbb, SUFFIX)(CPUX86State *env) 144 | { 145 | int cf; 146 | target_long src1, src2; 147 | src1 = CC_DST + CC_SRC + 1; 148 | src2 = CC_SRC; 149 | cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2; 150 | return cf; 151 | } 152 | 153 | static int glue(compute_all_logic, SUFFIX)(CPUX86State *env) 154 | { 155 | int cf, pf, af, zf, sf, of; 156 | cf = 0; 157 | pf = parity_table[(uint8_t)CC_DST]; 158 | af = 0; 159 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 160 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 161 | of = 0; 162 | return cf | pf | af | zf | sf | of; 163 | } 164 | 165 | static int glue(compute_c_logic, SUFFIX)(CPUX86State *env) 166 | { 167 | return 0; 168 | } 169 | 170 | static int glue(compute_all_inc, SUFFIX)(CPUX86State *env) 171 | { 172 | int cf, pf, af, zf, sf, of; 173 | target_long src1, src2; 174 | src1 = CC_DST - 1; 175 | src2 = 1; 176 | cf = CC_SRC; 177 | pf = parity_table[(uint8_t)CC_DST]; 178 | af = (CC_DST ^ src1 ^ src2) & 0x10; 179 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 180 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 181 | of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11; 182 | return cf | pf | af | zf | sf | of; 183 | } 184 | 185 | #if DATA_BITS == 32 186 | static int glue(compute_c_inc, SUFFIX)(CPUX86State *env) 187 | { 188 | return CC_SRC; 189 | } 190 | #endif 191 | 192 | static int glue(compute_all_dec, SUFFIX)(CPUX86State *env) 193 | { 194 | int cf, pf, af, zf, sf, of; 195 | target_long src1, src2; 196 | src1 = CC_DST + 1; 197 | src2 = 1; 198 | cf = CC_SRC; 199 | pf = parity_table[(uint8_t)CC_DST]; 200 | af = (CC_DST ^ src1 ^ src2) & 0x10; 201 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 202 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 203 | of = ((CC_DST & DATA_MASK) == ((target_ulong)SIGN_MASK - 1)) << 11; 204 | return cf | pf | af | zf | sf | of; 205 | } 206 | 207 | static int glue(compute_all_shl, SUFFIX)(CPUX86State *env) 208 | { 209 | int cf, pf, af, zf, sf, of; 210 | cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C; 211 | pf = parity_table[(uint8_t)CC_DST]; 212 | af = 0; /* undefined */ 213 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 214 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 215 | /* of is defined if shift count == 1 */ 216 | of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O; 217 | return cf | pf | af | zf | sf | of; 218 | } 219 | 220 | static int glue(compute_c_shl, SUFFIX)(CPUX86State *env) 221 | { 222 | return (CC_SRC >> (DATA_BITS - 1)) & CC_C; 223 | } 224 | 225 | #if DATA_BITS == 32 226 | static int glue(compute_c_sar, SUFFIX)(CPUX86State *env) 227 | { 228 | return CC_SRC & 1; 229 | } 230 | #endif 231 | 232 | static int glue(compute_all_sar, SUFFIX)(CPUX86State *env) 233 | { 234 | int cf, pf, af, zf, sf, of; 235 | cf = CC_SRC & 1; 236 | pf = parity_table[(uint8_t)CC_DST]; 237 | af = 0; /* undefined */ 238 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 239 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 240 | /* of is defined if shift count == 1 */ 241 | of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O; 242 | return cf | pf | af | zf | sf | of; 243 | } 244 | 245 | #if DATA_BITS == 32 246 | static int glue(compute_c_mul, SUFFIX)(CPUX86State *env) 247 | { 248 | int cf; 249 | cf = (CC_SRC != 0); 250 | return cf; 251 | } 252 | #endif 253 | 254 | /* NOTE: we compute the flags like the P4. On olders CPUs, only OF and 255 | CF are modified and it is slower to do that. */ 256 | static int glue(compute_all_mul, SUFFIX)(CPUX86State *env) 257 | { 258 | int cf, pf, af, zf, sf, of; 259 | cf = (CC_SRC != 0); 260 | pf = parity_table[(uint8_t)CC_DST]; 261 | af = 0; /* undefined */ 262 | zf = ((DATA_TYPE)CC_DST == 0) << 6; 263 | sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; 264 | of = cf << 11; 265 | return cf | pf | af | zf | sf | of; 266 | } 267 | 268 | #undef DATA_BITS 269 | #undef SHIFT_MASK 270 | #undef SHIFT1_MASK 271 | #undef SIGN_MASK 272 | #undef DATA_TYPE 273 | #undef DATA_STYPE 274 | #undef DATA_MASK 275 | #undef SUFFIX 276 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/cpu-qom.h: -------------------------------------------------------------------------------- 1 | #ifndef QEMU_X86_CPU_QOM_H 2 | #define QEMU_X86_CPU_QOM_H 3 | 4 | #include "qemu/osdep.h" 5 | #include "qom/cpu.h" 6 | 7 | typedef struct X86CPU { 8 | CPUState parent_obj; 9 | 10 | CPUX86State env; 11 | } X86CPU; 12 | 13 | static inline X86CPU *x86_env_get_cpu(CPUX86State *env) 14 | { 15 | return container_of(env, X86CPU, env); 16 | } 17 | 18 | #define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e)) 19 | #define ENV_OFFSET offsetof(X86CPU, env) 20 | 21 | #endif // QEMU_X86_CPU_QOM_H 22 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/excp_helper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * x86 exception helpers 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | 20 | #include "cpu.h" 21 | #include "qemu/log.h" 22 | #include "sysemu/sysemu.h" 23 | #include "helper.h" 24 | 25 | #if 0 26 | #define raise_exception_err(a, b)\ 27 | do {\ 28 | qemu_log("raise_exception line=%d\n", __LINE__);\ 29 | (raise_exception_err)(a, b);\ 30 | } while (0) 31 | #endif 32 | 33 | void helper_raise_interrupt(CPUX86State *env, int intno, int next_eip_addend) 34 | { 35 | raise_interrupt(env, intno, 1, 0, next_eip_addend); 36 | } 37 | 38 | void helper_raise_exception(CPUX86State *env, int exception_index) 39 | { 40 | raise_exception(env, exception_index); 41 | } 42 | 43 | /* 44 | * Check nested exceptions and change to double or triple fault if 45 | * needed. It should only be called, if this is not an interrupt. 46 | * Returns the new exception number. 47 | */ 48 | static int check_exception(CPUX86State *env, int intno, int *error_code) 49 | { 50 | int first_contributory = env->old_exception == 0 || 51 | (env->old_exception >= 10 && 52 | env->old_exception <= 13); 53 | int second_contributory = intno == 0 || 54 | (intno >= 10 && intno <= 13); 55 | 56 | qemu_log_mask(CPU_LOG_INT, "check_exception old: 0x%x new 0x%x\n", 57 | env->old_exception, intno); 58 | 59 | #if !defined(CONFIG_USER_ONLY) 60 | if (env->old_exception == EXCP08_DBLE) { 61 | if (env->hflags & HF_SVMI_MASK) 62 | helper_vmexit(env, SVM_EXIT_SHUTDOWN, 0); /* does not return */ 63 | 64 | qemu_log_mask(CPU_LOG_RESET, "Triple fault\n"); 65 | 66 | qemu_system_reset_request(); 67 | return EXCP_HLT; 68 | } 69 | #endif 70 | 71 | if ((first_contributory && second_contributory) 72 | || (env->old_exception == EXCP0E_PAGE && 73 | (second_contributory || (intno == EXCP0E_PAGE)))) { 74 | intno = EXCP08_DBLE; 75 | *error_code = 0; 76 | } 77 | 78 | if (second_contributory || (intno == EXCP0E_PAGE) || 79 | (intno == EXCP08_DBLE)) 80 | env->old_exception = intno; 81 | 82 | return intno; 83 | } 84 | 85 | /* 86 | * Signal an interruption. It is executed in the main CPU loop. 87 | * is_int is TRUE if coming from the int instruction. next_eip is the 88 | * EIP value AFTER the interrupt instruction. It is only relevant if 89 | * is_int is TRUE. 90 | */ 91 | void QEMU_NORETURN raise_interrupt(CPUX86State *env, 92 | int intno, int is_int, int error_code, 93 | int next_eip_addend) 94 | { 95 | if (!is_int) { 96 | helper_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno, error_code); 97 | intno = check_exception(env, intno, &error_code); 98 | } else { 99 | helper_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0); 100 | } 101 | 102 | env->exception_index = intno; 103 | env->error_code = error_code; 104 | env->exception_is_int = is_int; 105 | env->exception_next_eip = env->eip + next_eip_addend; 106 | cpu_loop_exit(env); 107 | } 108 | 109 | /* shortcuts to generate exceptions */ 110 | 111 | void raise_exception_err(CPUX86State *env, 112 | int exception_index, int error_code) 113 | { 114 | raise_interrupt(env, exception_index, 0, error_code, 0); 115 | } 116 | 117 | void raise_exception(CPUX86State *env, int exception_index) 118 | { 119 | raise_interrupt(env, exception_index, 0, 0, 0); 120 | } 121 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/hax-darwin.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2011, Intel Corporation 3 | ** 4 | ** This software is licensed under the terms of the GNU General Public 5 | ** License version 2, as published by the Free Software Foundation, and 6 | ** may be copied, distributed, and modified under those terms. 7 | ** 8 | ** This program is distributed in the hope that it will be useful, 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ** GNU General Public License for more details. 12 | */ 13 | 14 | /* HAX module interface - darwin version */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "exec/ram_addr.h" 22 | #include "target-i386/hax-i386.h" 23 | 24 | hax_fd hax_mod_open(void) 25 | { 26 | int fd = open("/dev/HAX", O_RDWR); 27 | 28 | if (fd == -1) 29 | { 30 | dprint("Failed to open the hax module\n"); 31 | return -errno; 32 | } 33 | 34 | return fd; 35 | } 36 | 37 | int hax_populate_ram(uint64_t va, uint32_t size) 38 | { 39 | int ret; 40 | struct hax_alloc_ram_info info; 41 | 42 | if (!hax_global.vm || !hax_global.vm->fd) 43 | { 44 | dprint("Allocate memory before vm create?\n"); 45 | return -EINVAL; 46 | } 47 | 48 | info.size = size; 49 | info.va = va; 50 | ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ALLOC_RAM, &info); 51 | if (ret < 0) 52 | { 53 | dprint("Failed to allocate %x memory\n", size); 54 | return ret; 55 | } 56 | return 0; 57 | } 58 | 59 | int hax_set_phys_mem(hwaddr start_addr, ram_addr_t size, ram_addr_t phys_offset) 60 | { 61 | struct hax_set_ram_info info, *pinfo = &info; 62 | int ret; 63 | ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK; 64 | 65 | /* We look for the RAM and ROM only */ 66 | if (flags >= IO_MEM_UNASSIGNED) 67 | return 0; 68 | 69 | if ( (start_addr & ~TARGET_PAGE_MASK) || (size & ~TARGET_PAGE_MASK)) 70 | { 71 | dprint("set_phys_mem %x %lx requires page aligned addr and size\n", start_addr, size); 72 | exit(1); 73 | return -1; 74 | } 75 | 76 | info.pa_start = start_addr; 77 | info.size = size; 78 | info.va = (uint64_t)(uintptr_t)qemu_get_ram_ptr(phys_offset); 79 | info.flags = (flags & IO_MEM_ROM) ? 1 : 0; 80 | 81 | ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_SET_RAM, pinfo); 82 | if (ret < 0) 83 | { 84 | dprint("has set phys mem failed\n"); 85 | exit(1); 86 | } 87 | return ret; 88 | } 89 | 90 | int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap) 91 | { 92 | int ret; 93 | 94 | ret = ioctl(hax->fd, HAX_IOCTL_CAPABILITY, cap); 95 | if (ret == -1) 96 | { 97 | dprint("Failed to get HAX capability\n"); 98 | return -errno; 99 | } 100 | 101 | return 0; 102 | } 103 | 104 | int hax_mod_version(struct hax_state *hax, struct hax_module_version *version) 105 | { 106 | int ret; 107 | 108 | ret = ioctl(hax->fd, HAX_IOCTL_VERSION, version); 109 | if (ret == -1) 110 | { 111 | dprint("Failed to get HAX version\n"); 112 | return -errno; 113 | } 114 | 115 | return 0; 116 | } 117 | 118 | static char *hax_vm_devfs_string(int vm_id) 119 | { 120 | char *name; 121 | 122 | if (vm_id > MAX_VM_ID) 123 | { 124 | dprint("Too big VM id\n"); 125 | return NULL; 126 | } 127 | 128 | name = g_strdup("/dev/hax_vm/vmxx"); 129 | if (!name) 130 | return NULL; 131 | sprintf(name, "/dev/hax_vm/vm%02d", vm_id); 132 | 133 | return name; 134 | } 135 | 136 | static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id) 137 | { 138 | char *name; 139 | 140 | if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) 141 | { 142 | dprint("Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id); 143 | return NULL; 144 | } 145 | 146 | name = g_strdup("/dev/hax_vmxx/vcpuyy"); 147 | if (!name) 148 | return NULL; 149 | 150 | sprintf(name, "/dev/hax_vm%02d/vcpu%02d", vm_id, vcpu_id); 151 | 152 | return name; 153 | } 154 | 155 | int hax_host_create_vm(struct hax_state *hax, int *vmid) 156 | { 157 | int ret; 158 | int vm_id = 0; 159 | 160 | if (hax_invalid_fd(hax->fd)) 161 | return -EINVAL; 162 | 163 | if (hax->vm) 164 | return 0; 165 | 166 | ret = ioctl(hax->fd, HAX_IOCTL_CREATE_VM, &vm_id); 167 | *vmid = vm_id; 168 | return ret; 169 | } 170 | 171 | hax_fd hax_host_open_vm(struct hax_state *hax, int vm_id) 172 | { 173 | hax_fd fd; 174 | char *vm_name = NULL; 175 | 176 | vm_name = hax_vm_devfs_string(vm_id); 177 | if (!vm_name) 178 | return -1; 179 | 180 | fd = open(vm_name, O_RDWR); 181 | g_free(vm_name); 182 | 183 | return fd; 184 | } 185 | 186 | int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion) 187 | { 188 | int ret; 189 | 190 | if (hax_invalid_fd(vm_fd)) 191 | return -EINVAL; 192 | 193 | ret = ioctl(vm_fd, HAX_VM_IOCTL_NOTIFY_QEMU_VERSION, qversion); 194 | if (ret == -1) 195 | { 196 | dprint("Failed to notify qemu API version\n"); 197 | return -errno; 198 | } 199 | 200 | return 0; 201 | } 202 | 203 | /* 204 | * Simply assume that the size should be bigger than the hax_tunnel, 205 | * since the hax_tunnel can be extended later with backward 206 | * compatibility. 207 | */ 208 | int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid) 209 | { 210 | int ret; 211 | 212 | ret = ioctl(vm_fd, HAX_VM_IOCTL_VCPU_CREATE, &vcpuid); 213 | if (ret < 0) 214 | dprint("Failed to create vcpu %x\n", vcpuid); 215 | 216 | return ret; 217 | } 218 | 219 | hax_fd hax_host_open_vcpu(int vmid, int vcpuid) 220 | { 221 | char *devfs_path = NULL; 222 | hax_fd fd; 223 | 224 | devfs_path = hax_vcpu_devfs_string(vmid, vcpuid); 225 | if (!devfs_path) 226 | { 227 | dprint("Failed to get the devfs\n"); 228 | return -EINVAL; 229 | } 230 | 231 | fd = open(devfs_path, O_RDWR); 232 | g_free(devfs_path); 233 | if (fd < 0) 234 | dprint("Failed to open the vcpu devfs\n"); 235 | return fd; 236 | } 237 | 238 | int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu) 239 | { 240 | int ret; 241 | struct hax_tunnel_info info; 242 | 243 | ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_SETUP_TUNNEL, &info); 244 | if (ret) 245 | { 246 | dprint("Failed to setup the hax tunnel\n"); 247 | return ret; 248 | } 249 | 250 | if (!valid_hax_tunnel_size(info.size)) 251 | { 252 | dprint("Invalid hax tunnel size %x\n", info.size); 253 | ret = -EINVAL; 254 | return ret; 255 | } 256 | 257 | vcpu->tunnel = (struct hax_tunnel *)(uintptr_t)(info.va); 258 | vcpu->iobuf = (unsigned char *)(uintptr_t)(info.io_va); 259 | return 0; 260 | } 261 | 262 | int hax_vcpu_run(struct hax_vcpu_state* vcpu) 263 | { 264 | int ret; 265 | 266 | ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_RUN, NULL); 267 | return ret; 268 | } 269 | 270 | int hax_sync_fpu(CPUState *cpu, struct fx_layout *fl, int set) 271 | { 272 | int ret, fd; 273 | 274 | fd = hax_vcpu_get_fd(cpu); 275 | if (fd <= 0) 276 | return -1; 277 | 278 | if (set) 279 | ret = ioctl(fd, HAX_VCPU_IOCTL_SET_FPU, fl); 280 | else 281 | ret = ioctl(fd, HAX_VCPU_IOCTL_GET_FPU, fl); 282 | return ret; 283 | } 284 | 285 | int hax_sync_msr(CPUState *cpu, struct hax_msr_data *msrs, int set) 286 | { 287 | int ret, fd; 288 | 289 | fd = hax_vcpu_get_fd(cpu); 290 | if (fd <= 0) 291 | return -1; 292 | if (set) 293 | ret = ioctl(fd, HAX_VCPU_IOCTL_SET_MSRS, msrs); 294 | else 295 | ret = ioctl(fd, HAX_VCPU_IOCTL_GET_MSRS, msrs); 296 | return ret; 297 | } 298 | 299 | int hax_sync_vcpu_state(CPUState *cpu, struct vcpu_state_t *state, int set) 300 | { 301 | int ret, fd; 302 | 303 | fd = hax_vcpu_get_fd(cpu); 304 | if (fd <= 0) 305 | return -1; 306 | 307 | if (set) 308 | ret = ioctl(fd, HAX_VCPU_SET_REGS, state); 309 | else 310 | ret = ioctl(fd, HAX_VCPU_GET_REGS, state); 311 | return ret; 312 | } 313 | 314 | int hax_inject_interrupt(CPUState *cpu, int vector) 315 | { 316 | int ret, fd; 317 | 318 | fd = hax_vcpu_get_fd(cpu); 319 | if (fd <= 0) 320 | return -1; 321 | 322 | ret = ioctl(fd, HAX_VCPU_IOCTL_INTERRUPT, &vector); 323 | return ret; 324 | } 325 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/hax-darwin.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2011, Intel Corporation 3 | ** 4 | ** This software is licensed under the terms of the GNU General Public 5 | ** License version 2, as published by the Free Software Foundation, and 6 | ** may be copied, distributed, and modified under those terms. 7 | ** 8 | ** This program is distributed in the hope that it will be useful, 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ** GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef __HAX_UNIX_H 15 | #define __HAX_UNIX_H 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define HAX_INVALID_FD (-1) 23 | static inline int hax_invalid_fd(hax_fd fd) 24 | { 25 | return fd <= 0; 26 | } 27 | 28 | static inline void hax_mod_close(struct hax_state *hax) 29 | { 30 | close(hax->fd); 31 | } 32 | 33 | static inline void hax_close_fd(hax_fd fd) 34 | { 35 | close(fd); 36 | } 37 | 38 | /* HAX model level ioctl */ 39 | /* Get API version the HAX driver supports */ 40 | #define HAX_IOCTL_VERSION _IOWR(0, 0x20, struct hax_module_version) 41 | /* Create VM instance and return the vm_id */ 42 | #define HAX_IOCTL_CREATE_VM _IOWR(0, 0x21, int) 43 | /* Get HAXM capability information */ 44 | #define HAX_IOCTL_CAPABILITY _IOR(0, 0x23, struct hax_capabilityinfo) 45 | 46 | /* Pass down a VM_ID, create a VCPU instance for it */ 47 | #define HAX_VM_IOCTL_VCPU_CREATE _IOR(0, 0x80, int) 48 | /* 49 | * Allocate guest memory, the step of allocate guest memory is: 50 | * 1. QEMU will allocate the virtual address to cover the guest memory ranges 51 | * 2. QEMU passing down the virtual address and length in the 52 | * HAX_VM_IOCTL_ALLOC_RAM ioctl through hax_alloc_ram_info structure 53 | * 3. HAX driver populate physical memory for the virtual address range, and 54 | * lock these physical memory lock, so that they will not be swapped out 55 | * 4. HAX driver map the populated physical memory into kernel address space 56 | */ 57 | #define HAX_VM_IOCTL_ALLOC_RAM _IOWR(0, 0x81, struct hax_alloc_ram_info) 58 | /* 59 | * Setup translation between guest physical address and host physical address 60 | */ 61 | #define HAX_VM_IOCTL_SET_RAM _IOWR(0, 0x82, struct hax_set_ram_info) 62 | 63 | /* 64 | * QEMU notify HAXM driver of the API version currently in use, so that 65 | * HAXM driver will not present features that possibly not supported 66 | * by QEMU 67 | */ 68 | #define HAX_VM_IOCTL_NOTIFY_QEMU_VERSION _IOW(0, 0x84, struct hax_qemu_version) 69 | 70 | /* Run the guest in non-root mode */ 71 | #define HAX_VCPU_IOCTL_RUN _IO(0, 0xc0) 72 | /* Sync QEMU's guest MSR value to HAX driver */ 73 | #define HAX_VCPU_IOCTL_SET_MSRS _IOWR(0, 0xc1, struct hax_msr_data) 74 | /* Sync HAX driver's guest MSR value to QEMU */ 75 | #define HAX_VCPU_IOCTL_GET_MSRS _IOWR(0, 0xc2, struct hax_msr_data) 76 | #define HAX_VCPU_IOCTL_SET_FPU _IOW(0, 0xc3, struct fx_layout) 77 | #define HAX_VCPU_IOCTL_GET_FPU _IOR(0, 0xc4, struct fx_layout) 78 | 79 | /* Setup HAX tunnel, see structure hax_tunnel comments in hax-interface.h */ 80 | #define HAX_VCPU_IOCTL_SETUP_TUNNEL _IOWR(0, 0xc5, struct hax_tunnel_info) 81 | /* A interrupt need to be injected into guest */ 82 | #define HAX_VCPU_IOCTL_INTERRUPT _IOWR(0, 0xc6, uint32_t) 83 | #define HAX_VCPU_SET_REGS _IOWR(0, 0xc7, struct vcpu_state_t) 84 | #define HAX_VCPU_GET_REGS _IOWR(0, 0xc8, struct vcpu_state_t) 85 | 86 | #endif /* __HAX_UNIX_H */ 87 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/hax-i386.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2011, Intel Corporation 3 | ** 4 | ** This software is licensed under the terms of the GNU General Public 5 | ** License version 2, as published by the Free Software Foundation, and 6 | ** may be copied, distributed, and modified under those terms. 7 | ** 8 | ** This program is distributed in the hope that it will be useful, 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ** GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef _HAX_I386_H 15 | #define _HAX_I386_H 16 | 17 | #include "android/utils/debug.h" 18 | #include "exec/hax.h" 19 | 20 | #ifdef CONFIG_DARWIN 21 | typedef int hax_fd; 22 | #endif 23 | 24 | #ifdef CONFIG_WIN32 25 | typedef HANDLE hax_fd; 26 | #endif 27 | 28 | extern struct hax_state hax_global; 29 | struct hax_vcpu_state 30 | { 31 | hax_fd fd; 32 | int vcpu_id; 33 | int emulation_state; 34 | struct hax_tunnel *tunnel; 35 | unsigned char *iobuf; 36 | }; 37 | 38 | struct hax_state 39 | { 40 | hax_fd fd; /* the global hax device interface */ 41 | uint32_t version; 42 | struct hax_vm *vm; 43 | uint64_t mem_quota; 44 | }; 45 | 46 | #define HAX_MAX_VCPU 0x10 47 | #define MAX_VM_ID 0x40 48 | #define MAX_VCPU_ID 0x40 49 | 50 | struct hax_vm 51 | { 52 | hax_fd fd; 53 | int id; 54 | struct hax_vcpu_state *vcpus[HAX_MAX_VCPU]; 55 | }; 56 | 57 | /* Functions exported to host specific mode */ 58 | hax_fd hax_vcpu_get_fd(CPUState *cpu); 59 | int valid_hax_tunnel_size(uint16_t size); 60 | 61 | /* Host specific functions */ 62 | int hax_mod_version(struct hax_state *hax, struct hax_module_version *version); 63 | int hax_inject_interrupt(CPUState *cpu, int vector); 64 | struct hax_vm *hax_vm_create(struct hax_state *hax); 65 | int hax_vcpu_run(struct hax_vcpu_state *vcpu); 66 | int hax_vcpu_create(int id); 67 | int hax_sync_vcpu_state(CPUState *cpu, struct vcpu_state_t *state, int set); 68 | int hax_sync_msr(CPUState *cpu, struct hax_msr_data *msrs, int set); 69 | int hax_sync_fpu(CPUState *cpu, struct fx_layout *fl, int set); 70 | int hax_vm_destroy(struct hax_vm *vm); 71 | int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap); 72 | int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion); 73 | 74 | /* Common host function */ 75 | int hax_host_create_vm(struct hax_state *hax, int *vm_id); 76 | hax_fd hax_host_open_vm(struct hax_state *hax, int vm_id); 77 | int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid); 78 | hax_fd hax_host_open_vcpu(int vmid, int vcpuid); 79 | int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu); 80 | hax_fd hax_mod_open(void); 81 | 82 | 83 | #ifdef CONFIG_DARWIN 84 | #include "target-i386/hax-darwin.h" 85 | #endif 86 | 87 | #ifdef CONFIG_WIN32 88 | #include "target-i386/hax-windows.h" 89 | #endif 90 | 91 | #include "target-i386/hax-interface.h" 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/hax-windows.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2011, Intel Corporation 3 | ** 4 | ** This software is licensed under the terms of the GNU General Public 5 | ** License version 2, as published by the Free Software Foundation, and 6 | ** may be copied, distributed, and modified under those terms. 7 | ** 8 | ** This program is distributed in the hope that it will be useful, 9 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ** GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef __HAX_WINDOWS_H 15 | #define __HAX_WINDOWS_H 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define HAX_INVALID_FD INVALID_HANDLE_VALUE 26 | 27 | static inline void hax_mod_close(struct hax_state *hax) 28 | { 29 | CloseHandle(hax->fd); 30 | } 31 | 32 | static inline void hax_close_fd(hax_fd fd) 33 | { 34 | CloseHandle(fd); 35 | } 36 | 37 | static inline int hax_invalid_fd(hax_fd fd) 38 | { 39 | return (fd == INVALID_HANDLE_VALUE); 40 | } 41 | 42 | 43 | #define HAX_DEVICE_TYPE 0x4000 44 | 45 | /* See comments for the ioctl in hax-darwin.h */ 46 | #define HAX_IOCTL_VERSION CTL_CODE(HAX_DEVICE_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS) 47 | #define HAX_IOCTL_CREATE_VM CTL_CODE(HAX_DEVICE_TYPE, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS) 48 | #define HAX_IOCTL_CAPABILITY CTL_CODE(HAX_DEVICE_TYPE, 0x910, METHOD_BUFFERED, FILE_ANY_ACCESS) 49 | 50 | #define HAX_VM_IOCTL_VCPU_CREATE CTL_CODE(HAX_DEVICE_TYPE, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS) 51 | #define HAX_VM_IOCTL_ALLOC_RAM CTL_CODE(HAX_DEVICE_TYPE, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS) 52 | #define HAX_VM_IOCTL_SET_RAM CTL_CODE(HAX_DEVICE_TYPE, 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS) 53 | 54 | #define HAX_VCPU_IOCTL_RUN CTL_CODE(HAX_DEVICE_TYPE, 0x906, METHOD_BUFFERED, FILE_ANY_ACCESS) 55 | #define HAX_VCPU_IOCTL_SET_MSRS CTL_CODE(HAX_DEVICE_TYPE, 0x907, METHOD_BUFFERED, FILE_ANY_ACCESS) 56 | #define HAX_VCPU_IOCTL_GET_MSRS CTL_CODE(HAX_DEVICE_TYPE, 0x908, METHOD_BUFFERED, FILE_ANY_ACCESS) 57 | 58 | #define HAX_VCPU_IOCTL_SET_FPU CTL_CODE(HAX_DEVICE_TYPE, 0x909, METHOD_BUFFERED, FILE_ANY_ACCESS) 59 | #define HAX_VCPU_IOCTL_GET_FPU CTL_CODE(HAX_DEVICE_TYPE, 0x90a, METHOD_BUFFERED, FILE_ANY_ACCESS) 60 | 61 | #define HAX_VCPU_IOCTL_SETUP_TUNNEL CTL_CODE(HAX_DEVICE_TYPE, 0x90b, METHOD_BUFFERED, FILE_ANY_ACCESS) 62 | #define HAX_VCPU_IOCTL_INTERRUPT CTL_CODE(HAX_DEVICE_TYPE, 0x90c, METHOD_BUFFERED, FILE_ANY_ACCESS) 63 | #define HAX_VCPU_SET_REGS CTL_CODE(HAX_DEVICE_TYPE, 0x90d, METHOD_BUFFERED, FILE_ANY_ACCESS) 64 | #define HAX_VCPU_GET_REGS CTL_CODE(HAX_DEVICE_TYPE, 0x90e, METHOD_BUFFERED, FILE_ANY_ACCESS) 65 | 66 | #define HAX_VM_IOCTL_NOTIFY_QEMU_VERSION CTL_CODE(HAX_DEVICE_TYPE, 0x910, METHOD_BUFFERED, FILE_ANY_ACCESS) 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/helper.h: -------------------------------------------------------------------------------- 1 | #include "exec/def-helper.h" 2 | 3 | DEF_HELPER_FLAGS_2(cc_compute_all, TCG_CALL_NO_SE, i32, env, int) 4 | DEF_HELPER_FLAGS_2(cc_compute_c, TCG_CALL_NO_SE, i32, env, int) 5 | 6 | DEF_HELPER_0(lock, void) 7 | DEF_HELPER_0(unlock, void) 8 | DEF_HELPER_3(write_eflags, void, env, tl, i32) 9 | DEF_HELPER_1(read_eflags, tl, env) 10 | DEF_HELPER_2(divb_AL, void, env, tl) 11 | DEF_HELPER_2(idivb_AL, void, env, tl) 12 | DEF_HELPER_2(divw_AX, void, env, tl) 13 | DEF_HELPER_2(idivw_AX, void, env, tl) 14 | DEF_HELPER_2(divl_EAX, void, env, tl) 15 | DEF_HELPER_2(idivl_EAX, void, env, tl) 16 | #ifdef TARGET_X86_64 17 | DEF_HELPER_2(mulq_EAX_T0, void, env, tl) 18 | DEF_HELPER_2(imulq_EAX_T0, void, env, tl) 19 | DEF_HELPER_3(imulq_T0_T1, tl, env, tl, tl) 20 | DEF_HELPER_2(divq_EAX, void, env, tl) 21 | DEF_HELPER_2(idivq_EAX, void, env, tl) 22 | #endif 23 | 24 | DEF_HELPER_2(aam, void, env, int) 25 | DEF_HELPER_2(aad, void, env, int) 26 | DEF_HELPER_1(aaa, void, env) 27 | DEF_HELPER_1(aas, void, env) 28 | DEF_HELPER_1(daa, void, env) 29 | DEF_HELPER_1(das, void, env) 30 | 31 | DEF_HELPER_2(lsl, tl, env, tl) 32 | DEF_HELPER_2(lar, tl, env, tl) 33 | DEF_HELPER_2(verr, void, env, tl) 34 | DEF_HELPER_2(verw, void, env, tl) 35 | DEF_HELPER_2(lldt, void, env, int) 36 | DEF_HELPER_2(ltr, void, env, int) 37 | DEF_HELPER_3(load_seg, void, env, int, int) 38 | DEF_HELPER_4(ljmp_protected, void, env, int, tl, int) 39 | DEF_HELPER_5(lcall_real, void, env, int, tl, int, int) 40 | DEF_HELPER_5(lcall_protected, void, env, int, tl, int, int) 41 | DEF_HELPER_2(iret_real, void, env, int) 42 | DEF_HELPER_3(iret_protected, void, env, int, int) 43 | DEF_HELPER_3(lret_protected, void, env, int, int) 44 | DEF_HELPER_2(read_crN, tl, env, int) 45 | DEF_HELPER_3(write_crN, void, env, int, tl) 46 | DEF_HELPER_2(lmsw, void, env, tl) 47 | DEF_HELPER_1(clts, void, env) 48 | DEF_HELPER_3(movl_drN_T0, void, env, int, tl) 49 | DEF_HELPER_2(invlpg, void, env, tl) 50 | 51 | DEF_HELPER_4(enter_level, void, env, int, int, tl) 52 | #ifdef TARGET_X86_64 53 | DEF_HELPER_4(enter64_level, void, env, int, int, tl) 54 | #endif 55 | DEF_HELPER_1(sysenter, void, env) 56 | DEF_HELPER_2(sysexit, void, env, int) 57 | #ifdef TARGET_X86_64 58 | DEF_HELPER_2(syscall, void, env, int) 59 | DEF_HELPER_2(sysret, void, env, int) 60 | #endif 61 | DEF_HELPER_2(hlt, void, env, int) 62 | DEF_HELPER_2(monitor, void, env, tl) 63 | DEF_HELPER_2(mwait, void, env, int) 64 | DEF_HELPER_1(debug, void, env) 65 | DEF_HELPER_1(reset_rf, void, env) 66 | DEF_HELPER_3(raise_interrupt, void, env, int, int) 67 | DEF_HELPER_2(raise_exception, void, env, int) 68 | DEF_HELPER_1(cli, void, env) 69 | DEF_HELPER_1(sti, void, env) 70 | DEF_HELPER_1(set_inhibit_irq, void, env) 71 | DEF_HELPER_1(reset_inhibit_irq, void, env) 72 | DEF_HELPER_3(boundw, void, env, tl, int) 73 | DEF_HELPER_3(boundl, void, env, tl, int) 74 | DEF_HELPER_1(rsm, void, env) 75 | DEF_HELPER_2(into, void, env, int) 76 | DEF_HELPER_2(cmpxchg8b, void, env, tl) 77 | #ifdef TARGET_X86_64 78 | DEF_HELPER_2(cmpxchg16b, void, env, tl) 79 | #endif 80 | DEF_HELPER_1(single_step, void, env) 81 | DEF_HELPER_1(cpuid, void, env) 82 | DEF_HELPER_1(rdtsc, void, env) 83 | DEF_HELPER_1(rdpmc, void, env) 84 | DEF_HELPER_1(rdmsr, void, env) 85 | DEF_HELPER_1(wrmsr, void, env) 86 | 87 | DEF_HELPER_2(check_iob, void, env, i32) 88 | DEF_HELPER_2(check_iow, void, env, i32) 89 | DEF_HELPER_2(check_iol, void, env, i32) 90 | DEF_HELPER_2(outb, void, i32, i32) 91 | DEF_HELPER_1(inb, tl, i32) 92 | DEF_HELPER_2(outw, void, i32, i32) 93 | DEF_HELPER_1(inw, tl, i32) 94 | DEF_HELPER_2(outl, void, i32, i32) 95 | DEF_HELPER_1(inl, tl, i32) 96 | 97 | DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64) 98 | DEF_HELPER_3(vmexit, void, env, i32, i64) 99 | DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32) 100 | DEF_HELPER_3(vmrun, void, env, int, int) 101 | DEF_HELPER_1(vmmcall, void, env) 102 | DEF_HELPER_2(vmload, void, env, int) 103 | DEF_HELPER_2(vmsave, void, env, int) 104 | DEF_HELPER_1(stgi, void, env) 105 | DEF_HELPER_1(clgi, void, env) 106 | DEF_HELPER_1(skinit, void, env) 107 | DEF_HELPER_2(invlpga, void, env, int) 108 | 109 | /* x86 FPU */ 110 | 111 | DEF_HELPER_2(flds_FT0, void, env, i32) 112 | DEF_HELPER_2(fldl_FT0, void, env, i64) 113 | DEF_HELPER_2(fildl_FT0, void, env, s32) 114 | DEF_HELPER_2(flds_ST0, void, env, i32) 115 | DEF_HELPER_2(fldl_ST0, void, env, i64) 116 | DEF_HELPER_2(fildl_ST0, void, env, s32) 117 | DEF_HELPER_2(fildll_ST0, void, env, s64) 118 | DEF_HELPER_1(fsts_ST0, i32, env) 119 | DEF_HELPER_1(fstl_ST0, i64, env) 120 | DEF_HELPER_1(fist_ST0, s32, env) 121 | DEF_HELPER_1(fistl_ST0, s32, env) 122 | DEF_HELPER_1(fistll_ST0, s64, env) 123 | DEF_HELPER_1(fistt_ST0, s32, env) 124 | DEF_HELPER_1(fisttl_ST0, s32, env) 125 | DEF_HELPER_1(fisttll_ST0, s64, env) 126 | DEF_HELPER_2(fldt_ST0, void, env, tl) 127 | DEF_HELPER_2(fstt_ST0, void, env, tl) 128 | DEF_HELPER_1(fpush, void, env) 129 | DEF_HELPER_1(fpop, void, env) 130 | DEF_HELPER_1(fdecstp, void, env) 131 | DEF_HELPER_1(fincstp, void, env) 132 | DEF_HELPER_2(ffree_STN, void, env, int) 133 | DEF_HELPER_1(fmov_ST0_FT0, void, env) 134 | DEF_HELPER_2(fmov_FT0_STN, void, env, int) 135 | DEF_HELPER_2(fmov_ST0_STN, void, env, int) 136 | DEF_HELPER_2(fmov_STN_ST0, void, env, int) 137 | DEF_HELPER_2(fxchg_ST0_STN, void, env, int) 138 | DEF_HELPER_1(fcom_ST0_FT0, void, env) 139 | DEF_HELPER_1(fucom_ST0_FT0, void, env) 140 | DEF_HELPER_1(fcomi_ST0_FT0, void, env) 141 | DEF_HELPER_1(fucomi_ST0_FT0, void, env) 142 | DEF_HELPER_1(fadd_ST0_FT0, void, env) 143 | DEF_HELPER_1(fmul_ST0_FT0, void, env) 144 | DEF_HELPER_1(fsub_ST0_FT0, void, env) 145 | DEF_HELPER_1(fsubr_ST0_FT0, void, env) 146 | DEF_HELPER_1(fdiv_ST0_FT0, void, env) 147 | DEF_HELPER_1(fdivr_ST0_FT0, void, env) 148 | DEF_HELPER_2(fadd_STN_ST0, void, env, int) 149 | DEF_HELPER_2(fmul_STN_ST0, void, env, int) 150 | DEF_HELPER_2(fsub_STN_ST0, void, env, int) 151 | DEF_HELPER_2(fsubr_STN_ST0, void, env, int) 152 | DEF_HELPER_2(fdiv_STN_ST0, void, env, int) 153 | DEF_HELPER_2(fdivr_STN_ST0, void, env, int) 154 | DEF_HELPER_1(fchs_ST0, void, env) 155 | DEF_HELPER_1(fabs_ST0, void, env) 156 | DEF_HELPER_1(fxam_ST0, void, env) 157 | DEF_HELPER_1(fld1_ST0, void, env) 158 | DEF_HELPER_1(fldl2t_ST0, void, env) 159 | DEF_HELPER_1(fldl2e_ST0, void, env) 160 | DEF_HELPER_1(fldpi_ST0, void, env) 161 | DEF_HELPER_1(fldlg2_ST0, void, env) 162 | DEF_HELPER_1(fldln2_ST0, void, env) 163 | DEF_HELPER_1(fldz_ST0, void, env) 164 | DEF_HELPER_1(fldz_FT0, void, env) 165 | DEF_HELPER_1(fnstsw, i32, env) 166 | DEF_HELPER_1(fnstcw, i32, env) 167 | DEF_HELPER_2(fldcw, void, env, i32) 168 | DEF_HELPER_1(fclex, void, env) 169 | DEF_HELPER_1(fwait, void, env) 170 | DEF_HELPER_1(fninit, void, env) 171 | DEF_HELPER_2(fbld_ST0, void, env, tl) 172 | DEF_HELPER_2(fbst_ST0, void, env, tl) 173 | DEF_HELPER_1(f2xm1, void, env) 174 | DEF_HELPER_1(fyl2x, void, env) 175 | DEF_HELPER_1(fptan, void, env) 176 | DEF_HELPER_1(fpatan, void, env) 177 | DEF_HELPER_1(fxtract, void, env) 178 | DEF_HELPER_1(fprem1, void, env) 179 | DEF_HELPER_1(fprem, void, env) 180 | DEF_HELPER_1(fyl2xp1, void, env) 181 | DEF_HELPER_1(fsqrt, void, env) 182 | DEF_HELPER_1(fsincos, void, env) 183 | DEF_HELPER_1(frndint, void, env) 184 | DEF_HELPER_1(fscale, void, env) 185 | DEF_HELPER_1(fsin, void, env) 186 | DEF_HELPER_1(fcos, void, env) 187 | DEF_HELPER_3(fstenv, void, env, tl, int) 188 | DEF_HELPER_3(fldenv, void, env, tl, int) 189 | DEF_HELPER_3(fsave, void, env, tl, int) 190 | DEF_HELPER_3(frstor, void, env, tl, int) 191 | DEF_HELPER_3(fxsave, void, env, tl, int) 192 | DEF_HELPER_3(fxrstor, void, env, tl, int) 193 | DEF_HELPER_1(bsf, tl, tl) 194 | DEF_HELPER_1(bsr, tl, tl) 195 | 196 | /* MMX/SSE */ 197 | 198 | DEF_HELPER_1(enter_mmx, void, env) 199 | DEF_HELPER_1(emms, void, env) 200 | DEF_HELPER_3(movq, void, env, ptr, ptr) 201 | 202 | #define SHIFT 0 203 | #include "ops_sse_header.h" 204 | #define SHIFT 1 205 | #include "ops_sse_header.h" 206 | 207 | DEF_HELPER_3(rclb, tl, env, tl, tl) 208 | DEF_HELPER_3(rclw, tl, env, tl, tl) 209 | DEF_HELPER_3(rcll, tl, env, tl, tl) 210 | DEF_HELPER_3(rcrb, tl, env, tl, tl) 211 | DEF_HELPER_3(rcrw, tl, env, tl, tl) 212 | DEF_HELPER_3(rcrl, tl, env, tl, tl) 213 | #ifdef TARGET_X86_64 214 | DEF_HELPER_3(rclq, tl, env, tl, tl) 215 | DEF_HELPER_3(rcrq, tl, env, tl, tl) 216 | #endif 217 | 218 | #include "exec/def-helper.h" 219 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/kvm-gs-restore.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "qemu-common.h" 4 | 5 | #ifdef CONFIG_KVM_GS_RESTORE 6 | 7 | #define INVALID_GS_REG 0xffff 8 | #define KVM_GS_RESTORE_NODETECTED 0x1 9 | #define KVM_GS_RESTORE_NO 0x2 10 | #define KVM_GS_RESTORE_YES 0x3 11 | int initial_gs = INVALID_GS_REG; 12 | int gs_need_restore = KVM_GS_RESTORE_NODETECTED; 13 | 14 | static void restoregs(int gs) 15 | { 16 | asm("movl %0, %%gs"::"r"(gs)); 17 | } 18 | 19 | static unsigned int _getgs() 20 | { 21 | unsigned int gs = 0; 22 | asm("movl %%gs,%0" :"=r"(gs):); 23 | return gs; 24 | } 25 | 26 | /* No fprintf or any system call before the gs is restored successfully */ 27 | static void check_and_restore_gs(void) 28 | { 29 | if (gs_need_restore == KVM_GS_RESTORE_NO) 30 | return; 31 | 32 | restoregs(initial_gs); 33 | } 34 | 35 | struct sigact_status 36 | { 37 | unsigned int sigaction:1; 38 | __sighandler_t old_handler; 39 | void (*old_sigaction) (int, siginfo_t *, void *); 40 | }; 41 | static struct sigact_status o_sigact[SIGUNUSED]; 42 | 43 | static void temp_sig_handler(int signum) 44 | { 45 | /* !!! must restore gs firstly */ 46 | check_and_restore_gs(); 47 | 48 | if (signum < SIGHUP || signum >= SIGUNUSED) 49 | { 50 | fprintf(stderr, "Invalid signal %x in temp_sig_handler\n", signum); 51 | abort(); 52 | } 53 | 54 | if ( !o_sigact[signum].sigaction && o_sigact[signum].old_handler) 55 | o_sigact[signum].old_handler(signum); 56 | else 57 | { 58 | fprintf(stderr, "Invalid signal in temp_sig_handler: " 59 | "signal %x sa_info %s!!\n", 60 | signum, o_sigact[signum].sigaction ? "set":"not set" ); 61 | abort(); 62 | } 63 | } 64 | 65 | static void temp_sig_sigaction(int signum, siginfo_t *info, void *ucontext) 66 | { 67 | /* !!! must restore gs firstly */ 68 | check_and_restore_gs(); 69 | 70 | if (signum < SIGHUP || signum >= SIGUNUSED) 71 | { 72 | fprintf(stderr, "Invalid signal %x in temp_sig_sigaction\n", signum); 73 | abort(); 74 | } 75 | 76 | if ( o_sigact[signum].sigaction && o_sigact[signum].old_sigaction ) 77 | o_sigact[signum].old_sigaction(signum, info, ucontext); 78 | else 79 | { 80 | fprintf(stderr, "Invalid signal in temp_sig_sigaction: " 81 | "signal %x sa_info %s!!\n", 82 | signum, o_sigact[signum].sigaction ? "set":"not set" ); 83 | abort(); 84 | } 85 | } 86 | 87 | static int sig_taken = 0; 88 | 89 | static int take_signal_handler(void) 90 | { 91 | int i; 92 | 93 | if (gs_need_restore == KVM_GS_RESTORE_NO) 94 | return 0; 95 | if (sig_taken) 96 | return 0; 97 | 98 | memset(o_sigact, 0, sizeof(o_sigact)); 99 | 100 | /* SIGHUP is 1 in POSIX */ 101 | for (i = SIGHUP; i < SIGUNUSED; i++) 102 | { 103 | int sigret; 104 | struct sigaction act, old_act; 105 | 106 | sigret = sigaction(i, NULL, &old_act); 107 | if (sigret) 108 | continue; 109 | /* We don't need take the handler for default or ignore signals */ 110 | if ( !(old_act.sa_flags & SA_SIGINFO) && 111 | ((old_act.sa_handler == SIG_IGN ) || 112 | (old_act.sa_handler == SIG_DFL))) 113 | continue; 114 | 115 | memcpy(&act, &old_act, sizeof(struct sigaction)); 116 | 117 | if (old_act.sa_flags & SA_SIGINFO) 118 | { 119 | o_sigact[i].old_sigaction = old_act.sa_sigaction; 120 | o_sigact[i].sigaction = 1; 121 | act.sa_sigaction = temp_sig_sigaction; 122 | } 123 | else 124 | { 125 | o_sigact[i].old_handler = old_act.sa_handler; 126 | act.sa_handler = temp_sig_handler; 127 | } 128 | 129 | sigaction(i, &act, NULL); 130 | continue; 131 | } 132 | sig_taken = 1; 133 | return 1; 134 | } 135 | 136 | int gs_base_pre_run(void) 137 | { 138 | if (unlikely(initial_gs == INVALID_GS_REG) ) 139 | { 140 | initial_gs = _getgs(); 141 | /* 142 | * As 2.6.35-28 lucid will get correct gs but clobbered GS_BASE 143 | * we have to always re-write the gs base 144 | */ 145 | if (initial_gs == 0x0) 146 | gs_need_restore = KVM_GS_RESTORE_NO; 147 | else 148 | gs_need_restore = KVM_GS_RESTORE_YES; 149 | } 150 | 151 | take_signal_handler(); 152 | return 0; 153 | } 154 | 155 | int gs_base_post_run(void) 156 | { 157 | check_and_restore_gs(); 158 | return 0; 159 | } 160 | 161 | /* 162 | * ioctl may update errno, which is in thread local storage and 163 | * requires gs register, we have to provide our own ioctl 164 | * XXX should "call %%gs:$0x10" be replaced with call to vsyscall 165 | * page, which is more generic and clean? 166 | */ 167 | int no_gs_ioctl(int fd, int type, void *arg) 168 | { 169 | int ret=0; 170 | 171 | asm( 172 | "movl %3, %%edx;\n" 173 | "movl %2, %%ecx;\n" 174 | "movl %1, %%ebx;\n" 175 | "movl $0x36, %%eax;\n" 176 | "call *%%gs:0x10;\n" 177 | "movl %%eax, %0\n" 178 | : "=m"(ret) 179 | :"m"(fd),"m"(type),"m"(arg) 180 | :"%edx","%ecx","%eax","%ebx" 181 | ); 182 | 183 | return ret; 184 | } 185 | 186 | #endif 187 | 188 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/kvm-gs-restore.h: -------------------------------------------------------------------------------- 1 | #ifndef _KVM_GS_RESTORE_H 2 | #define _KVM_GS_RESTORE_H 3 | 4 | #ifdef CONFIG_KVM_GS_RESTORE 5 | int no_gs_ioctl(int fd, int type, void *arg); 6 | int gs_base_post_run(void); 7 | int gs_base_pre_run(void); 8 | extern int gs_need_restore; 9 | #define KVM_GS_RESTORE_NO 0x2 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/machine.c: -------------------------------------------------------------------------------- 1 | #include "hw/hw.h" 2 | #include "hw/boards.h" 3 | #include "hw/i386/pc.h" 4 | #include "hw/isa/isa.h" 5 | 6 | #include "cpu.h" 7 | #include "sysemu/kvm.h" 8 | 9 | static void cpu_put_seg(QEMUFile *f, SegmentCache *dt) 10 | { 11 | qemu_put_be32(f, dt->selector); 12 | qemu_put_betl(f, dt->base); 13 | qemu_put_be32(f, dt->limit); 14 | qemu_put_be32(f, dt->flags); 15 | } 16 | 17 | static void cpu_get_seg(QEMUFile *f, SegmentCache *dt) 18 | { 19 | dt->selector = qemu_get_be32(f); 20 | dt->base = qemu_get_betl(f); 21 | dt->limit = qemu_get_be32(f); 22 | dt->flags = qemu_get_be32(f); 23 | } 24 | 25 | void cpu_save(QEMUFile *f, void *opaque) 26 | { 27 | CPUX86State *env = opaque; 28 | uint16_t fptag, fpus, fpuc, fpregs_format; 29 | uint32_t hflags; 30 | int32_t a20_mask; 31 | int i; 32 | 33 | cpu_synchronize_state(ENV_GET_CPU(env), 0); 34 | 35 | for(i = 0; i < CPU_NB_REGS; i++) 36 | qemu_put_betls(f, &env->regs[i]); 37 | qemu_put_betls(f, &env->eip); 38 | qemu_put_betls(f, &env->eflags); 39 | hflags = env->hflags; /* XXX: suppress most of the redundant hflags */ 40 | qemu_put_be32s(f, &hflags); 41 | 42 | /* FPU */ 43 | fpuc = env->fpuc; 44 | fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; 45 | fptag = 0; 46 | for(i = 0; i < 8; i++) { 47 | fptag |= ((!env->fptags[i]) << i); 48 | } 49 | 50 | qemu_put_be16s(f, &fpuc); 51 | qemu_put_be16s(f, &fpus); 52 | qemu_put_be16s(f, &fptag); 53 | 54 | fpregs_format = 1; 55 | qemu_put_be16s(f, &fpregs_format); 56 | 57 | for(i = 0; i < 8; i++) { 58 | /* if we use doubles for float emulation, we save the doubles to 59 | avoid losing information in case of MMX usage. It can give 60 | problems if the image is restored on a CPU where long 61 | doubles are used instead. */ 62 | qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0)); 63 | } 64 | 65 | for(i = 0; i < 6; i++) 66 | cpu_put_seg(f, &env->segs[i]); 67 | cpu_put_seg(f, &env->ldt); 68 | cpu_put_seg(f, &env->tr); 69 | cpu_put_seg(f, &env->gdt); 70 | cpu_put_seg(f, &env->idt); 71 | 72 | qemu_put_be32s(f, &env->sysenter_cs); 73 | qemu_put_betls(f, &env->sysenter_esp); 74 | qemu_put_betls(f, &env->sysenter_eip); 75 | 76 | qemu_put_betls(f, &env->cr[0]); 77 | qemu_put_betls(f, &env->cr[2]); 78 | qemu_put_betls(f, &env->cr[3]); 79 | qemu_put_betls(f, &env->cr[4]); 80 | 81 | for(i = 0; i < 8; i++) 82 | qemu_put_betls(f, &env->dr[i]); 83 | 84 | /* MMU */ 85 | a20_mask = (int32_t) env->a20_mask; 86 | qemu_put_sbe32s(f, &a20_mask); 87 | 88 | /* XMM */ 89 | qemu_put_be32s(f, &env->mxcsr); 90 | for(i = 0; i < CPU_NB_REGS; i++) { 91 | qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0)); 92 | qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1)); 93 | } 94 | 95 | #ifdef TARGET_X86_64 96 | qemu_put_be64s(f, &env->efer); 97 | qemu_put_be64s(f, &env->star); 98 | qemu_put_be64s(f, &env->lstar); 99 | qemu_put_be64s(f, &env->cstar); 100 | qemu_put_be64s(f, &env->fmask); 101 | qemu_put_be64s(f, &env->kernelgsbase); 102 | #endif 103 | qemu_put_be32s(f, &env->smbase); 104 | 105 | qemu_put_be64s(f, &env->pat); 106 | qemu_put_be32s(f, &env->hflags2); 107 | 108 | qemu_put_be64s(f, &env->vm_hsave); 109 | qemu_put_be64s(f, &env->vm_vmcb); 110 | qemu_put_be64s(f, &env->tsc_offset); 111 | qemu_put_be64s(f, &env->intercept); 112 | qemu_put_be16s(f, &env->intercept_cr_read); 113 | qemu_put_be16s(f, &env->intercept_cr_write); 114 | qemu_put_be16s(f, &env->intercept_dr_read); 115 | qemu_put_be16s(f, &env->intercept_dr_write); 116 | qemu_put_be32s(f, &env->intercept_exceptions); 117 | qemu_put_8s(f, &env->v_tpr); 118 | 119 | /* MTRRs */ 120 | for(i = 0; i < 11; i++) 121 | qemu_put_be64s(f, &env->mtrr_fixed[i]); 122 | qemu_put_be64s(f, &env->mtrr_deftype); 123 | for(i = 0; i < 8; i++) { 124 | qemu_put_be64s(f, &env->mtrr_var[i].base); 125 | qemu_put_be64s(f, &env->mtrr_var[i].mask); 126 | } 127 | 128 | for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) { 129 | qemu_put_be64s(f, &env->interrupt_bitmap[i]); 130 | } 131 | qemu_put_be64s(f, &env->tsc); 132 | qemu_put_be32s(f, &env->mp_state); 133 | 134 | /* MCE */ 135 | qemu_put_be64s(f, &env->mcg_cap); 136 | if (env->mcg_cap) { 137 | qemu_put_be64s(f, &env->mcg_status); 138 | qemu_put_be64s(f, &env->mcg_ctl); 139 | for (i = 0; i < (env->mcg_cap & 0xff); i++) { 140 | qemu_put_be64s(f, &env->mce_banks[4*i]); 141 | qemu_put_be64s(f, &env->mce_banks[4*i + 1]); 142 | qemu_put_be64s(f, &env->mce_banks[4*i + 2]); 143 | qemu_put_be64s(f, &env->mce_banks[4*i + 3]); 144 | } 145 | } 146 | } 147 | 148 | int cpu_load(QEMUFile *f, void *opaque, int version_id) 149 | { 150 | CPUX86State *env = opaque; 151 | int i, guess_mmx; 152 | uint32_t hflags; 153 | uint16_t fpus, fpuc, fptag, fpregs_format; 154 | int32_t a20_mask; 155 | 156 | if (version_id < 3 || version_id > CPU_SAVE_VERSION) 157 | return -EINVAL; 158 | for(i = 0; i < CPU_NB_REGS; i++) 159 | qemu_get_betls(f, &env->regs[i]); 160 | qemu_get_betls(f, &env->eip); 161 | qemu_get_betls(f, &env->eflags); 162 | qemu_get_be32s(f, &hflags); 163 | 164 | qemu_get_be16s(f, &fpuc); 165 | qemu_get_be16s(f, &fpus); 166 | qemu_get_be16s(f, &fptag); 167 | qemu_get_be16s(f, &fpregs_format); 168 | 169 | /* NOTE: we cannot always restore the FPU state if the image come 170 | from a host with a different 'USE_X86LDOUBLE' define. We guess 171 | if we are in an MMX state to restore correctly in that case. */ 172 | guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0); 173 | for(i = 0; i < 8; i++) { 174 | uint64_t mant; 175 | uint16_t exp; 176 | 177 | switch(fpregs_format) { 178 | case 0: 179 | mant = qemu_get_be64(f); 180 | exp = qemu_get_be16(f); 181 | /* difficult case */ 182 | if (guess_mmx) 183 | env->fpregs[i].mmx.MMX_Q(0) = mant; 184 | else 185 | env->fpregs[i].d = cpu_set_fp80(mant, exp); 186 | break; 187 | case 1: 188 | mant = qemu_get_be64(f); 189 | env->fpregs[i].mmx.MMX_Q(0) = mant; 190 | break; 191 | default: 192 | return -EINVAL; 193 | } 194 | } 195 | 196 | env->fpuc = fpuc; 197 | /* XXX: restore FPU round state */ 198 | env->fpstt = (fpus >> 11) & 7; 199 | env->fpus = fpus & ~0x3800; 200 | fptag ^= 0xff; 201 | for(i = 0; i < 8; i++) { 202 | env->fptags[i] = (fptag >> i) & 1; 203 | } 204 | 205 | for(i = 0; i < 6; i++) 206 | cpu_get_seg(f, &env->segs[i]); 207 | cpu_get_seg(f, &env->ldt); 208 | cpu_get_seg(f, &env->tr); 209 | cpu_get_seg(f, &env->gdt); 210 | cpu_get_seg(f, &env->idt); 211 | 212 | qemu_get_be32s(f, &env->sysenter_cs); 213 | if (version_id >= 7) { 214 | qemu_get_betls(f, &env->sysenter_esp); 215 | qemu_get_betls(f, &env->sysenter_eip); 216 | } else { 217 | env->sysenter_esp = qemu_get_be32(f); 218 | env->sysenter_eip = qemu_get_be32(f); 219 | } 220 | 221 | qemu_get_betls(f, &env->cr[0]); 222 | qemu_get_betls(f, &env->cr[2]); 223 | qemu_get_betls(f, &env->cr[3]); 224 | qemu_get_betls(f, &env->cr[4]); 225 | 226 | for(i = 0; i < 8; i++) 227 | qemu_get_betls(f, &env->dr[i]); 228 | cpu_breakpoint_remove_all(env, BP_CPU); 229 | cpu_watchpoint_remove_all(env, BP_CPU); 230 | for (i = 0; i < 4; i++) 231 | hw_breakpoint_insert(env, i); 232 | 233 | /* MMU */ 234 | qemu_get_sbe32s(f, &a20_mask); 235 | env->a20_mask = a20_mask; 236 | 237 | qemu_get_be32s(f, &env->mxcsr); 238 | for(i = 0; i < CPU_NB_REGS; i++) { 239 | qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0)); 240 | qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1)); 241 | } 242 | 243 | #ifdef TARGET_X86_64 244 | qemu_get_be64s(f, &env->efer); 245 | qemu_get_be64s(f, &env->star); 246 | qemu_get_be64s(f, &env->lstar); 247 | qemu_get_be64s(f, &env->cstar); 248 | qemu_get_be64s(f, &env->fmask); 249 | qemu_get_be64s(f, &env->kernelgsbase); 250 | #endif 251 | if (version_id >= 4) { 252 | qemu_get_be32s(f, &env->smbase); 253 | } 254 | if (version_id >= 5) { 255 | qemu_get_be64s(f, &env->pat); 256 | qemu_get_be32s(f, &env->hflags2); 257 | if (version_id < 6) 258 | qemu_get_be32s(f, &ENV_GET_CPU(env)->halted); 259 | 260 | qemu_get_be64s(f, &env->vm_hsave); 261 | qemu_get_be64s(f, &env->vm_vmcb); 262 | qemu_get_be64s(f, &env->tsc_offset); 263 | qemu_get_be64s(f, &env->intercept); 264 | qemu_get_be16s(f, &env->intercept_cr_read); 265 | qemu_get_be16s(f, &env->intercept_cr_write); 266 | qemu_get_be16s(f, &env->intercept_dr_read); 267 | qemu_get_be16s(f, &env->intercept_dr_write); 268 | qemu_get_be32s(f, &env->intercept_exceptions); 269 | qemu_get_8s(f, &env->v_tpr); 270 | } 271 | 272 | if (version_id >= 8) { 273 | /* MTRRs */ 274 | for(i = 0; i < 11; i++) 275 | qemu_get_be64s(f, &env->mtrr_fixed[i]); 276 | qemu_get_be64s(f, &env->mtrr_deftype); 277 | for(i = 0; i < 8; i++) { 278 | qemu_get_be64s(f, &env->mtrr_var[i].base); 279 | qemu_get_be64s(f, &env->mtrr_var[i].mask); 280 | } 281 | } 282 | if (version_id >= 9) { 283 | for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) { 284 | qemu_get_be64s(f, &env->interrupt_bitmap[i]); 285 | } 286 | qemu_get_be64s(f, &env->tsc); 287 | qemu_get_be32s(f, &env->mp_state); 288 | } 289 | 290 | if (version_id >= 10) { 291 | qemu_get_be64s(f, &env->mcg_cap); 292 | if (env->mcg_cap) { 293 | qemu_get_be64s(f, &env->mcg_status); 294 | qemu_get_be64s(f, &env->mcg_ctl); 295 | for (i = 0; i < (env->mcg_cap & 0xff); i++) { 296 | qemu_get_be64s(f, &env->mce_banks[4*i]); 297 | qemu_get_be64s(f, &env->mce_banks[4*i + 1]); 298 | qemu_get_be64s(f, &env->mce_banks[4*i + 2]); 299 | qemu_get_be64s(f, &env->mce_banks[4*i + 3]); 300 | } 301 | } 302 | } 303 | 304 | 305 | /* XXX: ensure compatiblity for halted bit ? */ 306 | /* XXX: compute redundant hflags bits */ 307 | env->hflags = hflags; 308 | tlb_flush(env, 1); 309 | cpu_synchronize_state(ENV_GET_CPU(env), 1); 310 | return 0; 311 | } 312 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/mem_helper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * x86 memory access helpers 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | 20 | #include "cpu.h" 21 | #include "helper.h" 22 | 23 | #if !defined(CONFIG_USER_ONLY) 24 | #include "exec/softmmu_exec.h" 25 | #endif /* !defined(CONFIG_USER_ONLY) */ 26 | 27 | /* broken thread support */ 28 | 29 | static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; 30 | 31 | void helper_lock(void) 32 | { 33 | spin_lock(&global_cpu_lock); 34 | } 35 | 36 | void helper_unlock(void) 37 | { 38 | spin_unlock(&global_cpu_lock); 39 | } 40 | 41 | void helper_cmpxchg8b(CPUX86State *env, target_ulong a0) 42 | { 43 | uint64_t d; 44 | int eflags; 45 | 46 | eflags = helper_cc_compute_all(env, CC_OP); 47 | d = cpu_ldq_data(env, a0); 48 | if (d == (((uint64_t)EDX << 32) | (uint32_t)EAX)) { 49 | cpu_stq_data(env, a0, ((uint64_t)ECX << 32) | (uint32_t)EBX); 50 | eflags |= CC_Z; 51 | } else { 52 | /* always do the store */ 53 | cpu_stq_data(env, a0, d); 54 | EDX = (uint32_t)(d >> 32); 55 | EAX = (uint32_t)d; 56 | eflags &= ~CC_Z; 57 | } 58 | CC_SRC = eflags; 59 | } 60 | 61 | #ifdef TARGET_X86_64 62 | void helper_cmpxchg16b(CPUX86State *env, target_ulong a0) 63 | { 64 | uint64_t d0, d1; 65 | int eflags; 66 | 67 | if ((a0 & 0xf) != 0) 68 | raise_exception(env, EXCP0D_GPF); 69 | eflags = helper_cc_compute_all(env, CC_OP); 70 | d0 = cpu_ldq_data(env, a0); 71 | d1 = cpu_ldq_data(env, a0 + 8); 72 | if (d0 == EAX && d1 == EDX) { 73 | cpu_stq_data(env, a0, EBX); 74 | cpu_stq_data(env, a0 + 8, ECX); 75 | eflags |= CC_Z; 76 | } else { 77 | /* always do the store */ 78 | cpu_stq_data(env, a0, d0); 79 | cpu_stq_data(env, a0 + 8, d1); 80 | EDX = d1; 81 | EAX = d0; 82 | eflags &= ~CC_Z; 83 | } 84 | CC_SRC = eflags; 85 | } 86 | #endif 87 | 88 | void helper_boundw(CPUX86State *env, target_ulong a0, int v) 89 | { 90 | int low, high; 91 | low = cpu_ldsw_data(env, a0); 92 | high = cpu_ldsw_data(env, a0 + 2); 93 | v = (int16_t)v; 94 | if (v < low || v > high) { 95 | raise_exception(env, EXCP05_BOUND); 96 | } 97 | } 98 | 99 | void helper_boundl(CPUX86State *env, target_ulong a0, int v) 100 | { 101 | int low, high; 102 | low = cpu_ldl_data(env, a0); 103 | high = cpu_ldl_data(env, a0 + 4); 104 | if (v < low || v > high) { 105 | raise_exception(env, EXCP05_BOUND); 106 | } 107 | } 108 | 109 | #if !defined(CONFIG_USER_ONLY) 110 | 111 | #define MMUSUFFIX _mmu 112 | 113 | #define SHIFT 0 114 | #include "exec/softmmu_template.h" 115 | 116 | #define SHIFT 1 117 | #include "exec/softmmu_template.h" 118 | 119 | #define SHIFT 2 120 | #include "exec/softmmu_template.h" 121 | 122 | #define SHIFT 3 123 | #include "exec/softmmu_template.h" 124 | 125 | #endif 126 | 127 | #if !defined(CONFIG_USER_ONLY) 128 | /* try to fill the TLB and return an exception if error. If retaddr is 129 | NULL, it means that the function was called in C code (i.e. not 130 | from generated code or from helper.c) */ 131 | /* XXX: fix it to restore all registers */ 132 | void tlb_fill(CPUX86State* env, target_ulong addr, int is_write, int mmu_idx, 133 | uintptr_t retaddr) 134 | { 135 | int ret; 136 | 137 | ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx); 138 | if (ret) { 139 | if (retaddr) { 140 | /* now we have a real cpu fault */ 141 | cpu_restore_state(env, retaddr); 142 | } 143 | raise_exception_err(env, env->exception_index, env->error_code); 144 | } 145 | } 146 | #endif 147 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/shift_helper_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * i386 helpers 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA 19 | */ 20 | #define DATA_BITS (1 << (3 + SHIFT)) 21 | #define SHIFT_MASK (DATA_BITS - 1) 22 | #define SIGN_MASK (((target_ulong)1) << (DATA_BITS - 1)) 23 | #if DATA_BITS <= 32 24 | #define SHIFT1_MASK 0x1f 25 | #else 26 | #define SHIFT1_MASK 0x3f 27 | #endif 28 | 29 | #if DATA_BITS == 8 30 | #define SUFFIX b 31 | #define DATA_TYPE uint8_t 32 | #define DATA_STYPE int8_t 33 | #define DATA_MASK 0xff 34 | #elif DATA_BITS == 16 35 | #define SUFFIX w 36 | #define DATA_TYPE uint16_t 37 | #define DATA_STYPE int16_t 38 | #define DATA_MASK 0xffff 39 | #elif DATA_BITS == 32 40 | #define SUFFIX l 41 | #define DATA_TYPE uint32_t 42 | #define DATA_STYPE int32_t 43 | #define DATA_MASK 0xffffffff 44 | #elif DATA_BITS == 64 45 | #define SUFFIX q 46 | #define DATA_TYPE uint64_t 47 | #define DATA_STYPE int64_t 48 | #define DATA_MASK 0xffffffffffffffffULL 49 | #else 50 | #error unhandled operand size 51 | #endif 52 | 53 | /* shifts */ 54 | 55 | target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, 56 | target_ulong t0, target_ulong t1) 57 | { 58 | int count, eflags; 59 | target_ulong src; 60 | target_long res; 61 | 62 | count = t1 & SHIFT1_MASK; 63 | #if DATA_BITS == 16 64 | count = rclw_table[count]; 65 | #elif DATA_BITS == 8 66 | count = rclb_table[count]; 67 | #endif 68 | if (count) { 69 | eflags = env->cc_src; 70 | t0 &= DATA_MASK; 71 | src = t0; 72 | res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1)); 73 | if (count > 1) 74 | res |= t0 >> (DATA_BITS + 1 - count); 75 | t0 = res; 76 | env->cc_src = (eflags & ~(CC_C | CC_O)) | 77 | (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) | 78 | ((src >> (DATA_BITS - count)) & CC_C); 79 | } 80 | return t0; 81 | } 82 | 83 | target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, 84 | target_ulong t0, target_ulong t1) 85 | { 86 | int count, eflags; 87 | target_ulong src; 88 | target_long res; 89 | 90 | count = t1 & SHIFT1_MASK; 91 | #if DATA_BITS == 16 92 | count = rclw_table[count]; 93 | #elif DATA_BITS == 8 94 | count = rclb_table[count]; 95 | #endif 96 | if (count) { 97 | eflags = env->cc_src; 98 | t0 &= DATA_MASK; 99 | src = t0; 100 | res = (t0 >> count) | ((target_ulong)(eflags & CC_C) << (DATA_BITS - count)); 101 | if (count > 1) 102 | res |= t0 << (DATA_BITS + 1 - count); 103 | t0 = res; 104 | env->cc_src = (eflags & ~(CC_C | CC_O)) | 105 | (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) | 106 | ((src >> (count - 1)) & CC_C); 107 | } 108 | return t0; 109 | } 110 | 111 | #undef DATA_BITS 112 | #undef SHIFT_MASK 113 | #undef SHIFT1_MASK 114 | #undef SIGN_MASK 115 | #undef DATA_TYPE 116 | #undef DATA_STYPE 117 | #undef DATA_MASK 118 | #undef SUFFIX 119 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/smm_helper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * x86 SMM helpers 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | 20 | #include "cpu.h" 21 | #include "helper.h" 22 | 23 | /* SMM support */ 24 | 25 | #if defined(CONFIG_USER_ONLY) 26 | 27 | void do_smm_enter(CPUArchState *env1) 28 | { 29 | } 30 | 31 | void helper_rsm(CPUX86State *env) 32 | { 33 | } 34 | 35 | #else 36 | 37 | #ifdef TARGET_X86_64 38 | #define SMM_REVISION_ID 0x00020064 39 | #else 40 | #define SMM_REVISION_ID 0x00020000 41 | #endif 42 | 43 | void do_smm_enter(CPUArchState *env) 44 | { 45 | target_ulong sm_state; 46 | SegmentCache *dt; 47 | int i, offset; 48 | 49 | qemu_log_mask(CPU_LOG_INT, "SMM: enter\n"); 50 | log_cpu_state_mask(CPU_LOG_INT, ENV_GET_CPU(env), X86_DUMP_CCOP); 51 | 52 | env->hflags |= HF_SMM_MASK; 53 | cpu_smm_update(env); 54 | 55 | sm_state = env->smbase + 0x8000; 56 | 57 | #ifdef TARGET_X86_64 58 | for(i = 0; i < 6; i++) { 59 | dt = &env->segs[i]; 60 | offset = 0x7e00 + i * 16; 61 | stw_phys(sm_state + offset, dt->selector); 62 | stw_phys(sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff); 63 | stl_phys(sm_state + offset + 4, dt->limit); 64 | stq_phys(sm_state + offset + 8, dt->base); 65 | } 66 | 67 | stq_phys(sm_state + 0x7e68, env->gdt.base); 68 | stl_phys(sm_state + 0x7e64, env->gdt.limit); 69 | 70 | stw_phys(sm_state + 0x7e70, env->ldt.selector); 71 | stq_phys(sm_state + 0x7e78, env->ldt.base); 72 | stl_phys(sm_state + 0x7e74, env->ldt.limit); 73 | stw_phys(sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff); 74 | 75 | stq_phys(sm_state + 0x7e88, env->idt.base); 76 | stl_phys(sm_state + 0x7e84, env->idt.limit); 77 | 78 | stw_phys(sm_state + 0x7e90, env->tr.selector); 79 | stq_phys(sm_state + 0x7e98, env->tr.base); 80 | stl_phys(sm_state + 0x7e94, env->tr.limit); 81 | stw_phys(sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff); 82 | 83 | stq_phys(sm_state + 0x7ed0, env->efer); 84 | 85 | stq_phys(sm_state + 0x7ff8, EAX); 86 | stq_phys(sm_state + 0x7ff0, ECX); 87 | stq_phys(sm_state + 0x7fe8, EDX); 88 | stq_phys(sm_state + 0x7fe0, EBX); 89 | stq_phys(sm_state + 0x7fd8, ESP); 90 | stq_phys(sm_state + 0x7fd0, EBP); 91 | stq_phys(sm_state + 0x7fc8, ESI); 92 | stq_phys(sm_state + 0x7fc0, EDI); 93 | for(i = 8; i < 16; i++) 94 | stq_phys(sm_state + 0x7ff8 - i * 8, env->regs[i]); 95 | stq_phys(sm_state + 0x7f78, env->eip); 96 | stl_phys(sm_state + 0x7f70, cpu_compute_eflags(env)); 97 | stl_phys(sm_state + 0x7f68, env->dr[6]); 98 | stl_phys(sm_state + 0x7f60, env->dr[7]); 99 | 100 | stl_phys(sm_state + 0x7f48, env->cr[4]); 101 | stl_phys(sm_state + 0x7f50, env->cr[3]); 102 | stl_phys(sm_state + 0x7f58, env->cr[0]); 103 | 104 | stl_phys(sm_state + 0x7efc, SMM_REVISION_ID); 105 | stl_phys(sm_state + 0x7f00, env->smbase); 106 | #else 107 | stl_phys(sm_state + 0x7ffc, env->cr[0]); 108 | stl_phys(sm_state + 0x7ff8, env->cr[3]); 109 | stl_phys(sm_state + 0x7ff4, cpu_compute_eflags(env)); 110 | stl_phys(sm_state + 0x7ff0, env->eip); 111 | stl_phys(sm_state + 0x7fec, EDI); 112 | stl_phys(sm_state + 0x7fe8, ESI); 113 | stl_phys(sm_state + 0x7fe4, EBP); 114 | stl_phys(sm_state + 0x7fe0, ESP); 115 | stl_phys(sm_state + 0x7fdc, EBX); 116 | stl_phys(sm_state + 0x7fd8, EDX); 117 | stl_phys(sm_state + 0x7fd4, ECX); 118 | stl_phys(sm_state + 0x7fd0, EAX); 119 | stl_phys(sm_state + 0x7fcc, env->dr[6]); 120 | stl_phys(sm_state + 0x7fc8, env->dr[7]); 121 | 122 | stl_phys(sm_state + 0x7fc4, env->tr.selector); 123 | stl_phys(sm_state + 0x7f64, env->tr.base); 124 | stl_phys(sm_state + 0x7f60, env->tr.limit); 125 | stl_phys(sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff); 126 | 127 | stl_phys(sm_state + 0x7fc0, env->ldt.selector); 128 | stl_phys(sm_state + 0x7f80, env->ldt.base); 129 | stl_phys(sm_state + 0x7f7c, env->ldt.limit); 130 | stl_phys(sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff); 131 | 132 | stl_phys(sm_state + 0x7f74, env->gdt.base); 133 | stl_phys(sm_state + 0x7f70, env->gdt.limit); 134 | 135 | stl_phys(sm_state + 0x7f58, env->idt.base); 136 | stl_phys(sm_state + 0x7f54, env->idt.limit); 137 | 138 | for(i = 0; i < 6; i++) { 139 | dt = &env->segs[i]; 140 | if (i < 3) 141 | offset = 0x7f84 + i * 12; 142 | else 143 | offset = 0x7f2c + (i - 3) * 12; 144 | stl_phys(sm_state + 0x7fa8 + i * 4, dt->selector); 145 | stl_phys(sm_state + offset + 8, dt->base); 146 | stl_phys(sm_state + offset + 4, dt->limit); 147 | stl_phys(sm_state + offset, (dt->flags >> 8) & 0xf0ff); 148 | } 149 | stl_phys(sm_state + 0x7f14, env->cr[4]); 150 | 151 | stl_phys(sm_state + 0x7efc, SMM_REVISION_ID); 152 | stl_phys(sm_state + 0x7ef8, env->smbase); 153 | #endif 154 | /* init SMM cpu state */ 155 | 156 | #ifdef TARGET_X86_64 157 | cpu_load_efer(env, 0); 158 | #endif 159 | cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 160 | env->eip = 0x00008000; 161 | cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase, 162 | 0xffffffff, 0); 163 | cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0); 164 | cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff, 0); 165 | cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0); 166 | cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0); 167 | cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0); 168 | 169 | cpu_x86_update_cr0(env, 170 | env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK | CR0_PG_MASK)); 171 | cpu_x86_update_cr4(env, 0); 172 | env->dr[7] = 0x00000400; 173 | CC_OP = CC_OP_EFLAGS; 174 | } 175 | 176 | void helper_rsm(CPUX86State *env) 177 | { 178 | target_ulong sm_state; 179 | int i, offset; 180 | uint32_t val; 181 | 182 | sm_state = env->smbase + 0x8000; 183 | #ifdef TARGET_X86_64 184 | cpu_load_efer(env, ldq_phys(sm_state + 0x7ed0)); 185 | 186 | for(i = 0; i < 6; i++) { 187 | offset = 0x7e00 + i * 16; 188 | cpu_x86_load_seg_cache(env, i, 189 | lduw_phys(sm_state + offset), 190 | ldq_phys(sm_state + offset + 8), 191 | ldl_phys(sm_state + offset + 4), 192 | (lduw_phys(sm_state + offset + 2) & 0xf0ff) << 8); 193 | } 194 | 195 | env->gdt.base = ldq_phys(sm_state + 0x7e68); 196 | env->gdt.limit = ldl_phys(sm_state + 0x7e64); 197 | 198 | env->ldt.selector = lduw_phys(sm_state + 0x7e70); 199 | env->ldt.base = ldq_phys(sm_state + 0x7e78); 200 | env->ldt.limit = ldl_phys(sm_state + 0x7e74); 201 | env->ldt.flags = (lduw_phys(sm_state + 0x7e72) & 0xf0ff) << 8; 202 | 203 | env->idt.base = ldq_phys(sm_state + 0x7e88); 204 | env->idt.limit = ldl_phys(sm_state + 0x7e84); 205 | 206 | env->tr.selector = lduw_phys(sm_state + 0x7e90); 207 | env->tr.base = ldq_phys(sm_state + 0x7e98); 208 | env->tr.limit = ldl_phys(sm_state + 0x7e94); 209 | env->tr.flags = (lduw_phys(sm_state + 0x7e92) & 0xf0ff) << 8; 210 | 211 | EAX = ldq_phys(sm_state + 0x7ff8); 212 | ECX = ldq_phys(sm_state + 0x7ff0); 213 | EDX = ldq_phys(sm_state + 0x7fe8); 214 | EBX = ldq_phys(sm_state + 0x7fe0); 215 | ESP = ldq_phys(sm_state + 0x7fd8); 216 | EBP = ldq_phys(sm_state + 0x7fd0); 217 | ESI = ldq_phys(sm_state + 0x7fc8); 218 | EDI = ldq_phys(sm_state + 0x7fc0); 219 | for(i = 8; i < 16; i++) 220 | env->regs[i] = ldq_phys(sm_state + 0x7ff8 - i * 8); 221 | env->eip = ldq_phys(sm_state + 0x7f78); 222 | cpu_load_eflags(env, ldl_phys(sm_state + 0x7f70), 223 | ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 224 | env->dr[6] = ldl_phys(sm_state + 0x7f68); 225 | env->dr[7] = ldl_phys(sm_state + 0x7f60); 226 | 227 | cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f48)); 228 | cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7f50)); 229 | cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7f58)); 230 | 231 | val = ldl_phys(sm_state + 0x7efc); /* revision ID */ 232 | if (val & 0x20000) { 233 | env->smbase = ldl_phys(sm_state + 0x7f00) & ~0x7fff; 234 | } 235 | #else 236 | cpu_x86_update_cr0(env, ldl_phys(sm_state + 0x7ffc)); 237 | cpu_x86_update_cr3(env, ldl_phys(sm_state + 0x7ff8)); 238 | cpu_load_eflags(env, ldl_phys(sm_state + 0x7ff4), 239 | ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 240 | env->eip = ldl_phys(sm_state + 0x7ff0); 241 | EDI = ldl_phys(sm_state + 0x7fec); 242 | ESI = ldl_phys(sm_state + 0x7fe8); 243 | EBP = ldl_phys(sm_state + 0x7fe4); 244 | ESP = ldl_phys(sm_state + 0x7fe0); 245 | EBX = ldl_phys(sm_state + 0x7fdc); 246 | EDX = ldl_phys(sm_state + 0x7fd8); 247 | ECX = ldl_phys(sm_state + 0x7fd4); 248 | EAX = ldl_phys(sm_state + 0x7fd0); 249 | env->dr[6] = ldl_phys(sm_state + 0x7fcc); 250 | env->dr[7] = ldl_phys(sm_state + 0x7fc8); 251 | 252 | env->tr.selector = ldl_phys(sm_state + 0x7fc4) & 0xffff; 253 | env->tr.base = ldl_phys(sm_state + 0x7f64); 254 | env->tr.limit = ldl_phys(sm_state + 0x7f60); 255 | env->tr.flags = (ldl_phys(sm_state + 0x7f5c) & 0xf0ff) << 8; 256 | 257 | env->ldt.selector = ldl_phys(sm_state + 0x7fc0) & 0xffff; 258 | env->ldt.base = ldl_phys(sm_state + 0x7f80); 259 | env->ldt.limit = ldl_phys(sm_state + 0x7f7c); 260 | env->ldt.flags = (ldl_phys(sm_state + 0x7f78) & 0xf0ff) << 8; 261 | 262 | env->gdt.base = ldl_phys(sm_state + 0x7f74); 263 | env->gdt.limit = ldl_phys(sm_state + 0x7f70); 264 | 265 | env->idt.base = ldl_phys(sm_state + 0x7f58); 266 | env->idt.limit = ldl_phys(sm_state + 0x7f54); 267 | 268 | for(i = 0; i < 6; i++) { 269 | if (i < 3) 270 | offset = 0x7f84 + i * 12; 271 | else 272 | offset = 0x7f2c + (i - 3) * 12; 273 | cpu_x86_load_seg_cache(env, i, 274 | ldl_phys(sm_state + 0x7fa8 + i * 4) & 0xffff, 275 | ldl_phys(sm_state + offset + 8), 276 | ldl_phys(sm_state + offset + 4), 277 | (ldl_phys(sm_state + offset) & 0xf0ff) << 8); 278 | } 279 | cpu_x86_update_cr4(env, ldl_phys(sm_state + 0x7f14)); 280 | 281 | val = ldl_phys(sm_state + 0x7efc); /* revision ID */ 282 | if (val & 0x20000) { 283 | env->smbase = ldl_phys(sm_state + 0x7ef8) & ~0x7fff; 284 | } 285 | #endif 286 | CC_OP = CC_OP_EFLAGS; 287 | env->hflags &= ~HF_SMM_MASK; 288 | cpu_smm_update(env); 289 | 290 | qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n"); 291 | log_cpu_state_mask(CPU_LOG_INT, ENV_GET_CPU(env), X86_DUMP_CCOP); 292 | } 293 | 294 | #endif /* !CONFIG_USER_ONLY */ 295 | -------------------------------------------------------------------------------- /ShellcodeVM/target-i386/svm.h: -------------------------------------------------------------------------------- 1 | #ifndef __SVM_H 2 | #define __SVM_H 3 | 4 | #define TLB_CONTROL_DO_NOTHING 0 5 | #define TLB_CONTROL_FLUSH_ALL_ASID 1 6 | 7 | #define V_TPR_MASK 0x0f 8 | 9 | #define V_IRQ_SHIFT 8 10 | #define V_IRQ_MASK (1 << V_IRQ_SHIFT) 11 | 12 | #define V_INTR_PRIO_SHIFT 16 13 | #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) 14 | 15 | #define V_IGN_TPR_SHIFT 20 16 | #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) 17 | 18 | #define V_INTR_MASKING_SHIFT 24 19 | #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) 20 | 21 | #define SVM_INTERRUPT_SHADOW_MASK 1 22 | 23 | #define SVM_IOIO_STR_SHIFT 2 24 | #define SVM_IOIO_REP_SHIFT 3 25 | #define SVM_IOIO_SIZE_SHIFT 4 26 | #define SVM_IOIO_ASIZE_SHIFT 7 27 | 28 | #define SVM_IOIO_TYPE_MASK 1 29 | #define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT) 30 | #define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT) 31 | #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) 32 | #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) 33 | 34 | #define SVM_EVTINJ_VEC_MASK 0xff 35 | 36 | #define SVM_EVTINJ_TYPE_SHIFT 8 37 | #define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT) 38 | 39 | #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT) 40 | #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT) 41 | #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT) 42 | #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT) 43 | 44 | #define SVM_EVTINJ_VALID (1 << 31) 45 | #define SVM_EVTINJ_VALID_ERR (1 << 11) 46 | 47 | #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK 48 | 49 | #define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR 50 | #define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI 51 | #define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT 52 | #define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT 53 | 54 | #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID 55 | #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR 56 | 57 | #define SVM_EXIT_READ_CR0 0x000 58 | #define SVM_EXIT_READ_CR3 0x003 59 | #define SVM_EXIT_READ_CR4 0x004 60 | #define SVM_EXIT_READ_CR8 0x008 61 | #define SVM_EXIT_WRITE_CR0 0x010 62 | #define SVM_EXIT_WRITE_CR3 0x013 63 | #define SVM_EXIT_WRITE_CR4 0x014 64 | #define SVM_EXIT_WRITE_CR8 0x018 65 | #define SVM_EXIT_READ_DR0 0x020 66 | #define SVM_EXIT_READ_DR1 0x021 67 | #define SVM_EXIT_READ_DR2 0x022 68 | #define SVM_EXIT_READ_DR3 0x023 69 | #define SVM_EXIT_READ_DR4 0x024 70 | #define SVM_EXIT_READ_DR5 0x025 71 | #define SVM_EXIT_READ_DR6 0x026 72 | #define SVM_EXIT_READ_DR7 0x027 73 | #define SVM_EXIT_WRITE_DR0 0x030 74 | #define SVM_EXIT_WRITE_DR1 0x031 75 | #define SVM_EXIT_WRITE_DR2 0x032 76 | #define SVM_EXIT_WRITE_DR3 0x033 77 | #define SVM_EXIT_WRITE_DR4 0x034 78 | #define SVM_EXIT_WRITE_DR5 0x035 79 | #define SVM_EXIT_WRITE_DR6 0x036 80 | #define SVM_EXIT_WRITE_DR7 0x037 81 | #define SVM_EXIT_EXCP_BASE 0x040 82 | #define SVM_EXIT_INTR 0x060 83 | #define SVM_EXIT_NMI 0x061 84 | #define SVM_EXIT_SMI 0x062 85 | #define SVM_EXIT_INIT 0x063 86 | #define SVM_EXIT_VINTR 0x064 87 | #define SVM_EXIT_CR0_SEL_WRITE 0x065 88 | #define SVM_EXIT_IDTR_READ 0x066 89 | #define SVM_EXIT_GDTR_READ 0x067 90 | #define SVM_EXIT_LDTR_READ 0x068 91 | #define SVM_EXIT_TR_READ 0x069 92 | #define SVM_EXIT_IDTR_WRITE 0x06a 93 | #define SVM_EXIT_GDTR_WRITE 0x06b 94 | #define SVM_EXIT_LDTR_WRITE 0x06c 95 | #define SVM_EXIT_TR_WRITE 0x06d 96 | #define SVM_EXIT_RDTSC 0x06e 97 | #define SVM_EXIT_RDPMC 0x06f 98 | #define SVM_EXIT_PUSHF 0x070 99 | #define SVM_EXIT_POPF 0x071 100 | #define SVM_EXIT_CPUID 0x072 101 | #define SVM_EXIT_RSM 0x073 102 | #define SVM_EXIT_IRET 0x074 103 | #define SVM_EXIT_SWINT 0x075 104 | #define SVM_EXIT_INVD 0x076 105 | #define SVM_EXIT_PAUSE 0x077 106 | #define SVM_EXIT_HLT 0x078 107 | #define SVM_EXIT_INVLPG 0x079 108 | #define SVM_EXIT_INVLPGA 0x07a 109 | #define SVM_EXIT_IOIO 0x07b 110 | #define SVM_EXIT_MSR 0x07c 111 | #define SVM_EXIT_TASK_SWITCH 0x07d 112 | #define SVM_EXIT_FERR_FREEZE 0x07e 113 | #define SVM_EXIT_SHUTDOWN 0x07f 114 | #define SVM_EXIT_VMRUN 0x080 115 | #define SVM_EXIT_VMMCALL 0x081 116 | #define SVM_EXIT_VMLOAD 0x082 117 | #define SVM_EXIT_VMSAVE 0x083 118 | #define SVM_EXIT_STGI 0x084 119 | #define SVM_EXIT_CLGI 0x085 120 | #define SVM_EXIT_SKINIT 0x086 121 | #define SVM_EXIT_RDTSCP 0x087 122 | #define SVM_EXIT_ICEBP 0x088 123 | #define SVM_EXIT_WBINVD 0x089 124 | /* only included in documentation, maybe wrong */ 125 | #define SVM_EXIT_MONITOR 0x08a 126 | #define SVM_EXIT_MWAIT 0x08b 127 | #define SVM_EXIT_NPF 0x400 128 | 129 | #define SVM_EXIT_ERR -1 130 | 131 | #define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */ 132 | 133 | struct QEMU_PACKED vmcb_control_area { 134 | uint16_t intercept_cr_read; 135 | uint16_t intercept_cr_write; 136 | uint16_t intercept_dr_read; 137 | uint16_t intercept_dr_write; 138 | uint32_t intercept_exceptions; 139 | uint64_t intercept; 140 | uint8_t reserved_1[44]; 141 | uint64_t iopm_base_pa; 142 | uint64_t msrpm_base_pa; 143 | uint64_t tsc_offset; 144 | uint32_t asid; 145 | uint8_t tlb_ctl; 146 | uint8_t reserved_2[3]; 147 | uint32_t int_ctl; 148 | uint32_t int_vector; 149 | uint32_t int_state; 150 | uint8_t reserved_3[4]; 151 | uint64_t exit_code; 152 | uint64_t exit_info_1; 153 | uint64_t exit_info_2; 154 | uint32_t exit_int_info; 155 | uint32_t exit_int_info_err; 156 | uint64_t nested_ctl; 157 | uint8_t reserved_4[16]; 158 | uint32_t event_inj; 159 | uint32_t event_inj_err; 160 | uint64_t nested_cr3; 161 | uint64_t lbr_ctl; 162 | uint8_t reserved_5[832]; 163 | }; 164 | 165 | struct QEMU_PACKED vmcb_seg { 166 | uint16_t selector; 167 | uint16_t attrib; 168 | uint32_t limit; 169 | uint64_t base; 170 | }; 171 | 172 | struct QEMU_PACKED vmcb_save_area { 173 | struct vmcb_seg es; 174 | struct vmcb_seg cs; 175 | struct vmcb_seg ss; 176 | struct vmcb_seg ds; 177 | struct vmcb_seg fs; 178 | struct vmcb_seg gs; 179 | struct vmcb_seg gdtr; 180 | struct vmcb_seg ldtr; 181 | struct vmcb_seg idtr; 182 | struct vmcb_seg tr; 183 | uint8_t reserved_1[43]; 184 | uint8_t cpl; 185 | uint8_t reserved_2[4]; 186 | uint64_t efer; 187 | uint8_t reserved_3[112]; 188 | uint64_t cr4; 189 | uint64_t cr3; 190 | uint64_t cr0; 191 | uint64_t dr7; 192 | uint64_t dr6; 193 | uint64_t rflags; 194 | uint64_t rip; 195 | uint8_t reserved_4[88]; 196 | uint64_t rsp; 197 | uint8_t reserved_5[24]; 198 | uint64_t rax; 199 | uint64_t star; 200 | uint64_t lstar; 201 | uint64_t cstar; 202 | uint64_t sfmask; 203 | uint64_t kernel_gs_base; 204 | uint64_t sysenter_cs; 205 | uint64_t sysenter_esp; 206 | uint64_t sysenter_eip; 207 | uint64_t cr2; 208 | uint8_t reserved_6[32]; 209 | uint64_t g_pat; 210 | uint64_t dbgctl; 211 | uint64_t br_from; 212 | uint64_t br_to; 213 | uint64_t last_excp_from; 214 | uint64_t last_excp_to; 215 | }; 216 | 217 | struct QEMU_PACKED vmcb { 218 | struct vmcb_control_area control; 219 | struct vmcb_save_area save; 220 | }; 221 | 222 | #endif 223 | -------------------------------------------------------------------------------- /nasm/nasm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/nasm/nasm.exe -------------------------------------------------------------------------------- /nasm/ndisasm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/nasm/ndisasm.exe -------------------------------------------------------------------------------- /同步文档.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imgits/ShellcodeVM/9a16b806bc18fb6da45907a1c1a3337cf3a9fce2/同步文档.docx --------------------------------------------------------------------------------