└── linux ├── Makefile ├── apic.c ├── apic.h ├── codeview.c ├── codeview.h ├── console.c ├── console.h ├── dbg.c ├── dbg.h ├── dbgprint.c ├── dbgprint.h ├── define.h ├── exp.c ├── exp.h ├── font_inc.c ├── keyboard.c ├── keyboard.h ├── libudis86 ├── decode.c ├── decode.h ├── extern.h ├── input.c ├── input.h ├── itab.c ├── itab.h ├── syn-att.c ├── syn-intel.c ├── syn.c ├── syn.h ├── types.h └── udis86.c ├── main.c ├── mmu.c ├── mmu.h ├── scancode.c ├── scancode.h ├── sym.c ├── sym.h ├── udis86.h ├── video.c ├── video.h ├── vmm.c ├── vmm.h ├── vmmstring.c ├── vmmstring.h ├── vmx-x86.asm ├── vmx.c ├── vmx.h └── x86.h /linux/Makefile: -------------------------------------------------------------------------------- 1 | libudis86-objs := libudis86/decode.o libudis86/input.o libudis86/itab.o libudis86/syn-att.o \ 2 | libudis86/syn.o libudis86/syn-intel.o libudis86/udis86.o 3 | 4 | obj-m := vmxice.o 5 | vmxice-objs := $(libudis86-objs) \ 6 | main.o vmx-x86.o vmx.o vmm.o video.o dbgprint.o console.o apic.o keyboard.o scancode.o dbg.o codeview.o mmu.o \ 7 | sym.o exp.o vmmstring.o 8 | 9 | CURRENT_PATH := $(shell pwd) 10 | LINUX_KERNEL := $(shell uname -r) 11 | LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL) 12 | 13 | 14 | all: 15 | yasm -felf vmx-x86.asm 16 | make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules 17 | 18 | clean: 19 | make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean 20 | 21 | -------------------------------------------------------------------------------- /linux/apic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "apic.h" 3 | 4 | VOID MaskKeyboardInterrupt(PGUEST_CPU pCpu) 5 | { 6 | _WritePRT(pCpu->IOAPIC_va,1*2,_ReadPRT(pCpu->IOAPIC_va,1*2) | 0x10000); 7 | } 8 | 9 | VOID RestoreKeyboardInterrupt(PGUEST_CPU pCpu) 10 | { 11 | _WritePRT(pCpu->IOAPIC_va,1*2,_ReadPRT(pCpu->IOAPIC_va,1*2) & ~0x10000); 12 | } 13 | -------------------------------------------------------------------------------- /linux/apic.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | #include "vmx.h" 3 | 4 | #ifndef _APIC_H_ 5 | #define _APIC_H_ 6 | 7 | VOID MaskKeyboardInterrupt(PGUEST_CPU pCpu); 8 | VOID RestoreKeyboardInterrupt(PGUEST_CPU pCpu); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /linux/codeview.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "x86.h" 3 | #include "dbg.h" 4 | #include "video.h" 5 | #include "console.h" 6 | #include "codeview.h" 7 | #include "udis86.h" 8 | #include "sym.h" 9 | #include "mmu.h" 10 | 11 | #define MAX_DISASM_LINES 30 12 | #define OPCODE_MAX_LEN 15 13 | 14 | ULONG CodeViewHeight; 15 | UCHAR DisasmInstrs[MAX_DISASM_LINES][128]; 16 | ULONG DisasmIPS[MAX_DISASM_LINES]; 17 | 18 | VOID CodeViewInit(void) 19 | { 20 | CodeViewHeight = 19; 21 | } 22 | 23 | VOID FormatInstruction(PUCHAR dst,PUCHAR src) 24 | { 25 | PUCHAR s; 26 | ULONG i=0; 27 | UCHAR c; 28 | 29 | s = src; 30 | while(*s) 31 | { 32 | c = *s; 33 | if(c >= 'a' && c<= 'z') 34 | c -= 32; 35 | *s = c; 36 | s++; 37 | } 38 | 39 | while(*src) 40 | { 41 | c = *src++; 42 | *dst++ = c; 43 | if(c == ' ') 44 | { 45 | while(i < 10) 46 | { 47 | *dst++ = ' '; 48 | i++; 49 | } 50 | } 51 | i++; 52 | } 53 | *dst = 0; 54 | } 55 | 56 | ULONG OriDisasm(PUCHAR str,ULONG Eip) 57 | { 58 | UDIS ud_obj; 59 | ULONG len; 60 | 61 | ud_init(&ud_obj); 62 | ud_set_mode(&ud_obj, 32); 63 | ud_set_syntax(&ud_obj, UD_SYN_INTEL); 64 | ud_set_pc(&ud_obj,(int)Eip); 65 | ud_set_input_buffer(&ud_obj, (uint8_t*)Eip, 32); 66 | len = ud_disassemble(&ud_obj); 67 | strcpy(str,ud_insn_asm(&ud_obj)); 68 | return len; 69 | } 70 | 71 | ULONG FastDisasm(ULONG Eip) 72 | { 73 | UDIS ud_obj; 74 | ULONG len; 75 | 76 | ud_init(&ud_obj); 77 | ud_set_mode(&ud_obj, 32); 78 | ud_set_syntax(&ud_obj, UD_SYN_INTEL); 79 | ud_set_pc(&ud_obj,(int)Eip); 80 | ud_set_input_buffer(&ud_obj, (uint8_t*)Eip, 32); 81 | len = ud_decode(&ud_obj); 82 | return len; 83 | } 84 | 85 | ULONG GetRegValue(PGUEST_CPU pCpu,ULONG RegIndex) 86 | { 87 | CHAR str[128]; 88 | 89 | switch(RegIndex) 90 | { 91 | case 0: 92 | return 0; 93 | case UD_R_EAX: 94 | return pCpu->pGuestRegs->eax; 95 | case UD_R_ECX: 96 | return pCpu->pGuestRegs->ecx; 97 | case UD_R_EDX: 98 | return pCpu->pGuestRegs->edx; 99 | case UD_R_EBX: 100 | return pCpu->pGuestRegs->ebx; 101 | case UD_R_ESP: 102 | return pCpu->pGuestRegs->esp; 103 | case UD_R_EBP: 104 | return pCpu->pGuestRegs->ebp; 105 | case UD_R_ESI: 106 | return pCpu->pGuestRegs->esi; 107 | case UD_R_EDI: 108 | return pCpu->pGuestRegs->edi; 109 | default: 110 | snprintf(str,128,"GetRegValue %x\n",RegIndex); 111 | ConsolePrintStr(str,7,0); 112 | return 0; 113 | } 114 | } 115 | 116 | ULONG GetCallReg(PGUEST_CPU pCpu,PUDIS pUdis) //call [reg] 117 | { 118 | if(pUdis->operand[0].type == UD_OP_REG) 119 | return GetRegValue(pCpu,pUdis->operand[0].base); 120 | else if(pUdis->operand[0].type == UD_OP_MEM) 121 | { 122 | ULONG BaseReg = GetRegValue(pCpu,pUdis->operand[0].base); 123 | ULONG IndexReg = GetRegValue(pCpu,pUdis->operand[0].index); 124 | ULONG Scale = GetRegValue(pCpu,pUdis->operand[0].scale); 125 | ULONG Address = 0; 126 | CHAR Buf[256]; 127 | 128 | switch(pUdis->operand[0].offset) 129 | { 130 | case 0: 131 | Address = (BaseReg+IndexReg*Scale); 132 | case 8: 133 | Address = (BaseReg+IndexReg*Scale + pUdis->operand[0].lval.sbyte); 134 | case 16: 135 | Address = (BaseReg+IndexReg*Scale + pUdis->operand[0].lval.sword); 136 | case 32: 137 | Address = (BaseReg+IndexReg*Scale + pUdis->operand[0].lval.sdword); 138 | } 139 | 140 | if(!Address) 141 | return 0; 142 | 143 | if(!IsAddressExist(Address)) 144 | { 145 | sprintf(Buf,"callmem [%08X] is invalid!!\n",Address); 146 | ConsolePrintStr(Buf,7,0); 147 | return 0; 148 | } 149 | 150 | return *(PULONG)Address; 151 | } 152 | return 0; 153 | } 154 | 155 | ULONG GetCallImm(PGUEST_CPU pCpu,PUDIS pUdis) //call xxx 156 | { 157 | if(pUdis->operand[0].type == UD_OP_IMM) 158 | return pUdis->operand[0].lval.udword; 159 | else if(pUdis->operand[0].type == UD_OP_JIMM) 160 | { 161 | return pUdis->pc + pUdis->operand[0].lval.sdword; 162 | } 163 | return 0; 164 | } 165 | 166 | ULONG GetSymbolAndOffset(ULONG CallAddr,ULONG ShowOffset,PCHAR Buf,ULONG BufLen) 167 | { 168 | const char *Ret; 169 | char SymName[256]; 170 | char *pModName; 171 | unsigned long SymSize; 172 | unsigned long Offset; 173 | 174 | Buf[0] = 0; 175 | 176 | Ret = LookupAddress((int)CallAddr,&SymSize,&Offset,&pModName,SymName); 177 | if(!Ret) 178 | return 0; 179 | 180 | if(pModName) 181 | { 182 | if(Offset || ShowOffset) 183 | { 184 | snprintf(Buf,BufLen,"%s!%s + %04Xh",pModName,SymName,(ULONG)Offset); 185 | return 1; 186 | } 187 | else 188 | { 189 | snprintf(Buf,BufLen,"%s!%s",pModName,SymName); 190 | return 1; 191 | } 192 | } 193 | else 194 | { 195 | if(Offset || ShowOffset) 196 | { 197 | snprintf(Buf,BufLen,"%s + %04Xh",SymName,(ULONG)Offset); 198 | return 1; 199 | } 200 | else 201 | { 202 | snprintf(Buf,BufLen,"%s",SymName); 203 | return 1; 204 | } 205 | } 206 | } 207 | 208 | ULONG DisasmInstruction(PGUEST_CPU pCpu,PUCHAR str,ULONG Eip,ULONG Detail) 209 | { 210 | UDIS ud_obj; 211 | UCHAR instr[80]; 212 | ULONG len; 213 | UCHAR CodeImage[16]; 214 | ULONG i,j; 215 | 216 | if(!IsAddressRangeExist((ULONG)Eip,OPCODE_MAX_LEN)) 217 | { 218 | snprintf(str,96,"%04X:%08X INVALID PAGE",_ReadVMCS(GUEST_CS_SELECTOR),Eip); 219 | return -1; 220 | } 221 | 222 | 223 | for(i = 0; i < MAX_SW_BP; i++) 224 | { 225 | if(SoftBPs[i].Address == Eip) 226 | { 227 | memcpy(CodeImage,(PVOID)Eip,16); 228 | CodeImage[0] = SoftBPs[i].OldOpcode; 229 | break; 230 | } 231 | } 232 | 233 | for(j = 0; j < MAX_STEP_BP; j++) 234 | { 235 | if(StepBPs[j].Address == Eip) 236 | { 237 | memcpy(CodeImage,(PVOID)Eip,16); 238 | CodeImage[0] = StepBPs[i].OldOpcode; 239 | break; 240 | } 241 | } 242 | /* 243 | RtlZeroMemory(&dis,sizeof(dis)); 244 | if(i != MAX_SW_BP || j != MAX_STEP_BP) 245 | dis.EIP = CodeImage; 246 | else 247 | dis.EIP = Eip; 248 | dis.VirtualAddr = Eip; 249 | dis.Archi = 32; 250 | len = Disasm(&dis); 251 | if(len == -1) 252 | { 253 | snprintf(str,96,"%04X:%08X INVALID OPCODE",_ReadVMCS(GUEST_CS_SELECTOR),Eip); 254 | return -1; 255 | } 256 | */ 257 | ud_init(&ud_obj); 258 | ud_set_mode(&ud_obj, 32); 259 | ud_set_syntax(&ud_obj, UD_SYN_INTEL); 260 | ud_set_pc(&ud_obj,(int)Eip); 261 | if(i != MAX_SW_BP || j != MAX_STEP_BP) 262 | ud_set_input_buffer(&ud_obj, (uint8_t*)CodeImage, 32); 263 | else 264 | ud_set_input_buffer(&ud_obj, (uint8_t*)Eip, 32); 265 | len = ud_disassemble(&ud_obj); 266 | if(len == -1) 267 | { 268 | snprintf(str,96,"%04X:%08X INVALID OPCODE",_ReadVMCS(GUEST_CS_SELECTOR),(ULONG)Eip); 269 | return -1; 270 | } 271 | 272 | if(!strncmp(ud_insn_asm(&ud_obj),"call",4)) 273 | { 274 | ULONG CallAddr; 275 | CHAR SymName[256]; 276 | ULONG Ret; 277 | 278 | if(Detail) 279 | { 280 | CallAddr = GetCallReg(pCpu,&ud_obj); 281 | if(CallAddr) 282 | { 283 | Ret = GetSymbolAndOffset(CallAddr,FALSE,SymName,256); 284 | if(Ret) 285 | { 286 | FormatInstruction(instr,ud_insn_asm(&ud_obj)); 287 | snprintf(str,96,"%04X:%08X %s ;%s",_ReadVMCS(GUEST_CS_SELECTOR),(ULONG)Eip,instr,SymName); 288 | return len; 289 | } 290 | } 291 | } 292 | 293 | CallAddr = GetCallImm(pCpu,&ud_obj); 294 | if(CallAddr) 295 | { 296 | Ret = GetSymbolAndOffset(CallAddr,FALSE,SymName,256); 297 | if(Ret) 298 | { 299 | snprintf(str,96,"%04X:%08X CALL %s",_ReadVMCS(GUEST_CS_SELECTOR),(ULONG)Eip,SymName); 300 | return len; 301 | } 302 | } 303 | } 304 | 305 | FormatInstruction(instr,ud_insn_asm(&ud_obj)); 306 | snprintf(str,96,"%04X:%08X %s",_ReadVMCS(GUEST_CS_SELECTOR),(ULONG)Eip,instr); 307 | return len; 308 | } 309 | 310 | VOID AddHit(PPREV_INSTR_HITTEST pHitTest,ULONG HitTestArrCount,ULONG PrevAddr) 311 | { 312 | ULONG i; 313 | 314 | for(i = 0; i < HitTestArrCount && pHitTest[i].pInstrAddr; i++) 315 | { 316 | if(pHitTest[i].pInstrAddr == PrevAddr) 317 | { 318 | pHitTest[i].HitCount++; 319 | return; 320 | } 321 | } 322 | pHitTest[i].pInstrAddr = PrevAddr; 323 | pHitTest[i].HitCount = 1; 324 | } 325 | 326 | ULONG GetPrevIp(ULONG Eip) 327 | { 328 | PREV_INSTR_HITTEST HitTest[16]; 329 | ULONG CurrentAddr = Eip - 1; 330 | ULONG PrevAddr; 331 | ULONG DisasmLimit = 0x100; 332 | ULONG len; 333 | ULONG i; 334 | ULONG PrevAddr_MaxHit = 0; 335 | ULONG MaxHit = 0; 336 | 337 | if(!Eip) 338 | return FALSE; 339 | 340 | memset(&HitTest,0,sizeof(HitTest)); 341 | while(DisasmLimit) 342 | { 343 | PrevAddr = CurrentAddr; 344 | if(!IsAddressExist(PrevAddr)) //ÄÚ´æ¿É¶ÁÐÔ²âÊÔ 345 | break; 346 | 347 | while(1) 348 | { 349 | len = FastDisasm(PrevAddr); 350 | if(len != -1 && len) 351 | { 352 | if(len + PrevAddr >= Eip) 353 | { 354 | AddHit(&HitTest[0],16,PrevAddr); 355 | break; 356 | } 357 | else if(len + PrevAddr > Eip) 358 | { 359 | break; 360 | } 361 | } 362 | else 363 | { 364 | break; 365 | } 366 | PrevAddr += len; 367 | } 368 | 369 | DisasmLimit--; 370 | CurrentAddr--; 371 | } 372 | 373 | for(i = 0; i < 16; i++) 374 | { 375 | if(HitTest[i].HitCount > MaxHit) 376 | { 377 | MaxHit = HitTest[i].HitCount; 378 | PrevAddr_MaxHit = HitTest[i].pInstrAddr; 379 | } 380 | } 381 | return PrevAddr_MaxHit; 382 | } 383 | 384 | ULONG IsInstrBeSetBp(ULONG Address) 385 | { 386 | ULONG i; 387 | for(i = 0; i < MAX_SW_BP; i++) 388 | { 389 | if(Address == SoftBPs[i].Address) 390 | return TRUE; 391 | } 392 | return FALSE; 393 | } 394 | 395 | VOID ShowDisasm(PGUEST_CPU pCpu,ULONG StartAddress,ULONG NeedPageChange) 396 | { 397 | ULONG i; 398 | ULONG Eip; 399 | ULONG Len; 400 | ULONG CurrentEip; 401 | CHAR str[128]; 402 | CHAR szSeparate1[100]; 403 | ULONG Ring; 404 | ULONG ForeColor,BackColor; 405 | PCHAR pDisasmStr; 406 | 407 | if(!bScreenBackuped) 408 | return; 409 | 410 | memset(szSeparate1,0,100); 411 | memset(szSeparate1,196,98); 412 | 413 | CurrentEip = _ReadVMCS(GUEST_RIP); 414 | 415 | GetSymbolAndOffset(StartAddress,TRUE,str,50); 416 | memcpy(&szSeparate1[0],str,strlen(str)); 417 | 418 | Ring = _ReadVMCS(GUEST_CS_SELECTOR) & 3; 419 | snprintf(str,128,"Ring%d",Ring); 420 | memcpy(&szSeparate1[GUI_Width-15],str,strlen(str)); 421 | snprintf(str,128,"CPU%d",pCpu->ProcessorNumber); 422 | memcpy(&szSeparate1[GUI_Width-7],str,strlen(str)); 423 | PrintStr(1,4,2,0,FALSE,szSeparate1,FALSE); 424 | 425 | for(i = 0; i < CodeViewHeight; i++) 426 | { 427 | if(DisasmIPS[i] == StartAddress) 428 | { 429 | break; 430 | } 431 | } 432 | 433 | if(NeedPageChange) 434 | i = CodeViewHeight; 435 | 436 | if(i == CodeViewHeight) 437 | { 438 | Eip = StartAddress; 439 | for(i = 0; i < CodeViewHeight; i++) 440 | { 441 | pDisasmStr = DisasmInstrs[i]; 442 | if(Eip == CurrentEip) 443 | { 444 | Len = DisasmInstruction(pCpu,DisasmInstrs[i],Eip,FALSE); 445 | Len = DisasmInstruction(pCpu,str,Eip,TRUE); 446 | pDisasmStr = str; 447 | } 448 | else 449 | { 450 | Len = DisasmInstruction(pCpu,DisasmInstrs[i],Eip,FALSE); 451 | } 452 | 453 | if(Eip == CurrentEip) 454 | { 455 | ForeColor = 1; 456 | BackColor = 7; 457 | } 458 | else 459 | { 460 | if(IsInstrBeSetBp(Eip)) 461 | { 462 | ForeColor = 0xb; 463 | BackColor = 0; 464 | } 465 | else 466 | { 467 | ForeColor = 7; 468 | BackColor = 0; 469 | } 470 | } 471 | 472 | PrintStr(1,5+i,ForeColor,BackColor,FALSE,pDisasmStr,TRUE); 473 | 474 | if(Len != -1) 475 | { 476 | DisasmIPS[i] = Eip; 477 | Eip += Len; 478 | } 479 | else 480 | { 481 | DisasmIPS[i] = -1; 482 | Eip += 1; 483 | } 484 | } 485 | return; 486 | } 487 | 488 | for(i = 0; i < CodeViewHeight; i++) 489 | { 490 | pDisasmStr = DisasmInstrs[i]; 491 | if(DisasmIPS[i] == CurrentEip) 492 | { 493 | Len = DisasmInstruction(pCpu,str,CurrentEip,TRUE); 494 | pDisasmStr = str; 495 | ForeColor = 1; 496 | BackColor = 7; 497 | } 498 | else 499 | { 500 | if(IsInstrBeSetBp(DisasmIPS[i])) 501 | { 502 | ForeColor = 0xb; 503 | BackColor = 0; 504 | } 505 | else 506 | { 507 | ForeColor = 7; 508 | BackColor = 0; 509 | } 510 | } 511 | PrintStr(1,5+i,ForeColor,BackColor,FALSE,pDisasmStr,TRUE); 512 | } 513 | } 514 | 515 | VOID ShowCurrentDisasm(PGUEST_CPU pCpu) 516 | { 517 | ShowDisasm(pCpu,_ReadVMCS(GUEST_RIP),FALSE); 518 | } 519 | 520 | VOID RefreshCurrentDisasm(PGUEST_CPU pCpu) 521 | { 522 | ULONG i; 523 | ULONG Len; 524 | ULONG CurrentEip; 525 | CHAR str[128]; 526 | ULONG ForeColor,BackColor; 527 | PCHAR pDisasmStr; 528 | 529 | if(!bScreenBackuped) 530 | return; 531 | 532 | CurrentEip = _ReadVMCS(GUEST_RIP); 533 | for(i = 0; i < CodeViewHeight; i++) 534 | { 535 | pDisasmStr = DisasmInstrs[i]; 536 | if(DisasmIPS[i] == CurrentEip) 537 | { 538 | Len = DisasmInstruction(pCpu,str,CurrentEip,TRUE); 539 | pDisasmStr = str; 540 | ForeColor = 1; 541 | BackColor = 7; 542 | } 543 | else 544 | { 545 | if(IsInstrBeSetBp(DisasmIPS[i])) 546 | { 547 | ForeColor = 0xb; 548 | BackColor = 0; 549 | } 550 | else 551 | { 552 | ForeColor = 7; 553 | BackColor = 0; 554 | } 555 | } 556 | PrintStr(1,5+i,ForeColor,BackColor,FALSE,pDisasmStr,TRUE); 557 | } 558 | } 559 | 560 | VOID ClearCurrentDisasm() 561 | { 562 | memset(DisasmInstrs,0,sizeof(DisasmInstrs)); 563 | memset(DisasmIPS,0,sizeof(DisasmIPS)); 564 | } 565 | 566 | VOID ShowNextIpDisasm(PGUEST_CPU pCpu) 567 | { 568 | ULONG Eip; 569 | 570 | Eip = DisasmIPS[1]; 571 | ShowDisasm(pCpu,Eip,TRUE); 572 | } 573 | 574 | VOID ShowPrevIpDisasm(PGUEST_CPU pCpu) 575 | { 576 | ULONG Eip; 577 | 578 | Eip = GetPrevIp(DisasmIPS[0]); 579 | if(!Eip) 580 | return; 581 | 582 | ShowDisasm(pCpu,Eip,TRUE); 583 | } 584 | -------------------------------------------------------------------------------- /linux/codeview.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | #include "vmx.h" 3 | 4 | #ifndef _CODEVIEW_H_ 5 | #define _CODEVIEW_H_ 6 | 7 | typedef struct { 8 | ULONG pInstrAddr; 9 | ULONG HitCount; 10 | }PREV_INSTR_HITTEST,*PPREV_INSTR_HITTEST; 11 | 12 | VOID CodeViewInit(void); 13 | VOID ShowDisasm(PGUEST_CPU pCpu,ULONG StartAddress,ULONG NeedPageChange); 14 | VOID ShowCurrentDisasm(PGUEST_CPU pCpu); 15 | VOID RefreshCurrentDisasm(PGUEST_CPU pCpu); 16 | VOID ClearCurrentDisasm(void); 17 | VOID ShowNextIpDisasm(PGUEST_CPU pCpu); 18 | VOID ShowPrevIpDisasm(PGUEST_CPU pCpu); 19 | ULONG OriDisasm(PUCHAR str,ULONG Eip); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /linux/console.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "dbgprint.h" 5 | #include "video.h" 6 | #include "console.h" 7 | #include "dbg.h" 8 | 9 | ULONG ConsoleHeight; 10 | ULONG ConsoleWidth; 11 | PUCHAR ConsoleBuffer; 12 | ULONG ConsoleHistoryHeight = 100; 13 | ULONG ConsoleHistoryTempHeight = 100; 14 | PUCHAR ConsoleEndPtr; 15 | PUCHAR ConsoleTempEndPtr; 16 | PUCHAR ConsoleCurrentPtr; 17 | PUCHAR ConsoleCurrentPagePtr; 18 | 19 | ULONG ConsoleInit(void) 20 | { 21 | ConsoleHeight = 12; 22 | ConsoleWidth = GUI_Width-2; 23 | ConsoleBuffer = (PUCHAR)kmalloc(ConsoleWidth*2*(ConsoleHistoryHeight+ConsoleHistoryTempHeight),GFP_ATOMIC); 24 | printf("console init\n"); 25 | if(!ConsoleBuffer) 26 | { 27 | RED_FONT; 28 | printf("InitConsole: kmalloc for ConsoleBuffer failed\n"); 29 | return false; 30 | } 31 | memset(ConsoleBuffer,0,(GUI_Width-2)*2*ConsoleHistoryHeight); 32 | ConsoleCurrentPtr = ConsoleBuffer; 33 | ConsoleCurrentPagePtr = ConsoleBuffer; 34 | ConsoleEndPtr = ConsoleBuffer + (GUI_Width-2)*2*ConsoleHistoryHeight; 35 | ConsoleTempEndPtr = ConsoleBuffer + (GUI_Width-2)*2*(ConsoleHistoryHeight+ConsoleHistoryTempHeight); 36 | ConsolePrintStr("VMXICE for linux - A Kernel Debugger Based On Intel VT-x\n",14,0); 37 | ConsolePrintStr(" \n",7,0); 38 | ConsolePrintStr("E-mail: mxz@live.cn\n",13,0); 39 | ConsolePrintStr("Website: http://www.vxgate.net\n",13,0); 40 | ConsolePrintStr(" \n",7,0); 41 | 42 | return true; 43 | } 44 | 45 | VOID ConsoleRelease(void) 46 | { 47 | if(ConsoleBuffer) 48 | { 49 | kfree(ConsoleBuffer); 50 | ConsoleBuffer = NULL; 51 | } 52 | } 53 | 54 | ULONG IsNewLine(PUCHAR ptr) 55 | { 56 | return (((ptr-ConsoleBuffer) % (ConsoleWidth*2)) == 0); 57 | } 58 | 59 | VOID ConsolePrintChar(UCHAR c,ULONG ForeColor,ULONG BackColor) 60 | { 61 | ConsoleCurrentPtr[0] = c; 62 | ConsoleCurrentPtr[1] = (ForeColor << 4) + (BackColor & 0xF); 63 | ConsoleCurrentPtr += 2; 64 | } 65 | 66 | VOID ConsolePrintCurrentPage(void) 67 | { 68 | PUCHAR p = ConsoleCurrentPagePtr; 69 | ULONG i = 0; 70 | ULONG x = 1,y = 25; 71 | UCHAR c; 72 | ULONG ForeColor; 73 | ULONG BackColor; 74 | 75 | while(i < ConsoleWidth*ConsoleHeight*2) 76 | { 77 | c = p[0]; 78 | ForeColor = p[1] >> 4; 79 | BackColor = p[1] & 0xF; 80 | PrintChar(x,y,ForeColor,BackColor,FALSE,c); 81 | x++; 82 | if(x == GUI_Width-1) 83 | { 84 | x = 1; 85 | y++; 86 | } 87 | i+=2; 88 | p+=2; 89 | } 90 | } 91 | 92 | VOID ConsolePrintPreviousPage(void) 93 | { 94 | if(ConsoleCurrentPagePtr > ConsoleBuffer) 95 | { 96 | ConsoleCurrentPagePtr -= ConsoleWidth*2; 97 | ConsolePrintCurrentPage(); 98 | } 99 | } 100 | 101 | VOID ConsolePrintNextPage(void) 102 | { 103 | PUCHAR NewLinePtr = ConsoleCurrentPagePtr + ConsoleWidth*2; 104 | 105 | if((NewLinePtr < ConsoleEndPtr) && ((NewLinePtr + ConsoleWidth*ConsoleHeight*2)= ConsoleEndPtr) 135 | { 136 | OverflowBytes = ((ConsoleCurrentPtr - ConsoleEndPtr + ConsoleWidth*2) / ConsoleWidth*2) * ConsoleWidth*2; 137 | ConsoleCurrentPtr -= OverflowBytes; 138 | memcpy(ConsoleBuffer, ConsoleBuffer+OverflowBytes, ConsoleWidth*2*(ConsoleHistoryHeight)); 139 | memset(ConsoleCurrentPtr,0,ConsoleEndPtr-ConsoleCurrentPtr); 140 | } 141 | 142 | if((ConsoleCurrentPtr - ConsoleWidth*ConsoleHeight*2) <= ConsoleBuffer) 143 | { 144 | ConsoleCurrentPagePtr = ConsoleBuffer; 145 | } 146 | else 147 | { 148 | ConsoleCurrentPagePtr = ConsoleCurrentPtr - ConsoleWidth*ConsoleHeight*2; 149 | while(!IsNewLine(ConsoleCurrentPagePtr)) 150 | ConsoleCurrentPagePtr += 2; 151 | } 152 | 153 | if(bScreenBackuped) 154 | ConsolePrintCurrentPage(); 155 | } 156 | 157 | -------------------------------------------------------------------------------- /linux/console.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | ULONG ConsoleInit(void); 4 | VOID ConsoleRelease(void); 5 | VOID ConsolePrintChar(UCHAR c,ULONG ForeColor,ULONG BackColor); 6 | VOID ConsolePrintStr(PUCHAR str,ULONG ForeColor,ULONG BackColor); 7 | //VOID ConsolePrintStr2(PUCHAR str,ULONG ForeColor,ULONG BackColor,ULONG RefreshScreen); 8 | VOID ConsolePrintCurrentPage(void); 9 | VOID ConsolePrintPreviousPage(void); 10 | VOID ConsolePrintNextPage(void); 11 | -------------------------------------------------------------------------------- /linux/dbg.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | #include "vmx.h" 3 | 4 | #ifndef _DBG_H_ 5 | #define _DBG_H_ 6 | 7 | #define INT3_OPCODE 0xCC 8 | #define PUSHFD_OPCODE 0x9C 9 | #define SYSEXIT_OPCODE 0x350F 10 | 11 | #define MAX_SW_BP 10 12 | #define MAX_STEP_BP 10 13 | 14 | typedef struct{ 15 | ULONG ProcessCR3; 16 | USHORT CodeSeg; 17 | ULONG Address; 18 | CHAR OldOpcode; 19 | CHAR IfCondition[128]; 20 | CHAR DoCmd[128]; 21 | }SW_BP, *PSW_BP; 22 | 23 | typedef struct{ 24 | ULONG BpType; //0:BPMB 1:BPMW 2:BPIO 3:BPMD 25 | ULONG BpRWE; //0:X 1:W 2:R 3:RW 26 | ULONG Address; 27 | CHAR IfCondition[128]; 28 | CHAR DoCmd[128]; 29 | }HW_BP, *PHW_BP; 30 | 31 | 32 | extern SW_BP SoftBPs[MAX_SW_BP]; 33 | extern SW_BP StepBPs[MAX_STEP_BP]; 34 | extern HW_BP HardBPs[4]; 35 | extern PSW_BP pCurrentSwBp; 36 | extern ULONG iCurrentHwBp; 37 | 38 | 39 | extern ULONG IsAddressRangeExist(ULONG Addr,ULONG Len); 40 | 41 | extern ULONG bSingleStepping; 42 | extern ULONG bSingleStepPushfd; 43 | 44 | extern ULONG bNeedRestoreScreen; 45 | extern ULONG bScreenBackuped; 46 | extern ULONG bShowGUIwhileSingleStepping; 47 | 48 | extern ULONG bDebuggerBreak; 49 | 50 | VOID RefreshOldRegister(PGUEST_CPU pCpu); 51 | VOID EnterHyperDebugger(PGUEST_CPU pCpu); 52 | VOID CmdSetSingleStep(PGUEST_CPU pCpu); 53 | 54 | VOID SwBreakpointEvent(PGUEST_CPU pCpu,PSW_BP pSoftBp); 55 | VOID SwStepOverEvent(PGUEST_CPU pCpu); 56 | 57 | VOID CmdStepOver(PGUEST_CPU pCpu); 58 | VOID ClearStepBps(void); 59 | VOID DebugCommandHandler(PGUEST_CPU pCpu,PUCHAR cmd); 60 | 61 | typedef VOID CMD_HANDLER (PGUEST_CPU pCpu,PCHAR cmd); 62 | typedef CMD_HANDLER *PCMD_HANDLER; 63 | 64 | typedef struct{ 65 | CHAR *Cmd; 66 | CHAR *Desc; 67 | CHAR *Usage; 68 | CHAR *Example; 69 | PCMD_HANDLER pHandler; 70 | }CMD_HELP, *PCMD_HELP; 71 | 72 | typedef struct{ 73 | PCHAR pszLine; 74 | ULONG ForeColor; 75 | ULONG BackColor; 76 | }HELP_INFO; 77 | 78 | VOID CmdDisplayHelp(PGUEST_CPU pCpu,PCHAR cmd); 79 | VOID CmdCalcExp(PGUEST_CPU pCpu,PCHAR cmd); 80 | VOID CmdDisplayMemoryByte(PGUEST_CPU pCpu,PCHAR cmd); 81 | VOID CmdDisplayMemoryWord(PGUEST_CPU pCpu,PCHAR cmd); 82 | VOID CmdDisplayMemoryDword(PGUEST_CPU pCpu,PCHAR cmd); 83 | VOID CmdDisplayIdt(PGUEST_CPU pCpu,PCHAR cmd); 84 | VOID CmdDisplayCpuReg(PGUEST_CPU pCpu,PCHAR cmd); 85 | VOID CmdGetPageInfo(PGUEST_CPU pCpu,PCHAR cmd); 86 | VOID CmdGetVirtAddr(PGUEST_CPU pCpu,PCHAR cmd); 87 | VOID CmdDisplayDisasm(PGUEST_CPU pCpu,PCHAR cmd); 88 | VOID CmdDisplayCallstack(PGUEST_CPU pCpu,PCHAR cmd); 89 | VOID CmdClearBreakpoint(PGUEST_CPU pCpu,PCHAR cmd); 90 | VOID CmdListBreakpoint(PGUEST_CPU pCpu,PCHAR cmd); 91 | VOID CmdSetSwBreakpoint(PGUEST_CPU pCpu,PCHAR cmd); 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /linux/dbgprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include /* For current */ 4 | #include /* For the tty declarations */ 5 | #include /* For LINUX_VERSION_CODE */ 6 | 7 | #include "dbgprint.h" 8 | 9 | void ttyprint(char *str) 10 | { 11 | struct tty_struct *my_tty; 12 | 13 | #if ( LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,5) ) 14 | my_tty = current->tty; 15 | #else 16 | my_tty = current->signal->tty; 17 | #endif 18 | if (my_tty != NULL) 19 | { 20 | my_tty->ops->write (my_tty,str,strlen(str)); 21 | } 22 | } 23 | 24 | void asmlinkage printf(const char* fmt, ...) 25 | { 26 | va_list args; 27 | char str[256] = {0}; 28 | 29 | va_start(args,fmt); 30 | vsprintf(str,fmt,args); 31 | va_end(args); 32 | 33 | ttyprint(str); 34 | } 35 | -------------------------------------------------------------------------------- /linux/dbgprint.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | #ifndef _DBGPRINT_H_ 4 | #define _DBGPRINT_H_ 5 | 6 | void asmlinkage printf(const char* fmt, ...); 7 | void ttyprint(char *str); 8 | 9 | #define RED_FONT ttyprint("\033[40;31m") 10 | #define GREEN_FONT ttyprint("\033[40;32m") 11 | #define YELLOW_FONT ttyprint("\033[40;33m") 12 | #define DEFAULT_FONT ttyprint("\033[0m") 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /linux/define.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINE_H_ 2 | #define _DEFINE_H_ 3 | 4 | typedef unsigned char UCHAR,*PUCHAR; 5 | typedef signed char CHAR,*PCHAR; 6 | typedef unsigned short int USHORT,*PUSHORT; 7 | typedef signed short int SHORT,*PSHORT; 8 | typedef unsigned int ULONG,*PULONG; 9 | typedef signed int LONG,*PLONG; 10 | typedef unsigned long long int ULONG64,*PULONG64; 11 | typedef signed long long int LONG64,*PLONG64; 12 | 13 | typedef void VOID,*PVOID; 14 | typedef bool BOOLEAN,*PBOOLEAN; 15 | 16 | #define TRUE true 17 | #define FALSE false 18 | 19 | typedef struct _LARGE_INTEGER { 20 | union { 21 | ULONG64 QuadPart; 22 | struct{ 23 | ULONG LowPart; 24 | ULONG HighPart; 25 | }; 26 | }; 27 | }LARGE_INTEGER; 28 | 29 | typedef LARGE_INTEGER PHYSICAL_ADDRESS; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /linux/exp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "mmu.h" 4 | #include "exp.h" 5 | #include "sym.h" 6 | #include "vmx.h" 7 | #include "vmmstring.h" 8 | #include "console.h" 9 | 10 | #define TYPE_DWORD 0 11 | #define TYPE_WORD 1 12 | #define TYPE_BYTE 2 13 | 14 | #define STACK_SIZE 48 15 | 16 | typedef struct { 17 | ULONG Stack[STACK_SIZE]; 18 | ULONG Top; 19 | }STACK,*PSTACK; 20 | 21 | VOID StackInit(PSTACK s) 22 | { 23 | s->Top = -1; 24 | } 25 | 26 | ULONG StackIsEmpty(PSTACK s) 27 | { 28 | return (s->Top == -1); 29 | } 30 | 31 | ULONG StackGetTop(PSTACK s,PULONG e) 32 | { 33 | *e = 0; 34 | if(StackIsEmpty(s)) 35 | return 0; 36 | *e = s->Stack[s->Top]; 37 | return 1; 38 | } 39 | 40 | VOID StackPush(PSTACK s,ULONG e) 41 | { 42 | s->Top++; 43 | s->Stack[s->Top] = e; 44 | } 45 | 46 | ULONG StackPop(PSTACK s,PULONG e) 47 | { 48 | *e = 0; 49 | if(StackIsEmpty(s)) 50 | return 0; 51 | *e = s->Stack[s->Top--]; 52 | return 1; 53 | } 54 | 55 | ULONG GetNumber(PCHAR ptr,PULONG v) 56 | { 57 | ULONG ret = 0; 58 | ULONG i = 0; 59 | CHAR c; 60 | 61 | while(1) 62 | { 63 | c = *ptr; 64 | if(c >= 'A' && c <= 'F') 65 | c = c - 'A' + 10; 66 | else if(c >= 'a' && c <= 'f') 67 | c = c - 'a' + 10; 68 | else if(c >= '0' && c <= '9') 69 | c = c - '0'; 70 | else 71 | break; 72 | 73 | ret = ret * 16 + c; 74 | ptr++; 75 | i++; 76 | } 77 | *v = ret; 78 | return i; 79 | } 80 | 81 | ULONG GetSymbol(PCHAR ptr,PCHAR str) 82 | { 83 | CHAR c; 84 | ULONG i = 0; 85 | 86 | while(*ptr) 87 | { 88 | c = *ptr; 89 | if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '@' || c == '?' || c == '_' || (c =='!' && *(ptr+1) != '=')) 90 | *str = c; 91 | else 92 | break; 93 | ptr++; 94 | str++; 95 | i++; 96 | } 97 | *str = 0; 98 | return i; 99 | } 100 | 101 | ULONG GetString(PCHAR ptr,PCHAR str) 102 | { 103 | ULONG i = 1; 104 | 105 | ptr++; 106 | while(*ptr) 107 | { 108 | *str = *ptr; 109 | if(*str == '"') 110 | break; 111 | str++; 112 | ptr++; 113 | i++; 114 | } 115 | *str = 0; 116 | return i+1; //×îºóÒ»¸öÒýºÅ 117 | } 118 | 119 | ULONG IsNumber(CHAR c) 120 | { 121 | return (c >= '0' && c <= '9'); 122 | } 123 | 124 | ULONG IsSpecOp(ULONG c) 125 | { 126 | PUCHAR pc = (PUCHAR)&c; 127 | switch(pc[0]) 128 | { 129 | case '=': 130 | if(pc[1] == '=') 131 | return 1; 132 | break; 133 | case '>': 134 | return 1; 135 | case '<': 136 | return 1; 137 | case '!': 138 | if(pc[1] == '=') 139 | return 1; 140 | break; 141 | case '|': 142 | if(pc[1] == '|') 143 | return 1; 144 | break; 145 | case '&': 146 | return 1; 147 | break; 148 | } 149 | return 0; 150 | } 151 | 152 | ULONG SafeStrCopy(PCHAR str1,PCHAR str2) 153 | { 154 | if(!IsAddressExist((ULONG)str2)) 155 | return FALSE; 156 | 157 | while(*str2) 158 | { 159 | *str1 = *str2; 160 | str1++; 161 | str2++; 162 | } 163 | *str1 = 0; 164 | return TRUE; 165 | } 166 | 167 | //È¡µØÖ·Öµ 168 | ULONG ReadValue(ULONG addr,ULONG type,PULONG value) 169 | { 170 | ULONG bRet = FALSE; 171 | 172 | *value = 0; 173 | if(!IsAddressExist(addr)) 174 | return FALSE; 175 | 176 | switch(type) 177 | { 178 | case TYPE_BYTE: 179 | *value = *(PUCHAR)addr; 180 | bRet = TRUE; 181 | break; 182 | 183 | case TYPE_WORD: 184 | *value = *(PUSHORT)addr; 185 | bRet = TRUE; 186 | break; 187 | 188 | case TYPE_DWORD: 189 | *value = *(PULONG)addr; 190 | bRet = TRUE; 191 | break; 192 | 193 | default: 194 | break; 195 | } 196 | 197 | return bRet; 198 | } 199 | 200 | //¼ÆËãÕ»ÖÐÒ»¸ö±í´ïʽµÄÖµ²¢ÈëÕ» 201 | //·µ»Ø0ʧ°Ü 1³É¹¦ 202 | ULONG CalcInStack(PSTACK ss,PSTACK sr) 203 | { 204 | ULONG a,b,r; 205 | ULONG s; 206 | PCHAR pc = (PCHAR)&s; 207 | CHAR str1[128]; 208 | CHAR str2[128]; 209 | ULONG ret; 210 | 211 | r = StackPop(sr,&b); 212 | if(!r) 213 | return 0; 214 | r = StackPop(sr,&a); 215 | if(!r) 216 | return 0; 217 | r = StackPop(ss,&s); 218 | if(!r) 219 | return 0; 220 | 221 | //printf("%d %c%c %d\n",a,pc[0],pc[1]?pc[1]:' ',b); 222 | 223 | switch(pc[0]) 224 | { 225 | case '+': 226 | StackPush(sr,a+b); 227 | break; 228 | case '-': 229 | StackPush(sr,a-b); 230 | break; 231 | case '*': 232 | StackPush(sr,a*b); 233 | break; 234 | case '/': 235 | if(!b) 236 | { 237 | //printf("³ý0´íÎó£¡\n"); 238 | return 0; 239 | } 240 | StackPush(sr,a/b); 241 | break; 242 | 243 | case '>': 244 | if(pc[1] == '=') 245 | StackPush(sr,a>=b); 246 | else 247 | StackPush(sr,a>b); 248 | break; 249 | case '<': 250 | if(pc[1] == '=') 251 | StackPush(sr,a<=b); 252 | else 253 | StackPush(sr,a': 311 | if(pc[1] == '=') 312 | return 2; 313 | break; 314 | case '<': 315 | if(pc[1] == '=') 316 | return 2; 317 | break; 318 | case '!': 319 | if(pc[1] == '=') 320 | return 2; 321 | break; 322 | case '|': 323 | if(pc[1] == '|') 324 | return 2; 325 | break; 326 | case '&': 327 | if(pc[1] == '&') 328 | return 2; 329 | break; 330 | 331 | default: 332 | break; 333 | } 334 | 335 | *c = 0; 336 | *c = *exp; 337 | return 1; 338 | } 339 | 340 | ULONG GetAddressForSymbol(PGUEST_CPU pCpu,PCHAR FullSymbolName) 341 | { 342 | if(!vmm_strcmpi(FullSymbolName,"eax")) 343 | return pCpu->pGuestRegs->eax; 344 | else if(!vmm_strcmpi(FullSymbolName,"ebx")) 345 | return pCpu->pGuestRegs->ebx; 346 | else if(!vmm_strcmpi(FullSymbolName,"ecx")) 347 | return pCpu->pGuestRegs->ecx; 348 | else if(!vmm_strcmpi(FullSymbolName,"edx")) 349 | return pCpu->pGuestRegs->edx; 350 | else if(!vmm_strcmpi(FullSymbolName,"esi")) 351 | return pCpu->pGuestRegs->esi; 352 | else if(!vmm_strcmpi(FullSymbolName,"edi")) 353 | return pCpu->pGuestRegs->edi; 354 | else if(!vmm_strcmpi(FullSymbolName,"esp")) 355 | return pCpu->pGuestRegs->esp; 356 | else if(!vmm_strcmpi(FullSymbolName,"ebp")) 357 | return pCpu->pGuestRegs->ebp; 358 | else if(!vmm_strcmpi(FullSymbolName,"eip")) 359 | return _ReadVMCS(GUEST_RIP); 360 | 361 | return LookupName(FullSymbolName); 362 | } 363 | 364 | /* 365 | Start: 366 | 1.Èç¹ûµ±Ç°ÊäÈë´®Öеõ½µÄÊÇÊý×Ö,ÔòÖ±½ÓѹÈëÖµÕ».È»ºóתµ½Start. 367 | 2.Èç¹ûµ±Ç°ÊäÈë´®Öеõ½µÄÊÇ·ûºÅ,ÄÇô¶Ô·ûºÅ½øÐÐÅжÏ. 368 | 1)Èç¹û·ûºÅÊÇ'+'»òÕß'-',ÔòÒÀ´Îµ¯³ö·ûºÅÕ»µÄ·ûºÅ,¼ÆËãÕ»ÖÐÊýÖµ,Ö±µ½µ¯³öµÄ·ûºÅ²»ÊÇ*,/,+,-¡£×îºóѹÈë·ûºÅ¡£ 369 | 2)Èç¹û·ûºÅÊÇ'*'»òÕß'/',ÔòѹÈë·ûºÅÕ» 370 | 3)Èç¹û·ûºÅÊÇ'(' '[' ,ÔòÖ±½Óѹ'(' '['Èë·ûºÅÕ» 371 | 4)Èç¹û·ûºÅÊÇ')',ÔòÒÀÕÕ·ûºÅÕ»µÄ˳Ðòµ¯³ö·ûºÅ,¼ÆËãÕ»ÖÐÊýÖµ,°Ñ½á¹ûѹÈëÖµÕ»,Ö±µ½·ûºÅÕ»¶¥ÊÇ'(',×îºóÔÙµ¯³ö'(' 372 | 5)Èç¹û·ûºÅÊÇ']',ÔòÒÀÕÕ·ûºÅÕ»µÄ˳Ðòµ¯³ö·ûºÅ,¼ÆËãÕ»ÖÐÊýÖµ,°Ñ½á¹ûѹÈëÖµÕ»,Ö±µ½·ûºÅÕ»¶¥ÊÇ'[',×îºóÔÙµ¯³ö'[' È»ºóµ¯³öµØÖ·£¬È¡µØÖ·ÖµÑ¹Èë¶ÑÕ» 373 | 6)Èç¹û·ûºÅÊÇ == >= <= != || && & > < ÄÇôÔòÒÀ´Îµ¯³ö·ûºÅÕ»µÄ·ûºÅ,¼ÆËãÕ»ÖÐÊýÖµ,Ö±µ½µ¯³öµÄ·ûºÅ²»ÊÇ ( && ||¡£×îºóѹÈë·ûºÅ¡£ 374 | ×îºóתµ½Start. 375 | 3.Èç¹ûµ±Ç°ÊäÈë´®µÃµ½µÄÊÇEOF(×Ö·û´®½áÊø·ûºÅ),Ôò¼ÆËãÕ»ÖÐÊýÖµ,ÖªµÀ·ûºÅջûÓзûºÅ. 376 | */ 377 | ULONG CalcExp(PVOID pCpu2,PCHAR exp,PULONG ret) 378 | { 379 | STACK ss,sr,st; //·ûºÅÕ»¡¢ÖµÕ»¡¢Àà±ðÕ» 380 | ULONG c; 381 | ULONG v,i,r; 382 | PUCHAR pv = (PUCHAR)&v; 383 | CHAR str[128]; 384 | CHAR sym[128]; 385 | ULONG type = 0; 386 | ULONG type2; 387 | PGUEST_CPU pCpu = (PGUEST_CPU)pCpu2; 388 | 389 | StackInit(&ss); 390 | StackInit(&sr); 391 | StackInit(&st); 392 | 393 | while(1) 394 | { 395 | i = GetChar(exp,&c); //ȡһ¸ö×Ö·û 396 | if(c == ' ') //ºöÂÔ¿Õ×Ö·û 397 | { 398 | exp++; 399 | continue; 400 | } 401 | if(IsNumber((CHAR)c)) //Êý×Ö£¿ 402 | { 403 | i = GetNumber(exp,&v); //Ö±½ÓѹÈëÖµÕ» 404 | StackPush(&sr,v); 405 | exp += i; 406 | continue; 407 | } 408 | else if(IsSpecOp(c)) //ÌØÊâ²Ù×÷·û£¿ 409 | { 410 | r = StackGetTop(&ss,&v); 411 | while(r && v != '(' && pv[0]!='&' && pv[1]!='&' && pv[0]!='|' && pv[1]!='|') //¼ÆËãÕ»Öбí´ïʽֱµ½È¡³öµÄÊÇ ( && || 412 | { 413 | v = CalcInStack(&ss,&sr); 414 | if(!v) 415 | return 0; 416 | r = StackGetTop(&ss,&v); 417 | } 418 | StackPush(&ss,c); //ѹÈëÌØÊâ²Ù×÷·û 419 | } 420 | else if(c == '+' || c == '-') //+-ÔËËã·û 421 | { 422 | r = StackGetTop(&ss,&v); 423 | while(v == '+' || v == '-' || v == '*' || v == '/') //¼ÆËãÕ»Öбí´ïʽֱµ½È¡³öµÄ²»ÊÇ +-*/ 424 | { 425 | v = CalcInStack(&ss,&sr); 426 | if(!v) 427 | return 0; 428 | r = StackGetTop(&ss,&v); 429 | } 430 | StackPush(&ss,c); //+-ÔËËã·ûÈëÕ» 431 | } 432 | else if(c == '*' || c == '/' || c == '(' || c == '[') // * / ( [ Ö±½ÓÈëÕ» 433 | { 434 | StackPush(&ss,c); 435 | if(c == '[') 436 | { 437 | //printf("type = %d\n",type); 438 | StackPush(&st,type); 439 | type = 0; 440 | } 441 | } 442 | else if(c == ')') // ×Ö·û) 443 | { 444 | r = StackGetTop(&ss,&v); 445 | if(!r) 446 | return 0; 447 | while(v != '(') //¼ÆËãÕ»Öбí´ïʽֱµ½È¡³öµÄÊÇ ( 448 | { 449 | v = CalcInStack(&ss,&sr); 450 | if(!v) 451 | return 0; 452 | r = StackGetTop(&ss,&v); 453 | } 454 | StackPop(&ss,&v); //µ¯³ö( 455 | } 456 | else if(c == ']') //×Ö·û] 457 | { 458 | r = StackGetTop(&ss,&v); 459 | if(!r) 460 | return 0; 461 | while(v != '[') //¼ÆËãÕ»Öбí´ïʽֱµ½È¡³öµÄÊÇ [ 462 | { 463 | v = CalcInStack(&ss,&sr); 464 | if(!v) 465 | return 0; 466 | r = StackGetTop(&ss,&v); 467 | } 468 | StackPop(&ss,&v); //µ¯³ö[ 469 | r = StackPop(&sr,&v); //µ¯³öµØÖ· 470 | if(!r) 471 | return 0; 472 | r = StackPop(&st,&type2); 473 | if(!r) 474 | return 0; 475 | r = ReadValue(v,type2,&v); 476 | if(!r) 477 | return 0; 478 | StackPush(&sr,v); //È¡µØÖ·ÖµÈëÕ» 479 | } 480 | else if(c == 0) //½áÊø·û 481 | { 482 | while(!StackIsEmpty(&ss)) //¼ÆËãÕ»Öбí´ïʽֱµ½Õ»¿Õ 483 | { 484 | v = CalcInStack(&ss,&sr); 485 | if(!v) 486 | return 0; 487 | } 488 | r = StackPop(&sr,ret); //µ¯³ö±í´ïʽ½á¹ûÖµ 489 | if(!r) 490 | return 0; 491 | return 1; 492 | } 493 | else if(c == '"') //ÒýºÅ 494 | { 495 | i = GetString(exp,str); 496 | //printf("È¡µ½×Ö·û´® %s\n",str); 497 | StackPush(&sr,(ULONG)&str); 498 | exp += i; 499 | continue; 500 | } 501 | else 502 | { 503 | i = GetSymbol(exp,sym); //·ûºÅ»òÕ߼ĴæÆ÷Ãû£¿ 504 | if(!i) 505 | { 506 | //printf("ÎÞ·¨Ê¶±ðµÄ×Ö·û£º%c\n",*exp); 507 | return 0; 508 | } 509 | if(!vmm_strncmpi(sym,"dword",5)) 510 | { 511 | type = TYPE_DWORD; 512 | } 513 | else if(!vmm_strncmpi(sym,"word",4)) 514 | { 515 | type = TYPE_WORD; 516 | } 517 | else if(!vmm_strncmpi(sym,"byte",4)) 518 | { 519 | type = TYPE_BYTE; 520 | } 521 | else 522 | { 523 | v = GetAddressForSymbol(pCpu,sym); 524 | StackPush(&sr,v); 525 | } 526 | exp += i; 527 | continue; 528 | } 529 | exp += i; 530 | } 531 | return 0; 532 | } 533 | -------------------------------------------------------------------------------- /linux/exp.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | #ifndef EXP_H 4 | #define EXP_H 5 | 6 | ULONG CalcExp(PVOID pCpu,PCHAR exp,PULONG ret); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /linux/font_inc.c: -------------------------------------------------------------------------------- 1 | char cFontData[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, 0x99, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7, 0xE7, 0xE7, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7, 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6C, 0xFE, 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18, 0x30, 0x66, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0x8C, 0x18, 0x30, 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x70, 0x1C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, 0x30, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xFE, 0x66, 0x60, 0x7C, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x76, 0x36, 0x7E, 0xD8, 0xD8, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC, 0xFE, 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00, 0x00, 0xC6, 0xC6, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xF8, 0xC4, 0xCC, 0xDE, 0xCC, 0xCC, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1B, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC6, 0xCC, 0xD8, 0x30, 0x60, 0xDC, 0x86, 0x0C, 0x18, 0x3E, 0x00, 0x00, 0xC0, 0xC0, 0xC6, 0xCC, 0xD8, 0x30, 0x66, 0xCE, 0x9E, 0x3E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6C, 0xD8, 0x6C, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6C, 0x36, 0x6C, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0xC0, 0xC0, 0x40, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C, 0x3E, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xDB, 0xDB, 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xD8, 0x30, 0x60, 0xC8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 2 | 3 | -------------------------------------------------------------------------------- /linux/keyboard.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "vmx.h" 3 | #include "keyboard.h" 4 | 5 | ULONG i8042ReadKeyboardData(PUCHAR pc, PBOOLEAN pisMouse) 6 | { 7 | UCHAR port_status; 8 | 9 | port_status = READ_PORT_UCHAR(KEYB_REGISTER_STATUS); 10 | while (port_status & KEYB_STATUS_OBUFFER_FULL) 11 | { 12 | /* Data is available */ 13 | *pc = READ_PORT_UCHAR(KEYB_REGISTER_DATA); 14 | /* Check if data is valid (i.e., no timeout, no parity error) */ 15 | if ((port_status & KEYB_STATUS_PARITY_ERROR) == 0) 16 | { 17 | /* Check if this is a mouse event or not */ 18 | *pisMouse = (port_status & KEYB_STATUS_TRANSMIT_TIMEOUT) != 0; 19 | return true; 20 | } 21 | } 22 | return false; 23 | } 24 | 25 | /* Inspired from ReactOS's i8042 keyboard driver */ 26 | ULONG KeyboardReadKeystroke(PUCHAR pc, PBOOLEAN pisMouse) 27 | { 28 | ULONG counter; 29 | UCHAR port_status; 30 | UCHAR scancode; 31 | ULONG r; 32 | 33 | counter = POLL_STATUS_ITERATIONS; 34 | while (counter) 35 | { 36 | port_status = READ_PORT_UCHAR(KEYB_REGISTER_STATUS); 37 | r = i8042ReadKeyboardData(&scancode, pisMouse); 38 | if (r == true) 39 | break; 40 | 41 | _CpuSleep(1); 42 | counter--; 43 | } 44 | 45 | if (counter == 0) 46 | return false; 47 | 48 | *pc = scancode; 49 | return true; 50 | } 51 | -------------------------------------------------------------------------------- /linux/keyboard.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | #ifndef _KEYBOARD_H_ 4 | #define _KEYBOARD_H_ 5 | 6 | /* In READ mode. Can be read at any time */ 7 | #define KEYB_REGISTER_STATUS 0x64 8 | 9 | /* In WRITE mode. Writing this port sets Bit 3 of the status register to 1 and 10 | the byte is treated as a controller command */ 11 | #define KEYB_REGISTER_COMMAND 0x64 12 | 13 | /* In READ mode. Should be read if bit 0 of status register is 1 */ 14 | #define KEYB_REGISTER_OUTPUT 0x60 15 | 16 | /* In WRITE mode. Data should only be written if Bit 1 of the status register 17 | is zero (register is empty) */ 18 | #define KEYB_REGISTER_DATA 0x60 19 | 20 | #define POLL_STATUS_ITERATIONS 12000 21 | 22 | /* 23 | 8042 Status Register (port 64h read) 24 | 25 | |7|6|5|4|3|2|1|0| 8042 Status Register 26 | | | | | | | | `---- output register (60h) has data for system 27 | | | | | | | `----- input register (60h/64h) has data for 8042 28 | | | | | | `------ system flag (set to 0 after power on reset) 29 | | | | | `------- data in input register is command (1) or data (0) 30 | | | | `-------- 1=keyboard enabled, 0=keyboard disabled (via switch) 31 | | | `--------- 1=transmit timeout (data transmit not complete) 32 | | `---------- 1=receive timeout (data transmit not complete) 33 | `----------- 1=even parity rec'd, 0=odd parity rec'd (should be odd) 34 | */ 35 | 36 | /* Status register bits */ 37 | #define KEYB_STATUS_OBUFFER_FULL (1 << 0) 38 | #define KEYB_STATUS_IBUFFER_FULL (1 << 1) 39 | #define KEYB_STATUS_TRANSMIT_TIMEOUT (1 << 5) 40 | #define KEYB_STATUS_PARITY_ERROR (1 << 7) 41 | 42 | /* i8042 Commands */ 43 | #define KEYB_COMMAND_WRITE_OUTPUT 0xd2 44 | #define KEYB_COMMAND_DISABLE_KEYBOARD 0xad 45 | #define KEYB_COMMAND_ENABLE_KEYBOARD 0xae 46 | #define KEYB_COMMAND_DISABLE_MOUSE 0xa7 47 | #define KEYB_COMMAND_ENABLE_MOUSE 0xa8 48 | 49 | /* Scancode flags */ 50 | #define IS_SCANCODE_RELEASE(c) (c & 0x80) 51 | #define SCANCODE_RELEASE_FLAG 0x80 52 | 53 | 54 | ULONG KeyboardReadKeystroke(PUCHAR pc, PBOOLEAN pisMouse); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /linux/libudis86/decode.h: -------------------------------------------------------------------------------- 1 | #ifndef UD_DECODE_H 2 | #define UD_DECODE_H 3 | 4 | #define MAX_INSN_LENGTH 15 5 | 6 | /* register classes */ 7 | #define T_NONE 0 8 | #define T_GPR 1 9 | #define T_MMX 2 10 | #define T_CRG 3 11 | #define T_DBG 4 12 | #define T_SEG 5 13 | #define T_XMM 6 14 | 15 | /* itab prefix bits */ 16 | #define P_none ( 0 ) 17 | #define P_c1 ( 1 << 0 ) 18 | #define P_C1(n) ( ( n >> 0 ) & 1 ) 19 | #define P_rexb ( 1 << 1 ) 20 | #define P_REXB(n) ( ( n >> 1 ) & 1 ) 21 | #define P_depM ( 1 << 2 ) 22 | #define P_DEPM(n) ( ( n >> 2 ) & 1 ) 23 | #define P_c3 ( 1 << 3 ) 24 | #define P_C3(n) ( ( n >> 3 ) & 1 ) 25 | #define P_inv64 ( 1 << 4 ) 26 | #define P_INV64(n) ( ( n >> 4 ) & 1 ) 27 | #define P_rexw ( 1 << 5 ) 28 | #define P_REXW(n) ( ( n >> 5 ) & 1 ) 29 | #define P_c2 ( 1 << 6 ) 30 | #define P_C2(n) ( ( n >> 6 ) & 1 ) 31 | #define P_def64 ( 1 << 7 ) 32 | #define P_DEF64(n) ( ( n >> 7 ) & 1 ) 33 | #define P_rexr ( 1 << 8 ) 34 | #define P_REXR(n) ( ( n >> 8 ) & 1 ) 35 | #define P_oso ( 1 << 9 ) 36 | #define P_OSO(n) ( ( n >> 9 ) & 1 ) 37 | #define P_aso ( 1 << 10 ) 38 | #define P_ASO(n) ( ( n >> 10 ) & 1 ) 39 | #define P_rexx ( 1 << 11 ) 40 | #define P_REXX(n) ( ( n >> 11 ) & 1 ) 41 | #define P_ImpAddr ( 1 << 12 ) 42 | #define P_IMPADDR(n) ( ( n >> 12 ) & 1 ) 43 | 44 | /* rex prefix bits */ 45 | #define REX_W(r) ( ( 0xF & ( r ) ) >> 3 ) 46 | #define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 ) 47 | #define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 ) 48 | #define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 ) 49 | #define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \ 50 | ( P_REXR(n) << 2 ) | \ 51 | ( P_REXX(n) << 1 ) | \ 52 | ( P_REXB(n) << 0 ) ) 53 | 54 | /* scable-index-base bits */ 55 | #define SIB_S(b) ( ( b ) >> 6 ) 56 | #define SIB_I(b) ( ( ( b ) >> 3 ) & 7 ) 57 | #define SIB_B(b) ( ( b ) & 7 ) 58 | 59 | /* modrm bits */ 60 | #define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 ) 61 | #define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 ) 62 | #define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 ) 63 | #define MODRM_RM(b) ( ( b ) & 7 ) 64 | 65 | /* operand type constants -- order is important! */ 66 | 67 | enum ud_operand_code { 68 | OP_NONE, 69 | 70 | OP_A, OP_E, OP_M, OP_G, 71 | OP_I, 72 | 73 | OP_AL, OP_CL, OP_DL, OP_BL, 74 | OP_AH, OP_CH, OP_DH, OP_BH, 75 | 76 | OP_ALr8b, OP_CLr9b, OP_DLr10b, OP_BLr11b, 77 | OP_AHr12b, OP_CHr13b, OP_DHr14b, OP_BHr15b, 78 | 79 | OP_AX, OP_CX, OP_DX, OP_BX, 80 | OP_SI, OP_DI, OP_SP, OP_BP, 81 | 82 | OP_rAX, OP_rCX, OP_rDX, OP_rBX, 83 | OP_rSP, OP_rBP, OP_rSI, OP_rDI, 84 | 85 | OP_rAXr8, OP_rCXr9, OP_rDXr10, OP_rBXr11, 86 | OP_rSPr12, OP_rBPr13, OP_rSIr14, OP_rDIr15, 87 | 88 | OP_eAX, OP_eCX, OP_eDX, OP_eBX, 89 | OP_eSP, OP_eBP, OP_eSI, OP_eDI, 90 | 91 | OP_ES, OP_CS, OP_SS, OP_DS, 92 | OP_FS, OP_GS, 93 | 94 | OP_ST0, OP_ST1, OP_ST2, OP_ST3, 95 | OP_ST4, OP_ST5, OP_ST6, OP_ST7, 96 | 97 | OP_J, OP_S, OP_O, 98 | OP_I1, OP_I3, 99 | 100 | OP_V, OP_W, OP_Q, OP_P, 101 | 102 | OP_R, OP_C, OP_D, OP_VR, OP_PR 103 | }; 104 | 105 | 106 | /* operand size constants */ 107 | 108 | enum ud_operand_size { 109 | SZ_NA = 0, 110 | SZ_Z = 1, 111 | SZ_V = 2, 112 | SZ_P = 3, 113 | SZ_WP = 4, 114 | SZ_DP = 5, 115 | SZ_MDQ = 6, 116 | SZ_RDQ = 7, 117 | 118 | /* the following values are used as is, 119 | * and thus hard-coded. changing them 120 | * will break internals 121 | */ 122 | SZ_B = 8, 123 | SZ_W = 16, 124 | SZ_D = 32, 125 | SZ_Q = 64, 126 | SZ_T = 80, 127 | }; 128 | 129 | /* itab entry operand definitions */ 130 | 131 | #define O_rSPr12 { OP_rSPr12, SZ_NA } 132 | #define O_BL { OP_BL, SZ_NA } 133 | #define O_BH { OP_BH, SZ_NA } 134 | #define O_BP { OP_BP, SZ_NA } 135 | #define O_AHr12b { OP_AHr12b, SZ_NA } 136 | #define O_BX { OP_BX, SZ_NA } 137 | #define O_Jz { OP_J, SZ_Z } 138 | #define O_Jv { OP_J, SZ_V } 139 | #define O_Jb { OP_J, SZ_B } 140 | #define O_rSIr14 { OP_rSIr14, SZ_NA } 141 | #define O_GS { OP_GS, SZ_NA } 142 | #define O_D { OP_D, SZ_NA } 143 | #define O_rBPr13 { OP_rBPr13, SZ_NA } 144 | #define O_Ob { OP_O, SZ_B } 145 | #define O_P { OP_P, SZ_NA } 146 | #define O_Ow { OP_O, SZ_W } 147 | #define O_Ov { OP_O, SZ_V } 148 | #define O_Gw { OP_G, SZ_W } 149 | #define O_Gv { OP_G, SZ_V } 150 | #define O_rDX { OP_rDX, SZ_NA } 151 | #define O_Gx { OP_G, SZ_MDQ } 152 | #define O_Gd { OP_G, SZ_D } 153 | #define O_Gb { OP_G, SZ_B } 154 | #define O_rBXr11 { OP_rBXr11, SZ_NA } 155 | #define O_rDI { OP_rDI, SZ_NA } 156 | #define O_rSI { OP_rSI, SZ_NA } 157 | #define O_ALr8b { OP_ALr8b, SZ_NA } 158 | #define O_eDI { OP_eDI, SZ_NA } 159 | #define O_Gz { OP_G, SZ_Z } 160 | #define O_eDX { OP_eDX, SZ_NA } 161 | #define O_DHr14b { OP_DHr14b, SZ_NA } 162 | #define O_rSP { OP_rSP, SZ_NA } 163 | #define O_PR { OP_PR, SZ_NA } 164 | #define O_NONE { OP_NONE, SZ_NA } 165 | #define O_rCX { OP_rCX, SZ_NA } 166 | #define O_jWP { OP_J, SZ_WP } 167 | #define O_rDXr10 { OP_rDXr10, SZ_NA } 168 | #define O_Md { OP_M, SZ_D } 169 | #define O_C { OP_C, SZ_NA } 170 | #define O_G { OP_G, SZ_NA } 171 | #define O_Mb { OP_M, SZ_B } 172 | #define O_Mt { OP_M, SZ_T } 173 | #define O_S { OP_S, SZ_NA } 174 | #define O_Mq { OP_M, SZ_Q } 175 | #define O_W { OP_W, SZ_NA } 176 | #define O_ES { OP_ES, SZ_NA } 177 | #define O_rBX { OP_rBX, SZ_NA } 178 | #define O_Ed { OP_E, SZ_D } 179 | #define O_DLr10b { OP_DLr10b, SZ_NA } 180 | #define O_Mw { OP_M, SZ_W } 181 | #define O_Eb { OP_E, SZ_B } 182 | #define O_Ex { OP_E, SZ_MDQ } 183 | #define O_Ez { OP_E, SZ_Z } 184 | #define O_Ew { OP_E, SZ_W } 185 | #define O_Ev { OP_E, SZ_V } 186 | #define O_Ep { OP_E, SZ_P } 187 | #define O_FS { OP_FS, SZ_NA } 188 | #define O_Ms { OP_M, SZ_W } 189 | #define O_rAXr8 { OP_rAXr8, SZ_NA } 190 | #define O_eBP { OP_eBP, SZ_NA } 191 | #define O_Isb { OP_I, SZ_SB } 192 | #define O_eBX { OP_eBX, SZ_NA } 193 | #define O_rCXr9 { OP_rCXr9, SZ_NA } 194 | #define O_jDP { OP_J, SZ_DP } 195 | #define O_CH { OP_CH, SZ_NA } 196 | #define O_CL { OP_CL, SZ_NA } 197 | #define O_R { OP_R, SZ_RDQ } 198 | #define O_V { OP_V, SZ_NA } 199 | #define O_CS { OP_CS, SZ_NA } 200 | #define O_CHr13b { OP_CHr13b, SZ_NA } 201 | #define O_eCX { OP_eCX, SZ_NA } 202 | #define O_eSP { OP_eSP, SZ_NA } 203 | #define O_SS { OP_SS, SZ_NA } 204 | #define O_SP { OP_SP, SZ_NA } 205 | #define O_BLr11b { OP_BLr11b, SZ_NA } 206 | #define O_SI { OP_SI, SZ_NA } 207 | #define O_eSI { OP_eSI, SZ_NA } 208 | #define O_DL { OP_DL, SZ_NA } 209 | #define O_DH { OP_DH, SZ_NA } 210 | #define O_DI { OP_DI, SZ_NA } 211 | #define O_DX { OP_DX, SZ_NA } 212 | #define O_rBP { OP_rBP, SZ_NA } 213 | #define O_Gvw { OP_G, SZ_MDQ } 214 | #define O_I1 { OP_I1, SZ_NA } 215 | #define O_I3 { OP_I3, SZ_NA } 216 | #define O_DS { OP_DS, SZ_NA } 217 | #define O_ST4 { OP_ST4, SZ_NA } 218 | #define O_ST5 { OP_ST5, SZ_NA } 219 | #define O_ST6 { OP_ST6, SZ_NA } 220 | #define O_ST7 { OP_ST7, SZ_NA } 221 | #define O_ST0 { OP_ST0, SZ_NA } 222 | #define O_ST1 { OP_ST1, SZ_NA } 223 | #define O_ST2 { OP_ST2, SZ_NA } 224 | #define O_ST3 { OP_ST3, SZ_NA } 225 | #define O_E { OP_E, SZ_NA } 226 | #define O_AH { OP_AH, SZ_NA } 227 | #define O_M { OP_M, SZ_NA } 228 | #define O_AL { OP_AL, SZ_NA } 229 | #define O_CLr9b { OP_CLr9b, SZ_NA } 230 | #define O_Q { OP_Q, SZ_NA } 231 | #define O_eAX { OP_eAX, SZ_NA } 232 | #define O_VR { OP_VR, SZ_NA } 233 | #define O_AX { OP_AX, SZ_NA } 234 | #define O_rAX { OP_rAX, SZ_NA } 235 | #define O_Iz { OP_I, SZ_Z } 236 | #define O_rDIr15 { OP_rDIr15, SZ_NA } 237 | #define O_Iw { OP_I, SZ_W } 238 | #define O_Iv { OP_I, SZ_V } 239 | #define O_Ap { OP_A, SZ_P } 240 | #define O_CX { OP_CX, SZ_NA } 241 | #define O_Ib { OP_I, SZ_B } 242 | #define O_BHr15b { OP_BHr15b, SZ_NA } 243 | 244 | 245 | /* A single operand of an entry in the instruction table. 246 | * (internal use only) 247 | */ 248 | struct ud_itab_entry_operand 249 | { 250 | enum ud_operand_code type; 251 | enum ud_operand_size size; 252 | }; 253 | 254 | 255 | /* A single entry in an instruction table. 256 | *(internal use only) 257 | */ 258 | struct ud_itab_entry 259 | { 260 | enum ud_mnemonic_code mnemonic; 261 | struct ud_itab_entry_operand operand1; 262 | struct ud_itab_entry_operand operand2; 263 | struct ud_itab_entry_operand operand3; 264 | uint32_t prefix; 265 | }; 266 | 267 | extern const char * ud_lookup_mnemonic( enum ud_mnemonic_code c ); 268 | 269 | #endif /* UD_DECODE_H */ 270 | 271 | /* vim:cindent 272 | * vim:expandtab 273 | * vim:ts=4 274 | * vim:sw=4 275 | */ 276 | -------------------------------------------------------------------------------- /linux/libudis86/extern.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * extern.h 3 | * 4 | * Copyright (c) 2004, 2005, 2006, Vivek Mohan 5 | * All rights reserved. See LICENSE 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | #ifndef UD_EXTERN_H 9 | #define UD_EXTERN_H 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #include "types.h" 16 | 17 | /* ============================= PUBLIC API ================================= */ 18 | 19 | extern void ud_init(struct ud*); 20 | 21 | extern void ud_set_mode(struct ud*, uint8_t); 22 | 23 | extern void ud_set_pc(struct ud*, uint64_t); 24 | 25 | extern void ud_set_input_hook(struct ud*, int (*)(struct ud*)); 26 | 27 | extern void ud_set_input_buffer(struct ud*, uint8_t*, size_t); 28 | 29 | #ifndef __UD_STANDALONE__ 30 | extern void ud_set_input_file(struct ud*, FILE*); 31 | #endif /* __UD_STANDALONE__ */ 32 | 33 | extern void ud_set_vendor(struct ud*, unsigned); 34 | 35 | extern void ud_set_syntax(struct ud*, void (*)(struct ud*)); 36 | 37 | extern void ud_input_skip(struct ud*, size_t); 38 | 39 | extern int ud_input_end(struct ud*); 40 | 41 | extern unsigned int ud_decode(struct ud*); 42 | 43 | extern unsigned int ud_disassemble(struct ud*); 44 | 45 | extern void ud_translate_intel(struct ud*); 46 | 47 | extern void ud_translate_att(struct ud*); 48 | 49 | extern char* ud_insn_asm(struct ud* u); 50 | 51 | extern uint8_t* ud_insn_ptr(struct ud* u); 52 | 53 | extern uint64_t ud_insn_off(struct ud*); 54 | 55 | extern char* ud_insn_hex(struct ud*); 56 | 57 | extern unsigned int ud_insn_len(struct ud* u); 58 | 59 | extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); 60 | 61 | /* ========================================================================== */ 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | #endif 67 | -------------------------------------------------------------------------------- /linux/libudis86/input.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * input.c 3 | * 4 | * Copyright (c) 2004, 2005, 2006, Vivek Mohan 5 | * All rights reserved. See LICENSE 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | #include "extern.h" 9 | #include "types.h" 10 | #include "input.h" 11 | 12 | /* ----------------------------------------------------------------------------- 13 | * inp_buff_hook() - Hook for buffered inputs. 14 | * ----------------------------------------------------------------------------- 15 | */ 16 | static int 17 | inp_buff_hook(struct ud* u) 18 | { 19 | if (u->inp_buff < u->inp_buff_end) 20 | return *u->inp_buff++; 21 | else return -1; 22 | } 23 | 24 | #ifndef __UD_STANDALONE__ 25 | /* ----------------------------------------------------------------------------- 26 | * inp_file_hook() - Hook for FILE inputs. 27 | * ----------------------------------------------------------------------------- 28 | */ 29 | static int 30 | inp_file_hook(struct ud* u) 31 | { 32 | return 0; 33 | } 34 | #endif /* __UD_STANDALONE__*/ 35 | 36 | /* ============================================================================= 37 | * ud_inp_set_hook() - Sets input hook. 38 | * ============================================================================= 39 | */ 40 | extern void 41 | ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*)) 42 | { 43 | u->inp_hook = hook; 44 | inp_init(u); 45 | } 46 | 47 | /* ============================================================================= 48 | * ud_inp_set_buffer() - Set buffer as input. 49 | * ============================================================================= 50 | */ 51 | extern void 52 | ud_set_input_buffer(register struct ud* u, uint8_t* buf, size_t len) 53 | { 54 | u->inp_hook = inp_buff_hook; 55 | u->inp_buff = buf; 56 | u->inp_buff_end = buf + len; 57 | inp_init(u); 58 | } 59 | 60 | #ifndef __UD_STANDALONE__ 61 | /* ============================================================================= 62 | * ud_input_set_file() - Set buffer as input. 63 | * ============================================================================= 64 | */ 65 | extern void 66 | ud_set_input_file(register struct ud* u, FILE* f) 67 | { 68 | u->inp_hook = inp_file_hook; 69 | u->inp_file = f; 70 | inp_init(u); 71 | } 72 | #endif /* __UD_STANDALONE__ */ 73 | 74 | /* ============================================================================= 75 | * ud_input_skip() - Skip n input bytes. 76 | * ============================================================================= 77 | */ 78 | extern void 79 | ud_input_skip(struct ud* u, size_t n) 80 | { 81 | while (n--) { 82 | u->inp_hook(u); 83 | } 84 | } 85 | 86 | /* ============================================================================= 87 | * ud_input_end() - Test for end of input. 88 | * ============================================================================= 89 | */ 90 | extern int 91 | ud_input_end(struct ud* u) 92 | { 93 | return (u->inp_curr == u->inp_fill) && u->inp_end; 94 | } 95 | 96 | /* ----------------------------------------------------------------------------- 97 | * inp_next() - Loads and returns the next byte from input. 98 | * 99 | * inp_curr and inp_fill are pointers to the cache. The program is written based 100 | * on the property that they are 8-bits in size, and will eventually wrap around 101 | * forming a circular buffer. So, the size of the cache is 256 in size, kind of 102 | * unnecessary yet optimized. 103 | * 104 | * A buffer inp_sess stores the bytes disassembled for a single session. 105 | * ----------------------------------------------------------------------------- 106 | */ 107 | extern uint8_t inp_next(struct ud* u) 108 | { 109 | int c = -1; 110 | /* if current pointer is not upto the fill point in the 111 | * input cache. 112 | */ 113 | if ( u->inp_curr != u->inp_fill ) { 114 | c = u->inp_cache[ ++u->inp_curr ]; 115 | /* if !end-of-input, call the input hook and get a byte */ 116 | } else if ( u->inp_end || ( c = u->inp_hook( u ) ) == -1 ) { 117 | /* end-of-input, mark it as an error, since the decoder, 118 | * expected a byte more. 119 | */ 120 | u->error = 1; 121 | /* flag end of input */ 122 | u->inp_end = 1; 123 | return 0; 124 | } else { 125 | /* increment pointers, we have a new byte. */ 126 | u->inp_curr = ++u->inp_fill; 127 | /* add the byte to the cache */ 128 | u->inp_cache[ u->inp_fill ] = c; 129 | } 130 | /* record bytes input per decode-session. */ 131 | u->inp_sess[ u->inp_ctr++ ] = c; 132 | /* return byte */ 133 | return ( uint8_t ) c; 134 | } 135 | 136 | /* ----------------------------------------------------------------------------- 137 | * inp_back() - Move back a single byte in the stream. 138 | * ----------------------------------------------------------------------------- 139 | */ 140 | extern void 141 | inp_back(struct ud* u) 142 | { 143 | if ( u->inp_ctr > 0 ) { 144 | --u->inp_curr; 145 | --u->inp_ctr; 146 | } 147 | } 148 | 149 | /* ----------------------------------------------------------------------------- 150 | * inp_peek() - Peek into the next byte in source. 151 | * ----------------------------------------------------------------------------- 152 | */ 153 | extern uint8_t 154 | inp_peek(struct ud* u) 155 | { 156 | uint8_t r = inp_next(u); 157 | if ( !u->error ) inp_back(u); /* Don't backup if there was an error */ 158 | return r; 159 | } 160 | 161 | /* ----------------------------------------------------------------------------- 162 | * inp_move() - Move ahead n input bytes. 163 | * ----------------------------------------------------------------------------- 164 | */ 165 | extern void 166 | inp_move(struct ud* u, size_t n) 167 | { 168 | while (n--) 169 | inp_next(u); 170 | } 171 | 172 | /*------------------------------------------------------------------------------ 173 | * inp_uintN() - return uintN from source. 174 | *------------------------------------------------------------------------------ 175 | */ 176 | extern uint8_t 177 | inp_uint8(struct ud* u) 178 | { 179 | return inp_next(u); 180 | } 181 | 182 | extern uint16_t 183 | inp_uint16(struct ud* u) 184 | { 185 | uint16_t r, ret; 186 | 187 | ret = inp_next(u); 188 | r = inp_next(u); 189 | return ret | (r << 8); 190 | } 191 | 192 | extern uint32_t 193 | inp_uint32(struct ud* u) 194 | { 195 | uint32_t r, ret; 196 | 197 | ret = inp_next(u); 198 | r = inp_next(u); 199 | ret = ret | (r << 8); 200 | r = inp_next(u); 201 | ret = ret | (r << 16); 202 | r = inp_next(u); 203 | return ret | (r << 24); 204 | } 205 | 206 | extern uint64_t 207 | inp_uint64(struct ud* u) 208 | { 209 | uint64_t r, ret; 210 | 211 | ret = inp_next(u); 212 | r = inp_next(u); 213 | ret = ret | (r << 8); 214 | r = inp_next(u); 215 | ret = ret | (r << 16); 216 | r = inp_next(u); 217 | ret = ret | (r << 24); 218 | r = inp_next(u); 219 | ret = ret | (r << 32); 220 | r = inp_next(u); 221 | ret = ret | (r << 40); 222 | r = inp_next(u); 223 | ret = ret | (r << 48); 224 | r = inp_next(u); 225 | return ret | (r << 56); 226 | } 227 | -------------------------------------------------------------------------------- /linux/libudis86/input.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * input.h 3 | * 4 | * Copyright (c) 2006, Vivek Mohan 5 | * All rights reserved. See LICENSE 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | #ifndef UD_INPUT_H 9 | #define UD_INPUT_H 10 | 11 | #include "types.h" 12 | 13 | uint8_t inp_next(struct ud*); 14 | uint8_t inp_peek(struct ud*); 15 | uint8_t inp_uint8(struct ud*); 16 | uint16_t inp_uint16(struct ud*); 17 | uint32_t inp_uint32(struct ud*); 18 | uint64_t inp_uint64(struct ud*); 19 | void inp_move(struct ud*, size_t); 20 | void inp_back(struct ud*); 21 | 22 | /* inp_init() - Initializes the input system. */ 23 | #define inp_init(u) \ 24 | do { \ 25 | u->inp_curr = 0; \ 26 | u->inp_fill = 0; \ 27 | u->inp_ctr = 0; \ 28 | u->inp_end = 0; \ 29 | } while (0) 30 | 31 | /* inp_start() - Should be called before each de-code operation. */ 32 | #define inp_start(u) u->inp_ctr = 0 33 | 34 | /* inp_back() - Resets the current pointer to its position before the current 35 | * instruction disassembly was started. 36 | */ 37 | #define inp_reset(u) \ 38 | do { \ 39 | u->inp_curr -= u->inp_ctr; \ 40 | u->inp_ctr = 0; \ 41 | } while (0) 42 | 43 | /* inp_sess() - Returns the pointer to current session. */ 44 | #define inp_sess(u) (u->inp_sess) 45 | 46 | /* inp_cur() - Returns the current input byte. */ 47 | #define inp_curr(u) ((u)->inp_cache[(u)->inp_curr]) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /linux/libudis86/itab.h: -------------------------------------------------------------------------------- 1 | 2 | /* itab.h -- auto generated by opgen.py, do not edit. */ 3 | 4 | #ifndef UD_ITAB_H 5 | #define UD_ITAB_H 6 | 7 | 8 | 9 | enum ud_itab_vendor_index { 10 | ITAB__VENDOR_INDX__AMD, 11 | ITAB__VENDOR_INDX__INTEL, 12 | }; 13 | 14 | 15 | enum ud_itab_mode_index { 16 | ITAB__MODE_INDX__16, 17 | ITAB__MODE_INDX__32, 18 | ITAB__MODE_INDX__64 19 | }; 20 | 21 | 22 | enum ud_itab_mod_index { 23 | ITAB__MOD_INDX__NOT_11, 24 | ITAB__MOD_INDX__11 25 | }; 26 | 27 | 28 | enum ud_itab_index { 29 | ITAB__0F, 30 | ITAB__0F__OP_00__REG, 31 | ITAB__0F__OP_01__REG, 32 | ITAB__0F__OP_01__REG__OP_00__MOD, 33 | ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM, 34 | ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_01__VENDOR, 35 | ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_03__VENDOR, 36 | ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_04__VENDOR, 37 | ITAB__0F__OP_01__REG__OP_01__MOD, 38 | ITAB__0F__OP_01__REG__OP_01__MOD__OP_01__RM, 39 | ITAB__0F__OP_01__REG__OP_02__MOD, 40 | ITAB__0F__OP_01__REG__OP_03__MOD, 41 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM, 42 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_00__VENDOR, 43 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_01__VENDOR, 44 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_02__VENDOR, 45 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_03__VENDOR, 46 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_04__VENDOR, 47 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_05__VENDOR, 48 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_06__VENDOR, 49 | ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_07__VENDOR, 50 | ITAB__0F__OP_01__REG__OP_04__MOD, 51 | ITAB__0F__OP_01__REG__OP_06__MOD, 52 | ITAB__0F__OP_01__REG__OP_07__MOD, 53 | ITAB__0F__OP_01__REG__OP_07__MOD__OP_01__RM, 54 | ITAB__0F__OP_01__REG__OP_07__MOD__OP_01__RM__OP_01__VENDOR, 55 | ITAB__0F__OP_0D__REG, 56 | ITAB__0F__OP_18__REG, 57 | ITAB__0F__OP_71__REG, 58 | ITAB__0F__OP_72__REG, 59 | ITAB__0F__OP_73__REG, 60 | ITAB__0F__OP_AE__REG, 61 | ITAB__0F__OP_AE__REG__OP_05__MOD, 62 | ITAB__0F__OP_AE__REG__OP_05__MOD__OP_01__RM, 63 | ITAB__0F__OP_AE__REG__OP_06__MOD, 64 | ITAB__0F__OP_AE__REG__OP_06__MOD__OP_01__RM, 65 | ITAB__0F__OP_AE__REG__OP_07__MOD, 66 | ITAB__0F__OP_AE__REG__OP_07__MOD__OP_01__RM, 67 | ITAB__0F__OP_BA__REG, 68 | ITAB__0F__OP_C7__REG, 69 | ITAB__0F__OP_C7__REG__OP_00__VENDOR, 70 | ITAB__0F__OP_C7__REG__OP_07__VENDOR, 71 | ITAB__0F__OP_D9__MOD, 72 | ITAB__0F__OP_D9__MOD__OP_01__X87, 73 | ITAB__1BYTE, 74 | ITAB__1BYTE__OP_60__OSIZE, 75 | ITAB__1BYTE__OP_61__OSIZE, 76 | ITAB__1BYTE__OP_63__MODE, 77 | ITAB__1BYTE__OP_6D__OSIZE, 78 | ITAB__1BYTE__OP_6F__OSIZE, 79 | ITAB__1BYTE__OP_80__REG, 80 | ITAB__1BYTE__OP_81__REG, 81 | ITAB__1BYTE__OP_82__REG, 82 | ITAB__1BYTE__OP_83__REG, 83 | ITAB__1BYTE__OP_8F__REG, 84 | ITAB__1BYTE__OP_98__OSIZE, 85 | ITAB__1BYTE__OP_99__OSIZE, 86 | ITAB__1BYTE__OP_9C__MODE, 87 | ITAB__1BYTE__OP_9C__MODE__OP_00__OSIZE, 88 | ITAB__1BYTE__OP_9C__MODE__OP_01__OSIZE, 89 | ITAB__1BYTE__OP_9D__MODE, 90 | ITAB__1BYTE__OP_9D__MODE__OP_00__OSIZE, 91 | ITAB__1BYTE__OP_9D__MODE__OP_01__OSIZE, 92 | ITAB__1BYTE__OP_A5__OSIZE, 93 | ITAB__1BYTE__OP_A7__OSIZE, 94 | ITAB__1BYTE__OP_AB__OSIZE, 95 | ITAB__1BYTE__OP_AD__OSIZE, 96 | ITAB__1BYTE__OP_AE__MOD, 97 | ITAB__1BYTE__OP_AE__MOD__OP_00__REG, 98 | ITAB__1BYTE__OP_AF__OSIZE, 99 | ITAB__1BYTE__OP_C0__REG, 100 | ITAB__1BYTE__OP_C1__REG, 101 | ITAB__1BYTE__OP_C6__REG, 102 | ITAB__1BYTE__OP_C7__REG, 103 | ITAB__1BYTE__OP_CF__OSIZE, 104 | ITAB__1BYTE__OP_D0__REG, 105 | ITAB__1BYTE__OP_D1__REG, 106 | ITAB__1BYTE__OP_D2__REG, 107 | ITAB__1BYTE__OP_D3__REG, 108 | ITAB__1BYTE__OP_D8__MOD, 109 | ITAB__1BYTE__OP_D8__MOD__OP_00__REG, 110 | ITAB__1BYTE__OP_D8__MOD__OP_01__X87, 111 | ITAB__1BYTE__OP_D9__MOD, 112 | ITAB__1BYTE__OP_D9__MOD__OP_00__REG, 113 | ITAB__1BYTE__OP_D9__MOD__OP_01__X87, 114 | ITAB__1BYTE__OP_DA__MOD, 115 | ITAB__1BYTE__OP_DA__MOD__OP_00__REG, 116 | ITAB__1BYTE__OP_DA__MOD__OP_01__X87, 117 | ITAB__1BYTE__OP_DB__MOD, 118 | ITAB__1BYTE__OP_DB__MOD__OP_00__REG, 119 | ITAB__1BYTE__OP_DB__MOD__OP_01__X87, 120 | ITAB__1BYTE__OP_DC__MOD, 121 | ITAB__1BYTE__OP_DC__MOD__OP_00__REG, 122 | ITAB__1BYTE__OP_DC__MOD__OP_01__X87, 123 | ITAB__1BYTE__OP_DD__MOD, 124 | ITAB__1BYTE__OP_DD__MOD__OP_00__REG, 125 | ITAB__1BYTE__OP_DD__MOD__OP_01__X87, 126 | ITAB__1BYTE__OP_DE__MOD, 127 | ITAB__1BYTE__OP_DE__MOD__OP_00__REG, 128 | ITAB__1BYTE__OP_DE__MOD__OP_01__X87, 129 | ITAB__1BYTE__OP_DF__MOD, 130 | ITAB__1BYTE__OP_DF__MOD__OP_00__REG, 131 | ITAB__1BYTE__OP_DF__MOD__OP_01__X87, 132 | ITAB__1BYTE__OP_E3__ASIZE, 133 | ITAB__1BYTE__OP_F6__REG, 134 | ITAB__1BYTE__OP_F7__REG, 135 | ITAB__1BYTE__OP_FE__REG, 136 | ITAB__1BYTE__OP_FF__REG, 137 | ITAB__3DNOW, 138 | ITAB__PFX_SSE66__0F, 139 | ITAB__PFX_SSE66__0F__OP_71__REG, 140 | ITAB__PFX_SSE66__0F__OP_72__REG, 141 | ITAB__PFX_SSE66__0F__OP_73__REG, 142 | ITAB__PFX_SSE66__0F__OP_C7__REG, 143 | ITAB__PFX_SSE66__0F__OP_C7__REG__OP_00__VENDOR, 144 | ITAB__PFX_SSEF2__0F, 145 | ITAB__PFX_SSEF3__0F, 146 | ITAB__PFX_SSEF3__0F__OP_C7__REG, 147 | ITAB__PFX_SSEF3__0F__OP_C7__REG__OP_07__VENDOR, 148 | }; 149 | 150 | 151 | enum ud_mnemonic_code { 152 | UD_I3dnow, 153 | UD_Iaaa, 154 | UD_Iaad, 155 | UD_Iaam, 156 | UD_Iaas, 157 | UD_Iadc, 158 | UD_Iadd, 159 | UD_Iaddpd, 160 | UD_Iaddps, 161 | UD_Iaddsd, 162 | UD_Iaddss, 163 | UD_Iaddsubpd, 164 | UD_Iaddsubps, 165 | UD_Iand, 166 | UD_Iandpd, 167 | UD_Iandps, 168 | UD_Iandnpd, 169 | UD_Iandnps, 170 | UD_Iarpl, 171 | UD_Imovsxd, 172 | UD_Ibound, 173 | UD_Ibsf, 174 | UD_Ibsr, 175 | UD_Ibswap, 176 | UD_Ibt, 177 | UD_Ibtc, 178 | UD_Ibtr, 179 | UD_Ibts, 180 | UD_Icall, 181 | UD_Icbw, 182 | UD_Icwde, 183 | UD_Icdqe, 184 | UD_Iclc, 185 | UD_Icld, 186 | UD_Iclflush, 187 | UD_Iclgi, 188 | UD_Icli, 189 | UD_Iclts, 190 | UD_Icmc, 191 | UD_Icmovo, 192 | UD_Icmovno, 193 | UD_Icmovb, 194 | UD_Icmovae, 195 | UD_Icmovz, 196 | UD_Icmovnz, 197 | UD_Icmovbe, 198 | UD_Icmova, 199 | UD_Icmovs, 200 | UD_Icmovns, 201 | UD_Icmovp, 202 | UD_Icmovnp, 203 | UD_Icmovl, 204 | UD_Icmovge, 205 | UD_Icmovle, 206 | UD_Icmovg, 207 | UD_Icmp, 208 | UD_Icmppd, 209 | UD_Icmpps, 210 | UD_Icmpsb, 211 | UD_Icmpsw, 212 | UD_Icmpsd, 213 | UD_Icmpsq, 214 | UD_Icmpss, 215 | UD_Icmpxchg, 216 | UD_Icmpxchg8b, 217 | UD_Icomisd, 218 | UD_Icomiss, 219 | UD_Icpuid, 220 | UD_Icvtdq2pd, 221 | UD_Icvtdq2ps, 222 | UD_Icvtpd2dq, 223 | UD_Icvtpd2pi, 224 | UD_Icvtpd2ps, 225 | UD_Icvtpi2ps, 226 | UD_Icvtpi2pd, 227 | UD_Icvtps2dq, 228 | UD_Icvtps2pi, 229 | UD_Icvtps2pd, 230 | UD_Icvtsd2si, 231 | UD_Icvtsd2ss, 232 | UD_Icvtsi2ss, 233 | UD_Icvtss2si, 234 | UD_Icvtss2sd, 235 | UD_Icvttpd2pi, 236 | UD_Icvttpd2dq, 237 | UD_Icvttps2dq, 238 | UD_Icvttps2pi, 239 | UD_Icvttsd2si, 240 | UD_Icvtsi2sd, 241 | UD_Icvttss2si, 242 | UD_Icwd, 243 | UD_Icdq, 244 | UD_Icqo, 245 | UD_Idaa, 246 | UD_Idas, 247 | UD_Idec, 248 | UD_Idiv, 249 | UD_Idivpd, 250 | UD_Idivps, 251 | UD_Idivsd, 252 | UD_Idivss, 253 | UD_Iemms, 254 | UD_Ienter, 255 | UD_If2xm1, 256 | UD_Ifabs, 257 | UD_Ifadd, 258 | UD_Ifaddp, 259 | UD_Ifbld, 260 | UD_Ifbstp, 261 | UD_Ifchs, 262 | UD_Ifclex, 263 | UD_Ifcmovb, 264 | UD_Ifcmove, 265 | UD_Ifcmovbe, 266 | UD_Ifcmovu, 267 | UD_Ifcmovnb, 268 | UD_Ifcmovne, 269 | UD_Ifcmovnbe, 270 | UD_Ifcmovnu, 271 | UD_Ifucomi, 272 | UD_Ifcom, 273 | UD_Ifcom2, 274 | UD_Ifcomp3, 275 | UD_Ifcomi, 276 | UD_Ifucomip, 277 | UD_Ifcomip, 278 | UD_Ifcomp, 279 | UD_Ifcomp5, 280 | UD_Ifcompp, 281 | UD_Ifcos, 282 | UD_Ifdecstp, 283 | UD_Ifdiv, 284 | UD_Ifdivp, 285 | UD_Ifdivr, 286 | UD_Ifdivrp, 287 | UD_Ifemms, 288 | UD_Iffree, 289 | UD_Iffreep, 290 | UD_Ificom, 291 | UD_Ificomp, 292 | UD_Ifild, 293 | UD_Ifncstp, 294 | UD_Ifninit, 295 | UD_Ifiadd, 296 | UD_Ifidivr, 297 | UD_Ifidiv, 298 | UD_Ifisub, 299 | UD_Ifisubr, 300 | UD_Ifist, 301 | UD_Ifistp, 302 | UD_Ifisttp, 303 | UD_Ifld, 304 | UD_Ifld1, 305 | UD_Ifldl2t, 306 | UD_Ifldl2e, 307 | UD_Ifldlpi, 308 | UD_Ifldlg2, 309 | UD_Ifldln2, 310 | UD_Ifldz, 311 | UD_Ifldcw, 312 | UD_Ifldenv, 313 | UD_Ifmul, 314 | UD_Ifmulp, 315 | UD_Ifimul, 316 | UD_Ifnop, 317 | UD_Ifpatan, 318 | UD_Ifprem, 319 | UD_Ifprem1, 320 | UD_Ifptan, 321 | UD_Ifrndint, 322 | UD_Ifrstor, 323 | UD_Ifnsave, 324 | UD_Ifscale, 325 | UD_Ifsin, 326 | UD_Ifsincos, 327 | UD_Ifsqrt, 328 | UD_Ifstp, 329 | UD_Ifstp1, 330 | UD_Ifstp8, 331 | UD_Ifstp9, 332 | UD_Ifst, 333 | UD_Ifnstcw, 334 | UD_Ifnstenv, 335 | UD_Ifnstsw, 336 | UD_Ifsub, 337 | UD_Ifsubp, 338 | UD_Ifsubr, 339 | UD_Ifsubrp, 340 | UD_Iftst, 341 | UD_Ifucom, 342 | UD_Ifucomp, 343 | UD_Ifucompp, 344 | UD_Ifxam, 345 | UD_Ifxch, 346 | UD_Ifxch4, 347 | UD_Ifxch7, 348 | UD_Ifxrstor, 349 | UD_Ifxsave, 350 | UD_Ifpxtract, 351 | UD_Ifyl2x, 352 | UD_Ifyl2xp1, 353 | UD_Ihaddpd, 354 | UD_Ihaddps, 355 | UD_Ihlt, 356 | UD_Ihsubpd, 357 | UD_Ihsubps, 358 | UD_Iidiv, 359 | UD_Iin, 360 | UD_Iimul, 361 | UD_Iinc, 362 | UD_Iinsb, 363 | UD_Iinsw, 364 | UD_Iinsd, 365 | UD_Iint1, 366 | UD_Iint3, 367 | UD_Iint, 368 | UD_Iinto, 369 | UD_Iinvd, 370 | UD_Iinvlpg, 371 | UD_Iinvlpga, 372 | UD_Iiretw, 373 | UD_Iiretd, 374 | UD_Iiretq, 375 | UD_Ijo, 376 | UD_Ijno, 377 | UD_Ijb, 378 | UD_Ijae, 379 | UD_Ijz, 380 | UD_Ijnz, 381 | UD_Ijbe, 382 | UD_Ija, 383 | UD_Ijs, 384 | UD_Ijns, 385 | UD_Ijp, 386 | UD_Ijnp, 387 | UD_Ijl, 388 | UD_Ijge, 389 | UD_Ijle, 390 | UD_Ijg, 391 | UD_Ijcxz, 392 | UD_Ijecxz, 393 | UD_Ijrcxz, 394 | UD_Ijmp, 395 | UD_Ilahf, 396 | UD_Ilar, 397 | UD_Ilddqu, 398 | UD_Ildmxcsr, 399 | UD_Ilds, 400 | UD_Ilea, 401 | UD_Iles, 402 | UD_Ilfs, 403 | UD_Ilgs, 404 | UD_Ilidt, 405 | UD_Ilss, 406 | UD_Ileave, 407 | UD_Ilfence, 408 | UD_Ilgdt, 409 | UD_Illdt, 410 | UD_Ilmsw, 411 | UD_Ilock, 412 | UD_Ilodsb, 413 | UD_Ilodsw, 414 | UD_Ilodsd, 415 | UD_Ilodsq, 416 | UD_Iloopnz, 417 | UD_Iloope, 418 | UD_Iloop, 419 | UD_Ilsl, 420 | UD_Iltr, 421 | UD_Imaskmovq, 422 | UD_Imaxpd, 423 | UD_Imaxps, 424 | UD_Imaxsd, 425 | UD_Imaxss, 426 | UD_Imfence, 427 | UD_Iminpd, 428 | UD_Iminps, 429 | UD_Iminsd, 430 | UD_Iminss, 431 | UD_Imonitor, 432 | UD_Imov, 433 | UD_Imovapd, 434 | UD_Imovaps, 435 | UD_Imovd, 436 | UD_Imovddup, 437 | UD_Imovdqa, 438 | UD_Imovdqu, 439 | UD_Imovdq2q, 440 | UD_Imovhpd, 441 | UD_Imovhps, 442 | UD_Imovlhps, 443 | UD_Imovlpd, 444 | UD_Imovlps, 445 | UD_Imovhlps, 446 | UD_Imovmskpd, 447 | UD_Imovmskps, 448 | UD_Imovntdq, 449 | UD_Imovnti, 450 | UD_Imovntpd, 451 | UD_Imovntps, 452 | UD_Imovntq, 453 | UD_Imovq, 454 | UD_Imovqa, 455 | UD_Imovq2dq, 456 | UD_Imovsb, 457 | UD_Imovsw, 458 | UD_Imovsd, 459 | UD_Imovsq, 460 | UD_Imovsldup, 461 | UD_Imovshdup, 462 | UD_Imovss, 463 | UD_Imovsx, 464 | UD_Imovupd, 465 | UD_Imovups, 466 | UD_Imovzx, 467 | UD_Imul, 468 | UD_Imulpd, 469 | UD_Imulps, 470 | UD_Imulsd, 471 | UD_Imulss, 472 | UD_Imwait, 473 | UD_Ineg, 474 | UD_Inop, 475 | UD_Inot, 476 | UD_Ior, 477 | UD_Iorpd, 478 | UD_Iorps, 479 | UD_Iout, 480 | UD_Ioutsb, 481 | UD_Ioutsw, 482 | UD_Ioutsd, 483 | UD_Ioutsq, 484 | UD_Ipacksswb, 485 | UD_Ipackssdw, 486 | UD_Ipackuswb, 487 | UD_Ipaddb, 488 | UD_Ipaddw, 489 | UD_Ipaddq, 490 | UD_Ipaddsb, 491 | UD_Ipaddsw, 492 | UD_Ipaddusb, 493 | UD_Ipaddusw, 494 | UD_Ipand, 495 | UD_Ipandn, 496 | UD_Ipause, 497 | UD_Ipavgb, 498 | UD_Ipavgw, 499 | UD_Ipcmpeqb, 500 | UD_Ipcmpeqw, 501 | UD_Ipcmpeqd, 502 | UD_Ipcmpgtb, 503 | UD_Ipcmpgtw, 504 | UD_Ipcmpgtd, 505 | UD_Ipextrw, 506 | UD_Ipinsrw, 507 | UD_Ipmaddwd, 508 | UD_Ipmaxsw, 509 | UD_Ipmaxub, 510 | UD_Ipminsw, 511 | UD_Ipminub, 512 | UD_Ipmovmskb, 513 | UD_Ipmulhuw, 514 | UD_Ipmulhw, 515 | UD_Ipmullw, 516 | UD_Ipmuludq, 517 | UD_Ipop, 518 | UD_Ipopa, 519 | UD_Ipopad, 520 | UD_Ipopfw, 521 | UD_Ipopfd, 522 | UD_Ipopfq, 523 | UD_Ipor, 524 | UD_Iprefetch, 525 | UD_Iprefetchnta, 526 | UD_Iprefetcht0, 527 | UD_Iprefetcht1, 528 | UD_Iprefetcht2, 529 | UD_Ipsadbw, 530 | UD_Ipshufd, 531 | UD_Ipshufhw, 532 | UD_Ipshuflw, 533 | UD_Ipshufw, 534 | UD_Ipslldq, 535 | UD_Ipsllw, 536 | UD_Ipslld, 537 | UD_Ipsllq, 538 | UD_Ipsraw, 539 | UD_Ipsrad, 540 | UD_Ipsrlw, 541 | UD_Ipsrld, 542 | UD_Ipsrlq, 543 | UD_Ipsrldq, 544 | UD_Ipsubb, 545 | UD_Ipsubw, 546 | UD_Ipsubd, 547 | UD_Ipsubq, 548 | UD_Ipsubsb, 549 | UD_Ipsubsw, 550 | UD_Ipsubusb, 551 | UD_Ipsubusw, 552 | UD_Ipunpckhbw, 553 | UD_Ipunpckhwd, 554 | UD_Ipunpckhdq, 555 | UD_Ipunpckhqdq, 556 | UD_Ipunpcklbw, 557 | UD_Ipunpcklwd, 558 | UD_Ipunpckldq, 559 | UD_Ipunpcklqdq, 560 | UD_Ipi2fw, 561 | UD_Ipi2fd, 562 | UD_Ipf2iw, 563 | UD_Ipf2id, 564 | UD_Ipfnacc, 565 | UD_Ipfpnacc, 566 | UD_Ipfcmpge, 567 | UD_Ipfmin, 568 | UD_Ipfrcp, 569 | UD_Ipfrsqrt, 570 | UD_Ipfsub, 571 | UD_Ipfadd, 572 | UD_Ipfcmpgt, 573 | UD_Ipfmax, 574 | UD_Ipfrcpit1, 575 | UD_Ipfrspit1, 576 | UD_Ipfsubr, 577 | UD_Ipfacc, 578 | UD_Ipfcmpeq, 579 | UD_Ipfmul, 580 | UD_Ipfrcpit2, 581 | UD_Ipmulhrw, 582 | UD_Ipswapd, 583 | UD_Ipavgusb, 584 | UD_Ipush, 585 | UD_Ipusha, 586 | UD_Ipushad, 587 | UD_Ipushfw, 588 | UD_Ipushfd, 589 | UD_Ipushfq, 590 | UD_Ipxor, 591 | UD_Ircl, 592 | UD_Ircr, 593 | UD_Irol, 594 | UD_Iror, 595 | UD_Ircpps, 596 | UD_Ircpss, 597 | UD_Irdmsr, 598 | UD_Irdpmc, 599 | UD_Irdtsc, 600 | UD_Irdtscp, 601 | UD_Irepne, 602 | UD_Irep, 603 | UD_Iret, 604 | UD_Iretf, 605 | UD_Irsm, 606 | UD_Irsqrtps, 607 | UD_Irsqrtss, 608 | UD_Isahf, 609 | UD_Isal, 610 | UD_Isalc, 611 | UD_Isar, 612 | UD_Ishl, 613 | UD_Ishr, 614 | UD_Isbb, 615 | UD_Iscasb, 616 | UD_Iscasw, 617 | UD_Iscasd, 618 | UD_Iscasq, 619 | UD_Iseto, 620 | UD_Isetno, 621 | UD_Isetb, 622 | UD_Isetnb, 623 | UD_Isetz, 624 | UD_Isetnz, 625 | UD_Isetbe, 626 | UD_Iseta, 627 | UD_Isets, 628 | UD_Isetns, 629 | UD_Isetp, 630 | UD_Isetnp, 631 | UD_Isetl, 632 | UD_Isetge, 633 | UD_Isetle, 634 | UD_Isetg, 635 | UD_Isfence, 636 | UD_Isgdt, 637 | UD_Ishld, 638 | UD_Ishrd, 639 | UD_Ishufpd, 640 | UD_Ishufps, 641 | UD_Isidt, 642 | UD_Isldt, 643 | UD_Ismsw, 644 | UD_Isqrtps, 645 | UD_Isqrtpd, 646 | UD_Isqrtsd, 647 | UD_Isqrtss, 648 | UD_Istc, 649 | UD_Istd, 650 | UD_Istgi, 651 | UD_Isti, 652 | UD_Iskinit, 653 | UD_Istmxcsr, 654 | UD_Istosb, 655 | UD_Istosw, 656 | UD_Istosd, 657 | UD_Istosq, 658 | UD_Istr, 659 | UD_Isub, 660 | UD_Isubpd, 661 | UD_Isubps, 662 | UD_Isubsd, 663 | UD_Isubss, 664 | UD_Iswapgs, 665 | UD_Isyscall, 666 | UD_Isysenter, 667 | UD_Isysexit, 668 | UD_Isysret, 669 | UD_Itest, 670 | UD_Iucomisd, 671 | UD_Iucomiss, 672 | UD_Iud2, 673 | UD_Iunpckhpd, 674 | UD_Iunpckhps, 675 | UD_Iunpcklps, 676 | UD_Iunpcklpd, 677 | UD_Iverr, 678 | UD_Iverw, 679 | UD_Ivmcall, 680 | UD_Ivmclear, 681 | UD_Ivmxon, 682 | UD_Ivmptrld, 683 | UD_Ivmptrst, 684 | UD_Ivmresume, 685 | UD_Ivmxoff, 686 | UD_Ivmrun, 687 | UD_Ivmmcall, 688 | UD_Ivmload, 689 | UD_Ivmsave, 690 | UD_Iwait, 691 | UD_Iwbinvd, 692 | UD_Iwrmsr, 693 | UD_Ixadd, 694 | UD_Ixchg, 695 | UD_Ixlatb, 696 | UD_Ixor, 697 | UD_Ixorpd, 698 | UD_Ixorps, 699 | UD_Idb, 700 | UD_Iinvalid, 701 | UD_Id3vil, 702 | UD_Ina, 703 | UD_Igrp_reg, 704 | UD_Igrp_rm, 705 | UD_Igrp_vendor, 706 | UD_Igrp_x87, 707 | UD_Igrp_mode, 708 | UD_Igrp_osize, 709 | UD_Igrp_asize, 710 | UD_Igrp_mod, 711 | UD_Inone, 712 | }; 713 | 714 | 715 | 716 | extern const char* ud_mnemonics_str[];; 717 | extern struct ud_itab_entry* ud_itab_list[]; 718 | 719 | #endif 720 | -------------------------------------------------------------------------------- /linux/libudis86/syn-att.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * syn-att.c 3 | * 4 | * Copyright (c) 2004, 2005, 2006 Vivek Mohan 5 | * All rights reserved. See (LICENSE) 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | 9 | #include "types.h" 10 | #include "extern.h" 11 | #include "decode.h" 12 | #include "itab.h" 13 | #include "syn.h" 14 | 15 | /* ----------------------------------------------------------------------------- 16 | * opr_cast() - Prints an operand cast. 17 | * ----------------------------------------------------------------------------- 18 | */ 19 | static void 20 | opr_cast(struct ud* u, struct ud_operand* op) 21 | { 22 | switch(op->size) { 23 | case 16 : case 32 : 24 | mkasm(u, "*"); break; 25 | default: break; 26 | } 27 | } 28 | 29 | /* ----------------------------------------------------------------------------- 30 | * gen_operand() - Generates assembly output for each operand. 31 | * ----------------------------------------------------------------------------- 32 | */ 33 | static void 34 | gen_operand(struct ud* u, struct ud_operand* op) 35 | { 36 | switch(op->type) { 37 | case UD_OP_REG: 38 | mkasm(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]); 39 | break; 40 | 41 | case UD_OP_MEM: 42 | if (u->br_far) opr_cast(u, op); 43 | if (u->pfx_seg) 44 | mkasm(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); 45 | if (op->offset == 8) { 46 | if (op->lval.sbyte < 0) 47 | mkasm(u, "-0x%x", (-op->lval.sbyte) & 0xff); 48 | else mkasm(u, "0x%x", op->lval.sbyte); 49 | } 50 | else if (op->offset == 16) 51 | mkasm(u, "0x%x", op->lval.uword); 52 | else if (op->offset == 32) 53 | mkasm(u, "0x%lx", op->lval.udword); 54 | else if (op->offset == 64) 55 | mkasm(u, "0x" FMT64 "x", op->lval.uqword); 56 | 57 | if (op->base) 58 | mkasm(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]); 59 | if (op->index) { 60 | if (op->base) 61 | mkasm(u, ","); 62 | else mkasm(u, "("); 63 | mkasm(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]); 64 | } 65 | if (op->scale) 66 | mkasm(u, ",%d", op->scale); 67 | if (op->base || op->index) 68 | mkasm(u, ")"); 69 | break; 70 | 71 | case UD_OP_IMM: 72 | switch (op->size) { 73 | case 8: mkasm(u, "$0x%x", op->lval.ubyte); break; 74 | case 16: mkasm(u, "$0x%x", op->lval.uword); break; 75 | case 32: mkasm(u, "$0x%lx", op->lval.udword); break; 76 | case 64: mkasm(u, "$0x" FMT64 "x", op->lval.uqword); break; 77 | default: break; 78 | } 79 | break; 80 | 81 | case UD_OP_JIMM: 82 | switch (op->size) { 83 | case 8: 84 | mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte); 85 | break; 86 | case 16: 87 | mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword); 88 | break; 89 | case 32: 90 | mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword); 91 | break; 92 | default:break; 93 | } 94 | break; 95 | 96 | case UD_OP_PTR: 97 | switch (op->size) { 98 | case 32: 99 | mkasm(u, "$0x%x, $0x%x", op->lval.ptr.seg, 100 | op->lval.ptr.off & 0xFFFF); 101 | break; 102 | case 48: 103 | mkasm(u, "$0x%x, $0x%lx", op->lval.ptr.seg, 104 | op->lval.ptr.off); 105 | break; 106 | } 107 | break; 108 | 109 | default: return; 110 | } 111 | } 112 | 113 | /* ============================================================================= 114 | * translates to AT&T syntax 115 | * ============================================================================= 116 | */ 117 | extern void 118 | ud_translate_att(struct ud *u) 119 | { 120 | int size = 0; 121 | 122 | /* check if P_OSO prefix is used */ 123 | if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) { 124 | switch (u->dis_mode) { 125 | case 16: 126 | mkasm(u, "o32 "); 127 | break; 128 | case 32: 129 | case 64: 130 | mkasm(u, "o16 "); 131 | break; 132 | } 133 | } 134 | 135 | /* check if P_ASO prefix was used */ 136 | if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) { 137 | switch (u->dis_mode) { 138 | case 16: 139 | mkasm(u, "a32 "); 140 | break; 141 | case 32: 142 | mkasm(u, "a16 "); 143 | break; 144 | case 64: 145 | mkasm(u, "a32 "); 146 | break; 147 | } 148 | } 149 | 150 | if (u->pfx_lock) 151 | mkasm(u, "lock "); 152 | if (u->pfx_rep) 153 | mkasm(u, "rep "); 154 | if (u->pfx_repne) 155 | mkasm(u, "repne "); 156 | 157 | /* special instructions */ 158 | switch (u->mnemonic) { 159 | case UD_Iretf: 160 | mkasm(u, "lret "); 161 | break; 162 | case UD_Idb: 163 | mkasm(u, ".byte 0x%x", u->operand[0].lval.ubyte); 164 | return; 165 | case UD_Ijmp: 166 | case UD_Icall: 167 | if (u->br_far) mkasm(u, "l"); 168 | mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 169 | break; 170 | case UD_Ibound: 171 | case UD_Ienter: 172 | if (u->operand[0].type != UD_NONE) 173 | gen_operand(u, &u->operand[0]); 174 | if (u->operand[1].type != UD_NONE) { 175 | mkasm(u, ","); 176 | gen_operand(u, &u->operand[1]); 177 | } 178 | return; 179 | default: 180 | mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 181 | } 182 | 183 | if (u->c1) 184 | size = u->operand[0].size; 185 | else if (u->c2) 186 | size = u->operand[1].size; 187 | else if (u->c3) 188 | size = u->operand[2].size; 189 | 190 | if (size == 8) 191 | mkasm(u, "b"); 192 | else if (size == 16) 193 | mkasm(u, "w"); 194 | else if (size == 64) 195 | mkasm(u, "q"); 196 | 197 | mkasm(u, " "); 198 | 199 | if (u->operand[2].type != UD_NONE) { 200 | gen_operand(u, &u->operand[2]); 201 | mkasm(u, ", "); 202 | } 203 | 204 | if (u->operand[1].type != UD_NONE) { 205 | gen_operand(u, &u->operand[1]); 206 | mkasm(u, ", "); 207 | } 208 | 209 | if (u->operand[0].type != UD_NONE) 210 | gen_operand(u, &u->operand[0]); 211 | } 212 | -------------------------------------------------------------------------------- /linux/libudis86/syn-intel.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * syn-intel.c 3 | * 4 | * Copyright (c) 2002, 2003, 2004 Vivek Mohan 5 | * All rights reserved. See (LICENSE) 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | 9 | #include "types.h" 10 | #include "extern.h" 11 | #include "decode.h" 12 | #include "itab.h" 13 | #include "syn.h" 14 | 15 | /* ----------------------------------------------------------------------------- 16 | * opr_cast() - Prints an operand cast. 17 | * ----------------------------------------------------------------------------- 18 | */ 19 | static void 20 | opr_cast(struct ud* u, struct ud_operand* op) 21 | { 22 | switch(op->size) { 23 | case 8: mkasm(u, "byte " ); break; 24 | case 16: mkasm(u, "word " ); break; 25 | case 32: mkasm(u, "dword "); break; 26 | case 64: mkasm(u, "qword "); break; 27 | case 80: mkasm(u, "tword "); break; 28 | default: break; 29 | } 30 | if (u->br_far) 31 | mkasm(u, "far "); 32 | else if (u->br_near) 33 | mkasm(u, ""); 34 | } 35 | 36 | /* ----------------------------------------------------------------------------- 37 | * gen_operand() - Generates assembly output for each operand. 38 | * ----------------------------------------------------------------------------- 39 | */ 40 | static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast) 41 | { 42 | switch(op->type) { 43 | case UD_OP_REG: 44 | mkasm(u, ud_reg_tab[op->base - UD_R_AL]); 45 | break; 46 | 47 | case UD_OP_MEM: { 48 | 49 | int op_f = 0; 50 | 51 | if (syn_cast) 52 | opr_cast(u, op); 53 | 54 | mkasm(u, "["); 55 | 56 | if (u->pfx_seg) 57 | mkasm(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); 58 | 59 | if (op->base) { 60 | mkasm(u, "%s", ud_reg_tab[op->base - UD_R_AL]); 61 | op_f = 1; 62 | } 63 | 64 | if (op->index) { 65 | if (op_f) 66 | mkasm(u, "+"); 67 | mkasm(u, "%s", ud_reg_tab[op->index - UD_R_AL]); 68 | op_f = 1; 69 | } 70 | 71 | if (op->scale) 72 | mkasm(u, "*%d", op->scale); 73 | 74 | if (op->offset == 8) { 75 | if (op->lval.sbyte < 0) 76 | mkasm(u, "-%02xh", -op->lval.sbyte); 77 | else 78 | mkasm(u, "%s%02xh", (op_f) ? "+" : "", op->lval.sbyte); 79 | } 80 | else if (op->offset == 16) 81 | mkasm(u, "%s%04xh", (op_f) ? "+" : "", op->lval.uword); 82 | else if (op->offset == 32) { 83 | if (u->adr_mode == 64) { 84 | if (op->lval.sdword < 0) 85 | mkasm(u, "-%08xh", -op->lval.sdword); 86 | else 87 | mkasm(u, "%s%08xh", (op_f) ? "+" : "", op->lval.sdword); 88 | } 89 | else 90 | mkasm(u, "%s%08lxh", (op_f) ? "+" : "", op->lval.udword); 91 | } 92 | else if (op->offset == 64) 93 | mkasm(u, "%s" FMT64 "xh", (op_f) ? "+" : "", op->lval.uqword); 94 | 95 | mkasm(u, "]"); 96 | break; 97 | } 98 | 99 | case UD_OP_IMM: 100 | //if (syn_cast) opr_cast(u, op); 101 | switch (op->size) { 102 | case 8: mkasm(u, "%02xh", op->lval.ubyte); break; 103 | case 16: mkasm(u, "%04xh", op->lval.uword); break; 104 | case 32: mkasm(u, "%08lxh", op->lval.udword); break; 105 | case 64: mkasm(u, "" FMT64 "xh", op->lval.uqword); break; 106 | default: break; 107 | } 108 | break; 109 | 110 | case UD_OP_JIMM: 111 | //if (syn_cast) opr_cast(u, op); 112 | switch (op->size) { 113 | case 8: 114 | mkasm(u, "%02xh", u->pc + op->lval.sbyte); 115 | break; 116 | case 16: 117 | mkasm(u, "%04xh", u->pc + op->lval.sword); 118 | break; 119 | case 32: 120 | mkasm(u, "%08xh", u->pc + op->lval.sdword); 121 | break; 122 | default:break; 123 | } 124 | break; 125 | 126 | case UD_OP_PTR: 127 | switch (op->size) { 128 | case 32: 129 | mkasm(u, "word %04xh:%08xh", op->lval.ptr.seg, 130 | op->lval.ptr.off & 0xFFFF); 131 | break; 132 | case 48: 133 | mkasm(u, "dword %04xh:%08lxh", op->lval.ptr.seg, 134 | op->lval.ptr.off); 135 | break; 136 | } 137 | break; 138 | 139 | case UD_OP_CONST: 140 | if (syn_cast) opr_cast(u, op); 141 | mkasm(u, "%d", op->lval.udword); 142 | break; 143 | 144 | default: return; 145 | } 146 | } 147 | 148 | /* ============================================================================= 149 | * translates to intel syntax 150 | * ============================================================================= 151 | */ 152 | extern void ud_translate_intel(struct ud* u) 153 | { 154 | /* -- prefixes -- */ 155 | 156 | /* check if P_OSO prefix is used */ 157 | if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) { 158 | switch (u->dis_mode) { 159 | case 16: 160 | mkasm(u, "o32 "); 161 | break; 162 | case 32: 163 | case 64: 164 | mkasm(u, "o16 "); 165 | break; 166 | } 167 | } 168 | 169 | /* check if P_ASO prefix was used */ 170 | if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) { 171 | switch (u->dis_mode) { 172 | case 16: 173 | mkasm(u, "a32 "); 174 | break; 175 | case 32: 176 | mkasm(u, "a16 "); 177 | break; 178 | case 64: 179 | mkasm(u, "a32 "); 180 | break; 181 | } 182 | } 183 | 184 | if (u->pfx_lock) 185 | mkasm(u, "lock "); 186 | if (u->pfx_rep) 187 | mkasm(u, "rep "); 188 | if (u->pfx_repne) 189 | mkasm(u, "repne "); 190 | if (u->implicit_addr && u->pfx_seg) 191 | mkasm(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]); 192 | 193 | /* print the instruction mnemonic */ 194 | mkasm(u, "%s ", ud_lookup_mnemonic(u->mnemonic)); 195 | 196 | /* operand 1 */ 197 | if (u->operand[0].type != UD_NONE) { 198 | gen_operand(u, &u->operand[0], u->c1); 199 | } 200 | /* operand 2 */ 201 | if (u->operand[1].type != UD_NONE) { 202 | mkasm(u, ", "); 203 | gen_operand(u, &u->operand[1], u->c2); 204 | } 205 | 206 | /* operand 3 */ 207 | if (u->operand[2].type != UD_NONE) { 208 | mkasm(u, ", "); 209 | gen_operand(u, &u->operand[2], u->c3); 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /linux/libudis86/syn.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * syn.c 3 | * 4 | * Copyright (c) 2002, 2003, 2004 Vivek Mohan 5 | * All rights reserved. See (LICENSE) 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | 9 | /* ----------------------------------------------------------------------------- 10 | * Intel Register Table - Order Matters (types.h)! 11 | * ----------------------------------------------------------------------------- 12 | */ 13 | const char* ud_reg_tab[] = 14 | { 15 | "al", "cl", "dl", "bl", 16 | "ah", "ch", "dh", "bh", 17 | "spl", "bpl", "sil", "dil", 18 | "r8b", "r9b", "r10b", "r11b", 19 | "r12b", "r13b", "r14b", "r15b", 20 | 21 | "ax", "cx", "dx", "bx", 22 | "sp", "bp", "si", "di", 23 | "r8w", "r9w", "r10w", "r11w", 24 | "r12w", "r13W" , "r14w", "r15w", 25 | 26 | "eax", "ecx", "edx", "ebx", 27 | "esp", "ebp", "esi", "edi", 28 | "r8d", "r9d", "r10d", "r11d", 29 | "r12d", "r13d", "r14d", "r15d", 30 | 31 | "rax", "rcx", "rdx", "rbx", 32 | "rsp", "rbp", "rsi", "rdi", 33 | "r8", "r9", "r10", "r11", 34 | "r12", "r13", "r14", "r15", 35 | 36 | "es", "cs", "ss", "ds", 37 | "fs", "gs", 38 | 39 | "cr0", "cr1", "cr2", "cr3", 40 | "cr4", "cr5", "cr6", "cr7", 41 | "cr8", "cr9", "cr10", "cr11", 42 | "cr12", "cr13", "cr14", "cr15", 43 | 44 | "dr0", "dr1", "dr2", "dr3", 45 | "dr4", "dr5", "dr6", "dr7", 46 | "dr8", "dr9", "dr10", "dr11", 47 | "dr12", "dr13", "dr14", "dr15", 48 | 49 | "mm0", "mm1", "mm2", "mm3", 50 | "mm4", "mm5", "mm6", "mm7", 51 | 52 | "st0", "st1", "st2", "st3", 53 | "st4", "st5", "st6", "st7", 54 | 55 | "xmm0", "xmm1", "xmm2", "xmm3", 56 | "xmm4", "xmm5", "xmm6", "xmm7", 57 | "xmm8", "xmm9", "xmm10", "xmm11", 58 | "xmm12", "xmm13", "xmm14", "xmm15", 59 | 60 | "rip" 61 | }; 62 | -------------------------------------------------------------------------------- /linux/libudis86/syn.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * syn.h 3 | * 4 | * Copyright (c) 2006, Vivek Mohan 5 | * All rights reserved. See LICENSE 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | #ifndef UD_SYN_H 9 | #define UD_SYN_H 10 | \ 11 | #include 12 | #include "types.h" 13 | 14 | extern const char* ud_reg_tab[]; 15 | 16 | static void mkasm(struct ud* u, const char* fmt, ...) 17 | { 18 | va_list ap; 19 | va_start(ap, fmt); 20 | u->insn_fill += vsprintf((char*) u->insn_buffer + u->insn_fill, fmt, ap); 21 | va_end(ap); 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /linux/libudis86/types.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * types.h 3 | * 4 | * Copyright (c) 2006, Vivek Mohan 5 | * All rights reserved. See LICENSE 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | #ifndef UD_TYPES_H 9 | #define UD_TYPES_H 10 | 11 | typedef void FILE; 12 | 13 | #include 14 | 15 | #ifdef _MSC_VER 16 | # define FMT64 "%I64" 17 | typedef unsigned __int8 uint8_t; 18 | typedef unsigned __int16 uint16_t; 19 | typedef unsigned __int32 uint32_t; 20 | typedef unsigned __int64 uint64_t; 21 | typedef __int8 int8_t; 22 | typedef __int16 int16_t; 23 | typedef __int32 int32_t; 24 | typedef __int64 int64_t; 25 | #else 26 | # define FMT64 "%16ll" 27 | //#include 28 | #endif 29 | 30 | #include "itab.h" 31 | 32 | /* ----------------------------------------------------------------------------- 33 | * All possible "types" of objects in udis86. Order is Important! 34 | * ----------------------------------------------------------------------------- 35 | */ 36 | enum ud_type 37 | { 38 | UD_NONE, 39 | 40 | /* 8 bit GPRs */ 41 | UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL, 42 | UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH, 43 | UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL, 44 | UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B, 45 | UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B, 46 | 47 | /* 16 bit GPRs */ 48 | UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX, 49 | UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI, 50 | UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W, 51 | UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W, 52 | 53 | /* 32 bit GPRs */ 54 | UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX, 55 | UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI, 56 | UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D, 57 | UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D, 58 | 59 | /* 64 bit GPRs */ 60 | UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX, 61 | UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI, 62 | UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11, 63 | UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15, 64 | 65 | /* segment registers */ 66 | UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS, 67 | UD_R_FS, UD_R_GS, 68 | 69 | /* control registers*/ 70 | UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3, 71 | UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7, 72 | UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11, 73 | UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15, 74 | 75 | /* debug registers */ 76 | UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3, 77 | UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7, 78 | UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11, 79 | UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15, 80 | 81 | /* mmx registers */ 82 | UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3, 83 | UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7, 84 | 85 | /* x87 registers */ 86 | UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3, 87 | UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7, 88 | 89 | /* extended multimedia registers */ 90 | UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3, 91 | UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7, 92 | UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11, 93 | UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15, 94 | 95 | UD_R_RIP, 96 | 97 | /* Operand Types */ 98 | UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM, 99 | UD_OP_JIMM, UD_OP_CONST 100 | }; 101 | 102 | /* ----------------------------------------------------------------------------- 103 | * struct ud_operand - Disassembled instruction Operand. 104 | * ----------------------------------------------------------------------------- 105 | */ 106 | struct ud_operand 107 | { 108 | enum ud_type type; 109 | uint8_t size; 110 | union { 111 | int8_t sbyte; 112 | uint8_t ubyte; 113 | int16_t sword; 114 | uint16_t uword; 115 | int32_t sdword; 116 | uint32_t udword; 117 | int64_t sqword; 118 | uint64_t uqword; 119 | 120 | struct { 121 | uint16_t seg; 122 | uint32_t off; 123 | } ptr; 124 | } lval; 125 | 126 | enum ud_type base; 127 | enum ud_type index; 128 | uint8_t offset; 129 | uint8_t scale; 130 | }; 131 | 132 | /* ----------------------------------------------------------------------------- 133 | * struct ud - The udis86 object. 134 | * ----------------------------------------------------------------------------- 135 | */ 136 | struct ud 137 | { 138 | int (*inp_hook) (struct ud*); 139 | uint8_t inp_curr; 140 | uint8_t inp_fill; 141 | FILE* inp_file; 142 | uint8_t inp_ctr; 143 | uint8_t* inp_buff; 144 | uint8_t* inp_buff_end; 145 | uint8_t inp_end; 146 | void (*translator)(struct ud*); 147 | uint64_t insn_offset; 148 | char insn_hexcode[32]; 149 | char insn_buffer[64]; 150 | unsigned int insn_fill; 151 | uint8_t dis_mode; 152 | uint64_t pc; 153 | uint8_t vendor; 154 | struct map_entry* mapen; 155 | enum ud_mnemonic_code mnemonic; 156 | struct ud_operand operand[3]; 157 | uint8_t error; 158 | uint8_t pfx_rex; 159 | uint8_t pfx_seg; 160 | uint8_t pfx_opr; 161 | uint8_t pfx_adr; 162 | uint8_t pfx_lock; 163 | uint8_t pfx_rep; 164 | uint8_t pfx_repe; 165 | uint8_t pfx_repne; 166 | uint8_t pfx_insn; 167 | uint8_t default64; 168 | uint8_t opr_mode; 169 | uint8_t adr_mode; 170 | uint8_t br_far; 171 | uint8_t br_near; 172 | uint8_t implicit_addr; 173 | uint8_t c1; 174 | uint8_t c2; 175 | uint8_t c3; 176 | uint8_t inp_cache[256]; 177 | uint8_t inp_sess[64]; 178 | struct ud_itab_entry * itab_entry; 179 | }; 180 | 181 | /* ----------------------------------------------------------------------------- 182 | * Type-definitions 183 | * ----------------------------------------------------------------------------- 184 | */ 185 | typedef enum ud_type ud_type_t; 186 | typedef enum ud_mnemonic_code ud_mnemonic_code_t; 187 | 188 | typedef struct ud ud_t,UDIS,*PUDIS; 189 | typedef struct ud_operand ud_operand_t; 190 | 191 | #define UD_SYN_INTEL ud_translate_intel 192 | #define UD_SYN_ATT ud_translate_att 193 | #define UD_EOI -1 194 | #define UD_INP_CACHE_SZ 32 195 | #define UD_VENDOR_AMD 0 196 | #define UD_VENDOR_INTEL 1 197 | 198 | #define bail_out(ud,error_code) longjmp( (ud)->bailout, error_code ) 199 | #define try_decode(ud) if ( setjmp( (ud)->bailout ) == 0 ) 200 | #define catch_error() else 201 | 202 | #endif 203 | -------------------------------------------------------------------------------- /linux/libudis86/udis86.c: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * udis86.c 3 | * 4 | * Copyright (c) 2004, 2005, 2006, Vivek Mohan 5 | * All rights reserved. See LICENSE 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | 11 | #include "input.h" 12 | #include "extern.h" 13 | 14 | /* ============================================================================= 15 | * ud_init() - Initializes ud_t object. 16 | * ============================================================================= 17 | */ 18 | extern void 19 | ud_init(struct ud* u) 20 | { 21 | memset((void*)u, 0, sizeof(struct ud)); 22 | ud_set_mode(u, 16); 23 | u->mnemonic = UD_Iinvalid; 24 | ud_set_pc(u, 0); 25 | #ifndef __UD_STANDALONE__ 26 | ud_set_input_file(u, 0); 27 | #endif /* __UD_STANDALONE__ */ 28 | } 29 | 30 | /* ============================================================================= 31 | * ud_disassemble() - disassembles one instruction and returns the number of 32 | * bytes disassembled. A zero means end of disassembly. 33 | * ============================================================================= 34 | */ 35 | extern unsigned int 36 | ud_disassemble(struct ud* u) 37 | { 38 | if (ud_input_end(u)) 39 | return 0; 40 | 41 | 42 | u->insn_buffer[0] = u->insn_hexcode[0] = 0; 43 | 44 | 45 | if (ud_decode(u) == 0) 46 | return 0; 47 | if (u->translator) 48 | u->translator(u); 49 | return ud_insn_len(u); 50 | } 51 | 52 | /* ============================================================================= 53 | * ud_set_mode() - Set Disassemly Mode. 54 | * ============================================================================= 55 | */ 56 | extern void 57 | ud_set_mode(struct ud* u, uint8_t m) 58 | { 59 | switch(m) { 60 | case 16: 61 | case 32: 62 | case 64: u->dis_mode = m ; return; 63 | default: u->dis_mode = 16; return; 64 | } 65 | } 66 | 67 | /* ============================================================================= 68 | * ud_set_vendor() - Set vendor. 69 | * ============================================================================= 70 | */ 71 | extern void 72 | ud_set_vendor(struct ud* u, unsigned v) 73 | { 74 | switch(v) { 75 | case UD_VENDOR_INTEL: 76 | u->vendor = v; 77 | break; 78 | default: 79 | u->vendor = UD_VENDOR_AMD; 80 | } 81 | } 82 | 83 | /* ============================================================================= 84 | * ud_set_pc() - Sets code origin. 85 | * ============================================================================= 86 | */ 87 | extern void 88 | ud_set_pc(struct ud* u, uint64_t o) 89 | { 90 | u->pc = o; 91 | } 92 | 93 | /* ============================================================================= 94 | * ud_set_syntax() - Sets the output syntax. 95 | * ============================================================================= 96 | */ 97 | extern void 98 | ud_set_syntax(struct ud* u, void (*t)(struct ud*)) 99 | { 100 | u->translator = t; 101 | } 102 | 103 | /* ============================================================================= 104 | * ud_insn() - returns the disassembled instruction 105 | * ============================================================================= 106 | */ 107 | extern char* 108 | ud_insn_asm(struct ud* u) 109 | { 110 | return u->insn_buffer; 111 | } 112 | 113 | /* ============================================================================= 114 | * ud_insn_offset() - Returns the offset. 115 | * ============================================================================= 116 | */ 117 | extern uint64_t 118 | ud_insn_off(struct ud* u) 119 | { 120 | return u->insn_offset; 121 | } 122 | 123 | 124 | /* ============================================================================= 125 | * ud_insn_hex() - Returns hex form of disassembled instruction. 126 | * ============================================================================= 127 | */ 128 | extern char* 129 | ud_insn_hex(struct ud* u) 130 | { 131 | return u->insn_hexcode; 132 | } 133 | 134 | /* ============================================================================= 135 | * ud_insn_ptr() - Returns code disassembled. 136 | * ============================================================================= 137 | */ 138 | extern uint8_t* 139 | ud_insn_ptr(struct ud* u) 140 | { 141 | return u->inp_sess; 142 | } 143 | 144 | /* ============================================================================= 145 | * ud_insn_len() - Returns the count of bytes disassembled. 146 | * ============================================================================= 147 | */ 148 | extern unsigned int 149 | ud_insn_len(struct ud* u) 150 | { 151 | return u->inp_ctr; 152 | } 153 | -------------------------------------------------------------------------------- /linux/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "define.h" 11 | #include "vmx.h" 12 | #include "vmm.h" 13 | #include "video.h" 14 | #include "console.h" 15 | #include "codeview.h" 16 | #include "dbgprint.h" 17 | #include "sym.h" 18 | 19 | extern LARGE_INTEGER SpecCode; 20 | 21 | BOOLEAN asmlinkage StartVirtualization(PVOID pGuestEsp) 22 | { 23 | BOOLEAN bRet; 24 | PGUEST_CPU pCpu; 25 | 26 | pCpu = (PGUEST_CPU)kmalloc(sizeof(GUEST_CPU), GFP_ATOMIC); 27 | memset(pCpu,0,sizeof(GUEST_CPU)); 28 | if (!pCpu) 29 | { 30 | RED_FONT; 31 | printf("can't allocate cpu structure!\r\n"); 32 | goto failexit; 33 | } 34 | 35 | GREEN_FONT; 36 | printf("SetupVMX...\r\n"); 37 | bRet = SetupVMX(pCpu); 38 | if (bRet == false) 39 | { 40 | RED_FONT; 41 | printf("SetupVMX Failed!\r\n"); 42 | goto failexit; 43 | } 44 | printf("\r\n"); 45 | 46 | GREEN_FONT; 47 | printf("SetupVMCS...\r\n"); 48 | bRet = SetupVMCS(pCpu, pGuestEsp); 49 | if (bRet == false) 50 | { 51 | RED_FONT; 52 | printf("SetupVMCS Failed!\r\n"); 53 | goto failexit; 54 | } 55 | printf("\r\n"); 56 | 57 | GREEN_FONT; 58 | printf("Virtualize...\r\n"); 59 | bRet = Virtualize(pCpu); 60 | 61 | failexit: 62 | DEFAULT_FONT; 63 | return false; 64 | } 65 | 66 | static int vmxice_init(void) 67 | { 68 | BOOLEAN bRet; 69 | 70 | YELLOW_FONT; 71 | printf("VMXICE for linux\r\n"); 72 | printf("MengXP Works 2011-2012 @ XUPT\r\n\r\n"); 73 | DEFAULT_FONT; 74 | 75 | SymbolInit(); 76 | VideoInit(); 77 | ConsoleInit(); 78 | CodeViewInit(); 79 | SpecCode.QuadPart = _TSC(); 80 | 81 | bRet = CheckForVirtualizationSupport(); 82 | if (bRet == false) 83 | { 84 | RED_FONT; 85 | printf("Not support VT-x!\r\n"); 86 | goto init_exit; 87 | } 88 | 89 | bRet = CheckIfVMXIsEnabled(); 90 | if (bRet == false) 91 | { 92 | RED_FONT; 93 | printf("BIOS Set VMX Disabled!\r\n"); 94 | goto init_exit; 95 | } 96 | 97 | bRet = _StartVirtualization(); 98 | if(bRet) 99 | { 100 | GREEN_FONT; 101 | printf("Virtualize successfully!\r\n"); 102 | printf("Press F12 to call VMXICE!\r\n"); 103 | } 104 | else 105 | { 106 | RED_FONT; 107 | printf("Virtualize failed!\r\n"); 108 | } 109 | 110 | init_exit: 111 | DEFAULT_FONT; 112 | return 0; 113 | } 114 | 115 | static void vmxice_exit(void) 116 | { 117 | mm_segment_t old_fs; 118 | struct file *fp = NULL; 119 | 120 | printf("vmxice_exit!!\n"); 121 | fp = filp_open("/home/screen.bmp",O_RDWR | O_CREAT, 0644); 122 | if(fp) 123 | { 124 | old_fs = get_fs(); 125 | set_fs(get_ds()); 126 | fp->f_op->write(fp,pVideoBufferPrint,VideoWidth*VideoHeight*4,&fp->f_pos); 127 | set_fs(old_fs); 128 | filp_close(fp,NULL); 129 | } 130 | else 131 | { 132 | printf("Can't open ~/screen.bmp\r\n"); 133 | } 134 | _StopVirtualization(SpecCode.LowPart,SpecCode.HighPart); 135 | VideoRelease(); 136 | ConsoleRelease(); 137 | 138 | } 139 | 140 | module_init(vmxice_init); 141 | module_exit(vmxice_exit); 142 | -------------------------------------------------------------------------------- /linux/mmu.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "mmu.h" 5 | #include "mmu.h" 6 | #include "vmx.h" 7 | 8 | ULONG GetPhysAddress(ULONG CR3,ULONG VirtAddress,PULONG PhysAddress) 9 | { 10 | ULONG PdeBaseVirs; 11 | ULONG Pde; 12 | PPDE pPde = (PPDE)&Pde; 13 | ULONG PteBaseVirt; 14 | ULONG Pte; 15 | 16 | *PhysAddress = 0; 17 | PdeBaseVirs = (ULONG)phys_to_virt(CR3); 18 | Pde = *(PULONG)(PdeBaseVirs + ((VirtAddress >> 22) << 2)); 19 | if(!(Pde & 1)) 20 | return 0; 21 | 22 | if(pPde->LargePage) 23 | { 24 | *PhysAddress = (Pde & 0xffc00000) + (VirtAddress & 0x3fffff); 25 | return 1; 26 | } 27 | 28 | if(Pde > 896*1024*1024) //Why PTE table may appear VMALLOC region..fuck.. 29 | { 30 | //printk("Can't directly map Pde: %x\n",Pde); 31 | return 0; 32 | } 33 | 34 | PteBaseVirt = (ULONG)phys_to_virt(Pde & 0xfffff000); 35 | Pte = *(PULONG)(PteBaseVirt + (((VirtAddress >> 12) & 0x3ff) << 2)); 36 | if(!(Pte & 1)) 37 | return 0; 38 | 39 | *PhysAddress = (Pte & 0xfffff000) + (VirtAddress & 0xfff); 40 | return 1; 41 | } 42 | 43 | ULONG IsAddressExist(ULONG VirtAddress) 44 | { 45 | ULONG PhysAddress; 46 | 47 | return GetPhysAddress(_CR3(),VirtAddress,&PhysAddress); 48 | } 49 | 50 | ULONG IsAddressRangeExist(ULONG VirtAddress,ULONG Len) 51 | { 52 | ULONG VirtAddress2 = VirtAddress + Len; 53 | ULONG PhysAddress; 54 | ULONG Ret1,Ret2; 55 | 56 | Ret1 = GetPhysAddress(_CR3(),VirtAddress,&PhysAddress); 57 | if(!Ret1) 58 | return 0; 59 | 60 | Ret2 = GetPhysAddress(_CR3(),VirtAddress2,&PhysAddress); 61 | if(!Ret2) 62 | return 0; 63 | 64 | return 1; 65 | } 66 | 67 | 68 | VOID GetVirtAddress(ULONG CR3,ULONG PhysAddress) 69 | { 70 | ULONG PhysBaseRet; 71 | ULONG PhysBase = PhysAddress & 0xfffff000; 72 | ULONG PageOffset = PhysAddress & 0xfff; 73 | ULONG VirtBase; 74 | ULONG VirtAddress; 75 | ULONG Ret; 76 | 77 | for(VirtBase = 0x1000; VirtBase < 0xfffff000; VirtBase += 0x1000) 78 | { 79 | Ret = GetPhysAddress(CR3,VirtBase,&PhysBaseRet); 80 | if(Ret && PhysBaseRet == PhysBase) 81 | { 82 | VirtAddress = VirtBase + PageOffset; 83 | printk("GetVirtAddress found %x [%x]\n",VirtAddress,*(PULONG)VirtAddress); 84 | } 85 | } 86 | } 87 | 88 | ULONG GetPde(ULONG CR3,ULONG VirtAddress) 89 | { 90 | ULONG PdeBaseVirs; 91 | ULONG Pde; 92 | 93 | PdeBaseVirs = (ULONG)phys_to_virt(CR3); 94 | Pde = *(PULONG)(PdeBaseVirs + ((VirtAddress >> 22) << 2)); 95 | if(!(Pde & 1)) 96 | return 0; 97 | 98 | if(Pde > 896*1024*1024) //Why PTE table may appear VMALLOC region..fuck.. 99 | { 100 | //printk("Can't directly map Pde: %x\n",Pde); 101 | return 0; 102 | } 103 | 104 | return Pde; 105 | } 106 | 107 | ULONG GetPte(ULONG CR3,ULONG VirtAddress) 108 | { 109 | ULONG PdeBaseVirs; 110 | ULONG Pde; 111 | PPDE pPde = (PPDE)&Pde; 112 | ULONG PteBaseVirt; 113 | ULONG Pte; 114 | 115 | PdeBaseVirs = (ULONG)phys_to_virt(CR3); 116 | Pde = *(PULONG)(PdeBaseVirs + ((VirtAddress >> 22) << 2)); 117 | if(!(Pde & 1)) 118 | return 0; 119 | 120 | if(pPde->LargePage) 121 | { 122 | return 0; 123 | } 124 | 125 | if(Pde > 896*1024*1024) //Why PTE table may appear VMALLOC region..fuck.. 126 | { 127 | //printk("Can't directly map Pde: %x\n",Pde); 128 | return 0; 129 | } 130 | 131 | PteBaseVirt = (ULONG)phys_to_virt(Pde & 0xfffff000); 132 | Pte = *(PULONG)(PteBaseVirt + (((VirtAddress >> 12) & 0x3ff) << 2)); 133 | return Pte; 134 | } 135 | -------------------------------------------------------------------------------- /linux/mmu.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | #ifndef MMU_H 4 | #define MMU_H 5 | 6 | typedef struct { 7 | unsigned Present:1; 8 | unsigned Writable:1; 9 | unsigned Owner:1; 10 | unsigned WriteThrough:1; 11 | unsigned CacheDisable:1; 12 | unsigned Accessed:1; 13 | unsigned Dirty:1; 14 | unsigned LargePage:1; 15 | unsigned Global:1; 16 | unsigned Ignored9_11:3; 17 | unsigned PAT:1; 18 | unsigned Reserved13_21:9; 19 | unsigned PhysFrame:10; 20 | }PDE4M,*PPDE4M; 21 | 22 | typedef struct { 23 | unsigned Present:1; 24 | unsigned Writable:1; 25 | unsigned Owner:1; 26 | unsigned WriteThrough:1; 27 | unsigned CacheDisable:1; 28 | unsigned Accessed:1; 29 | unsigned Dirty:1; 30 | unsigned LargePage:1; 31 | unsigned Ignored8_11:4; 32 | unsigned PageTable:20; 33 | }PDE,*PPDE; 34 | 35 | typedef struct { 36 | unsigned Present:1; 37 | unsigned Writable:1; 38 | unsigned Owner:1; 39 | unsigned WriteThrough:1; 40 | unsigned CacheDisable:1; 41 | unsigned Accessed:1; 42 | unsigned Dirty:1; 43 | unsigned Reserved:1; 44 | unsigned Global:1; 45 | unsigned Ignored9_11:3; 46 | unsigned PhysFrame:20; 47 | }PTE,*PPTE; 48 | 49 | 50 | ULONG GetPhysAddress(ULONG CR3,ULONG VirtAddress,PULONG PhysAddress); 51 | VOID GetVirtAddress(ULONG CR3,ULONG PhysAddress); 52 | ULONG GetPde(ULONG CR3,ULONG VirtAddress); 53 | ULONG GetPte(ULONG CR3,ULONG VirtAddress); 54 | ULONG MapVmxiceToGuest(ULONG DstCR3,ULONG SrcCR3); 55 | ULONG UnmapVmxiceFromGuest(ULONG DstCR3); 56 | ULONG IsAddressExist(ULONG VirtAddress); 57 | ULONG IsAddressRangeExist(ULONG VirtAddress,ULONG Len); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /linux/scancode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "scancode.h" 3 | 4 | UCHAR ScancodeToAscii_NonShift(ULONG Scancode) 5 | { 6 | switch(Scancode) 7 | { 8 | case SCANCODE_BACK: return '\b'; //0x0E // \b 9 | case SCANCODE_ENTER: return '\n'; //0x1C // \n 10 | case SCANCODE_PADENTER: return '\n'; //0x60 // \n 11 | case SCANCODE_SPACE: return ' '; //0x39 12 | case SCANCODE_GACC: return '`'; //0x58 // "`" 13 | case SCANCODE_1: return '1'; //0x02 14 | case SCANCODE_2: return '2'; //0x03 15 | case SCANCODE_3: return '3'; //0x04 16 | case SCANCODE_4: return '4'; //0x05 17 | case SCANCODE_5: return '5'; //0x06 18 | case SCANCODE_6: return '6'; //0x07 19 | case SCANCODE_7: return '7'; //0x08 20 | case SCANCODE_8: return '8'; //0x09 21 | case SCANCODE_9: return '9'; //0x0A 22 | case SCANCODE_0: return '0'; //0x0B 23 | case SCANCODE_SUB: return '-'; //0x0C 24 | case SCANCODE_EQU: return '='; //0x0D 25 | case SCANCODE_TAB: return ' '; //0x0F 26 | case SCANCODE_Q: return 'q'; //0x10 27 | case SCANCODE_W: return 'w'; //0x11 28 | case SCANCODE_E: return 'e'; //0x12 29 | case SCANCODE_R: return 'r'; //0x13 30 | case SCANCODE_T: return 't'; //0x14 31 | case SCANCODE_Y: return 'y'; //0x15 32 | case SCANCODE_U: return 'u'; //0x16 33 | case SCANCODE_I: return 'i'; //0x17 34 | case SCANCODE_O: return 'o'; //0x18 35 | case SCANCODE_P: return 'p'; //0x19 36 | case SCANCODE_LSQU: return '['; //0x1A // "[" 37 | case SCANCODE_RSQU: return ']'; //0x1B // "]" 38 | case SCANCODE_BSLASH: return '\\'; //0x2B // "\" 39 | case SCANCODE_A: return 'a'; //0x1E 40 | case SCANCODE_S: return 's'; //0x1F 41 | case SCANCODE_D: return 'd'; //0x20 42 | case SCANCODE_F: return 'f'; //0x21 43 | case SCANCODE_G: return 'g'; //0x22 44 | case SCANCODE_H: return 'h'; //0x23 45 | case SCANCODE_J: return 'j'; //0x24 46 | case SCANCODE_K: return 'k'; //0x25 47 | case SCANCODE_L: return 'l'; //0x26 48 | case SCANCODE_SEMI: return ';'; //0x27 // ";" 49 | case SCANCODE_APOS: return '\''; //0x28 // "'" 50 | case SCANCODE_Z: return 'z'; //0x2C 51 | case SCANCODE_X: return 'x'; //0x2D 52 | case SCANCODE_C: return 'c'; //0x2E 53 | case SCANCODE_V: return 'v'; //0x2F 54 | case SCANCODE_B: return 'b'; //0x30 55 | case SCANCODE_N: return 'n'; //0x31 56 | case SCANCODE_M: return 'm'; //0x32 57 | case SCANCODE_COMMA: return ','; //0x33 58 | case SCANCODE_POINT: return '.'; //0x34 59 | case SCANCODE_SLASH: return '/'; //0x35 // "/" 60 | case SCANCODE_PAD0: return '0'; //0x52 61 | case SCANCODE_PAD1: return '1'; //0x4F 62 | case SCANCODE_PAD2: return '2'; //0x50 63 | case SCANCODE_PAD3: return '3'; //0x51 64 | case SCANCODE_PAD4: return '4'; //0x4B 65 | case SCANCODE_PAD5: return '5'; //0x4C 66 | case SCANCODE_PAD6: return '6'; //0x4D 67 | case SCANCODE_PAD7: return '7'; //0x47 68 | case SCANCODE_PAD8: return '8'; //0x48 69 | case SCANCODE_PAD9: return '9'; //0x49 70 | case SCANCODE_PADPOINT: return '.'; //0x53 71 | case SCANCODE_PADPLUS: return '+'; //0xE035 72 | case SCANCODE_PADSUB: return '-'; //0x4A 73 | case SCANCODE_PADMUL: return '*'; //0x37 74 | case SCANCODE_PADDIV: return '/'; //0x4E 75 | default: 76 | return 0; 77 | } 78 | } 79 | 80 | UCHAR ScancodeToAscii_Shift(ULONG Scancode) 81 | { 82 | switch(Scancode) 83 | { 84 | case SCANCODE_BACK: return '\b'; //0x0E // \b 85 | case SCANCODE_ENTER: return '\n'; //0x1C // \n 86 | case SCANCODE_PADENTER: return '\n'; //0x60 // \n 87 | case SCANCODE_SPACE: return ' '; //0x39 88 | case SCANCODE_GACC: return '~'; //0x58 // "`" 89 | case SCANCODE_1: return '!'; //0x02 90 | case SCANCODE_2: return '@'; //0x03 91 | case SCANCODE_3: return '#'; //0x04 92 | case SCANCODE_4: return '$'; //0x05 93 | case SCANCODE_5: return '%'; //0x06 94 | case SCANCODE_6: return '^'; //0x07 95 | case SCANCODE_7: return '&'; //0x08 96 | case SCANCODE_8: return '*'; //0x09 97 | case SCANCODE_9: return '('; //0x0A 98 | case SCANCODE_0: return ')'; //0x0B 99 | case SCANCODE_SUB: return '_'; //0x0C 100 | case SCANCODE_EQU: return '+'; //0x0D 101 | case SCANCODE_TAB: return ' '; //0x0F 102 | case SCANCODE_Q: return 'Q'; //0x10 103 | case SCANCODE_W: return 'W'; //0x11 104 | case SCANCODE_E: return 'E'; //0x12 105 | case SCANCODE_R: return 'R'; //0x13 106 | case SCANCODE_T: return 'T'; //0x14 107 | case SCANCODE_Y: return 'Y'; //0x15 108 | case SCANCODE_U: return 'U'; //0x16 109 | case SCANCODE_I: return 'I'; //0x17 110 | case SCANCODE_O: return 'O'; //0x18 111 | case SCANCODE_P: return 'P'; //0x19 112 | case SCANCODE_LSQU: return '{'; //0x1A // "[" 113 | case SCANCODE_RSQU: return '}'; //0x1B // "]" 114 | case SCANCODE_BSLASH: return '|'; //0x2B // "\" 115 | case SCANCODE_A: return 'A'; //0x1E 116 | case SCANCODE_S: return 'S'; //0x1F 117 | case SCANCODE_D: return 'D'; //0x20 118 | case SCANCODE_F: return 'F'; //0x21 119 | case SCANCODE_G: return 'G'; //0x22 120 | case SCANCODE_H: return 'H'; //0x23 121 | case SCANCODE_J: return 'J'; //0x24 122 | case SCANCODE_K: return 'K'; //0x25 123 | case SCANCODE_L: return 'L'; //0x26 124 | case SCANCODE_SEMI: return ':'; //0x27 // ";" 125 | case SCANCODE_APOS: return '"'; //0x28 // "'" 126 | case SCANCODE_Z: return 'Z'; //0x2C 127 | case SCANCODE_X: return 'X'; //0x2D 128 | case SCANCODE_C: return 'C'; //0x2E 129 | case SCANCODE_V: return 'V'; //0x2F 130 | case SCANCODE_B: return 'B'; //0x30 131 | case SCANCODE_N: return 'N'; //0x31 132 | case SCANCODE_M: return 'M'; //0x32 133 | case SCANCODE_COMMA: return '<'; //0x33 134 | case SCANCODE_POINT: return '>'; //0x34 135 | case SCANCODE_SLASH: return '?'; //0x35 // "/" 136 | case SCANCODE_PAD0: return '0'; //0x52 137 | case SCANCODE_PAD1: return '1'; //0x4F 138 | case SCANCODE_PAD2: return '2'; //0x50 139 | case SCANCODE_PAD3: return '3'; //0x51 140 | case SCANCODE_PAD4: return '4'; //0x4B 141 | case SCANCODE_PAD5: return '5'; //0x4C 142 | case SCANCODE_PAD6: return '6'; //0x4D 143 | case SCANCODE_PAD7: return '7'; //0x47 144 | case SCANCODE_PAD8: return '8'; //0x48 145 | case SCANCODE_PAD9: return '9'; //0x49 146 | case SCANCODE_PADPOINT: return '.'; //0x53 147 | case SCANCODE_PADPLUS: return '+'; //0xE035 148 | case SCANCODE_PADSUB: return '-'; //0x4A 149 | case SCANCODE_PADMUL: return '*'; //0x37 150 | case SCANCODE_PADDIV: return '/'; //0x4E 151 | default: 152 | return 0; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /linux/scancode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/npbool/vmxice/ee805d06c74fc41387a6a36aec7db878b5e63d91/linux/scancode.h -------------------------------------------------------------------------------- /linux/sym.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "dbgprint.h" 5 | #include "sym.h" 6 | 7 | kallsyms_lookup_name LookupName; 8 | kallsyms_lookup LookupAddress; 9 | 10 | int char2bin(char c) 11 | { 12 | switch(c) 13 | { 14 | case '0':return 0; 15 | case '1':return 1; 16 | case '2':return 2; 17 | case '3':return 3; 18 | case '4':return 4; 19 | case '5':return 5; 20 | case '6':return 6; 21 | case '7':return 7; 22 | case '8':return 8; 23 | case '9':return 9; 24 | case 'A': 25 | case 'a':return 10; 26 | case 'B': 27 | case 'b':return 11; 28 | case 'C': 29 | case 'c':return 12; 30 | case 'D': 31 | case 'd':return 13; 32 | case 'E': 33 | case 'e':return 14; 34 | case 'F': 35 | case 'f':return 15; 36 | default: 37 | return 0; 38 | } 39 | } 40 | 41 | int hex2bin_dword(char *lpszHex) 42 | { 43 | int value = 0; 44 | int i; 45 | 46 | for(i = 0; i < 8; i++) 47 | { 48 | value <<= 4; 49 | value |= char2bin(lpszHex[i]); 50 | } 51 | return value; 52 | } 53 | 54 | int Get_kallsyms_lookup_name(void) 55 | { 56 | int lpApiAddress = 0; 57 | mm_segment_t old_fs; 58 | struct file *fp = NULL; 59 | char *lpBuffer; 60 | int dwTotalRead = 0; 61 | int dwReadBytes; 62 | char szApiName[] = " kallsyms_lookup_name"; 63 | int dwApiNameLen = strlen(szApiName); 64 | int i; 65 | char szApiAddress[16]; 66 | 67 | printf("Lookup %s..\r\n",szApiName); 68 | 69 | lpBuffer = vmalloc(0x400000); 70 | memset(szApiAddress,0,16); 71 | 72 | fp = filp_open("/proc/kallsyms",O_RDWR,644); 73 | if(!fp) 74 | return 0; 75 | 76 | old_fs = get_fs(); 77 | set_fs(get_ds()); 78 | while(1) 79 | { 80 | dwReadBytes = fp->f_op->read(fp,&lpBuffer[dwTotalRead],0x1000,&fp->f_pos); 81 | if(!dwReadBytes) 82 | break; 83 | dwTotalRead += dwReadBytes; 84 | } 85 | set_fs(old_fs); 86 | filp_close(fp,NULL); 87 | printf("Total read %d bytes\r\n",dwTotalRead); 88 | 89 | for(i = 0; i < dwTotalRead-dwApiNameLen; i++) 90 | { 91 | if(!memcmp(&lpBuffer[i],szApiName,dwApiNameLen)) 92 | { 93 | memcpy(szApiAddress,&lpBuffer[i-10],8); 94 | lpApiAddress = hex2bin_dword(szApiAddress); 95 | printf("Found %s @ %08x\r\n",szApiName,lpApiAddress); 96 | break; 97 | } 98 | } 99 | 100 | vfree(lpBuffer); 101 | return lpApiAddress; 102 | } 103 | 104 | ULONG SymbolInit(void) 105 | { 106 | LookupName = (kallsyms_lookup_name)Get_kallsyms_lookup_name(); 107 | if(!LookupName) 108 | { 109 | printf("Can't get kallsyms_lookup_name!\r\n"); 110 | return 0; 111 | } 112 | LookupAddress = (kallsyms_lookup)LookupName("kallsyms_lookup"); 113 | printf("Found kallsyms_lookup @ %08x\r\n\r\n",LookupAddress); 114 | 115 | return 1; 116 | } 117 | -------------------------------------------------------------------------------- /linux/sym.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | #ifndef SYM_H 4 | #define SYM_H 5 | 6 | typedef unsigned long (*kallsyms_lookup_name)(const char *name); 7 | typedef const char *(*kallsyms_lookup)(unsigned long addr, 8 | unsigned long *symbolsize, 9 | unsigned long *offset, 10 | char **modname, char *namebuf); 11 | 12 | extern ULONG SymbolInit(void); 13 | 14 | extern kallsyms_lookup_name LookupName; 15 | extern kallsyms_lookup LookupAddress; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /linux/udis86.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------------- 2 | * udis86.h 3 | * 4 | * Copyright (c) 2002, 2003, 2004 Vivek Mohan 5 | * All rights reserved. See (LICENSE) 6 | * ----------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef UDIS86_H 10 | #define UDIS86_H 11 | 12 | #include "libudis86/types.h" 13 | #include "libudis86/extern.h" 14 | #include "libudis86/itab.h" 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /linux/video.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "dbgprint.h" 5 | #include "video.h" 6 | #include "font_inc.c" 7 | 8 | #define CHAR_WIDTH 8 9 | #define CHAR_HEIGHT 14 10 | #define CHAR_PIXELS CHAR_WIDTH * CHAR_HEIGHT 11 | #define CHAR_SIZE (CHAR_WIDTH * CHAR_HEIGHT / 8) 12 | 13 | //#define PRINT_IMAGE 1 14 | 15 | PCHAR VideoBuffer_va; 16 | ULONG VideoWidth; 17 | ULONG VideoHeight; 18 | ULONG VideoBitPerPixel; 19 | ULONG VideoPitch; 20 | 21 | ULONG StartX = 0; 22 | ULONG StartY = 0; 23 | 24 | ULONG GUI_Width = 100; 25 | ULONG GUI_Height = 40; 26 | 27 | PUCHAR pVideoBufferBak; 28 | PUCHAR pVideoBufferImage; 29 | PUCHAR pVideoBufferPrint; 30 | 31 | ULONG ColorTbl[] = {0x000000,0x000080,0x008000,0x008080,0x800000,0x800080,0x808000,0xC0C0C0,0x808080,0x0000FF,0x00FF00,0x00FFFF,0xFF0000,0xFF00FF,0xFFFF00,0xFFFFFF}; 32 | 33 | ULONG PrintChar(ULONG x,ULONG y,ULONG ForeColor,ULONG BackColor,ULONG bTransparent,UCHAR CharAscii) 34 | { 35 | ULONG CharForeColor; 36 | ULONG CharBackColor; 37 | register PUCHAR pFontBits; 38 | ULONG FontMask; 39 | ULONG x0,y0; 40 | register ULONG cx,cy; 41 | register PULONG p; 42 | #ifdef PRINT_IMAGE 43 | register PULONG p_img; 44 | #endif 45 | ULONG LinePitch1; 46 | 47 | if(x >= GUI_Width || y >= GUI_Height) 48 | return 0; 49 | 50 | CharForeColor = ColorTbl[ForeColor]; 51 | CharBackColor = ColorTbl[BackColor]; 52 | 53 | pFontBits = &cFontData[CharAscii*CHAR_SIZE]; 54 | 55 | x0 = x*CHAR_WIDTH + StartX; 56 | y0 = y*CHAR_HEIGHT + StartY; 57 | 58 | p = (PULONG)&VideoBuffer_va[(y0 * VideoPitch) + (x0 * 4)]; 59 | #ifdef PRINT_IMAGE 60 | p_img = (PULONG)&pVideoBufferImage[(y0 * VideoPitch) + (x0 * 4)]; 61 | #endif 62 | LinePitch1 = (VideoPitch - (CHAR_WIDTH<<2)) >> 2; 63 | for(cy = 0; cy < CHAR_HEIGHT; cy++) 64 | { 65 | for(cx = 0,FontMask = 0x80; cx < CHAR_WIDTH; cx++) 66 | { 67 | if((*pFontBits) & FontMask) 68 | { 69 | *p = CharForeColor; 70 | #ifdef PRINT_IMAGE 71 | *p_img = CharForeColor; 72 | #endif 73 | } 74 | else 75 | { 76 | if(!bTransparent) 77 | { 78 | *p = CharBackColor; 79 | #ifdef PRINT_IMAGE 80 | *p_img = CharBackColor; 81 | #endif 82 | } 83 | } 84 | p++; 85 | #ifdef PRINT_IMAGE 86 | p_img++; 87 | #endif 88 | FontMask = FontMask >> 1; 89 | } 90 | p += LinePitch1; 91 | #ifdef PRINT_IMAGE 92 | p_img += LinePitch1; 93 | #endif 94 | pFontBits++; 95 | 96 | } 97 | return 1; 98 | } 99 | 100 | VOID DrawCursor(ULONG x,ULONG y,BOOLEAN isInsertState,BOOLEAN ShowState) 101 | { 102 | ULONG x0,y0,cy; 103 | PUCHAR p; 104 | #ifdef PRINT_IMAGE 105 | PUCHAR p_img; 106 | #endif 107 | ULONG EmptyCharLineW[8] = {0xC0C0C0,0xC0C0C0,0xC0C0C0,0xC0C0C0,0xC0C0C0,0xC0C0C0,0xC0C0C0,0xC0C0C0}; 108 | ULONG EmptyCharLineB[8] = {0x0}; 109 | 110 | if(x >= GUI_Width || y >= GUI_Height) 111 | return; 112 | 113 | x0 = x*CHAR_WIDTH + StartX; 114 | y0 = y*CHAR_HEIGHT + StartY; 115 | 116 | p = &VideoBuffer_va[(y0 * VideoPitch) + (x0 * sizeof(ULONG))]; 117 | #ifdef PRINT_IMAGE 118 | p_img = &pVideoBufferImage[(y0 * VideoPitch) + (x0 * sizeof(ULONG))]; 119 | #endif 120 | for(cy = 0; cy < CHAR_HEIGHT; cy++) 121 | { 122 | if(cy < 11) 123 | { 124 | if(isInsertState) 125 | { 126 | if(ShowState) 127 | { 128 | memcpy(p,EmptyCharLineW,sizeof(EmptyCharLineW)); 129 | #ifdef PRINT_IMAGE 130 | memcpy(p_img,EmptyCharLineW,sizeof(EmptyCharLineW)); 131 | #endif 132 | } 133 | else 134 | { 135 | memcpy(p,EmptyCharLineB,sizeof(EmptyCharLineB)); 136 | #ifdef PRINT_IMAGE 137 | memcpy(p_img,EmptyCharLineW,sizeof(EmptyCharLineW)); 138 | #endif 139 | } 140 | } 141 | } 142 | else 143 | { 144 | if(ShowState) 145 | { 146 | memcpy(p,EmptyCharLineW,sizeof(EmptyCharLineW)); 147 | #ifdef PRINT_IMAGE 148 | memcpy(p_img,EmptyCharLineW,sizeof(EmptyCharLineW)); 149 | #endif 150 | } 151 | else 152 | { 153 | memcpy(p,EmptyCharLineB,sizeof(EmptyCharLineB)); 154 | #ifdef PRINT_IMAGE 155 | memcpy(p_img,EmptyCharLineB,sizeof(EmptyCharLineB)); 156 | #endif 157 | } 158 | } 159 | p += VideoPitch; 160 | #ifdef PRINT_IMAGE 161 | p_img += VideoPitch; 162 | #endif 163 | } 164 | } 165 | 166 | VOID PrintStr(ULONG x,ULONG y,ULONG ForeColor,ULONG BackColor,ULONG bTransparent,PUCHAR String,ULONG FillLine) 167 | { 168 | ULONG MaxLen = 1024; 169 | 170 | while(*String) 171 | { 172 | PrintChar(x,y,ForeColor,BackColor,bTransparent,*String); 173 | x++; 174 | if(x >= GUI_Width) 175 | { 176 | x = 1; 177 | y++; 178 | } 179 | String++; 180 | MaxLen--; 181 | if(!MaxLen) 182 | break; 183 | } 184 | 185 | while(FillLine) 186 | { 187 | PrintChar(x,y,ForeColor,BackColor,bTransparent,' '); 188 | x++; 189 | if(x >= (GUI_Width-1)) 190 | break; 191 | } 192 | } 193 | 194 | VOID DrawLineX(ULONG x0,ULONG x1,ULONG y,ULONG ForeColor,ULONG BackColor,UCHAR bChar) 195 | { 196 | while(1) 197 | { 198 | PrintChar(x0,y,ForeColor,BackColor,FALSE,bChar); 199 | x0++; 200 | if(x0 >= x1) 201 | break; 202 | } 203 | } 204 | 205 | 206 | VOID DrawLineY(ULONG y0,ULONG y1,ULONG x,ULONG ForeColor,ULONG BackColor,UCHAR bChar) 207 | { 208 | while(1) 209 | { 210 | PrintChar(x,y0,ForeColor,BackColor,FALSE,bChar); 211 | y0++; 212 | if(y0 >= y1) 213 | break; 214 | } 215 | } 216 | 217 | VOID DrawBackground(void) 218 | { 219 | ULONG y; 220 | PUCHAR p; 221 | #ifdef PRINT_IMAGE 222 | PUCHAR p_img; 223 | #endif 224 | 225 | p = &VideoBuffer_va[(StartY * VideoPitch) + (StartX * sizeof(ULONG))]; 226 | #ifdef PRINT_IMAGE 227 | p_img = &pVideoBufferImage[(StartY * VideoPitch) + (StartX * sizeof(ULONG))]; 228 | #endif 229 | for(y = 0; y < GUI_Height * CHAR_HEIGHT; y++) 230 | { 231 | memset(p,0,GUI_Width * CHAR_WIDTH * sizeof(ULONG)); 232 | p += VideoPitch; 233 | #ifdef PRINT_IMAGE 234 | memset(p_img,0,GUI_Width * CHAR_WIDTH * sizeof(ULONG)); 235 | p_img += VideoPitch; 236 | #endif 237 | } 238 | } 239 | 240 | VOID FillScreen(void) 241 | { 242 | ULONG i; 243 | for(i = 0; i < 40; i++) 244 | PrintStr(0,i,7,0,FALSE,"Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test ",FALSE); 245 | } 246 | 247 | VOID DrawBorder(void) 248 | { 249 | PrintChar(0,0,3,0,0,218); 250 | PrintChar(GUI_Width-1,0,3,0,0,191); 251 | PrintChar(0,GUI_Height-1,3,0,0,192); 252 | PrintChar(GUI_Width-1,GUI_Height-1,3,0,0,217); 253 | 254 | DrawLineX(1,GUI_Width-1,0,3,0,196); 255 | DrawLineX(1,GUI_Width-1,GUI_Height-1,3,0,196); 256 | DrawLineY(1,GUI_Height-1,0,3,0,179); 257 | DrawLineY(1,GUI_Height-1,GUI_Width-1,3,0,179); 258 | 259 | //DrawLineX(1,GUI_Width-1,4,2,0,196); 260 | //DrawLineX(1,GUI_Width-1,24,2,0,196); 261 | DrawLineX(1,GUI_Width-1,GUI_Height-2,0,3,' '); 262 | 263 | PrintStr(GUI_Width-33,GUI_Height-1,15,0,0," [ VMXICE v0.1 MengXP Works ] ",FALSE); 264 | } 265 | 266 | VOID BackupScreen(void) 267 | { 268 | ULONG y; 269 | 270 | for(y = 0; y < VideoHeight; y++) 271 | { 272 | memcpy(pVideoBufferBak+y*VideoWidth*4,VideoBuffer_va+VideoPitch*y,VideoWidth*4); 273 | #ifdef PRINT_IMAGE 274 | memcpy(pVideoBufferImage+y*VideoWidth*4,VideoBuffer_va+VideoPitch*y,VideoWidth*4); 275 | #endif 276 | } 277 | } 278 | 279 | VOID RestoreScreen(void) 280 | { 281 | ULONG y; 282 | 283 | for(y = 0; y < VideoHeight; y++) 284 | { 285 | memcpy(VideoBuffer_va+VideoPitch*y,pVideoBufferBak+y*VideoWidth*4,VideoWidth*4); 286 | } 287 | } 288 | 289 | VOID PrintScreen(void) 290 | { 291 | ULONG y; 292 | 293 | for(y = 0; y < VideoHeight; y++) 294 | { 295 | memcpy(pVideoBufferPrint+y*VideoWidth*4,pVideoBufferImage+VideoPitch*y,VideoWidth*4); 296 | } 297 | } 298 | 299 | VOID VideoInit(void) 300 | { 301 | struct fb_info *fbi = registered_fb[0]; 302 | 303 | VideoBuffer_va = (char *)fbi->screen_base; 304 | VideoWidth = fbi->var.xres; 305 | VideoHeight = fbi->var.yres; 306 | VideoBitPerPixel = fbi->var.bits_per_pixel; 307 | VideoPitch = fbi->fix.line_length; 308 | 309 | printf("FrameBuffer Virt: 0x%p\r\n",(PVOID)VideoBuffer_va); 310 | printf("FrameBuffer Phys: 0x%p\r\n",(PVOID)fbi->fix.smem_start); 311 | printf("Resolution: %d x %d x %d\r\n",VideoWidth,VideoHeight,VideoBitPerPixel); 312 | printf("Pitch: %d\r\n\r\n",VideoPitch); 313 | 314 | StartX = (VideoWidth - GUI_Width * CHAR_WIDTH) / 2; 315 | StartY = (VideoHeight - GUI_Height * CHAR_HEIGHT) / 2; 316 | 317 | pVideoBufferBak = (PUCHAR)kmalloc(VideoHeight * VideoWidth * 4,GFP_ATOMIC); 318 | pVideoBufferPrint = (PUCHAR)kmalloc(VideoHeight * VideoWidth * 4,GFP_ATOMIC); 319 | pVideoBufferImage = (PUCHAR)kmalloc(VideoHeight * VideoWidth * 4,GFP_ATOMIC); 320 | } 321 | 322 | VOID VideoRelease(void) 323 | { 324 | if(pVideoBufferBak) 325 | kfree(pVideoBufferBak); 326 | if(pVideoBufferPrint) 327 | kfree(pVideoBufferPrint); 328 | if(pVideoBufferImage) 329 | kfree(pVideoBufferImage); 330 | } 331 | -------------------------------------------------------------------------------- /linux/video.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | extern ULONG GUI_Width; 4 | extern ULONG GUI_Height; 5 | 6 | extern ULONG VideoWidth; 7 | extern ULONG VideoHeight; 8 | 9 | extern PUCHAR pVideoBufferBak; 10 | extern PUCHAR pVideoBufferPrint; 11 | 12 | VOID VideoInit(void); 13 | VOID VideoRelease(void); 14 | VOID BackupScreen(void); 15 | VOID RestoreScreen(void); 16 | ULONG PrintChar(ULONG x,ULONG y,ULONG ForeColor,ULONG BackColor,ULONG bTransparent,UCHAR CharAscii); 17 | VOID DrawCursor(ULONG x,ULONG y,BOOLEAN isInsertState,BOOLEAN ShowState); 18 | VOID PrintStr(ULONG x,ULONG y,ULONG ForeColor,ULONG BackColor,ULONG bTransparent,PUCHAR String,ULONG FillLine); 19 | VOID DrawBackground(void); 20 | VOID FillScreen(void); 21 | VOID DrawBorder(void); 22 | VOID PrintScreen(void); 23 | 24 | 25 | -------------------------------------------------------------------------------- /linux/vmm.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | #ifndef _VMM_H_ 4 | #define _VMM_H_ 5 | 6 | typedef struct _MOV_CR_QUALIFICATION { 7 | unsigned ControlRegister:4; 8 | unsigned AccessType:2; 9 | unsigned LMSWOperandType:1; 10 | unsigned Reserved1:1; 11 | unsigned Register:4; 12 | unsigned Reserved2:4; 13 | unsigned LMSWSourceData:16; 14 | } MOV_CR_QUALIFICATION, *PMOV_CR_QUALIFICATION; 15 | 16 | typedef struct _INTERRUPT_INFO_FIELD { 17 | unsigned Vector:8; 18 | unsigned InterruptionType:3; 19 | unsigned ErrorCodeValid:1; 20 | unsigned NMIUnblocking:1; 21 | unsigned Reserved:18; 22 | unsigned Valid:1; 23 | } INTERRUPT_INFO_FIELD, *PINTERRUPT_INFO_FIELD; 24 | 25 | typedef struct _INTERRUPT_INJECT_INFO_FIELD{ 26 | unsigned Vector:8; 27 | unsigned InterruptionType:3; 28 | unsigned DeliverErrorCode:1; 29 | unsigned Reserved:19; 30 | unsigned Valid:1; 31 | } INTERRUPT_INJECT_INFO_FIELD, *PINTERRUPT_INJECT_INFO_FIELD; 32 | 33 | #define EXIT_REASON_EXCEPTION_NMI 0 34 | #define EXIT_REASON_EXTERNAL_INTERRUPT 1 35 | #define EXIT_REASON_TRIPLE_FAULT 2 36 | #define EXIT_REASON_INIT 3 37 | #define EXIT_REASON_SIPI 4 38 | #define EXIT_REASON_IO_SMI 5 39 | #define EXIT_REASON_OTHER_SMI 6 40 | #define EXIT_REASON_PENDING_INTERRUPT 7 41 | 42 | #define EXIT_REASON_TASK_SWITCH 9 43 | #define EXIT_REASON_CPUID 10 44 | #define EXIT_REASON_HLT 12 45 | #define EXIT_REASON_INVD 13 46 | #define EXIT_REASON_INVLPG 14 47 | #define EXIT_REASON_RDPMC 15 48 | #define EXIT_REASON_RDTSC 16 49 | #define EXIT_REASON_RSM 17 50 | #define EXIT_REASON_VMCALL 18 51 | #define EXIT_REASON_VMCLEAR 19 52 | #define EXIT_REASON_VMLAUNCH 20 53 | #define EXIT_REASON_VMPTRLD 21 54 | #define EXIT_REASON_VMPTRST 22 55 | #define EXIT_REASON_VMREAD 23 56 | #define EXIT_REASON_VMRESUME 24 57 | #define EXIT_REASON_VMWRITE 25 58 | #define EXIT_REASON_VMXOFF 26 59 | #define EXIT_REASON_VMXON 27 60 | #define EXIT_REASON_CR_ACCESS 28 61 | #define EXIT_REASON_DR_ACCESS 29 62 | #define EXIT_REASON_IO_INSTRUCTION 30 63 | #define EXIT_REASON_MSR_READ 31 64 | #define EXIT_REASON_MSR_WRITE 32 65 | 66 | #define EXIT_REASON_INVALID_GUEST_STATE 33 67 | #define EXIT_REASON_MSR_LOADING 34 68 | 69 | #define EXIT_REASON_MWAIT_INSTRUCTION 36 70 | #define EXIT_REASON_MONITOR_INSTRUCTION 39 71 | #define EXIT_REASON_PAUSE_INSTRUCTION 40 72 | 73 | #define EXIT_REASON_MACHINE_CHECK 41 74 | 75 | #define EXIT_REASON_TPR_BELOW_THRESHOLD 43 76 | 77 | #define DIVIDE_ERROR_EXCEPTION 0 78 | #define DEBUG_EXCEPTION 1 79 | #define NMI_INTERRUPT 2 80 | #define BREAKPOINT_EXCEPTION 3 81 | #define OVERFLOW_EXCEPTION 4 82 | #define BOUND_EXCEPTION 5 83 | #define INVALID_OPCODE_EXCEPTION 6 84 | #define DEVICE_NOT_AVAILABLE_EXCEPTION 7 85 | #define DOUBLE_FAULT_EXCEPTION 8 86 | #define COPROCESSOR_SEGMENT_OVERRUN 9 87 | #define INVALID_TSS_EXCEPTION 10 88 | #define SEGMENT_NOT_PRESENT 11 89 | #define STACK_FAULT_EXCEPTION 12 90 | #define GENERAL_PROTECTION_EXCEPTION 13 91 | #define PAGE_FAULT_EXCEPTION 14 92 | #define X87_FLOATING_POINT_ERROR 16 93 | #define ALIGNMENT_CHECK_EXCEPTION 17 94 | //#define MACHINE_CHECK_EXCEPTION 18 95 | #define SIMD_FLOATING_POINT_EXCEPTION 19 96 | 97 | #define EXTERNAL_INTERRUPT 0 98 | #define HARDWARE_EXCEPTION 3 99 | #define SOFTWARE_INTERRUPT 4 100 | #define PRIVILEGED_SOFTWARE_EXCEPTION 5 101 | #define SOFTWARE_EXCEPTION 6 102 | #define OTHER_EVENT 7 103 | 104 | #define IO_IN 1 105 | #define IO_OUT 0 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /linux/vmmstring.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "mmu.h" 4 | #include "vmmstring.h" 5 | 6 | static UCHAR vmm_chartohex(char c); 7 | static ULONG vmm_power(ULONG base, ULONG exp); 8 | 9 | BOOLEAN vmm_islower(char c) 10 | { 11 | return (c >= 'a' && c <= 'z'); 12 | } 13 | 14 | BOOLEAN vmm_isupper(char c) 15 | { 16 | return (c >= 'A' && c <= 'Z'); 17 | } 18 | 19 | BOOLEAN vmm_isalpha(char c) 20 | { 21 | return (vmm_islower(c) || vmm_isupper(c)); 22 | } 23 | 24 | UCHAR vmm_tolower(UCHAR c) 25 | { 26 | if (!vmm_isupper(c)) 27 | return c; 28 | 29 | return (c - 'A' + 'a'); 30 | } 31 | 32 | UCHAR vmm_toupper(UCHAR c) 33 | { 34 | if (!vmm_islower(c)) 35 | return c; 36 | 37 | return (c - 'a' + 'A'); 38 | } 39 | 40 | VOID vmm_memset(VOID *s, int c, ULONG n) 41 | { 42 | UCHAR *p; 43 | ULONG i; 44 | 45 | p = (UCHAR*) s; 46 | for (i=0; i 9) 126 | return FALSE; 127 | 128 | *result = *result + tmp * vmm_power(10, i); 129 | } 130 | 131 | return TRUE; 132 | } 133 | 134 | BOOLEAN vmm_strtoul(char *str, PULONG result) 135 | { 136 | ULONG i, len; 137 | UCHAR tmp; 138 | len = 0; 139 | *result = 0; 140 | if (str[0] == '0' && str[1] == 'x') 141 | str = &str[2]; 142 | 143 | /* Get the length of the string */ 144 | while(str[len] != 0) len++; 145 | 146 | for(i = 0; str[i] != 0; i++) { 147 | tmp = vmm_chartohex(str[len-1-i]); 148 | if (tmp > 15) 149 | return FALSE; 150 | 151 | *result = *result + tmp * vmm_power(16, i); 152 | } 153 | 154 | return TRUE; 155 | } 156 | 157 | BOOLEAN vmm_strtoul_64(char *str, PULONG64 result) 158 | { 159 | ULONG i, len; 160 | UCHAR tmp; 161 | len = 0; 162 | *result = 0; 163 | if (str[0] == '0' && str[1] == 'x') 164 | str = &str[2]; 165 | 166 | /* Get the length of the string */ 167 | while(str[len] != 0) len++; 168 | 169 | for(i = 0; str[i] != 0; i++) { 170 | tmp = vmm_chartohex(str[len-1-i]); 171 | if (tmp > 15) 172 | return FALSE; 173 | 174 | *result = *result + tmp * vmm_power(16, i); 175 | } 176 | 177 | return TRUE; 178 | } 179 | 180 | static ULONG vmm_power(ULONG base, ULONG exp) 181 | { 182 | if (exp == 0) return (ULONG) 1; 183 | else return (ULONG) (base * vmm_power(base, exp-1)); 184 | } 185 | 186 | static UCHAR vmm_chartohex(char c) 187 | { 188 | switch(c) { 189 | case '0': 190 | case '1': 191 | case '2': 192 | case '3': 193 | case '4': 194 | case '5': 195 | case '6': 196 | case '7': 197 | case '8': 198 | case '9': 199 | return c - '0'; 200 | case 'a': 201 | case 'b': 202 | case 'c': 203 | case 'd': 204 | case 'e': 205 | case 'f': 206 | return c - 'a' + 10; 207 | case 'A': 208 | case 'B': 209 | case 'C': 210 | case 'D': 211 | case 'E': 212 | case 'F': 213 | return c - 'A' + 10; 214 | default: 215 | return -1; 216 | } 217 | } 218 | 219 | ULONG vmm_strcmpi(PCHAR str1,PCHAR str2) 220 | { 221 | ULONG len1; 222 | 223 | if(!IsAddressExist((ULONG)str1)) 224 | return 1; 225 | if(!IsAddressExist((ULONG)str2)) 226 | return 1; 227 | 228 | len1 = strlen(str1); 229 | if(len1 != strlen(str2)) 230 | return 1; 231 | 232 | if(!vmm_strncmpi(str1,str2,len1)) 233 | return 0; 234 | return 1; 235 | } 236 | -------------------------------------------------------------------------------- /linux/vmmstring.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | //UCHAR* vmm_strncpy(UCHAR *dst, UCHAR *src, ULONG n); 4 | VOID vmm_strnrep(UCHAR *str1, UCHAR *str2); 5 | ULONG vmm_strncmp(UCHAR *str1, UCHAR *str2, ULONG n); 6 | ULONG vmm_strncmpi(UCHAR *str1, UCHAR *str2, ULONG n); 7 | ULONG vmm_strlen(UCHAR *str); 8 | BOOLEAN vmm_strtoul(char *str, PULONG out); 9 | BOOLEAN vmm_strtoul_10(char *str, PULONG result); 10 | BOOLEAN vmm_strtoul_64(char *str, PULONG64 result); 11 | VOID vmm_memset(VOID *s, int c, ULONG n); 12 | int vmm_snprintf(char*, size_t, const char*, ...); 13 | int vmm_vsnprintf(char*, size_t, const char*, va_list); 14 | BOOLEAN vmm_islower(char c); 15 | BOOLEAN vmm_isupper(char c); 16 | BOOLEAN vmm_isalpha(char c); 17 | UCHAR vmm_tolower(UCHAR c); 18 | UCHAR vmm_toupper(UCHAR c); 19 | ULONG vmm_strcmpi(PCHAR str1,PCHAR str2); 20 | -------------------------------------------------------------------------------- /linux/vmx-x86.asm: -------------------------------------------------------------------------------- 1 | bits 32 2 | 3 | section .data 4 | TSCEvery1us dd 0 5 | 6 | section .text 7 | extern StartVirtualization 8 | extern VmExitHandler 9 | 10 | global _ScaleTSCBasedTimer 11 | global _CpuSleep 12 | global _FlushTLB 13 | global TSCEvery1us 14 | 15 | global _Reboot 16 | global _BeepOn 17 | global _BeepOff 18 | 19 | global READ_PORT_UCHAR 20 | global READ_PORT_USHORT 21 | global READ_PORT_ULONG 22 | global WRITE_PORT_UCHAR 23 | global WRITE_PORT_USHORT 24 | global WRITE_PORT_ULONG 25 | global _ReadPRT 26 | global _WritePRT 27 | 28 | global _VmCallFillScreen 29 | global _Return1 30 | global _ReadMSR 31 | global _WriteMSR 32 | global _TSC 33 | 34 | global _CS 35 | global _DS 36 | global _ES 37 | global _FS 38 | global _GS 39 | global _SS 40 | 41 | global _CR0 42 | global _CR2 43 | global _CR3 44 | global _CR4 45 | 46 | global _DR0 47 | global _DR1 48 | global _DR2 49 | global _DR3 50 | global _DR6 51 | global _DR7 52 | 53 | global _SetCR0 54 | global _SetCR2 55 | global _SetCR3 56 | global _SetCR4 57 | 58 | global _SetDR0 59 | global _SetDR1 60 | global _SetDR2 61 | global _SetDR3 62 | global _SetDR6 63 | global _SetDR7 64 | 65 | global _CpuId 66 | 67 | global _Ldtr 68 | global _TrSelector 69 | global _Eflags 70 | global _Invd 71 | 72 | global _GdtBase 73 | global _IdtBase 74 | global _GdtLimit 75 | global _IdtLimit 76 | global _RegSetIdtr 77 | global _RegSetGdtr 78 | global _DisableWP 79 | global _EnableWP 80 | 81 | global _VmxOn 82 | global _VmClear 83 | global _VmPtrLd 84 | global _ReadVMCS 85 | global _WriteVMCS 86 | global _VmLaunch 87 | global _VmxOff 88 | global _VmxOff_NoGuest 89 | global _VmFailValid 90 | global _VmFailInvalid 91 | 92 | global _StartVirtualization 93 | global _GuestEntryPoint 94 | 95 | global _StopVirtualization 96 | global _GuestExit 97 | 98 | global _VmExitHandler 99 | 100 | _VmCallFillScreen: 101 | mov eax,0deadc0deh 102 | vmcall 103 | ret 104 | 105 | _Read8254Counter0: 106 | xor eax,eax 107 | out 43h,al 108 | in al,40h 109 | mov ah,al 110 | in al,40h 111 | xchg al,ah 112 | ret 113 | 114 | _ScaleTSCBasedTimer: 115 | push ebp 116 | mov ebp,esp 117 | sub esp,8 118 | pushad 119 | rdtsc 120 | mov [ebp-4],eax ;StartTSC 121 | call _Read8254Counter0 122 | mov [ebp-8],eax ;StartCount 123 | LoopRead: 124 | call _Read8254Counter0 125 | mov ecx,[ebp-8] 126 | sub ecx,eax 127 | cmp cx,59659 ;25ms (1193181/(1000/25*2)) 128 | jb LoopRead 129 | rdtsc 130 | sub eax,[ebp-4] ;TSC Every 25ms 131 | xor edx,edx 132 | mov ecx,25000 133 | div ecx 134 | mov [TSCEvery1us],eax 135 | popad 136 | leave 137 | ret 138 | 139 | _CpuSleep: 140 | push ebp 141 | mov ebp,esp 142 | sub esp,10h 143 | pushad 144 | rdtsc 145 | mov [ebp-4],eax 146 | mov [ebp-8],edx 147 | mov eax,[ebp+8] ;Sleep x MicroSecond 148 | mov ecx,[TSCEvery1us] 149 | mul ecx 150 | mov [ebp-0ch],eax 151 | mov [ebp-10h],edx 152 | LoopWait: 153 | rdtsc 154 | sub eax,[ebp-4] 155 | sbb edx,[ebp-8] 156 | cmp eax,[ebp-0ch] 157 | jb LoopWait 158 | popad 159 | leave 160 | ret 161 | 162 | _FlushTLB: 163 | mov eax,cr3 164 | mov cr3,eax 165 | ret 166 | 167 | _Reboot: 168 | mov edx,64h 169 | mov eax,0feh 170 | out dx,al 171 | ret 172 | 173 | _BeepOn: 174 | mov al,0b6h 175 | out 43h,al ; Timer 8253-5 (AT: 8254.2). 176 | 177 | mov eax,1500h 178 | out 42h,al 179 | 180 | mov al,ah 181 | out 42h,al 182 | 183 | ; speaker ON 184 | in al,61h 185 | or al,3 186 | out 61h,al 187 | deadloop: 188 | jmp deadloop 189 | ret 190 | 191 | _BeepOff: 192 | ; speaker OFF 193 | in al,61h 194 | and al,0fch 195 | out 61h,al 196 | ret 197 | 198 | READ_PORT_UCHAR: 199 | xor eax,eax 200 | mov edx,[esp+4] 201 | in al,dx 202 | ret 203 | 204 | READ_PORT_USHORT: 205 | xor eax,eax 206 | mov edx,[esp+4] 207 | in ax,dx 208 | ret 209 | 210 | READ_PORT_ULONG: 211 | mov edx,[esp+4] 212 | in eax,dx 213 | ret 214 | 215 | WRITE_PORT_UCHAR: 216 | mov edx,[esp+4] 217 | mov eax,[esp+8] 218 | out dx,al 219 | ret 220 | 221 | WRITE_PORT_USHORT: 222 | mov edx,[esp+4] 223 | mov eax,[esp+8] 224 | out dx,ax 225 | ret 226 | 227 | WRITE_PORT_ULONG: 228 | mov edx,[esp+4] 229 | mov eax,[esp+8] 230 | out dx,eax 231 | ret 232 | 233 | _ReadPRT: 234 | push ebp 235 | mov ebp,esp 236 | push ecx 237 | mov ecx,[ebp+8] 238 | mov eax,[ebp+0ch] 239 | add eax,10h 240 | mov [ecx],eax 241 | mov eax,[ecx+10h] 242 | pop ecx 243 | leave 244 | ret 245 | 246 | _WritePRT: 247 | push ebp 248 | mov ebp,esp 249 | push ecx 250 | mov ecx,[ebp+8] 251 | mov eax,[ebp+0ch] 252 | add eax,10h 253 | mov [ecx],eax 254 | mov eax,[ebp+10h] 255 | mov [ecx+10h],eax 256 | pop ecx 257 | leave 258 | ret 259 | 260 | 261 | _Return1: 262 | mov eax,1 263 | ret 264 | 265 | _ReadMSR: 266 | push ebp 267 | mov ebp,esp 268 | push ecx 269 | mov ecx,[ebp+8] 270 | rdmsr 271 | pop ecx 272 | leave 273 | ret 274 | 275 | _WriteMSR: 276 | push ebp 277 | mov ebp,esp 278 | pushad 279 | mov ecx,[ebp+8] 280 | mov eax,[ebp+0ch] 281 | mov edx,[ebp+10h] 282 | wrmsr 283 | popad 284 | leave 285 | ret 286 | 287 | _TSC: 288 | rdtsc 289 | ret 290 | 291 | _CS: 292 | xor eax,eax 293 | mov ax,cs 294 | ret 295 | _DS: 296 | xor eax,eax 297 | mov ax,ds 298 | ret 299 | _ES: 300 | xor eax,eax 301 | mov ax,es 302 | ret 303 | _FS: 304 | xor eax,eax 305 | mov ax,fs 306 | ret 307 | _GS: 308 | xor eax,eax 309 | mov ax,gs 310 | ret 311 | _SS: 312 | xor eax,eax 313 | mov ax,ss 314 | ret 315 | 316 | _CR0: 317 | mov eax,cr0 318 | ret 319 | _CR2: 320 | mov eax,cr2 321 | ret 322 | _CR3: 323 | mov eax,cr3 324 | ret 325 | _CR4: 326 | mov eax,cr4 327 | ret 328 | 329 | _DR0: 330 | mov eax,dr0 331 | ret 332 | _DR1: 333 | mov eax,dr1 334 | ret 335 | _DR2: 336 | mov eax,dr2 337 | ret 338 | _DR3: 339 | mov eax,dr3 340 | ret 341 | _DR6: 342 | mov eax,dr6 343 | ret 344 | _DR7: 345 | mov eax,dr7 346 | ret 347 | 348 | _SetCR0: 349 | mov eax,[esp+4] 350 | mov cr0,eax 351 | ret 352 | _SetCR2: 353 | mov eax,[esp+4] 354 | mov cr2,eax 355 | ret 356 | _SetCR3: 357 | mov eax,[esp+4] 358 | mov cr3,eax 359 | ret 360 | _SetCR4: 361 | mov eax,[esp+4] 362 | mov cr4,eax 363 | ret 364 | 365 | _SetDR0: 366 | mov eax,[esp+4] 367 | mov dr0,eax 368 | ret 369 | _SetDR1: 370 | mov eax,[esp+4] 371 | mov dr1,eax 372 | ret 373 | _SetDR2: 374 | mov eax,[esp+4] 375 | mov dr2,eax 376 | ret 377 | _SetDR3: 378 | mov eax,[esp+4] 379 | mov dr3,eax 380 | ret 381 | _SetDR6: 382 | mov eax,[esp+4] 383 | mov dr6,eax 384 | ret 385 | _SetDR7: 386 | mov eax,[esp+4] 387 | mov dr7,eax 388 | ret 389 | 390 | _CpuId: 391 | push ebp 392 | mov ebp,esp 393 | pushad 394 | mov esi,[ebp+8] 395 | mov eax,[esi] 396 | mov esi,[ebp+0ch] 397 | mov ebx,[esi] 398 | mov esi,[ebp+10h] 399 | mov ecx,[esi] 400 | mov esi,[ebp+14h] 401 | mov edx,[esi] 402 | cpuid 403 | mov esi,[ebp+8] 404 | mov [esi],eax 405 | mov esi,[ebp+0ch] 406 | mov [esi],ebx 407 | mov esi,[ebp+10h] 408 | mov [esi],ecx 409 | mov esi,[ebp+14h] 410 | mov [esi],edx 411 | popad 412 | leave 413 | ret 414 | 415 | _Ldtr: 416 | sldt ax 417 | ret 418 | 419 | _TrSelector: 420 | str ax 421 | ret 422 | 423 | _Eflags: 424 | pushfd 425 | pop eax 426 | ret 427 | 428 | _Invd: 429 | invd 430 | ret 431 | 432 | _GdtBase: 433 | push ebp 434 | mov ebp,esp 435 | sub esp,8 436 | sgdt [ebp-8] 437 | mov eax,[ebp-6] 438 | leave 439 | ret 440 | 441 | _IdtBase: 442 | push ebp 443 | mov ebp,esp 444 | sub esp,8 445 | sidt [ebp-8] 446 | mov eax,[ebp-6] 447 | leave 448 | ret 449 | 450 | _GdtLimit: 451 | push ebp 452 | mov ebp,esp 453 | sub esp,8 454 | sgdt [ebp-8] 455 | mov ax,[ebp-8] 456 | leave 457 | ret 458 | 459 | _IdtLimit: 460 | push ebp 461 | mov ebp,esp 462 | sub esp,8 463 | sidt [ebp-8] 464 | mov ax,[ebp-8] 465 | leave 466 | ret 467 | 468 | _RegSetIdtr: 469 | push ebp 470 | mov ebp,esp 471 | push dword [ebp+8] 472 | mov eax,[ebp+0ch] 473 | shl eax,16 474 | push eax 475 | lidt [esp+2] 476 | add esp,8 477 | leave 478 | ret 479 | 480 | _RegSetGdtr: 481 | push ebp 482 | mov ebp,esp 483 | push dword [ebp+8] 484 | mov eax,[ebp+0ch] 485 | shl eax,16 486 | push eax 487 | lgdt [esp+2] 488 | add esp,8 489 | leave 490 | ret 491 | 492 | _DisableWP: 493 | mov eax,cr0 494 | and eax,0fffeffffh 495 | mov cr0,eax 496 | ret 497 | 498 | _EnableWP: 499 | mov eax,cr0 500 | or eax,10000h 501 | mov cr0,eax 502 | ret 503 | 504 | _VmxOn: 505 | push ebp 506 | mov ebp,esp 507 | push dword [ebp+0ch] 508 | push dword [ebp+8] 509 | vmxon qword [esp] 510 | add esp,8 511 | pushfd 512 | pop eax 513 | leave 514 | ret 515 | 516 | _VmClear: 517 | push ebp 518 | mov ebp,esp 519 | push dword [ebp+0ch] 520 | push dword [ebp+8] 521 | vmclear qword [esp] 522 | add esp,8 523 | pushfd 524 | pop eax 525 | leave 526 | ret 527 | 528 | _VmPtrLd: 529 | push ebp 530 | mov ebp,esp 531 | push dword [ebp+0ch] 532 | push dword [ebp+8] 533 | vmptrld qword [esp] 534 | add esp,8 535 | pushfd 536 | pop eax 537 | leave 538 | ret 539 | 540 | _ReadVMCS: 541 | push ebp 542 | mov ebp,esp 543 | push ecx 544 | mov eax,[ebp+8] 545 | vmread ecx,eax 546 | mov eax,ecx 547 | pop ecx 548 | leave 549 | ret 550 | 551 | _WriteVMCS: 552 | push ebp 553 | mov ebp,esp 554 | push ecx 555 | mov eax,[ebp+8] 556 | mov ecx,[ebp+0ch] 557 | vmwrite eax,ecx 558 | pop ecx 559 | leave 560 | ret 561 | 562 | _VmFailInvalid: 563 | push ebp 564 | mov ebp,esp 565 | push ecx 566 | mov eax,[ebp+8] 567 | xor ecx,ecx 568 | bt eax,0 ;RFLAGS.CF 569 | adc cl,cl 570 | mov eax,ecx 571 | pop ecx 572 | leave 573 | ret 574 | 575 | _VmFailValid: 576 | push ebp 577 | mov ebp,esp 578 | push ecx 579 | mov eax,[ebp+8] 580 | xor ecx,ecx 581 | bt eax,6 ;RFLAGS.ZF 582 | adc cl,cl 583 | mov eax,ecx 584 | pop ecx 585 | leave 586 | ret 587 | 588 | _VmLaunch: 589 | vmlaunch 590 | pushfd 591 | pop eax 592 | ret 593 | 594 | _VmxOff: 595 | push ebp 596 | mov ebp,esp 597 | 598 | push 00006818h ;GUEST_IDTR_BASE 599 | call _ReadVMCS 600 | add esp,4 601 | push eax 602 | push 00004812h ;GUEST_IDTR_LIMIT 603 | call _ReadVMCS 604 | add esp,4 605 | shl eax,16 606 | push eax 607 | lidt [esp+2] 608 | add esp,8 609 | 610 | push 00006816h ;GUEST_GDTR_BASE 611 | call _ReadVMCS 612 | add esp,4 613 | push eax 614 | push 00004810h ;GUEST_GDTR_LIMIT 615 | call _ReadVMCS 616 | add esp,4 617 | shl eax,16 618 | push eax 619 | lgdt [esp+2] 620 | add esp,8 621 | 622 | push 00006800h ;GUEST_CR0 623 | call _ReadVMCS 624 | add esp,4 625 | mov cr0,eax 626 | 627 | push 00006802h ;GUEST_CR3 628 | call _ReadVMCS 629 | add esp,4 630 | mov cr3,eax 631 | 632 | push 00006804h ;GUEST_CR4 633 | call _ReadVMCS 634 | add esp,4 635 | mov cr4,eax 636 | 637 | mov eax,[ebp+0ch] 638 | mov ecx,[ebp+8] 639 | vmxoff 640 | leave 641 | mov esp,ecx 642 | push eax 643 | mov eax,cr4 644 | and eax,0ffffdfffh 645 | mov cr4,eax 646 | 647 | xor eax,eax 648 | mov dr0,eax 649 | mov dr1,eax 650 | mov dr2,eax 651 | mov dr3,eax 652 | mov eax,400h 653 | mov dr7,eax 654 | 655 | pop eax 656 | jmp eax 657 | 658 | _VmxOff_NoGuest: 659 | vmxoff 660 | ret 661 | 662 | _StartVirtualization: 663 | pushad 664 | pushfd 665 | cli 666 | push esp 667 | call StartVirtualization 668 | add esp,4 669 | 670 | _GuestEntryPoint: 671 | mov [esp+20h],eax 672 | sti 673 | popfd 674 | popad 675 | ret 676 | 677 | _StopVirtualization: 678 | push ebp 679 | mov ebp,esp 680 | pushad 681 | pushfd 682 | push ebp 683 | mov eax,[ebp+8] 684 | mov edx,[ebp+0ch] 685 | vmcall 686 | 687 | _GuestExit: 688 | pop ebp 689 | popfd 690 | popad 691 | leave 692 | ret 693 | 694 | _VmExitHandler: 695 | cli 696 | push edi 697 | push esi 698 | push ebp 699 | push esp ;invalid esp 700 | push edx 701 | push ecx 702 | push ebx 703 | push eax 704 | 705 | lea eax,[esp+20h] ;PGUEST_CPU 706 | push eax 707 | call VmExitHandler 708 | add esp,4 709 | 710 | pop eax 711 | pop ebx 712 | pop ecx 713 | pop edx 714 | pop ebp ;pop esp 715 | pop ebp 716 | pop esi 717 | pop edi 718 | vmresume 719 | -------------------------------------------------------------------------------- /linux/vmx.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "vmx.h" 5 | #include "vmm.h" 6 | #include "x86.h" 7 | #include "video.h" 8 | #include "dbgprint.h" 9 | 10 | #define KMALLOC_FLAGS GFP_ATOMIC 11 | 12 | PHYSICAL_ADDRESS HostPDE_pa; 13 | PVOID HostPDE_va; 14 | PVOID GuestPDE_va; 15 | 16 | VOID HostCr3Init(void) 17 | { 18 | GuestPDE_va = phys_to_virt(_CR3()); 19 | HostPDE_va = kmalloc(0x1000,KMALLOC_FLAGS); 20 | HostPDE_pa.QuadPart = virt_to_phys(HostPDE_va); 21 | memcpy(HostPDE_va,GuestPDE_va,0x1000); 22 | printf("Guest CR3: 0x%p\r\n",(PVOID)_CR3()); 23 | printf("Host CR3: 0x%p\r\n",(PVOID)HostPDE_pa.LowPart); 24 | } 25 | 26 | BOOLEAN IsBitSet(ULONG64 v, UCHAR bitNo) 27 | { 28 | ULONG64 mask = (ULONG64) 1 << bitNo; 29 | return (BOOLEAN) ((v & mask) != 0); 30 | } 31 | 32 | BOOLEAN CheckIfVMXIsEnabled(void) 33 | { 34 | ULONG64 msr; 35 | 36 | msr = _ReadMSR(MSR_IA32_FEATURE_CONTROL); 37 | if (!(msr & 4)) 38 | { 39 | return false; 40 | } 41 | return true; 42 | } 43 | 44 | BOOLEAN CheckForVirtualizationSupport(void) 45 | { 46 | ULONG eax, ebx, ecx, edx; 47 | 48 | eax = 0; 49 | _CpuId(&eax, &ebx, &ecx, &edx); 50 | if (eax < 1) 51 | { 52 | return false; 53 | } 54 | 55 | /* Intel Genuine */ 56 | if (!(ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)) 57 | { 58 | return false; 59 | } 60 | 61 | eax = 1; 62 | _CpuId(&eax, &ebx, &ecx, &edx); 63 | if (!IsBitSet(ecx, 5)) 64 | { 65 | return false; 66 | } 67 | return true; 68 | } 69 | 70 | BOOLEAN SetupVMX(PGUEST_CPU pCpu) 71 | { 72 | PHYSICAL_ADDRESS pa; 73 | ULONG64 msr; 74 | PVMX_BASIC_MSR pvmx; 75 | PVOID va; 76 | ULONG size; 77 | //ULONG i; 78 | ULONG cr4; 79 | ULONG Eflags; 80 | 81 | DEFAULT_FONT; 82 | 83 | /* vmxon supported ? */ 84 | _SetCR4(_CR4() | X86_CR4_VMXE); 85 | cr4 = _CR4(); 86 | 87 | if (!(cr4 & X86_CR4_VMXE)) 88 | { 89 | RED_FONT; 90 | printf("error: VMXON not supported\r\n"); 91 | return false; 92 | } 93 | 94 | //i = KeGetCurrentProcessorNumber(); 95 | //pCpu->ProcessorNumber = i; 96 | 97 | msr = _ReadMSR(MSR_IA32_VMX_BASIC); 98 | pvmx = (PVMX_BASIC_MSR)&msr; 99 | size = pvmx->szVmxOnRegion; 100 | printf("VMXON region size: 0x%x\r\n", size); 101 | printf("VMX revision ID: 0x%x\r\n", pvmx->RevId); 102 | 103 | va = kmalloc(0x1000,KMALLOC_FLAGS); 104 | if (va == NULL) 105 | { 106 | RED_FONT; 107 | printf("error: can't allocate vmxon region\r\n"); 108 | return false; 109 | } 110 | memset(va,0,0x1000); 111 | *(ULONG *)va = pvmx->RevId; 112 | pa.QuadPart = virt_to_phys(va); 113 | pCpu->VMXON_pa = pa; 114 | pCpu->VMXON_va = va; 115 | 116 | Eflags = _VmxOn(pa.LowPart,pa.HighPart); 117 | if (_VmFailInvalid(Eflags)) 118 | { 119 | RED_FONT; 120 | printf("_VmxOn failed\r\n"); 121 | return false; 122 | } 123 | 124 | va = kmalloc(0x1000,KMALLOC_FLAGS); 125 | if (va == NULL) 126 | { 127 | RED_FONT; 128 | printf("error: can't allocate vmcs region\r\n"); 129 | return false; 130 | } 131 | memset(va,0,0x1000); 132 | *(ULONG *)va = pvmx->RevId; 133 | pa.QuadPart = virt_to_phys(va); 134 | pCpu->VMCS_pa = pa; 135 | pCpu->VMCS_va = va; 136 | 137 | va = kmalloc(0x1000,KMALLOC_FLAGS); 138 | if (va == NULL) 139 | { 140 | RED_FONT; 141 | printf("error: can't allocate io bitmap a\r\n"); 142 | return false; 143 | } 144 | memset(va,0,0x1000); 145 | pa.QuadPart = virt_to_phys(va); 146 | pCpu->IO_Bitmap_A_pa = pa; 147 | pCpu->IO_Bitmap_A_va = va; 148 | 149 | va = kmalloc(0x1000,KMALLOC_FLAGS); 150 | if (va == NULL) 151 | { 152 | RED_FONT; 153 | printf("error: can't allocate io bitmap b\r\n"); 154 | return false; 155 | } 156 | memset(va,0,0x1000); 157 | pa.QuadPart = virt_to_phys(va); 158 | pCpu->IO_Bitmap_B_pa = pa; 159 | pCpu->IO_Bitmap_B_va = va; 160 | 161 | va = kmalloc(0x1000,KMALLOC_FLAGS); 162 | if (va == NULL) 163 | { 164 | RED_FONT; 165 | printf("error: can't allocate msr bitmap\r\n"); 166 | return false; 167 | } 168 | memset(va,0,0x1000); 169 | pa.QuadPart = virt_to_phys(va); 170 | pCpu->MSR_bitmap_pa = pa; 171 | pCpu->MSR_bitmap_va = va; 172 | 173 | va = kmalloc(0x8000,KMALLOC_FLAGS); 174 | if (va == NULL) 175 | { 176 | RED_FONT; 177 | printf("error: can't allocate stack for host\r\n"); 178 | return false; 179 | } 180 | memset(va,0,0x8000); 181 | pCpu->Host_Stack_va = va; 182 | 183 | va = kmalloc(0x1000,KMALLOC_FLAGS); 184 | if (va == NULL) 185 | { 186 | RED_FONT; 187 | printf("error: can't allocate IDT for host\r\n"); 188 | return false; 189 | } 190 | memset(va,0,0x1000); 191 | pCpu->VMMIDT = va; 192 | 193 | pa.LowPart = 0xFEE00000; 194 | pa.HighPart = 0; 195 | va = ioremap_nocache(pa.QuadPart,256); 196 | if (va == NULL) 197 | { 198 | RED_FONT; 199 | printf("error: can't map LocalAPIC\r\n"); 200 | return false; 201 | } 202 | pCpu->LocalAPIC_va = va; 203 | 204 | pa.LowPart = 0xFEC00000; 205 | pa.HighPart = 0; 206 | va = ioremap_nocache(pa.QuadPart,256); 207 | if (va == NULL) 208 | { 209 | RED_FONT; 210 | printf("error: can't map IOAPIC\r\n"); 211 | return false; 212 | } 213 | pCpu->IOAPIC_va = va; 214 | 215 | printf("LocalAPIC map to 0x%p\r\n",pCpu->LocalAPIC_va); 216 | printf("IOAPIC map to 0x%p\r\n",pCpu->IOAPIC_va); 217 | return true; 218 | } 219 | 220 | BOOLEAN InitializeSegmentSelector(PSEGMENT_SELECTOR SegmentSelector,USHORT Selector,ULONG GdtBase) 221 | { 222 | PSEGMENT_DESCRIPTOR2 SegDesc; 223 | 224 | if (!SegmentSelector) 225 | return false; 226 | 227 | if (Selector & 0x4) 228 | { 229 | RED_FONT; 230 | printf("WARNING: InitializeSegmentSelector(): Given selector(%d) points to LDT\r\n", Selector); 231 | return false; 232 | } 233 | 234 | SegDesc = (PSEGMENT_DESCRIPTOR2) ((PUCHAR) GdtBase + (Selector & ~0x7)); 235 | 236 | SegmentSelector->sel = Selector; 237 | SegmentSelector->base = SegDesc->base0 | SegDesc->base1 << 16 | SegDesc->base2 << 24; 238 | SegmentSelector->limit = SegDesc->limit0 | (SegDesc->limit1attr1 & 0xf) << 16; 239 | SegmentSelector->attributes.UCHARs = SegDesc->attr0 | (SegDesc->limit1attr1 & 0xf0) << 4; 240 | 241 | if (!(SegDesc->attr0 & LA_STANDARD)) 242 | { 243 | ULONG64 tmp; 244 | // this is a TSS or callgate etc, save the base high part 245 | tmp = (*(PULONG64) ((PUCHAR) SegDesc + 8)); 246 | SegmentSelector->base = (SegmentSelector->base & 0xffffffff) | (tmp << 32); 247 | } 248 | 249 | if (SegmentSelector->attributes.fields.g) 250 | { 251 | // 4096-bit granularity is enabled for this segment, scale the limit 252 | SegmentSelector->limit = (SegmentSelector->limit << 12) + 0xfff; 253 | } 254 | 255 | return true; 256 | } 257 | 258 | ULONG GetSegmentDescriptorBase(ULONG gdt_base, USHORT seg_selector) 259 | { 260 | ULONG base = 0; 261 | SEGMENT_DESCRIPTOR segDescriptor = {0}; 262 | 263 | memcpy(&segDescriptor, (ULONG *)(gdt_base + (seg_selector >> 3) * 8), 8 ); 264 | base = segDescriptor.BaseHi; 265 | base <<= 8; 266 | base |= segDescriptor.BaseMid; 267 | base <<= 16; 268 | base |= segDescriptor.BaseLo; 269 | 270 | return base; 271 | } 272 | 273 | ULONG GetSegmentDescriptorDPL(ULONG gdt_base, USHORT seg_selector) 274 | { 275 | SEGMENT_DESCRIPTOR segDescriptor = {0}; 276 | 277 | memcpy(&segDescriptor, (ULONG *)(gdt_base + (seg_selector >> 3) * 8), 8); 278 | 279 | return segDescriptor.DPL; 280 | } 281 | 282 | ULONG GetSegmentDescriptorLimit(ULONG gdt_base, USHORT selector) 283 | { 284 | SEGMENT_SELECTOR SegmentSelector = { 0 }; 285 | 286 | InitializeSegmentSelector(&SegmentSelector, selector, gdt_base); 287 | 288 | return SegmentSelector.limit; 289 | } 290 | 291 | ULONG GetSegmentDescriptorAR(ULONG gdt_base, USHORT selector) 292 | { 293 | SEGMENT_SELECTOR SegmentSelector = { 0 }; 294 | ULONG uAccessRights; 295 | 296 | InitializeSegmentSelector(&SegmentSelector, selector, gdt_base); 297 | 298 | uAccessRights = ((PUCHAR) & SegmentSelector.attributes)[0] + (((PUCHAR) & SegmentSelector.attributes)[1] << 12); 299 | 300 | if (!selector) 301 | uAccessRights |= 0x10000; 302 | 303 | return uAccessRights; 304 | } 305 | 306 | ULONG VmxAdjustControls(ULONG Ctl, ULONG Msr) 307 | { 308 | LARGE_INTEGER MsrValue; 309 | 310 | MsrValue.QuadPart = _ReadMSR(Msr); 311 | Ctl &= MsrValue.HighPart; /* bit == 0 in high word ==> must be zero */ 312 | Ctl |= MsrValue.LowPart; /* bit == 1 in low word ==> must be one */ 313 | return Ctl; 314 | } 315 | 316 | VOID IntHandler(void) 317 | { 318 | 319 | } 320 | 321 | VOID PageFaultHandler(void) 322 | { 323 | 324 | } 325 | 326 | VOID InitVMMIDT(PIDT_ENTRY pidt) 327 | { 328 | ULONG i; 329 | IDT_ENTRY idte_null; 330 | //PIDT_ENTRY pGuestIdt = (PIDT_ENTRY)_IdtBase(); 331 | 332 | memset(&idte_null,0,sizeof(idte_null)); 333 | idte_null.Selector = _CS(); 334 | 335 | /* Present, DPL 0, Type 0xe (INT gate) */ 336 | idte_null.P = 1; 337 | idte_null.GateSize = 1; 338 | idte_null.GateType = 6; 339 | 340 | idte_null.LowOffset = (ULONG)_BeepOn & 0xffff; 341 | idte_null.HighOffset = (ULONG)_BeepOn >> 16; 342 | for (i=0; i<256; i++) 343 | pidt[i] = idte_null; 344 | 345 | //#PF异常自动重启 346 | idte_null.LowOffset = (ULONG)_Reboot & 0xffff; 347 | idte_null.HighOffset = (ULONG)_Reboot >> 16; 348 | pidt[14] = idte_null; 349 | } 350 | 351 | BOOLEAN SetupVMCS(PGUEST_CPU pCpu, PVOID GuestEsp) 352 | { 353 | ULONG ExceptionBitmap; 354 | ULONG GdtBase; 355 | PHYSICAL_ADDRESS pa; 356 | ULONG64 msr; 357 | ULONG ioPort; 358 | // ULONG msrIndex; 359 | ULONG Eflags; 360 | 361 | DEFAULT_FONT; 362 | 363 | pa = pCpu->VMCS_pa; 364 | Eflags = _VmClear(pa.LowPart,pa.HighPart); 365 | if(_VmFailInvalid(Eflags)) 366 | { 367 | RED_FONT; 368 | printf("VmClear failed.\r\n"); 369 | return false; 370 | } 371 | 372 | Eflags = _VmPtrLd(pa.LowPart,pa.HighPart); 373 | if(_VmFailInvalid(Eflags)) 374 | { 375 | RED_FONT; 376 | printf("VmPtrLd failed.\r\n"); 377 | return false; 378 | } 379 | 380 | // 381 | // *********************************** 382 | // * H.1.1 16-Bit Guest-State Fields * 383 | // *********************************** 384 | _WriteVMCS(GUEST_CS_SELECTOR, _CS() & 0xfff8); 385 | _WriteVMCS(GUEST_SS_SELECTOR, _SS() & 0xfff8); 386 | _WriteVMCS(GUEST_DS_SELECTOR, _DS() & 0xfff8); 387 | _WriteVMCS(GUEST_ES_SELECTOR, _ES() & 0xfff8); 388 | _WriteVMCS(GUEST_FS_SELECTOR, _FS() & 0xfff8); 389 | _WriteVMCS(GUEST_GS_SELECTOR, _GS() & 0xfff8); 390 | _WriteVMCS(GUEST_LDTR_SELECTOR, _Ldtr() & 0xfff8); 391 | _WriteVMCS(GUEST_TR_SELECTOR, _TrSelector() & 0xfff8); 392 | 393 | // ********************************** 394 | // * H.1.2 16-Bit Host-State Fields * 395 | // ********************************** 396 | 397 | /* FIXME: Host DS, ES & FS mascherati con 0xFFFC? */ 398 | _WriteVMCS(HOST_CS_SELECTOR, _CS() & 0xfff8); 399 | _WriteVMCS(HOST_SS_SELECTOR, _SS() & 0xfff8); 400 | _WriteVMCS(HOST_DS_SELECTOR, _DS() & 0xfff8); 401 | _WriteVMCS(HOST_ES_SELECTOR, _ES() & 0xfff8); 402 | _WriteVMCS(HOST_FS_SELECTOR, _FS() & 0xfff8); 403 | _WriteVMCS(HOST_GS_SELECTOR, _GS() & 0xfff8); 404 | _WriteVMCS(HOST_TR_SELECTOR, _TrSelector() & 0xfff8); 405 | 406 | // *********************************** 407 | // * H.2.2 64-Bit Guest-State Fields * 408 | // *********************************** 409 | 410 | _WriteVMCS(VMCS_LINK_POINTER, 0xFFFFFFFF); 411 | _WriteVMCS(VMCS_LINK_POINTER_HIGH, 0xFFFFFFFF); 412 | 413 | 414 | /* Reserved Bits of IA32_DEBUGCTL MSR must be 0 */ 415 | msr = _ReadMSR(MSR_IA32_DEBUGCTL); 416 | _WriteVMCS(GUEST_IA32_DEBUGCTL, (ULONG)(msr & 0xFFFFFFFF)); 417 | _WriteVMCS(GUEST_IA32_DEBUGCTL_HIGH, (ULONG)(msr >> 32)); 418 | 419 | // ******************************* 420 | // * H.3.1 32-Bit Control Fields * 421 | // ******************************* 422 | 423 | /* Pin-based VM-execution controls */ 424 | _WriteVMCS(PIN_BASED_VM_EXEC_CONTROL, VmxAdjustControls(0, MSR_IA32_VMX_PINBASED_CTLS)); 425 | _WriteVMCS(CPU_BASED_VM_EXEC_CONTROL, VmxAdjustControls(CPU_BASED_ACTIVATE_MSR_BITMAP + CPU_BASED_ACTIVATE_IO_BITMAP,MSR_IA32_VMX_PROCBASED_CTLS)); 426 | 427 | /* I/O bitmap */ 428 | _WriteVMCS(IO_BITMAP_A_HIGH, pCpu->IO_Bitmap_A_pa.HighPart); 429 | _WriteVMCS(IO_BITMAP_A, pCpu->IO_Bitmap_A_pa.LowPart); 430 | _WriteVMCS(IO_BITMAP_B_HIGH, pCpu->IO_Bitmap_B_pa.HighPart); 431 | _WriteVMCS(IO_BITMAP_B, pCpu->IO_Bitmap_B_pa.LowPart); 432 | 433 | ioPort = 0x60; 434 | ((PUCHAR)(pCpu->IO_Bitmap_A_va))[ioPort / 8] = 1<<(ioPort%8); 435 | 436 | _WriteVMCS(MSR_BITMAP, pCpu->MSR_bitmap_pa.LowPart); 437 | _WriteVMCS(MSR_BITMAP_HIGH, pCpu->MSR_bitmap_pa.HighPart); 438 | 439 | //msrIndex = MSR_IA32_FEATURE_CONTROL; 440 | //((PUCHAR)(pCpu->MSR_bitmap_va))[msrIndex / 8] = 1<<(msrIndex%8); 441 | 442 | 443 | /* Exception bitmap */ 444 | ExceptionBitmap = 0; 445 | ExceptionBitmap |= 1<VMMIDT); 577 | //_WriteVMCS(HOST_IDTR_BASE, _IdtBase()); 578 | _WriteVMCS(HOST_IDTR_BASE, (ULONG)pCpu->VMMIDT); 579 | InitVMMIDT((PIDT_ENTRY)pCpu->VMMIDT); 580 | 581 | /* Host IA32_SYSENTER_ESP/EIP/CS */ 582 | msr = _ReadMSR(MSR_IA32_SYSENTER_ESP); 583 | _WriteVMCS(HOST_IA32_SYSENTER_ESP, (ULONG)(msr & 0xFFFFFFFF)); 584 | 585 | msr = _ReadMSR(MSR_IA32_SYSENTER_EIP); 586 | _WriteVMCS(HOST_IA32_SYSENTER_EIP, (ULONG)(msr & 0xFFFFFFFF)); 587 | 588 | msr = _ReadMSR(MSR_IA32_SYSENTER_CS); 589 | _WriteVMCS(HOST_IA32_SYSENTER_CS, (ULONG)(msr & 0xFFFFFFFF)); 590 | 591 | /* Clear the VMX Abort Error Code prior to VMLAUNCH */ 592 | memset((PULONG)pCpu->VMCS_va + 1,0,4); 593 | 594 | /* Set EIP, ESP for the Guest right before calling VMLAUNCH */ 595 | printf("Setting Guest ESP 0x%p\r\n", GuestEsp); 596 | _WriteVMCS(GUEST_RSP, (ULONG) GuestEsp); 597 | 598 | printf("Setting Guest EIP 0x%p\r\n", _GuestEntryPoint); 599 | _WriteVMCS(GUEST_RIP, (ULONG)_GuestEntryPoint); 600 | 601 | /* Set EIP, ESP for the Host right before calling VMLAUNCH */ 602 | printf("Setting Host ESP 0x%p\r\n", (PVOID)((PUCHAR) pCpu->Host_Stack_va + 0x7000)); 603 | _WriteVMCS(HOST_RSP, (ULONG)((PUCHAR) pCpu->Host_Stack_va + 0x7000)); 604 | 605 | memcpy((PUCHAR)pCpu->Host_Stack_va + 0x7000,pCpu,sizeof(GUEST_CPU)); 606 | pCpu = (PGUEST_CPU)((PUCHAR)pCpu->Host_Stack_va + 0x7000); 607 | pCpu->pGuestRegs = (PGUEST_REGS)((PUCHAR)pCpu - 0x20); 608 | 609 | printf("Setting Host EIP 0x%p\r\n", _VmExitHandler); 610 | _WriteVMCS(HOST_RIP, (ULONG) _VmExitHandler); 611 | 612 | return true; 613 | } 614 | 615 | BOOLEAN Virtualize(PGUEST_CPU pCpu) 616 | { 617 | //ULONG i; 618 | ULONG Eflags; 619 | 620 | //i = KeGetCurrentProcessorNumber(); 621 | 622 | _Return1(); 623 | 624 | Eflags = _VmLaunch(); 625 | if (_VmFailInvalid(Eflags)) 626 | { 627 | RED_FONT; 628 | printf("no current VMCS\r\n"); 629 | return false; 630 | } 631 | 632 | if (_VmFailValid(Eflags)) 633 | { 634 | RED_FONT; 635 | printf("vmlaunch failed: 0x%x\r\n", _ReadVMCS(VM_INSTRUCTION_ERROR)); 636 | return false; 637 | } 638 | return false; 639 | } 640 | -------------------------------------------------------------------------------- /linux/vmx.h: -------------------------------------------------------------------------------- 1 | #include "define.h" 2 | 3 | #ifndef _VMX_H_ 4 | #define _VMX_H_ 5 | 6 | enum { 7 | GUEST_ES_SELECTOR = 0x00000800, 8 | GUEST_CS_SELECTOR = 0x00000802, 9 | GUEST_SS_SELECTOR = 0x00000804, 10 | GUEST_DS_SELECTOR = 0x00000806, 11 | GUEST_FS_SELECTOR = 0x00000808, 12 | GUEST_GS_SELECTOR = 0x0000080a, 13 | GUEST_LDTR_SELECTOR = 0x0000080c, 14 | GUEST_TR_SELECTOR = 0x0000080e, 15 | HOST_ES_SELECTOR = 0x00000c00, 16 | HOST_CS_SELECTOR = 0x00000c02, 17 | HOST_SS_SELECTOR = 0x00000c04, 18 | HOST_DS_SELECTOR = 0x00000c06, 19 | HOST_FS_SELECTOR = 0x00000c08, 20 | HOST_GS_SELECTOR = 0x00000c0a, 21 | HOST_TR_SELECTOR = 0x00000c0c, 22 | IO_BITMAP_A = 0x00002000, 23 | IO_BITMAP_A_HIGH = 0x00002001, 24 | IO_BITMAP_B = 0x00002002, 25 | IO_BITMAP_B_HIGH = 0x00002003, 26 | MSR_BITMAP = 0x00002004, 27 | MSR_BITMAP_HIGH = 0x00002005, 28 | VM_EXIT_MSR_STORE_ADDR = 0x00002006, 29 | VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007, 30 | VM_EXIT_MSR_LOAD_ADDR = 0x00002008, 31 | VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009, 32 | VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a, 33 | VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b, 34 | TSC_OFFSET = 0x00002010, 35 | TSC_OFFSET_HIGH = 0x00002011, 36 | VIRTUAL_APIC_PAGE_ADDR = 0x00002012, 37 | VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013, 38 | VMCS_LINK_POINTER = 0x00002800, 39 | VMCS_LINK_POINTER_HIGH = 0x00002801, 40 | GUEST_IA32_DEBUGCTL = 0x00002802, 41 | GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, 42 | PIN_BASED_VM_EXEC_CONTROL = 0x00004000, 43 | CPU_BASED_VM_EXEC_CONTROL = 0x00004002, 44 | EXCEPTION_BITMAP = 0x00004004, 45 | PAGE_FAULT_ERROR_CODE_MASK = 0x00004006, 46 | PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008, 47 | CR3_TARGET_COUNT = 0x0000400a, 48 | VM_EXIT_CONTROLS = 0x0000400c, 49 | VM_EXIT_MSR_STORE_COUNT = 0x0000400e, 50 | VM_EXIT_MSR_LOAD_COUNT = 0x00004010, 51 | VM_ENTRY_CONTROLS = 0x00004012, 52 | VM_ENTRY_MSR_LOAD_COUNT = 0x00004014, 53 | VM_ENTRY_INTR_INFO_FIELD = 0x00004016, 54 | VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018, 55 | VM_ENTRY_INSTRUCTION_LEN = 0x0000401a, 56 | TPR_THRESHOLD = 0x0000401c, 57 | SECONDARY_VM_EXEC_CONTROL = 0x0000401e, 58 | VM_INSTRUCTION_ERROR = 0x00004400, 59 | VM_EXIT_REASON = 0x00004402, 60 | VM_EXIT_INTR_INFO = 0x00004404, 61 | VM_EXIT_INTR_ERROR_CODE = 0x00004406, 62 | IDT_VECTORING_INFO_FIELD = 0x00004408, 63 | IDT_VECTORING_ERROR_CODE = 0x0000440a, 64 | VM_EXIT_INSTRUCTION_LEN = 0x0000440c, 65 | VMX_INSTRUCTION_INFO = 0x0000440e, 66 | GUEST_ES_LIMIT = 0x00004800, 67 | GUEST_CS_LIMIT = 0x00004802, 68 | GUEST_SS_LIMIT = 0x00004804, 69 | GUEST_DS_LIMIT = 0x00004806, 70 | GUEST_FS_LIMIT = 0x00004808, 71 | GUEST_GS_LIMIT = 0x0000480a, 72 | GUEST_LDTR_LIMIT = 0x0000480c, 73 | GUEST_TR_LIMIT = 0x0000480e, 74 | GUEST_GDTR_LIMIT = 0x00004810, 75 | GUEST_IDTR_LIMIT = 0x00004812, 76 | GUEST_ES_AR_BYTES = 0x00004814, 77 | GUEST_CS_AR_BYTES = 0x00004816, 78 | GUEST_SS_AR_BYTES = 0x00004818, 79 | GUEST_DS_AR_BYTES = 0x0000481a, 80 | GUEST_FS_AR_BYTES = 0x0000481c, 81 | GUEST_GS_AR_BYTES = 0x0000481e, 82 | GUEST_LDTR_AR_BYTES = 0x00004820, 83 | GUEST_TR_AR_BYTES = 0x00004822, 84 | GUEST_INTERRUPTIBILITY_INFO = 0x00004824, 85 | GUEST_ACTIVITY_STATE = 0x00004826, 86 | GUEST_SM_BASE = 0x00004828, 87 | GUEST_SYSENTER_CS = 0x0000482A, 88 | HOST_IA32_SYSENTER_CS = 0x00004c00, 89 | CR0_GUEST_HOST_MASK = 0x00006000, 90 | CR4_GUEST_HOST_MASK = 0x00006002, 91 | CR0_READ_SHADOW = 0x00006004, 92 | CR4_READ_SHADOW = 0x00006006, 93 | CR3_TARGET_VALUE0 = 0x00006008, 94 | CR3_TARGET_VALUE1 = 0x0000600a, 95 | CR3_TARGET_VALUE2 = 0x0000600c, 96 | CR3_TARGET_VALUE3 = 0x0000600e, 97 | EXIT_QUALIFICATION = 0x00006400, 98 | GUEST_LINEAR_ADDRESS = 0x0000640a, 99 | GUEST_CR0 = 0x00006800, 100 | GUEST_CR3 = 0x00006802, 101 | GUEST_CR4 = 0x00006804, 102 | GUEST_ES_BASE = 0x00006806, 103 | GUEST_CS_BASE = 0x00006808, 104 | GUEST_SS_BASE = 0x0000680a, 105 | GUEST_DS_BASE = 0x0000680c, 106 | GUEST_FS_BASE = 0x0000680e, 107 | GUEST_GS_BASE = 0x00006810, 108 | GUEST_LDTR_BASE = 0x00006812, 109 | GUEST_TR_BASE = 0x00006814, 110 | GUEST_GDTR_BASE = 0x00006816, 111 | GUEST_IDTR_BASE = 0x00006818, 112 | GUEST_DR7 = 0x0000681a, 113 | GUEST_RSP = 0x0000681c, 114 | GUEST_RIP = 0x0000681e, 115 | GUEST_RFLAGS = 0x00006820, 116 | GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822, 117 | GUEST_SYSENTER_ESP = 0x00006824, 118 | GUEST_SYSENTER_EIP = 0x00006826, 119 | HOST_CR0 = 0x00006c00, 120 | HOST_CR3 = 0x00006c02, 121 | HOST_CR4 = 0x00006c04, 122 | HOST_FS_BASE = 0x00006c06, 123 | HOST_GS_BASE = 0x00006c08, 124 | HOST_TR_BASE = 0x00006c0a, 125 | HOST_GDTR_BASE = 0x00006c0c, 126 | HOST_IDTR_BASE = 0x00006c0e, 127 | HOST_IA32_SYSENTER_ESP = 0x00006c10, 128 | HOST_IA32_SYSENTER_EIP = 0x00006c12, 129 | HOST_RSP = 0x00006c14, 130 | HOST_RIP = 0x00006c16, 131 | }; 132 | 133 | 134 | #define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004 135 | #define CPU_BASED_USE_TSC_OFFSETING 0x00000008 136 | #define CPU_BASED_HLT_EXITING 0x00000080 137 | #define CPU_BASED_INVDPG_EXITING 0x00000200 138 | #define CPU_BASED_MWAIT_EXITING 0x00000400 139 | #define CPU_BASED_RDPMC_EXITING 0x00000800 140 | #define CPU_BASED_RDTSC_EXITING 0x00001000 141 | #define CPU_BASED_CR8_LOAD_EXITING 0x00080000 142 | #define CPU_BASED_CR8_STORE_EXITING 0x00100000 143 | #define CPU_BASED_TPR_SHADOW 0x00200000 144 | #define CPU_BASED_MOV_DR_EXITING 0x00800000 145 | #define CPU_BASED_UNCOND_IO_EXITING 0x01000000 146 | #define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000 147 | #define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000 148 | #define CPU_BASED_MONITOR_EXITING 0x20000000 149 | #define CPU_BASED_PAUSE_EXITING 0x40000000 150 | 151 | #define VM_EXIT_IA32E_MODE 0x00000200 152 | #define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 153 | 154 | 155 | typedef struct _VMX_BASIC_MSR { 156 | unsigned RevId:32; 157 | unsigned szVmxOnRegion:12; 158 | unsigned ClearBit:1; 159 | unsigned Reserved:3; 160 | unsigned PhysicalWidth:1; 161 | unsigned DualMonitor:1; 162 | unsigned MemoryType:4; 163 | unsigned VmExitInformation:1; 164 | unsigned Reserved2:9; 165 | } VMX_BASIC_MSR, *PVMX_BASIC_MSR; 166 | 167 | 168 | 169 | #pragma pack (push, 1) 170 | 171 | /* 172 | * Attribute for segment selector. This is a copy of bit 40:47 & 52:55 of the 173 | * segment descriptor. 174 | */ 175 | typedef union 176 | { 177 | USHORT UCHARs; 178 | struct 179 | { 180 | USHORT type:4; /* 0; Bit 40-43 */ 181 | USHORT s:1; /* 4; Bit 44 */ 182 | USHORT dpl:2; /* 5; Bit 45-46 */ 183 | USHORT p:1; /* 7; Bit 47 */ 184 | // gap! 185 | USHORT avl:1; /* 8; Bit 52 */ 186 | USHORT l:1; /* 9; Bit 53 */ 187 | USHORT db:1; /* 10; Bit 54 */ 188 | USHORT g:1; /* 11; Bit 55 */ 189 | USHORT Gap:4; 190 | } fields; 191 | } SEGMENT_ATTRIBUTES; 192 | 193 | typedef struct _SEGMENT_SELECTOR 194 | { 195 | USHORT sel; 196 | SEGMENT_ATTRIBUTES attributes; 197 | ULONG limit; 198 | ULONG64 base; 199 | } SEGMENT_SELECTOR, *PSEGMENT_SELECTOR; 200 | 201 | typedef struct 202 | { 203 | unsigned LimitLo:16; 204 | unsigned BaseLo:16; 205 | unsigned BaseMid:8; 206 | unsigned Type:4; 207 | unsigned System:1; 208 | unsigned DPL:2; 209 | unsigned Present:1; 210 | unsigned LimitHi:4; 211 | unsigned AVL:1; 212 | unsigned L:1; 213 | unsigned DB:1; 214 | unsigned Gran:1; // Granularity 215 | unsigned BaseHi:8; 216 | } SEGMENT_DESCRIPTOR, *PSEGMENT_DESCRIPTOR; 217 | 218 | typedef struct 219 | { 220 | USHORT limit0; 221 | USHORT base0; 222 | UCHAR base1; 223 | UCHAR attr0; 224 | UCHAR limit1attr1; 225 | UCHAR base2; 226 | } SEGMENT_DESCRIPTOR2, *PSEGMENT_DESCRIPTOR2; 227 | 228 | typedef struct _INTERRUPT_GATE_DESCRIPTOR 229 | { 230 | USHORT TargetOffset1500; 231 | USHORT TargetSelector; 232 | UCHAR InterruptStackTable; 233 | UCHAR Attributes; 234 | USHORT TargetOffset3116; 235 | ULONG TargetOffset6332; 236 | ULONG Reserved; 237 | } INTERRUPT_GATE_DESCRIPTOR,*PINTERRUPT_GATE_DESCRIPTOR; 238 | 239 | #pragma pack (pop) 240 | 241 | 242 | 243 | #define LA_ACCESSED 0x01 244 | #define LA_READABLE 0x02 // for code segments 245 | #define LA_WRITABLE 0x02 // for data segments 246 | #define LA_CONFORMING 0x04 // for code segments 247 | #define LA_EXPANDDOWN 0x04 // for data segments 248 | #define LA_CODE 0x08 249 | #define LA_STANDARD 0x10 250 | #define LA_DPL_0 0x00 251 | #define LA_DPL_1 0x20 252 | #define LA_DPL_2 0x40 253 | #define LA_DPL_3 0x60 254 | #define LA_PRESENT 0x80 255 | 256 | #define LA_LDT64 0x02 257 | #define LA_ATSS64 0x09 258 | #define LA_BTSS64 0x0b 259 | #define LA_CALLGATE64 0x0c 260 | #define LA_INTGATE64 0x0e 261 | #define LA_TRAPGATE64 0x0f 262 | 263 | #define HA_AVAILABLE 0x01 264 | #define HA_LONG 0x02 265 | #define HA_DB 0x04 266 | #define HA_GRANULARITY 0x08 267 | 268 | typedef enum _SEGREGS { 269 | R_ES = 0, 270 | R_CS, 271 | R_SS, 272 | R_DS, 273 | R_FS, 274 | R_GS, 275 | R_LDTR, 276 | R_TR, 277 | }SEGREGS; 278 | 279 | 280 | typedef struct _GUEST_REGS { 281 | ULONG eax; 282 | ULONG ebx; 283 | ULONG ecx; 284 | ULONG edx; 285 | ULONG esp; 286 | ULONG ebp; 287 | ULONG esi; 288 | ULONG edi; 289 | } GUEST_REGS, *PGUEST_REGS; 290 | 291 | typedef struct _GUEST_CPU { 292 | ULONG ProcessorNumber; 293 | PGUEST_REGS pGuestRegs; 294 | ULONG bSingleStepping; 295 | 296 | PVOID VMXON_va; 297 | PHYSICAL_ADDRESS VMXON_pa; 298 | PVOID VMCS_va; 299 | PHYSICAL_ADDRESS VMCS_pa; 300 | PVOID MSR_bitmap_va; 301 | PHYSICAL_ADDRESS MSR_bitmap_pa; 302 | PVOID IO_Bitmap_A_va; 303 | PHYSICAL_ADDRESS IO_Bitmap_A_pa; 304 | PVOID IO_Bitmap_B_va; 305 | PHYSICAL_ADDRESS IO_Bitmap_B_pa; 306 | PVOID VMMIDT; 307 | PVOID Host_Stack_va; 308 | 309 | PVOID IOAPIC_va; 310 | PVOID LocalAPIC_va; 311 | 312 | ULONG Old_eax; 313 | ULONG Old_ebx; 314 | ULONG Old_ecx; 315 | ULONG Old_edx; 316 | ULONG Old_esi; 317 | ULONG Old_edi; 318 | ULONG Old_esp; 319 | ULONG Old_ebp; 320 | ULONG Old_eip; 321 | ULONG Old_eflags; 322 | 323 | } GUEST_CPU, *PGUEST_CPU; 324 | 325 | VOID asmlinkage _ScaleTSCBasedTimer(void); 326 | VOID asmlinkage _CpuSleep(ULONG MicroSecond); 327 | VOID asmlinkage _FlushTLB(void); 328 | 329 | ULONG asmlinkage READ_PORT_UCHAR(ULONG Port); 330 | ULONG asmlinkage READ_PORT_USHORT(ULONG Port); 331 | ULONG asmlinkage READ_PORT_ULONG(ULONG Port); 332 | VOID asmlinkage WRITE_PORT_UCHAR(ULONG Port,ULONG Value); 333 | VOID asmlinkage WRITE_PORT_USHORT(ULONG Port,ULONG Value); 334 | VOID asmlinkage WRITE_PORT_ULONG(ULONG Port,ULONG Value); 335 | ULONG asmlinkage _ReadPRT(PVOID IoApicBase,ULONG PRTIndex); 336 | VOID asmlinkage _WritePRT(PVOID IoApicBase,ULONG PRTIndex,ULONG PRTData); 337 | 338 | VOID asmlinkage _Return1(void); 339 | 340 | ULONG64 asmlinkage _ReadMSR(ULONG MSRIndex); 341 | ULONG64 asmlinkage _WriteMSR(ULONG MSRIndex,ULONG LowPart,ULONG HighPart); 342 | 343 | VOID asmlinkage _VmCallFillScreen(void); 344 | VOID asmlinkage _BeepOn(void); 345 | VOID asmlinkage _BeepOff(void); 346 | VOID asmlinkage _Reboot(void); 347 | ULONG64 asmlinkage _TSC(void); 348 | 349 | ULONG asmlinkage _CS(void); 350 | ULONG asmlinkage _DS(void); 351 | ULONG asmlinkage _ES(void); 352 | ULONG asmlinkage _FS(void); 353 | ULONG asmlinkage _GS(void); 354 | ULONG asmlinkage _SS(void); 355 | ULONG asmlinkage _ES(void); 356 | 357 | ULONG asmlinkage _CR0(void); 358 | ULONG asmlinkage _CR2(void); 359 | ULONG asmlinkage _CR3(void); 360 | ULONG asmlinkage _CR4(void); 361 | 362 | ULONG asmlinkage _DR0(void); 363 | ULONG asmlinkage _DR1(void); 364 | ULONG asmlinkage _DR2(void); 365 | ULONG asmlinkage _DR3(void); 366 | ULONG asmlinkage _DR6(void); 367 | ULONG asmlinkage _DR7(void); 368 | 369 | VOID asmlinkage _SetCR0(ULONG value); 370 | VOID asmlinkage _SetCR2(ULONG value); 371 | VOID asmlinkage _SetCR3(ULONG value); 372 | VOID asmlinkage _SetCR4(ULONG value); 373 | 374 | VOID asmlinkage _SetDR0(ULONG value); 375 | VOID asmlinkage _SetDR1(ULONG value); 376 | VOID asmlinkage _SetDR2(ULONG value); 377 | VOID asmlinkage _SetDR3(ULONG value); 378 | VOID asmlinkage _SetDR6(ULONG value); 379 | VOID asmlinkage _SetDR7(ULONG value); 380 | 381 | VOID asmlinkage _CpuId(PULONG pEax,PULONG pEbx,PULONG pEcx,PULONG pEdx); 382 | 383 | ULONG asmlinkage _VmxOn(ULONG PtrLowPart,ULONG PtrHighPart); 384 | ULONG asmlinkage _VmClear(ULONG PtrLowPart,ULONG PtrHighPart); 385 | ULONG asmlinkage _VmPtrLd(ULONG PtrLowPart,ULONG PtrHighPart); 386 | ULONG asmlinkage _VmFailValid(ULONG Eflags); 387 | ULONG asmlinkage _VmFailInvalid(ULONG Eflags); 388 | ULONG asmlinkage _ReadVMCS(ULONG Field); 389 | VOID asmlinkage _WriteVMCS(ULONG Field, ULONG Value); 390 | ULONG asmlinkage _VmLaunch(void); 391 | 392 | ULONG asmlinkage _Eflags(void); 393 | 394 | ULONG asmlinkage _GdtBase(void); 395 | ULONG asmlinkage _IdtBase(void); 396 | USHORT asmlinkage _GdtLimit(void); 397 | USHORT asmlinkage _IdtLimit(void); 398 | 399 | USHORT asmlinkage _Ldtr(void); 400 | USHORT asmlinkage _TrSelector(void); 401 | 402 | 403 | ULONG asmlinkage _StartVirtualization(void); 404 | VOID asmlinkage _GuestEntryPoint(void); 405 | VOID asmlinkage _VmExitHandler(void); 406 | 407 | VOID asmlinkage _Invd(void); 408 | VOID asmlinkage _StopVirtualization(ULONG SpecCodeLow,ULONG SpecCodeHigh); 409 | VOID asmlinkage _GuestExit(void); 410 | VOID asmlinkage _VmxOff(ULONG RegEsp,ULONG RegEip); 411 | ULONG asmlinkage _VmxOff_NoGuest(void); 412 | 413 | VOID asmlinkage _RegSetIdtr(ULONG Base,ULONG Limit); 414 | VOID asmlinkage _RegSetGdtr(ULONG Base,ULONG Limit); 415 | 416 | VOID asmlinkage _DisableWP(void); 417 | VOID asmlinkage _EnableWP(void); 418 | 419 | 420 | BOOLEAN CheckForVirtualizationSupport(void); 421 | BOOLEAN CheckIfVMXIsEnabled(void); 422 | BOOLEAN SetupVMX(PGUEST_CPU pCpu); 423 | BOOLEAN SetupVMCS(PGUEST_CPU pCpu, PVOID GuestEsp); 424 | BOOLEAN Virtualize(PGUEST_CPU pCpu); 425 | 426 | #endif 427 | 428 | -------------------------------------------------------------------------------- /linux/x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Intel CPU features in CR4 3 | */ 4 | 5 | /* 6 | #define X86_CR4_VME 0x0001 // enable vm86 extensions 7 | #define X86_CR4_PVI 0x0002 // virtual interrupts flag enable 8 | #define X86_CR4_TSD 0x0004 // disable time stamp at ipl 3 9 | #define X86_CR4_DE 0x0008 // enable debugging extensions 10 | #define X86_CR4_PSE 0x0010 // enable page size extensions 11 | #define X86_CR4_PAE 0x0020 // enable physical address extensions 12 | #define X86_CR4_MCE 0x0040 // Machine check enable 13 | #define X86_CR4_PGE 0x0080 // enable global pages 14 | #define X86_CR4_PCE 0x0100 // enable performance counters at ipl 3 15 | #define X86_CR4_OSFXSR 0x0200 // enable fast FPU save and restore 16 | #define X86_CR4_OSXMMEXCPT 0x0400 // enable unmasked SSE exceptions 17 | #define X86_CR4_VMXE 0x2000 // enable VMX 18 | */ 19 | 20 | /* 21 | * Intel CPU MSR 22 | * MSRs & bits used for VMX enabling 23 | */ 24 | 25 | /* 26 | #define MSR_IA32_VMX_BASIC 0x480 27 | #define MSR_IA32_FEATURE_CONTROL 0x03a 28 | #define MSR_IA32_VMX_PINBASED_CTLS 0x481 29 | #define MSR_IA32_VMX_PROCBASED_CTLS 0x482 30 | #define MSR_IA32_VMX_EXIT_CTLS 0x483 31 | #define MSR_IA32_VMX_ENTRY_CTLS 0x484 32 | #define MSR_IA32_SYSENTER_CS 0x174 33 | #define MSR_IA32_SYSENTER_ESP 0x175 34 | #define MSR_IA32_SYSENTER_EIP 0x176 35 | */ 36 | #define MSR_IA32_DEBUGCTL 0x1d9 37 | 38 | #define FLAGS_CF_MASK (1 << 0) 39 | #define FLAGS_PF_MASK (1 << 2) 40 | #define FLAGS_AF_MASK (1 << 4) 41 | #define FLAGS_ZF_MASK (1 << 6) 42 | #define FLAGS_SF_MASK (1 << 7) 43 | #define FLAGS_TF_MASK (1 << 8) 44 | #define FLAGS_IF_MASK (1 << 9) 45 | #define FLAGS_RF_MASK (1 << 16) 46 | 47 | #define IDT_TYPE_TASK_GATE 0b00101 48 | #define IDT_TYPE_32_INT_GATE 0b01110 49 | #define IDT_TYPE_16_INT_GATE 0b00110 50 | #define IDT_TYPE_32_TRAP_GATE 0b01111 51 | #define IDT_TYPE_16_TRAP_GATE 0b00111 52 | 53 | typedef struct { 54 | unsigned LowOffset :16; 55 | unsigned Selector :16; 56 | // union{ 57 | // unsigned Access :16; 58 | // struct{ 59 | unsigned High_0_8 :8; 60 | unsigned GateType :3; 61 | unsigned GateSize :1; 62 | unsigned Bit12 :1; 63 | unsigned DPL :2; 64 | unsigned P :1; 65 | // }; 66 | // }; 67 | unsigned HighOffset :16; 68 | } IDT_ENTRY, *PIDT_ENTRY; 69 | 70 | typedef struct _IDTR { 71 | unsigned Limit :16; 72 | unsigned BaseLo :16; 73 | unsigned BaseHi :16; 74 | } IDTR; 75 | 76 | typedef struct { 77 | unsigned CF :1; 78 | unsigned Bit1 :1; 79 | unsigned PF :1; 80 | unsigned Bit3 :1; 81 | unsigned AF :1; 82 | unsigned Bit5 :1; 83 | unsigned ZF :1; 84 | unsigned SF :1; 85 | unsigned TF :1; 86 | unsigned IF :1; 87 | unsigned DF :1; 88 | unsigned OF :1; 89 | unsigned IOPL :2; 90 | unsigned NT :1; 91 | unsigned Bit15 :1; 92 | unsigned RF :1; 93 | unsigned VM :1; 94 | unsigned AC :1; 95 | unsigned VIF :1; 96 | unsigned VIP :1; 97 | unsigned ID :1; 98 | unsigned Reserved :10; 99 | } EFLAGS, *PEFLAGS; 100 | 101 | typedef struct { 102 | unsigned L0:1; 103 | unsigned G0:1; 104 | unsigned L1:1; 105 | unsigned G1:1; 106 | unsigned L2:1; 107 | unsigned G2:1; 108 | unsigned L3:1; 109 | unsigned G3:1; 110 | unsigned LE:1; 111 | unsigned GE:1; 112 | unsigned Bit10:1; 113 | unsigned Bit11:1; 114 | unsigned Bit12:1; 115 | unsigned GD:1; 116 | unsigned Bit14:1; 117 | unsigned Bit15:1; 118 | unsigned RWE0:2; 119 | unsigned LEN0:2; 120 | unsigned RWE1:2; 121 | unsigned LEN1:2; 122 | unsigned RWE2:2; 123 | unsigned LEN2:2; 124 | unsigned RWE3:2; 125 | unsigned LEN3:2; 126 | } DR7, *PDR7; 127 | 128 | typedef struct { 129 | unsigned B0:1; 130 | unsigned B1:1; 131 | unsigned B2:1; 132 | unsigned B3:1; 133 | unsigned Bit4_12:10; 134 | unsigned BD:1; 135 | unsigned BS:1; 136 | unsigned BT:1; 137 | unsigned Bit16_31:16; 138 | } DR6, *PDR6; 139 | 140 | typedef struct { 141 | unsigned PE:1; 142 | unsigned MP:1; 143 | unsigned EM:1; 144 | unsigned TS:1; 145 | unsigned ET:1; 146 | unsigned NE:1; 147 | unsigned Bit6_15:10; 148 | unsigned WP:1; 149 | unsigned Bit17:1; 150 | unsigned AM:1; 151 | unsigned Bit19_28:12; 152 | unsigned NW:1; 153 | unsigned CD:1; 154 | unsigned PG:1; 155 | } CR0, *PCR0; 156 | 157 | typedef struct { 158 | unsigned VME:1; 159 | unsigned PVI:1; 160 | unsigned TSD:1; 161 | unsigned DE:1; 162 | unsigned PSE:1; 163 | unsigned PAE:1; 164 | unsigned MCE:1; 165 | unsigned PGE:1; 166 | unsigned PCE:1; 167 | unsigned OSFXSR:1; 168 | unsigned OSXMMEXCPT:1; 169 | unsigned Bit11:1; 170 | unsigned Bit12:1; 171 | unsigned VMXE:1; 172 | unsigned SMXE:1; 173 | unsigned Bit15:1; 174 | unsigned Bit16:1; 175 | unsigned PCIDE:1; 176 | unsigned OSXSAVE:1; 177 | unsigned Bit19:1; 178 | unsigned SMEP:1; 179 | unsigned Bit20_31:11; 180 | } CR4, *PCR4; 181 | --------------------------------------------------------------------------------