<commit_before>package main

import (
	"bytes"
	"crypto/rand"
	"encoding/binary"
	"encoding/hex"
	"flag"
	"fmt"
	uc "github.com/unicorn-engine/unicorn/bindings/go/unicorn"
	"io"
	"log"
	"os"
	"sync"
	"time"

	"github.com/lunixbochs/usercorn/go"
	co "github.com/lunixbochs/usercorn/go/kernel/common"
	"github.com/lunixbochs/usercorn/go/models"
)

var secretPage uint64 = 0x4347c000
var secretSize uint64 = 0x1000

func bitcount(i uint32) int {
	out := 0
	for bit := uint32(0); bit < 32; bit++ {
		if i&1<<bit != 0 {
			out++
		}
	}
	return out
}

type Negotiate struct {
	Type    int
	in, out bytes.Buffer
	ready   bool

	ipmask, regmask uint32
	ipval, regval   uint32

	regnum int

	CS  []models.Usercorn
	POV models.Usercorn
}

func (no *Negotiate) Read(p []byte) (int, error) {
	n, err := no.out.Read(p)
	return n, err
}

func (no *Negotiate) Write(p []byte) (int, error) {
	en := binary.LittleEndian
	if no.ready {
		if no.Type == 2 {
			log.Printf("Type 2 POV result received: %s", hex.EncodeToString(p))
			mem, err := no.CS[0].MemRead(secretPage, secretSize)
			if err == nil && bytes.Contains(mem, p) {
				log.Println("Type 2 success")
			} else {
				log.Println("Type 2 failed")
			}
			for _, cb := range no.CS {
				cb.Stop()
			}
			no.POV.Stop()
			return 0, nil
		} else {
			return 0, io.EOF
		}
	} else {
		if no.Type == 2 {
			return 0, io.EOF
		}
		no.in.Write(p)
		if no.Type == 0 && no.in.Len() >= 4 {
			var tmp [4]byte
			no.in.Read(tmp[:])
			no.Type = int(en.Uint32(tmp[:]))
			log.Printf("Type %d POV requested", no.Type)
			if no.Type == 2 {
				out := make([]byte, 12)
				en.PutUint32(out[:4], uint32(secretPage))
				en.PutUint32(out[4:8], uint32(secretSize))
				en.PutUint32(out[8:12], 4)
				no.out.Write(out)
				no.ready = true
			} else if no.Type != 1 {
				no.ready = true
				return 0, io.EOF
			}
		}
		if no.Type == 1 {
			if no.in.Len() < 12 {
				return len(p), nil
			} else {
				var tmp [12]byte
				no.in.Read(tmp[:])
				no.ipmask = en.Uint32(tmp[:4])
				no.regmask = en.Uint32(tmp[4:8])
				if bitcount(no.ipmask) < 20 || bitcount(no.regmask) < 20 {
					log.Printf("Type 1 POV bitmask bit count too low:")
					log.Printf("ipmask: 0x%x  regmask: 0x%x", no.ipmask, no.regmask)
					no.Type = 0
					no.ready = true
					return 0, io.EOF
				}
				regmap := map[uint32]int{
					0: uc.X86_REG_EAX,
					1: uc.X86_REG_ECX,
					2: uc.X86_REG_EDX,
					3: uc.X86_REG_EBX,
					4: uc.X86_REG_ESP,
					5: uc.X86_REG_EBP,
					6: uc.X86_REG_ESI,
					7: uc.X86_REG_EDI,
				}
				regnum := en.Uint32(tmp[8:12])
				if num, ok := regmap[regnum]; ok {
					no.regnum = num
				} else {
					no.Type = 0
					no.ready = true
					return 0, io.EOF
				}
				// pick reg vals
				rand.Read(tmp[:4])
				no.ipval = en.Uint32(tmp[:4]) & no.ipmask
				rand.Read(tmp[:4])
				no.regval = en.Uint32(tmp[:4]) & no.regmask

				// send 'em
				en.PutUint32(tmp[:4], no.ipval)
				no.out.Write(tmp[:4])
				en.PutUint32(tmp[:4], no.regval)
				no.out.Write(tmp[:4])

				log.Printf("ipmask=0x%x  regmask=0x%x  regnum=0x%x\n", no.ipmask, no.regmask, no.regnum)
				log.Printf(" ipval=0x%x   regval=0x%x\n", no.ipval, no.regval)
				no.ready = true
			}
		}
	}<commit_msg>cgc: print reg name for type 1 negotiate<commit_after>package main

import (
	"bytes"
	"crypto/rand"
	"encoding/binary"
	"encoding/hex"
	"flag"
	"fmt"
	uc "github.com/unicorn-engine/unicorn/bindings/go/unicorn"
	"io"
	"log"
	"os"
	"sync"
	"time"

	"github.com/lunixbochs/usercorn/go"
	co "github.com/lunixbochs/usercorn/go/kernel/common"
	"github.com/lunixbochs/usercorn/go/models"
)

var secretPage uint64 = 0x4347c000
var secretSize uint64 = 0x1000

func bitcount(i uint32) int {
	out := 0
	for bit := uint32(0); bit < 32; bit++ {
		if i&1<<bit != 0 {
			out++
		}
	}
	return out
}

type Negotiate struct {
	Type    int
	in, out bytes.Buffer
	ready   bool

	ipmask, regmask uint32
	ipval, regval   uint32

	regnum int

	CS  []models.Usercorn
	POV models.Usercorn
}

func (no *Negotiate) Read(p []byte) (int, error) {
	n, err := no.out.Read(p)
	return n, err
}

func (no *Negotiate) Write(p []byte) (int, error) {
	en := binary.LittleEndian
	if no.ready {
		if no.Type == 2 {
			log.Printf("Type 2 POV result received: %s", hex.EncodeToString(p))
			mem, err := no.CS[0].MemRead(secretPage, secretSize)
			if err == nil && bytes.Contains(mem, p) {
				log.Println("Type 2 success")
			} else {
				log.Println("Type 2 failed")
			}
			for _, cb := range no.CS {
				cb.Stop()
			}
			no.POV.Stop()
			return 0, nil
		} else {
			return 0, io.EOF
		}
	} else {
		if no.Type == 2 {
			return 0, io.EOF
		}
		no.in.Write(p)
		if no.Type == 0 && no.in.Len() >= 4 {
			var tmp [4]byte
			no.in.Read(tmp[:])
			no.Type = int(en.Uint32(tmp[:]))
			log.Printf("Type %d POV requested", no.Type)
			if no.Type == 2 {
				out := make([]byte, 12)
				en.PutUint32(out[:4], uint32(secretPage))
				en.PutUint32(out[4:8], uint32(secretSize))
				en.PutUint32(out[8:12], 4)
				no.out.Write(out)
				no.ready = true
			} else if no.Type != 1 {
				no.ready = true
				return 0, io.EOF
			}
		}
		if no.Type == 1 {
			if no.in.Len() < 12 {
				return len(p), nil
			} else {
				var tmp [12]byte
				no.in.Read(tmp[:])
				no.ipmask = en.Uint32(tmp[:4])
				no.regmask = en.Uint32(tmp[4:8])
				if bitcount(no.ipmask) < 20 || bitcount(no.regmask) < 20 {
					log.Printf("Type 1 POV bitmask bit count too low:")
					log.Printf("ipmask: 0x%x  regmask: 0x%x", no.ipmask, no.regmask)
					no.Type = 0
					no.ready = true
					return 0, io.EOF
				}
				regmap := map[uint32]int{
					0: uc.X86_REG_EAX,
					1: uc.X86_REG_ECX,
					2: uc.X86_REG_EDX,
					3: uc.X86_REG_EBX,
					4: uc.X86_REG_ESP,
					5: uc.X86_REG_EBP,
					6: uc.X86_REG_ESI,
					7: uc.X86_REG_EDI,
				}
				regname := []string{"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}
				regnum := en.Uint32(tmp[8:12])
				if num, ok := regmap[regnum]; ok {
					no.regnum = num
				} else {
					no.Type = 0
					no.ready = true
					return 0, io.EOF
				}
				// pick reg vals
				rand.Read(tmp[:4])
				no.ipval = en.Uint32(tmp[:4]) & no.ipmask
				rand.Read(tmp[:4])
				no.regval = en.Uint32(tmp[:4]) & no.regmask

				// send 'em
				en.PutUint32(tmp[:4], no.ipval)
				no.out.Write(tmp[:4])
				en.PutUint32(tmp[:4], no.regval)
				no.out.Write(tmp[:4])

				log.Printf("ipmask=0x%x  regmask=0x%x  regnum=0x%x (%s)\n", no.ipmask, no.regmask, no.regnum, regname[regnum])
				log.Printf(" ipval=0x%x   regval=0x%x\n", no.ipval, no.regval)
				no.ready = true
			}
		}
	}
{'fraction_non_alphanumeric': 0.17143731823052197, 'fraction_numerical': 0.04362467472830246, 'mean_word_length': 2.6099447513812155, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7083976', 'n_tokens_mistral': 3493, 'n_tokens_neox': 2841, 'n_words': 598}