Best Syzkaller code snippet using main.parseModrm
emulator.go
Source:emulator.go
1package main2import (3 "fmt"4 "io"5 "os"6)7// ã¬ã¸ã¹ã¿çªå·8const (9 CEax = iota10 CEcx11 CEdx12 CEbx13 CEsp14 CEbp15 CEsi16 CEdi17 RegistersCount18)19const (20 CAl = CEax21 CAh = CEax + 422 CCl = CEcx23 CCh = CEcx + 424 CDl = CEdx25 CDh = CEdx + 426 CBl = CEbx27 CBh = CEbx + 428)29// eflagsé¢é£30const (31 CarryFlag = uint32(1)32 ZeroFlag = uint32(1 << 6)33 SignFlag = uint32(1 << 7)34 OverFlowFlag = uint32(1 << 11)35)36type Emulator struct {37 // æ±ç¨ã¬ã¸ã¹ã¿38 Registers [RegistersCount]uint3239 // eflagsã¬ã¸ã¹ã¿40 Eflags uint3241 // ã¡ã¢ãª42 Memory []uint843 // EIPã¬ã¸ã¹ã¿44 Eip uint3245 // æ大ã¡ã¢ãª46 MaxMemorySize uint3247}48func (e *Emulator) DumpEmulator() {49 fmt.Printf("EAX = 0x%08x\n", e.Registers[CEax])50 fmt.Printf("ECX = 0x%08x\n", e.Registers[CEcx])51 fmt.Printf("EDX = 0x%08x\n", e.Registers[CEdx])52 fmt.Printf("EBX = 0x%08x\n", e.Registers[CEbx])53 fmt.Printf("ESP = 0x%08x\n", e.Registers[CEsp])54 fmt.Printf("EBP = 0x%08x\n", e.Registers[CEbp])55 fmt.Printf("ESI = 0x%08x\n", e.Registers[CEsi])56 fmt.Printf("EDI = 0x%08x\n", e.Registers[CEdi])57 fmt.Printf("EIP = 0x%08x\n", e.Eip)58}59func (e *Emulator) ParseModrm() *ModRM {60 modRM := &ModRM{}61 code := e.GetCode8(0)62 // 76 543 21063 // 01 101 11164 // Mod Reg RM65 modRM.Mod = uint8((code & 0xc0) >> 6)66 modRM.Reg = uint8((code & 0x38) >> 3)67 modRM.Rm = uint8(code & 0x07)68 e.Eip += 169 // SIBã®åå¨ç¢ºèªã70 // åå¨ããã°ãå¾ç¶ã®SIBãåå¾ã71 if modRM.Mod != 3 && modRM.Rm == 4 {72 modRM.Sib = uint8(e.GetCode8(0))73 e.Eip += 174 }75 if (modRM.Mod == 0 && modRM.Rm == 5) || modRM.Mod == 2 {76 modRM.Disp32 = uint32(e.GetSignCode32(0))77 e.Eip += 478 } else if modRM.Mod == 1 {79 modRM.Disp8 = int8(e.GetSignCode8(0))80 e.Eip += 181 }82 return modRM83}84func (e *Emulator) GetCode8(index uint32) uint32 {85 return uint32(e.Memory[e.Eip+index])86}87func (e *Emulator) GetSignCode8(index uint32) int32 {88 val := e.Memory[e.Eip+index]89 sign := val >> 790 // 符å·ãæ£ã®æããã®ã¾ã¾int32ã«å¤æããªã¿ã¼ã³ã91 if sign == 0 {92 return int32(val)93 }94 // è² ã®æ°ãuint8ã®å¤ããè¨ç®ã95 // 符å·ãè² ã®æã2ã®è£æ°ãã¨ãint32ã«å¤æãããã¨ã«ãããè² ã®å¤ã®å¤§ãããåå¾ã96 // ãã®å¾ãã¤ãã¹ãæãããªã¿ã¼ã³ã97 return -(int32((^val + 1)))98}99func (e *Emulator) GetSignCode32(index uint32) int32 {100 val := e.GetCode32(index)101 sign := val >> 31102 // 符å·ãæ£ã®æããã®ã¾ã¾int32ã«å¤æããªã¿ã¼ã³ã103 if sign == 0 {104 return int32(val)105 }106 // è² ã®æ°ãuint8ã®å¤ããè¨ç®ã107 // 符å·ãè² ã®æã2ã®è£æ°ãã¨ãint32ã«å¤æãããã¨ã«ãããè² ã®å¤ã®å¤§ãããåå¾ã108 // ãã®å¾ãã¤ãã¹ãæãããªã¿ã¼ã³ã109 return -(int32((^val + 1)))110}111func (e *Emulator) GetCode32(index uint32) uint32 {112 var (113 ret uint32114 i uint32115 )116 for i = 0; i < 4; i++ {117 ret |= e.GetCode8(index+i) << (i * 8)118 }119 return ret120}121func (e *Emulator) MovR32Imm32() {122 reg := e.GetCode8(0) - 0xB8123 value := e.GetCode32(1)124 e.Registers[reg] = uint32(value)125 e.Eip += 5126}127func (e *Emulator) ShortJump() {128 diff := e.GetSignCode8(1)129 if diff > 0 {130 e.Eip += uint32(diff) + 2131 } else {132 e.Eip -= uint32(-diff)133 e.Eip += 2134 }135}136func (e *Emulator) NearJump() {137 diff := e.GetSignCode32(1)138 if diff > 0 {139 e.Eip += uint32(diff) + 5140 } else {141 e.Eip -= uint32(-diff)142 e.Eip += 5143 }144}145func (e *Emulator) MovRm32Imm32() {146 e.Eip += 1147 modRM := e.ParseModrm()148 value := e.GetCode32(0)149 e.Eip += 4150 e.setRm32(modRM, value)151}152func (e *Emulator) setRegister32(index uint8, value uint32) {153 e.Registers[index] = value154}155func (e *Emulator) getRegister32(index uint8) uint32 {156 return e.Registers[index]157}158// SIBã¯å®è£
ãã¦ããªãã159func (e *Emulator) calcMemoryAddress(m *ModRM) uint32 {160 if m.Mod == 0 {161 if m.Rm == 4 {162 fmt.Printf("Not implemented ModRM mod = 0, rm = 4\n")163 os.Exit(0)164 } else if m.Rm == 5 {165 return m.Disp32166 } else {167 return e.getRegister32(m.Rm)168 }169 } else if m.Mod == 1 {170 if m.Rm == 4 {171 fmt.Printf("Not implemented ModRM mod = 1, rm = 4\n")172 os.Exit(0)173 } else {174 if m.Disp8 > 0 {175 return e.getRegister32(m.Rm) + uint32(m.Disp8)176 } else {177 return e.getRegister32(m.Rm) - uint32(-m.Disp8)178 }179 }180 } else if m.Mod == 2 {181 if m.Rm == 4 {182 fmt.Printf("Not implemented ModRM mod = 0, rm = 4\n")183 os.Exit(0)184 } else {185 return e.getRegister32(m.Rm) + m.Disp32186 }187 } else {188 fmt.Printf("Not implemented ModRM rm = 3\n")189 os.Exit(0)190 }191 // ã¨ã©ã¼ãè¨è¨ã«ã¤ãã¦åæ¤è¨ããå¿
è¦ããã192 return 0193}194func (e *Emulator) setMemory8(address uint32, value uint32) {195 e.Memory[address] = uint8(value & 0xFF)196}197func (e *Emulator) getMemory8(address uint32) uint8 {198 return e.Memory[address]199}200func (e *Emulator) setMemory32(address uint32, value uint32) {201 var i uint32202 for i = 0; i < 4; i++ {203 e.setMemory8(address+i, (value>>(i*8))&0xFF)204 }205}206func (e *Emulator) getMemory32(address uint32) uint32 {207 var (208 i uint32209 ret uint32210 )211 for i = 0; i < 4; i++ {212 ret |= uint32(e.getMemory8(address+i)) << (i * 8)213 }214 return ret215}216func (e *Emulator) MovRm32R32() {217 e.Eip += 1218 modRM := e.ParseModrm()219 r32 := e.getR32(modRM)220 e.setRm32(modRM, r32)221}222func (e *Emulator) MovR32Rm32() {223 e.Eip += 1224 modRM := e.ParseModrm()225 rm32 := e.getRm32(modRM)226 e.setR32(modRM, rm32)227}228func (e *Emulator) AddRm32R32() {229 e.Eip += 1230 modRM := e.ParseModrm()231 r32 := e.getR32(modRM)232 rm32 := e.getRm32(modRM)233 e.setRm32(modRM, r32+rm32)234}235func (e *Emulator) AddRm32Imm8(m *ModRM) {236 rm32 := e.getRm32(m)237 imm8 := e.GetSignCode8(0)238 e.Eip += 1239 e.setRm32(m, rm32+uint32(imm8))240}241func (e *Emulator) Code83() {242 e.Eip += 1243 modRM := e.ParseModrm()244 //modRM.Regã¯opecodeã表ãã245 switch modRM.Reg {246 case 0:247 e.AddRm32Imm8(modRM)248 case 5:249 e.SubRm32Imm8(modRM)250 case 7:251 e.CmpRm32Imm8(modRM)252 default:253 fmt.Printf("Not implemented: 83 %d\n", modRM.Reg)254 os.Exit(1)255 }256}257func (e *Emulator) IncRm32(m *ModRM) {258 value := e.getRm32(m)259 e.setRm32(m, value+1)260}261func (e *Emulator) CodeFF() {262 e.Eip += 1263 modRM := e.ParseModrm()264 //modRM.Regã¯opecodeã表ãã265 switch modRM.Reg {266 case 0:267 e.IncRm32(modRM)268 default:269 fmt.Printf("Not implemented: FF %d\n", modRM.Reg)270 os.Exit(1)271 }272}273func (e *Emulator) PushR32() {274 reg := e.GetCode8(0) - 0x50275 e.push32(e.getRegister32(uint8(reg)))276 e.Eip += 1277}278func (e *Emulator) push32(value uint32) {279 address := e.getRegister32(CEsp) - 0x4280 e.setRegister32(CEsp, address)281 e.setMemory32(address, value)282}283func (e *Emulator) getR32(m *ModRM) uint32 {284 return e.getRegister32(m.Reg)285}286func (e *Emulator) popR32() {287 reg := e.GetCode8(0) - 0x58288 e.setRegister32(uint8(reg), e.pop32())289 e.Eip += 1290}291func (e *Emulator) pop32() uint32 {292 address := e.getRegister32(CEsp)293 ret := e.getMemory32(address)294 e.setRegister32(CEsp, address+0x4)295 return ret296}297func (e *Emulator) CallRel32() {298 diff := e.GetSignCode32(1)299 e.push32(e.Eip + 5)300 if diff > 0 {301 e.Eip += uint32(diff) + 5302 } else {303 e.Eip -= uint32(-diff)304 e.Eip += 5305 }306}307func (e *Emulator) Ret() {308 e.Eip = e.pop32()309}310func (e *Emulator) Leave() {311 ebp := e.getRegister32(CEbp)312 e.setRegister32(CEsp, ebp)313 e.setRegister32(CEbp, e.pop32())314 e.Eip += 1315}316func (e *Emulator) PushImm32() {317 value := e.GetCode32(1)318 e.push32(value)319 e.Eip += 5320}321func (e *Emulator) PushImm8() {322 value := e.GetCode8(1)323 e.push32(value)324 e.Eip += 2325}326func (e *Emulator) setR32(m *ModRM, value uint32) {327 e.setRegister32(m.Reg, value)328}329func (e *Emulator) getRm32(m *ModRM) uint32 {330 if m.Mod == 3 {331 return e.getRegister32(m.Rm)332 }333 address := e.calcMemoryAddress(m)334 return e.getMemory32(address)335}336func (e *Emulator) setRm32(m *ModRM, value uint32) {337 if m.Mod == 3 {338 e.setRegister32(m.Rm, value)339 } else {340 address := e.calcMemoryAddress(m)341 e.setMemory32(address, value)342 }343}344func (e *Emulator) CmpR32Rm32() {345 e.Eip += 1346 modRM := e.ParseModrm()347 r32 := e.getR32(modRM)348 rm32 := e.getRm32(modRM)349 result := uint64(r32) - uint64(rm32)350 e.updateEflagsSub(r32, rm32, result)351}352func (e *Emulator) CmpRm32Imm8(m *ModRM) {353 rm32 := e.getRm32(m)354 imm8 := uint32(e.GetSignCode8(0))355 e.Eip += 1356 result := uint64(rm32) - uint64(imm8)357 e.updateEflagsSub(rm32, imm8, result)358}359func (e *Emulator) SubRm32Imm8(m *ModRM) {360 rm32 := e.getRm32(m)361 imm8 := e.GetSignCode8(0)362 e.Eip += 1363 result := uint64(rm32) - uint64(imm8)364 e.setRm32(m, uint32(result))365 e.updateEflagsSub(rm32, uint32(imm8), result)366}367func (e *Emulator) updateEflagsSub(v1 uint32, v2 uint32, result uint64) {368 sign1 := v1 >> 31369 sign2 := v2 >> 31370 signr := (result >> 31) & 0x01371 e.setCarry((result >> 32) != 0)372 e.setZero(result == 0)373 e.setSign(signr == 1)374 e.setOverFlow(sign1 != sign2 && sign1 != uint32(signr))375}376func (e *Emulator) setCarry(b bool) {377 if b {378 e.Eflags |= CarryFlag379 } else {380 e.Eflags &= ^CarryFlag381 }382}383func (e *Emulator) setZero(b bool) {384 if b {385 e.Eflags |= ZeroFlag386 } else {387 e.Eflags &= ^ZeroFlag388 }389}390func (e *Emulator) setSign(b bool) {391 if b {392 e.Eflags |= SignFlag393 } else {394 e.Eflags &= ^SignFlag395 }396}397func (e *Emulator) setOverFlow(b bool) {398 if b {399 e.Eflags |= OverFlowFlag400 } else {401 e.Eflags &= ^OverFlowFlag402 }403}404func (e *Emulator) isCarry() bool {405 return e.Eflags&CarryFlag != 0406}407func (e *Emulator) isZero() bool {408 return e.Eflags&ZeroFlag != 0409}410func (e *Emulator) isSign() bool {411 return e.Eflags&SignFlag != 0412}413func (e *Emulator) isOverFlow() bool {414 return e.Eflags&OverFlowFlag != 0415}416func (e *Emulator) Js() {417 var diff int32418 if e.isSign() {419 diff = e.GetSignCode8(1)420 } else {421 diff = 0422 }423 if diff > 0 {424 e.Eip += uint32(diff) + 2425 } else {426 e.Eip -= uint32(-diff)427 e.Eip += 2428 }429}430func (e *Emulator) Jns() {431 var diff int32432 if e.isSign() {433 diff = 0434 } else {435 diff = e.GetSignCode8(1)436 }437 if diff > 0 {438 e.Eip += uint32(diff) + 2439 } else {440 e.Eip -= uint32(-diff)441 e.Eip += 2442 }443}444func (e *Emulator) Jc() {445 var diff int32446 if e.isCarry() {447 diff = e.GetSignCode8(1)448 } else {449 diff = 0450 }451 if diff > 0 {452 e.Eip += uint32(diff) + 2453 } else {454 e.Eip -= uint32(-diff)455 e.Eip += 2456 }457}458func (e *Emulator) Jnc() {459 var diff int32460 if e.isCarry() {461 diff = 0462 } else {463 diff = e.GetSignCode8(1)464 }465 if diff > 0 {466 e.Eip += uint32(diff) + 2467 } else {468 e.Eip -= uint32(-diff)469 e.Eip += 2470 }471}472func (e *Emulator) Jz() {473 var diff int32474 if e.isZero() {475 diff = e.GetSignCode8(1)476 } else {477 diff = 0478 }479 if diff > 0 {480 e.Eip += uint32(diff) + 2481 } else {482 e.Eip -= uint32(-diff)483 e.Eip += 2484 }485}486func (e *Emulator) Jnz() {487 var diff int32488 if e.isZero() {489 diff = 0490 } else {491 diff = e.GetSignCode8(1)492 }493 if diff > 0 {494 e.Eip += uint32(diff) + 2495 } else {496 e.Eip -= uint32(-diff)497 e.Eip += 2498 }499}500func (e *Emulator) Jo() {501 var diff int32502 if e.isOverFlow() {503 diff = e.GetSignCode8(1)504 } else {505 diff = 0506 }507 if diff > 0 {508 e.Eip += uint32(diff) + 2509 } else {510 e.Eip -= uint32(-diff)511 e.Eip += 2512 }513}514func (e *Emulator) Jno() {515 var diff int32516 if e.isOverFlow() {517 diff = 0518 } else {519 diff = e.GetSignCode8(1)520 }521 if diff > 0 {522 e.Eip += uint32(diff) + 2523 } else {524 e.Eip -= uint32(-diff)525 e.Eip += 2526 }527}528func (e *Emulator) Jl() {529 var diff int32530 if e.isSign() != e.isOverFlow() {531 diff = e.GetSignCode8(1)532 } else {533 diff = 0534 }535 if diff > 0 {536 e.Eip += uint32(diff) + 2537 } else {538 e.Eip -= uint32(-diff)539 e.Eip += 2540 }541}542func (e *Emulator) Jle() {543 var diff int32544 if e.isZero() || e.isSign() != e.isOverFlow() {545 diff = e.GetSignCode8(1)546 } else {547 diff = 0548 }549 if diff > 0 {550 e.Eip += uint32(diff) + 2551 } else {552 e.Eip -= uint32(-diff)553 e.Eip += 2554 }555}556func (e *Emulator) InAlDx() {557 address := e.getRegister32(CEdx) & 0xFFFF558 value := e.IoIn8(uint16(address))559 e.setRegister8(CAl, value)560 e.Eip += 1561}562func (e *Emulator) OutDxAl() {563 address := e.getRegister32(CEdx) & 0xFFFF564 value := e.getRegister8(CAl)565 e.IoOut8(uint16(address), value)566 e.Eip += 1567}568func (e *Emulator) IoIn8(address uint16) uint8 {569 switch address {570 case 0x03F8:571 var a uint32572 fmt.Scan(&a)573 return uint8(a)574 default:575 return 0576 }577}578func (e *Emulator) IoOut8(address uint16, value uint8) {579 switch address {580 case 0x03F8:581 fmt.Printf("%c\n", value)582 }583}584func (e *Emulator) getRegister8(index uint8) uint8 {585 if index < 4 {586 return uint8(e.Registers[index] & 0xFF)587 } else {588 //Highãè¿ãã®ã§8ãããå³ã·ãã589 return uint8((e.Registers[index-4] >> 8) & 0xFF)590 }591}592func (e *Emulator) setRegister8(index uint8, value uint8) {593 if index < 4 {594 v := e.Registers[index] & 0xFFFFFF00595 e.Registers[index] = v | uint32(value)596 } else {597 v := e.Registers[index-4] & 0xFFFF00FF598 e.Registers[index-4] = v | (uint32(value) << 8)599 }600}601func (e *Emulator) MovR8Imm8() {602 e.Eip += 1603 modRM := e.ParseModrm()604 rm8 := e.getRm8(modRM)605 e.setR8(modRM, rm8)606}607func (e *Emulator) getRm8(m *ModRM) uint8 {608 if m.Mod == 3 {609 return e.getRegister8(m.Rm)610 } else {611 address := e.calcMemoryAddress(m)612 return e.getMemory8(address)613 }614}615func (e *Emulator) setRm8(m *ModRM, value uint8) {616 if m.Mod == 3 {617 e.setRegister8(m.Rm, value)618 } else {619 address := e.calcMemoryAddress(m)620 e.setMemory8(address, uint32(value))621 }622}623func (e *Emulator) setR8(m *ModRM, value uint8) {624 e.setRegister8(m.Reg, value)625}626func (e *Emulator) getR8(m *ModRM) uint8 {627 return e.getRegister8(m.Reg)628}629func (e *Emulator) MovRm8R8() {630 e.Eip += 1631 modRM := e.ParseModrm()632 r8 := e.getR8(modRM)633 e.setRm8(modRM, r8)634}635func (e *Emulator) MovR8Rm8() {636 e.Eip += 1637 modRM := e.ParseModrm()638 rm8 := e.getRm8(modRM)639 e.setR8(modRM, rm8)640}641func (e *Emulator) CmpAlImm8() {642 value := e.GetCode8(1)643 al := e.getRegister8(CAl)644 var result uint64645 result = uint64(al) - uint64(value)646 e.updateEflagsSub(uint32(al), value, result)647 e.Eip += 2648}649func (e *Emulator) CmpEaxImm32() {650 value := e.GetCode32(1)651 eax := e.getRegister32(CEax)652 var result uint64653 result = uint64(eax) - uint64(value)654 e.updateEflagsSub(eax, value, result)655 e.Eip += 5656}657func (e *Emulator) IncR32() {658 reg := e.GetCode8(0) - 0x40659 e.setRegister32(uint8(reg), e.getRegister32(uint8(reg))+1)660 e.Eip += 1661}662// ã½ããã¦ã§ã¢å²è¾¼ã¿663func (e *Emulator) Swi() {664 intIndex := e.GetCode8(1)665 e.Eip += 2666 switch intIndex {667 case 0x10:668 e.biosVideo()669 default:670 fmt.Printf("Unknown interrupt: 0x%02x\n", intIndex)671 }672}673func (e *Emulator) biosVideo() {674 funcIndex := e.getRegister8(CAh)675 switch funcIndex {676 case 0x0e:677 e.biosVideoTeletype()678 default:679 fmt.Printf("Not implemented BIOS video function: 0x%02x\n", funcIndex)680 }681}682// alã¬ã¸ã¹ã¿ã«æ ¼ç´ãããæåã³ã¼ããblã¬ã¸ã¹ã¿ã«æ ¼ç´ãããæåè²ã§ç»é¢ã«æç»683func (e *Emulator) biosVideoTeletype() {684 biosToTerminal := [...]int{30, 34, 32, 36, 31, 35, 33, 37}685 color := e.getRegister8(CBl) & 0x0F686 char := e.getRegister8(CAl)687 terminalColor := biosToTerminal[color&0x07]688 bright := (color & 0x08) >> 3689 str := fmt.Sprintf("\x1b[%d;%dm%c\x1b[0m]", bright, terminalColor, char)690 e.putString(str)691}692func (e *Emulator) putString(s string) {693 for i := 0; i < len(s); i++ {694 e.IoOut8(0x03F8, s[i])695 }696}697func (e *Emulator) executeOpCode(opCode uint32) {698 switch opCode {699 case 0x01:700 e.AddRm32R32()701 case 0x3B:702 e.CmpR32Rm32()703 case 0x3C:704 e.CmpAlImm8()705 case 0x3D:706 e.CmpEaxImm32()707 case 0x40, 0x40 + 1, 0x40 + 2, 0x40 + 3, 0x40 + 4, 0x40 + 5, 0x40 + 6, 0x40 + 7:708 e.IncR32()709 case 0x50, 0x50 + 1, 0x50 + 2, 0x50 + 3, 0x50 + 4, 0x50 + 5, 0x50 + 6, 0x50 + 7:710 e.PushR32()711 case 0x58, 0x58 + 1, 0x58 + 2, 0x58 + 3, 0x58 + 4, 0x58 + 5, 0x58 + 6, 0x58 + 7:712 e.popR32()713 case 0x68:714 e.PushImm32()715 case 0x6A:716 e.PushImm8()717 case 0x70:718 e.Jo()719 case 0x71:720 e.Jno()721 case 0x72:722 e.Jc()723 case 0x73:724 e.Jnc()725 case 0x74:726 e.Jz()727 case 0x75:728 e.Jnz()729 case 0x78:730 e.Js()731 case 0x79:732 e.Jns()733 case 0x7C:734 e.Jl()735 case 0x7E:736 e.Jle()737 case 0x83:738 e.Code83()739 case 0x88:740 e.MovRm8R8()741 case 0x89:742 e.MovRm32R32()743 case 0x8A:744 e.MovRm32R32()745 case 0x8B:746 e.MovR32Rm32()747 case 0xB0, 0xB0 + 1, 0xB0 + 2, 0xB0 + 3, 0xB0 + 4, 0xB0 + 5, 0xB0 + 6, 0xB0 + 7:748 e.MovR8Imm8()749 case 0xB8, 0xB8 + 1, 0xB8 + 2, 0xB8 + 3, 0xB8 + 4, 0xB8 + 5, 0xB8 + 6, 0xB8 + 7:750 e.MovR32Imm32()751 case 0xC3:752 e.Ret()753 case 0xC7:754 e.MovRm32Imm32()755 case 0xC9:756 e.Leave()757 case 0xCD:758 e.Swi()759 case 0xE8:760 e.CallRel32()761 case 0xE9:762 e.NearJump()763 case 0xEB:764 e.ShortJump()765 case 0xEE:766 e.OutDxAl()767 case 0xFF:768 e.CodeFF()769 // å®è£
ããã¦ããªãå½ä»¤ã«å¯¾å¿ããå¦çã770 // å®è£
ããã¦ããªãå½ä»¤ãèªã¿è¾¼ãã ããVMãçµäºãããã771 default:772 fmt.Printf("\nNot Implemented: %x", opCode)773 e.Eip = 0774 }775}776func (e *Emulator) Run(quiet bool) {777 for {778 if e.Eip >= e.MaxMemorySize {779 break780 }781 code := e.GetCode8(0)782 if !quiet {783 fmt.Printf("EIP = %x, Code = %02x\n", e.Eip, code)784 }785 e.executeOpCode(code)786 if e.Eip == 0x0 {787 fmt.Printf("\nend of program.\n\n")788 break789 }790 }791}792func NewEmulator(memorySize uint32, eip uint32, esp uint32, fileName string) (*Emulator, error) {793 f, err := os.Open(fileName)794 if err != nil {795 return nil, err796 }797 defer f.Close()798 buf := make([]byte, memorySize)799 count := 0800 for {801 c, err := f.Read(buf)802 if err == io.EOF {803 count += c804 break805 }806 if err != nil {807 return nil, err808 }809 count += c810 }811 // []byteãã[]uint8ã¸ãã¹ã©ã¤ã¹ã®åå¤æã812 memory := make([]uint8, len(buf))813 for i := 0; i < count; i++ {814 memory[i+0x7c00] = uint8(buf[i])815 }816 emu := &Emulator{817 Memory: memory,818 Eip: eip,819 MaxMemorySize: memorySize,820 }821 emu.Registers[CEsp] = esp822 return emu, nil823}...
instruction.go
Source:instruction.go
1package main2import (3 "fmt"4 "log"5 "os"6)7var (8 instructions [256]instructionFunc9)10type instructionFunc func(emu *Emulator)11func init() {12 instructions[0x01] = addRm32R3213 instructions[0x3B] = cmpR32Rm3214 instructions[0x3C] = cmpAlImm815 instructions[0x3D] = cmpEaxImm3216 for i := 0; i < 8; i++ {17 instructions[0x40+i] = incR3218 instructions[0x50+i] = pushR3219 instructions[0x58+i] = popR3220 }21 instructions[0x68] = pushImm3222 instructions[0x6A] = pushImm823 instructions[0x70] = jo24 instructions[0x71] = jno25 instructions[0x72] = jc26 instructions[0x73] = jnc27 instructions[0x74] = jz28 instructions[0x75] = jnz29 instructions[0x78] = js30 instructions[0x79] = jns31 instructions[0x7C] = jl32 instructions[0x7E] = jle33 instructions[0x83] = code8334 instructions[0x88] = movRm8R835 instructions[0x89] = movRm32R3236 instructions[0x8A] = movR8Rm837 instructions[0x8B] = movR32Rm3238 for i := 0; i < 8; i++ {39 instructions[0xB0+i] = movR8Imm840 instructions[0xB8+i] = movR32Imm3241 }42 instructions[0xC3] = ret43 instructions[0xC7] = movRm32Imm3244 instructions[0xC9] = leave45 instructions[0xCD] = swi46 instructions[0xE8] = callRel3247 instructions[0xE9] = nearJump48 instructions[0xEB] = shortJump49 instructions[0xEC] = inAlDx50 instructions[0xEE] = outDxAl51 instructions[0xFF] = codeFF52}53func shortJump(emu *Emulator) {54 diff := emu.getSignCode8(1)55 emu.eip += uint32(diff + 2)56}57func nearJump(emu *Emulator) {58 diff := emu.getSignCode32(1)59 emu.eip += uint32(diff + 5)60}61func movR8Imm8(emu *Emulator) {62 reg := emu.getCode8(0) - 0xB063 emu.setRegister8(reg, emu.getCode8(1))64 emu.eip += 265}66func movRm8R8(emu *Emulator) {67 emu.eip++68 modrm := ParseModRM(emu)69 r8 := emu.getRegister8(modrm.regIndex)70 emu.setRm8(modrm, r8)71}72func movR8Rm8(emu *Emulator) {73 emu.eip++74 modrm := ParseModRM(emu)75 rm8 := emu.getRm8(modrm)76 emu.setRegister8(modrm.regIndex, rm8)77}78func movR32Imm32(emu *Emulator) {79 reg := emu.getCode8(0) - 0xB880 val := emu.getCode32(1)81 emu.registers[reg] = val82 emu.eip += 583}84func movRm32Imm32(emu *Emulator) {85 emu.eip++86 modrm := ParseModRM(emu)87 val := emu.getCode32(0)88 emu.eip += 489 emu.setRm32(modrm, val)90}91func movRm32R32(emu *Emulator) {92 emu.eip++93 modrm := ParseModRM(emu)94 r32 := emu.getRegister32(modrm.regIndex)95 emu.setRm32(modrm, r32)96}97func movR32Rm32(emu *Emulator) {98 emu.eip++99 modrm := ParseModRM(emu)100 rm32 := emu.getRm32(modrm)101 emu.setRegister32(modrm.regIndex, rm32)102}103func addRm32R32(emu *Emulator) {104 emu.eip++105 modrm := ParseModRM(emu)106 rm32 := emu.getRm32(modrm)107 r32 := emu.getRegister32(modrm.regIndex)108 emu.setRm32(modrm, rm32+r32)109}110func addRm32Imm8(emu *Emulator, modrm *ModRM) {111 rm32 := emu.getRm32(modrm)112 imm8 := emu.getSignCode8(0)113 emu.eip++114 emu.setRm32(modrm, rm32+uint32(imm8))115}116func code83(emu *Emulator) {117 emu.eip++118 modrm := ParseModRM(emu)119 switch modrm.opcode {120 case 0:121 addRm32Imm8(emu, modrm)122 case 5:123 subRm32Imm8(emu, modrm)124 case 7:125 cmpRm32Imm8(emu, modrm)126 default:127 log.Printf("not implemented: 83 /%d\n", modrm.opcode)128 os.Exit(1)129 }130}131func subRm32Imm8(emu *Emulator, modrm *ModRM) {132 rm32 := emu.getRm32(modrm)133 imm8 := uint32(emu.getSignCode8(0))134 emu.eip++135 emu.setRm32(modrm, rm32-imm8)136 emu.updateEflagsSub(rm32, imm8)137}138func codeFF(emu *Emulator) {139 emu.eip++140 modrm := ParseModRM(emu)141 switch modrm.opcode {142 case 0:143 incRm32(emu, modrm)144 default:145 log.Printf("not implemented: FF /%d\n", modrm.opcode)146 os.Exit(1)147 }148}149func incR32(emu *Emulator) {150 reg := emu.getCode8(0) - 0x40151 emu.setRegister32(reg, emu.getRegister32(reg)+1)152 emu.eip++153}154func incRm32(emu *Emulator, modrm *ModRM) {155 val := emu.getRm32(modrm)156 emu.setRm32(modrm, val+1)157}158func pushR32(emu *Emulator) {159 reg := emu.getCode8(0) - 0x50160 emu.push32(emu.getRegister32(reg))161 emu.eip++162}163func pushImm32(emu *Emulator) {164 val := emu.getCode32(1)165 emu.push32(val)166 emu.eip += 5167}168func pushImm8(emu *Emulator) {169 val := emu.getCode8(1)170 emu.push32(uint32(val))171 emu.eip += 2172}173func popR32(emu *Emulator) {174 reg := emu.getCode8(0) - 0x58175 emu.setRegister32(reg, emu.pop32())176 emu.eip++177}178func callRel32(emu *Emulator) {179 diff := emu.getSignCode32(1)180 emu.push32(emu.eip + 5)181 emu.eip += uint32(diff + 5)182}183func ret(emu *Emulator) {184 emu.eip = emu.pop32()185}186func leave(emu *Emulator) {187 ebp := emu.getRegister32(uint8(EBP))188 emu.setRegister32(uint8(ESP), ebp)189 emu.setRegister32(uint8(EBP), emu.pop32())190 emu.eip++191}192func cmpAlImm8(emu *Emulator) {193 al := emu.getRegister8(AL)194 val := emu.getCode8(1)195 emu.updateEflagsSub(uint32(al), uint32(val))196 emu.eip += 2197}198func cmpEaxImm32(emu *Emulator) {199 eax := emu.getRegister32(EAX)200 val := emu.getCode32(1)201 emu.updateEflagsSub(eax, val)202 emu.eip += 5203}204func cmpR32Rm32(emu *Emulator) {205 emu.eip++206 modrm := ParseModRM(emu)207 r32 := emu.getRegister32(modrm.regIndex)208 rm32 := emu.getRm32(modrm)209 emu.updateEflagsSub(r32, rm32)210}211func cmpRm32Imm8(emu *Emulator, modrm *ModRM) {212 rm32 := emu.getRm32(modrm)213 imm8 := uint32(emu.getCode8(0))214 emu.eip++215 emu.updateEflagsSub(rm32, imm8)216}217func jc(emu *Emulator) {218 var diff uint32219 if emu.isCarry() {220 diff = uint32(emu.getSignCode8(1))221 } else {222 diff = 0223 }224 emu.eip += diff + 2225}226func jz(emu *Emulator) {227 var diff uint32228 if emu.isZero() {229 diff = uint32(emu.getSignCode8(1))230 } else {231 diff = 0232 }233 emu.eip += diff + 2234}235func js(emu *Emulator) {236 var diff uint32237 if emu.isSign() {238 diff = uint32(emu.getSignCode8(1))239 } else {240 diff = 0241 }242 emu.eip += diff + 2243}244func jo(emu *Emulator) {245 var diff uint32246 if emu.isOverflow() {247 diff = uint32(emu.getSignCode8(1))248 } else {249 diff = 0250 }251 emu.eip += diff + 2252}253func jl(emu *Emulator) {254 var diff uint32255 if emu.isSign() != emu.isOverflow() {256 diff = uint32(emu.getSignCode8(1))257 } else {258 diff = 0259 }260 emu.eip += diff + 2261}262func jle(emu *Emulator) {263 var diff uint32264 if emu.isZero() || (emu.isSign() != emu.isOverflow()) {265 diff = uint32(emu.getSignCode8(1))266 } else {267 diff = 0268 }269 emu.eip += diff + 2270}271func jnc(emu *Emulator) {272 var diff uint32273 if emu.isCarry() {274 diff = 0275 } else {276 diff = uint32(emu.getSignCode8(1))277 }278 emu.eip += diff + 2279}280func jnz(emu *Emulator) {281 var diff uint32282 if emu.isZero() {283 diff = 0284 } else {285 diff = uint32(emu.getSignCode8(1))286 }287 emu.eip += diff + 2288}289func jns(emu *Emulator) {290 var diff uint32291 if emu.isSign() {292 diff = 0293 } else {294 diff = uint32(emu.getSignCode8(1))295 }296 emu.eip += diff + 2297}298func jno(emu *Emulator) {299 var diff uint32300 if emu.isOverflow() {301 diff = 0302 } else {303 diff = uint32(emu.getSignCode8(1))304 }305 emu.eip += diff + 2306}307func inAlDx(emu *Emulator) {308 address := uint16(emu.getRegister32(EDX))309 val := ioIn8(address)310 emu.setRegister8(AL, val)311 emu.eip++312}313func outDxAl(emu *Emulator) {314 address := uint16(emu.getRegister32(EDX))315 val := emu.getRegister8(AL)316 ioOut8(address, val)317 emu.eip++318}319func swi(emu *Emulator) {320 intIndex := emu.getCode8(1)321 emu.eip += 2322 switch intIndex {323 case 0x10:324 biosVideo(emu)325 default:326 fmt.Printf("unknown interrupt: 0x%02x\n", intIndex)327 }328}...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!