Advertisement
Guest User

Untitled

a guest
Jul 20th, 2017
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.41 KB | None | 0 0
  1. ##qvm.go
  2. package qvm
  3.  
  4. import (
  5.     "os"
  6.     "encoding/binary"
  7.     "fmt"
  8. )
  9.  
  10. const (
  11.     VM_MAGIC_VER1 = 0x12721444
  12.     VM_MAGIC_VER2 = 0x12721445
  13. )
  14.  
  15. //QVMHeader represents the header for a QVMFile. Note that even if VM_MAGIC_VER1
  16. //QVMHeader still contains a JumpTableLength field.
  17. type QVMHeader struct {
  18.     Magic uint32
  19.     InstructionCount uint32
  20.     CodeOffset uint32
  21.     CodeLength uint32
  22.     DataOffset uint32
  23.     DataLength uint32
  24.     LitLength uint32
  25.     BssLength uint32
  26.     JumpTableLength uint32
  27. }
  28.  
  29. //Pretty simple, QVMFile has a header and the three sections normally embedded
  30. //in a QVM file.
  31. type QVMFile struct {
  32.     Header QVMHeader
  33.     Code []byte
  34.     Data []byte
  35.     Lit []byte
  36. }
  37.  
  38. //Also simple. Takes an os.File and creates a QVMFile from it.
  39. //Also performs a few sanity check to save the programmer from
  40. //extra work and potentially malicious files.
  41. func NewQVMFile(file *os.File) (*QVMFile, os.Error) {
  42.  
  43.     //Read the header...
  44.     theFile := &QVMFile{QVMHeader{}, nil, nil, nil}
  45.     if err := binary.Read(file, binary.LittleEndian, &theFile.Header); err != nil {
  46.         return nil, err
  47.     }
  48.  
  49.     //Run a couple sanity checks on the header...
  50.     //First case: Unrecognized magic number
  51.     if theFile.Header.Magic != VM_MAGIC_VER1 && theFile.Header.Magic != VM_MAGIC_VER2 {
  52.         return nil, os.NewError(fmt.Sprintf("Unrecognized QVM version[Magic: 0x%08x]", theFile.Header.Magic))
  53.     }
  54.  
  55.     //Second case: Magic is VM_MAGIC_VER1 but CodeOffset != 32
  56.     if theFile.Header.Magic == VM_MAGIC_VER1 && theFile.Header.CodeOffset != 32 {
  57.         return nil, os.NewError(fmt.Sprintf("Invalid code offset[%d] for magic(Ver1)[0x%08x]", theFile.Header.CodeOffset, theFile.Header.Magic))
  58.     }
  59.  
  60.     //Third case: Magic is VM_MAGIC_VER2 but CodeOffset != 36
  61.     if theFile.Header.Magic == VM_MAGIC_VER2 && theFile.Header.CodeOffset != 36 {
  62.         return nil, os.NewError(fmt.Sprintf("Invalid code offset[%d] for magic(Ver2)[0x%08x]", theFile.Header.CodeOffset, theFile.Header.Magic))
  63.     }
  64.  
  65.     //Fourth case: CodeOffset + CodeLength + (CodeLength % 4) != DataOffset
  66.     if theFile.Header.CodeOffset + theFile.Header.CodeLength + (theFile.Header.CodeLength % 4) != theFile.Header.DataOffset {
  67.         return nil, os.NewError(fmt.Sprintf("Invalid data offset[0x%x] or code length[0x%x]", theFile.Header.DataOffset, theFile.Header.CodeLength))
  68.     }
  69.  
  70.     //Read the Code/Data/Lit sections...
  71.     theFile.Code = make([]byte, theFile.Header.CodeLength)
  72.     if _, err := file.ReadAt(theFile.Code, int64(theFile.Header.CodeOffset)); err != nil {
  73.         return nil, err
  74.     }
  75.  
  76.     theFile.Data = make([]byte, theFile.Header.DataLength)
  77.     if _, err := file.ReadAt(theFile.Data, int64(theFile.Header.DataOffset)); err != nil {
  78.         return nil, err
  79.     }
  80.  
  81.     theFile.Lit = make([]byte, theFile.Header.LitLength)
  82.     if _, err := file.ReadAt(theFile.Lit, int64(theFile.Header.LitLength)); err != nil {
  83.         return nil, err
  84.     }
  85.  
  86.     return theFile, nil
  87. }
  88.  
  89. ##QVMDisas.go
  90.  
  91. package main
  92.  
  93. import (
  94.     "fmt"
  95.     "flag"
  96.     "os"
  97.     "./qvm"
  98. )
  99.  
  100. var OpcodeTable = [...]string {
  101.     "UNDEF",
  102.     "IGNORE",
  103.     "BREAK",
  104.     "ENTER",
  105.     "LEAVE",
  106.     "CALL",
  107.     "PUSH",
  108.     "POP",
  109.     "CONST",
  110.     "LOCAL",
  111.     "JUMP",
  112.     "EQ",
  113.     "NE",
  114.     "LTI",
  115.     "LEI",
  116.     "GTI",
  117.     "GEI",
  118.     "LTU",
  119.     "LEU",
  120.     "GTU",
  121.     "GEU",
  122.     "EQF",
  123.     "NEF",
  124.     "LTF",
  125.     "LEF",
  126.     "GTF",
  127.     "GEF",
  128.     "LOAD1",
  129.     "LOAD2",
  130.     "LOAD4",
  131.     "STORE1",
  132.     "STORE2",
  133.     "STORE4",
  134.     "ARG",
  135.     "BLOCK_COPY",
  136.     "SEX8",
  137.     "SEX16",
  138.     "NEGI",
  139.     "ADD",
  140.     "SUB",
  141.     "DIVI",
  142.     "DIVU",
  143.     "MODI",
  144.     "MODU",
  145.     "MULI",
  146.     "MULU",
  147.     "BAND",
  148.     "BOR",
  149.     "BXOR",
  150.     "BCOM",
  151.     "LSH",
  152.     "RSHI",
  153.     "RSHU",
  154.     "NEGF",
  155.     "ADDF",
  156.     "SUBF",
  157.     "DIVF",
  158.     "MULF",
  159.     "CVIF",
  160.     "CVFI"}
  161.  
  162. var ArgTable = []byte {
  163.     0,
  164.     0,
  165.     0,
  166.     4,
  167.     4,
  168.     0,
  169.     0,
  170.     0,
  171.     4,
  172.     4,
  173.     0,
  174.     4,
  175.     4,
  176.     4,
  177.     4,
  178.     4,
  179.     4,
  180.     4,
  181.     4,
  182.     4,
  183.     4,
  184.     4,
  185.     4,
  186.     4,
  187.     4,
  188.     4,
  189.     4,
  190.     0,
  191.     0,
  192.     0,
  193.     0,
  194.     0,
  195.     0,
  196.     1,
  197.     4,
  198.     0,
  199.     0,
  200.     0,
  201.     0,
  202.     0,
  203.     0,
  204.     0,
  205.     0,
  206.     0,
  207.     0,
  208.     0,
  209.     0,
  210.     0,
  211.     0,
  212.     0,
  213.     0,
  214.     0,
  215.     0,
  216.     0,
  217.     0,
  218.     0,
  219.     0,
  220.     0,
  221.     0,
  222.     0}
  223.  
  224. func printHeader(qvmFile *qvm.QVMFile) {
  225.     version := "unknown"
  226.     switch qvmFile.Header.Magic {
  227.         case qvm.VM_MAGIC_VER1:
  228.             version = "Ver1"
  229.         case qvm.VM_MAGIC_VER2:
  230.             version = "Ver2"
  231.     }
  232.     fmt.Printf("Magic: 0x%x[%s]\n", qvmFile.Header.Magic, version)
  233.     fmt.Printf("Instruction Count: 0x%x\n", qvmFile.Header.InstructionCount)
  234.     fmt.Printf("Code Offset: 0x%x\n", qvmFile.Header.CodeOffset)
  235.     fmt.Printf("Code Length: 0x%x\n", qvmFile.Header.CodeLength)
  236.     fmt.Printf("Data Offset: 0x%x\n", qvmFile.Header.DataOffset)
  237.     fmt.Printf("Data Length: 0x%x\n", qvmFile.Header.DataLength)
  238.     fmt.Printf("Lit Length: 0x%x\n", qvmFile.Header.LitLength)
  239.     fmt.Printf("Bss Length: 0x%x\n", qvmFile.Header.BssLength)
  240.     if qvmFile.Header.Magic == qvm.VM_MAGIC_VER2 {
  241.         fmt.Printf("Jump Table Length: 0x%x\n", qvmFile.Header.JumpTableLength)
  242.     }
  243. }
  244.  
  245. func parseInstructions(qvmFile *qvm.QVMFile) {
  246.     return
  247. }
  248.  
  249. func parseProcedures(qvmFile *qvm.QVMFile) {
  250.     return
  251. }
  252.  
  253. func parseCodeXRefs(qvmFile *qvm.QVMFile) {
  254.     return
  255. }
  256. func parseStrings(qvmFile *qvm.QVMFile) {
  257.     return
  258. }
  259.  
  260. func main() {
  261.     var syscallsFile string
  262.     var commentsFile string
  263.     flag.StringVar(&syscallsFile, "s", "", "Specify a file defining the system calls for this QVM.")
  264.     flag.StringVar(&commentsFile, "c", "", "Specify a file containing comments from a previous disassembly.")
  265.     flag.Parse()
  266.  
  267.     if flag.NArg() != 1 {
  268.         fmt.Println("Must specify one QVM!")
  269.     }
  270.     file, err := os.Open(flag.Arg(0), os.O_RDONLY, 0444)
  271.     if err != nil {
  272.         fmt.Println(err.String())
  273.         os.Exit(-1)
  274.     }
  275.     qvmFile, err := qvm.NewQVMFile(file)
  276.     printHeader(qvmFile)
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement