Skip to content

Commit

Permalink
Adding Zydis status codes, latest gengo.
Browse files Browse the repository at this point in the history
  • Loading branch information
Me committed Apr 7, 2024
1 parent 05df61a commit 7efa1f6
Show file tree
Hide file tree
Showing 6 changed files with 569 additions and 392 deletions.
13 changes: 9 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@

xul.dll

build/

go.sum
*.pgo
*.id0
*.id1
*.id2
*.nam
*.til
examples/**/*.exe
examples/**/*.dll
examples/**/*.so
78 changes: 56 additions & 22 deletions examples/benchmark/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package main

import (
"flag"
"fmt"
"log"
"os"
"runtime/pprof"
"time"
"unsafe"

Expand All @@ -12,9 +15,43 @@ import (
const DISAS_BENCH_NO_FORMAT = true
const DISAS_BENCH_DECODE_MINIMAL = true

var (
fProfile = flag.Bool("cpuprofile", false, "write cpu profile to file")
fLoopCount = flag.Int("loops", 5, "number of loops")
fInputFile = flag.String("input", "xul.dll", "input file")
fCodeOffset = flag.Int("offset", 0x400, "code offset")
fCodeSize = flag.Int("size", 0x2460400, "code size")
)

func readFile() []byte {
file, err := os.Open(*fInputFile)
if err != nil {
log.Fatalf("Unable to open input file: %v", err)
}
defer file.Close()
if _, err := file.Seek(int64(*fCodeOffset), 0); err != nil {
log.Fatalf("Unable to seek input file: %v", err)
}
data := make([]byte, *fCodeSize)
if _, err := file.Read(data); err != nil {
log.Fatalf("Unable to read input file: %v", err)
}
return data
}

func main() {
fmt.Printf("Zydis Version: %x\n", zydis.GetVersion())

flag.Parse()
if *fProfile {
profile, _ := os.Create("default.pgo")
pprof.StartCPUProfile(profile)
defer pprof.StopCPUProfile()
defer profile.Close()
}

code := readFile()

formatter := zydis.Formatter{}
if !DISAS_BENCH_NO_FORMAT {
if zydis.Failed(formatter.Init(zydis.FORMATTER_STYLE_INTEL)) {
Expand All @@ -23,52 +60,48 @@ func main() {
}
}

loopCount := 4
code, err := os.ReadFile("xul.dll")
if err != nil {
fmt.Println("Unable to read input file")
os.Exit(1)
}

dec := zydis.Decoder{}
dec.Init(zydis.MACHINE_MODE_LONG_64, zydis.STACK_WIDTH_64)

if DISAS_BENCH_DECODE_MINIMAL {
dec.EnableMode(zydis.DECODER_MODE_MINIMAL, zydis.Bool(1))
}

numValidInsns := 0
numBadInsn := 0
readOffs := 0
startTime := time.Now()
loopCount := *fLoopCount
for i := 0; i < loopCount; i++ {
readOffs = 0
readOffs := 0

info := zydis.DecodedInstruction{}
ctx := zydis.DecoderContext{}
info := &zydis.DecodedInstruction{}
ctx := &zydis.DecoderContext{}
ops := [5]zydis.DecodedOperand{}
printBuffer := [256]byte{}
for readOffs < len(code) {
for {
bytesLeft := len(code) - readOffs
if bytesLeft <= 0 {
break
}
status := dec.DecodeInstruction(
&ctx,
unsafe.Pointer(&code[readOffs]), uint64(len(code)-readOffs),
&info,
ctx,
unsafe.Pointer(&code[readOffs]),
uint64(bytesLeft),
info,
)
if status == zydis.STATUS_OUT_OF_RANGE {
if status == zydis.STATUS_NO_MORE_DATA {
break
}
if !zydis.Ok(status) {
readOffs++
numBadInsn++
continue
}

readOffs += int(info.Length)
numValidInsns++
readOffs += int(info.Length)

if !DISAS_BENCH_NO_FORMAT {
res := formatter.FormatInstruction(
&info,
info,
&ops[0], 5,
&printBuffer[0], 256,
uint64(readOffs),
Expand All @@ -88,6 +121,7 @@ func main() {
endTime.Sub(startTime).Seconds()*1000)

// Calculate MB/s
mbPerMs := float64(len(code)*loopCount) / (1024 * 1024) / float64(endTime.Sub(startTime).Milliseconds())
fmt.Printf("Speed: %.2f MB/s\n", mbPerMs*1000)
dataSizeMb := float64(len(code)*loopCount) / (1024 * 1024)
timeSpentSec := float64(endTime.Sub(startTime)) / float64(time.Second)
fmt.Printf("Speed: %.2f MB/s\n", dataSizeMb/timeSpentSec)
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/can1357/zydis-go
go 1.22.1

require (
github.com/can1357/gengo v0.1.7
github.com/can1357/gengo v0.1.8
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/tools v0.1.12 // indirect
Expand All @@ -18,4 +18,4 @@ require (
require (
github.com/ebitengine/purego v0.7.1 // indirect
golang.org/x/sync v0.7.0 // indirect
)
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/can1357/gengo v0.1.7 h1:3+Tv29JfQ40YKAAF5kjuU3+LcZghuPv3iCoy5T3h30o=
github.com/can1357/gengo v0.1.7/go.mod h1:4qb/hPH3ONxXtgiXHDFHPteAfAm3LxafZX6A8/QCGsM=
github.com/can1357/gengo v0.1.8 h1:EkXhNUq3jO/UBU2Fsnu2enofA62wvODRPhFxRelwSic=
github.com/can1357/gengo v0.1.8/go.mod h1:4qb/hPH3ONxXtgiXHDFHPteAfAm3LxafZX6A8/QCGsM=
github.com/dave/dst v0.27.3 h1:P1HPoMza3cMEquVf9kKy8yXsFirry4zEnWOdYPOoIzY=
github.com/dave/dst v0.27.3/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc=
github.com/dave/jennifer v1.5.0 h1:HmgPN93bVDpkQyYbqhCHj5QlgvUkvEOzMyEvKLgCRrg=
Expand Down
91 changes: 51 additions & 40 deletions sugar.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,49 +19,60 @@ func (s ShortString) String() string {
return unsafe.String((*byte)(unsafe.Pointer(s.Data())), s.Size())
}

const (
TRUE Bool = 1
FALSE Bool = 0
)

const (
CODE_OKAY Status = 0x00000000
CODE_FAIL Status = 0x80000000
CODE_MASK Status = 0x80000000
MODULE_ZYCORE Status = (0x001) << 20
MODULE_ZYDIS Status = (0x002) << 20
MODULE_ARGPARSE Status = (0x003) << 20
MODULE_USER Status = (0x3FF) << 20
MODULE_MASK Status = (0x7FF) << 20
)

func Ok(status uint32) bool {
return status&0x80000000 == 0
return int32(status) >= 0
}
func Failed(status uint32) bool {
return status&0x80000000 != 0
}
func MakeStatus(err uint32, module uint32, code uint32) uint32 {
return (err & 0x01 << 31) | (module & 0x7FF << 20) | (code & 0xFFFFF)
}
func StatusModule(status uint32) uint32 {
return (status >> 20) & 0x7FF
}
func StatusCode(status uint32) uint32 {
return status & 0xFFFFF
func Failed(status Status) bool {
return int32(status) < 0
}

const ZYAN_TRUE = 1
const ZYAN_FALSE = 0

const (
MODULE_ZYCORE = 0x001
MODULE_ARGPARSE = 0x003
MODULE_USER = 0x3FF
)

var (
STATUS_SUCCESS = MakeStatus(0, MODULE_ZYCORE, 0x00)
STATUS_FAILED = MakeStatus(1, MODULE_ZYCORE, 0x01)
STATUS_TRUE = MakeStatus(0, MODULE_ZYCORE, 0x02)
STATUS_FALSE = MakeStatus(0, MODULE_ZYCORE, 0x03)
STATUS_INVALID_ARGUMENT = MakeStatus(1, MODULE_ZYCORE, 0x04)
STATUS_INVALID_OPERATION = MakeStatus(1, MODULE_ZYCORE, 0x05)
STATUS_ACCESS_DENIED = MakeStatus(1, MODULE_ZYCORE, 0x06)
STATUS_NOT_FOUND = MakeStatus(1, MODULE_ZYCORE, 0x07)
STATUS_OUT_OF_RANGE = MakeStatus(1, MODULE_ZYCORE, 0x08)
STATUS_INSUFFICIENT_BUFFER_SIZE = MakeStatus(1, MODULE_ZYCORE, 0x09)
STATUS_NOT_ENOUGH_MEMORY = MakeStatus(1, MODULE_ZYCORE, 0x0A)
STATUS_BAD_SYSTEMCALL = MakeStatus(1, MODULE_ZYCORE, 0x0B)
STATUS_OUT_OF_RESOURCES = MakeStatus(1, MODULE_ZYCORE, 0x0C)
STATUS_MISSING_DEPENDENCY = MakeStatus(1, MODULE_ZYCORE, 0x0D)
STATUS_ARG_NOT_UNDERSTOOD = MakeStatus(1, MODULE_ARGPARSE, 0x00)
STATUS_TOO_FEW_ARGS = MakeStatus(1, MODULE_ARGPARSE, 0x01)
STATUS_TOO_MANY_ARGS = MakeStatus(1, MODULE_ARGPARSE, 0x02)
STATUS_ARG_MISSES_VALUE = MakeStatus(1, MODULE_ARGPARSE, 0x03)
STATUS_REQUIRED_ARG_MISSING = MakeStatus(1, MODULE_ARGPARSE, 0x04)
STATUS_SUCCESS Status = 0x00 | CODE_OKAY | MODULE_ZYCORE
STATUS_FAILED Status = 0x01 | CODE_FAIL | MODULE_ZYCORE
STATUS_TRUE Status = 0x02 | CODE_OKAY | MODULE_ZYCORE
STATUS_FALSE Status = 0x03 | CODE_OKAY | MODULE_ZYCORE
STATUS_INVALID_ARGUMENT Status = 0x04 | CODE_FAIL | MODULE_ZYCORE
STATUS_INVALID_OPERATION Status = 0x05 | CODE_FAIL | MODULE_ZYCORE
STATUS_ACCESS_DENIED Status = 0x06 | CODE_FAIL | MODULE_ZYCORE
STATUS_NOT_FOUND Status = 0x07 | CODE_FAIL | MODULE_ZYCORE
STATUS_OUT_OF_RANGE Status = 0x08 | CODE_FAIL | MODULE_ZYCORE
STATUS_INSUFFICIENT_BUFFER_SIZE Status = 0x09 | CODE_FAIL | MODULE_ZYCORE
STATUS_NOT_ENOUGH_MEMORY Status = 0x0A | CODE_FAIL | MODULE_ZYCORE
STATUS_BAD_SYSTEMCALL Status = 0x0B | CODE_FAIL | MODULE_ZYCORE
STATUS_OUT_OF_RESOURCES Status = 0x0C | CODE_FAIL | MODULE_ZYCORE
STATUS_MISSING_DEPENDENCY Status = 0x0D | CODE_FAIL | MODULE_ZYCORE
STATUS_ARG_NOT_UNDERSTOOD Status = 0x00 | CODE_FAIL | MODULE_ARGPARSE
STATUS_TOO_FEW_ARGS Status = 0x01 | CODE_FAIL | MODULE_ARGPARSE
STATUS_TOO_MANY_ARGS Status = 0x02 | CODE_FAIL | MODULE_ARGPARSE
STATUS_ARG_MISSES_VALUE Status = 0x03 | CODE_FAIL | MODULE_ARGPARSE
STATUS_REQUIRED_ARG_MISSING Status = 0x04 | CODE_FAIL | MODULE_ARGPARSE
STATUS_NO_MORE_DATA Status = 0x00 | CODE_FAIL | MODULE_ZYDIS
STATUS_DECODING_ERROR Status = 0x01 | CODE_FAIL | MODULE_ZYDIS
STATUS_INSTRUCTION_TOO_LONG Status = 0x02 | CODE_FAIL | MODULE_ZYDIS
STATUS_BAD_REGISTER Status = 0x03 | CODE_FAIL | MODULE_ZYDIS
STATUS_ILLEGAL_LOCK Status = 0x04 | CODE_FAIL | MODULE_ZYDIS
STATUS_ILLEGAL_LEGACY_PFX Status = 0x05 | CODE_FAIL | MODULE_ZYDIS
STATUS_ILLEGAL_REX Status = 0x06 | CODE_FAIL | MODULE_ZYDIS
STATUS_INVALID_MAP Status = 0x07 | CODE_FAIL | MODULE_ZYDIS
STATUS_MALFORMED_EVEX Status = 0x08 | CODE_FAIL | MODULE_ZYDIS
STATUS_MALFORMED_MVEX Status = 0x09 | CODE_FAIL | MODULE_ZYDIS
STATUS_INVALID_MASK Status = 0x0A | CODE_FAIL | MODULE_ZYDIS
STATUS_SKIP_TOKEN Status = 0x0B | CODE_OKAY | MODULE_ZYDIS
STATUS_IMPOSSIBLE_INSTRUCTION Status = 0x0C | CODE_FAIL | MODULE_ZYDIS
)
Loading

0 comments on commit 7efa1f6

Please sign in to comment.