Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
c96647f5
Unverified
Commit
c96647f5
authored
Apr 28, 2023
by
protolambda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mipsevm: test Go unicorn pre-image oracle integration, fix oracle communication bugs
parent
fc3bf6e8
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
163 additions
and
26 deletions
+163
-26
Oracle.sol
contracts/src/Oracle.sol
+1
-0
main.go
example/claim/main.go
+5
-5
go.mod
mipsevm/go.mod
+7
-4
go.sum
mipsevm/go.sum
+10
-10
state.go
mipsevm/state.go
+3
-0
state_test.go
mipsevm/state_test.go
+107
-0
unicorn.go
mipsevm/unicorn.go
+30
-7
No files found.
contracts/src/Oracle.sol
View file @
c96647f5
...
...
@@ -12,6 +12,7 @@ contract Oracle {
require(preimagePartOk[key][offset], "preimage must exist");
datLen = 32;
uint256 length = preimageLengths[key];
// TODO: insert length prefix before data
if(offset + 32 >= length) {
datLen = length - offset;
}
...
...
example/claim/main.go
View file @
c96647f5
...
...
@@ -15,14 +15,14 @@ func (rh rawHint) Hint() string {
}
func
main
()
{
_
,
_
=
os
.
Std
out
.
Write
([]
byte
(
"started!"
))
_
,
_
=
os
.
Std
err
.
Write
([]
byte
(
"started!"
))
po
:=
preimage
.
NewOracleClient
(
preimage
.
ClientPreimageChannel
())
hinter
:=
preimage
.
NewHintWriter
(
preimage
.
ClientHinterChannel
())
preHash
:=
po
.
Get
(
preimage
.
LocalIndexKey
(
0
))
diffHash
:=
po
.
Get
(
preimage
.
LocalIndexKey
(
1
))
claimData
:=
po
.
Get
(
preimage
.
LocalIndexKey
(
2
))
preHash
:=
*
(
*
[
32
]
byte
)(
po
.
Get
(
preimage
.
LocalIndexKey
(
0
)
))
diffHash
:=
*
(
*
[
32
]
byte
)(
po
.
Get
(
preimage
.
LocalIndexKey
(
1
)
))
claimData
:=
*
(
*
[
8
]
byte
)(
po
.
Get
(
preimage
.
LocalIndexKey
(
2
)
))
// Hints are used to indicate which things the program will access,
// so the server can be prepared to serve the corresponding pre-images.
...
...
@@ -43,7 +43,7 @@ func main() {
fmt
.
Printf
(
"computing %d * %d + %d
\n
"
,
s
,
a
,
b
)
sOut
:=
s
*
a
+
b
sClaim
:=
binary
.
BigEndian
.
Uint64
(
claimData
)
sClaim
:=
binary
.
BigEndian
.
Uint64
(
claimData
[
:
]
)
if
sOut
!=
sClaim
{
fmt
.
Printf
(
"claim %d is bad! Correct result is %d
\n
"
,
sOut
,
sClaim
)
os
.
Exit
(
1
)
...
...
mipsevm/go.mod
View file @
c96647f5
...
...
@@ -3,8 +3,9 @@ module mipsevm
go 1.20
require (
github.com/ethereum-optimism/cannon/preimage v0.0.0
github.com/ethereum/go-ethereum v1.11.5
github.com/stretchr/testify v1.8.
0
github.com/stretchr/testify v1.8.
2
github.com/unicorn-engine/unicorn v0.0.0-20230207094436-7b8c63dfe650
)
...
...
@@ -50,15 +51,17 @@ require (
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
golang.org/x/crypto v0.
1
.0 // indirect
golang.org/x/crypto v0.
8
.0 // indirect
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect
golang.org/x/sys v0.
5
.0 // indirect
golang.org/x/text v0.
7
.0 // indirect
golang.org/x/sys v0.
7
.0 // indirect
golang.org/x/text v0.
9
.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum-optimism/cannon/preimage v0.0.0 => ../preimage
// We need to point to our local Unicorn clone for the shared object to be located correctly in all our Go commands.
// See https://github.com/unicorn-engine/unicorn/blob/7b8c63dfe650b5d4d2bf684526161971925e6350/bindings/go/unicorn/unicorn.go#L11
// The -L../../../ -lunicorn points to the unicorn root directory relative to the unicorn Go bindings.
...
...
mipsevm/go.sum
View file @
c96647f5
...
...
@@ -251,14 +251,16 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4=
...
...
@@ -269,8 +271,6 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/unicorn-engine/unicorn v0.0.0-20230207094436-7b8c63dfe650 h1:O8wGQwIFVKk04THvsqbrMi9rXfJwxRU1Bf04NBWvdhI=
github.com/unicorn-engine/unicorn v0.0.0-20230207094436-7b8c63dfe650/go.mod h1:mcHBrigWSHlMZYol9QOFnK7sbltIt/OaKP5CQBZsC+4=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
...
...
@@ -296,8 +296,8 @@ golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.
1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU
=
golang.org/x/crypto v0.
1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw
=
golang.org/x/crypto v0.
8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ
=
golang.org/x/crypto v0.
8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE
=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg=
golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
...
...
@@ -328,7 +328,7 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.
4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU
=
golang.org/x/net v0.
9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM
=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
...
...
@@ -368,8 +368,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.
5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4D
U=
golang.org/x/sys v0.
5
.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.
7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZR
U=
golang.org/x/sys v0.
7
.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
...
...
@@ -377,8 +377,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.
7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo
=
golang.org/x/text v0.
7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ
8=
golang.org/x/text v0.
9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE
=
golang.org/x/text v0.
9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU
8=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
...
...
mipsevm/state.go
View file @
c96647f5
...
...
@@ -31,6 +31,9 @@ type State struct {
// so a VM can start from any state without fetching prior pre-images,
// and instead just repeat the last hint on setup,
// to make sure pre-image requests can be served.
// The first 4 bytes are a uin32 length prefix.
// Warning: the hint MAY NOT BE COMPLETE. I.e. this is buffered,
// and should only be read when len(LastHint) > 4 && uint32(LastHint[:4]) >= len(LastHint[4:])
LastHint
hexutil
.
Bytes
`json:"lastHint,omitempty"`
}
...
...
mipsevm/state_test.go
View file @
c96647f5
...
...
@@ -3,12 +3,20 @@ package mipsevm
import
(
"bytes"
"debug/elf"
"encoding/binary"
"encoding/hex"
"fmt"
"io"
"os"
"path"
"strings"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/cannon/preimage"
)
// baseAddrStart - baseAddrEnd is used in tests to write the results to
...
...
@@ -108,3 +116,102 @@ func TestHello(t *testing.T) {
require
.
Equal
(
t
,
"hello world!"
,
stdOutBuf
.
String
(),
"stdout says hello"
)
require
.
Equal
(
t
,
""
,
stdErrBuf
.
String
(),
"stderr silent"
)
}
type
testOracle
struct
{
hint
func
(
v
[]
byte
)
getPreimage
func
(
k
[
32
]
byte
)
[]
byte
}
func
(
t
*
testOracle
)
Hint
(
v
[]
byte
)
{
t
.
hint
(
v
)
}
func
(
t
*
testOracle
)
GetPreimage
(
k
[
32
]
byte
)
[]
byte
{
return
t
.
getPreimage
(
k
)
}
var
_
PreimageOracle
=
(
*
testOracle
)(
nil
)
func
TestClaim
(
t
*
testing
.
T
)
{
elfProgram
,
err
:=
elf
.
Open
(
"../example/bin/claim.elf"
)
require
.
NoError
(
t
,
err
,
"open ELF file"
)
state
,
err
:=
LoadELF
(
elfProgram
)
require
.
NoError
(
t
,
err
,
"load ELF into state"
)
err
=
patchVM
(
elfProgram
,
state
)
require
.
NoError
(
t
,
err
,
"apply Go runtime patches"
)
mu
,
err
:=
NewUnicorn
()
require
.
NoError
(
t
,
err
,
"load unicorn"
)
defer
mu
.
Close
()
err
=
LoadUnicorn
(
state
,
mu
)
require
.
NoError
(
t
,
err
,
"load state into unicorn"
)
s
:=
uint64
(
1000
)
a
:=
uint64
(
3
)
b
:=
uint64
(
4
)
encodeU64
:=
func
(
x
uint64
)
[]
byte
{
return
binary
.
BigEndian
.
AppendUint64
(
nil
,
x
)
}
var
diff
[]
byte
diff
=
append
(
diff
,
crypto
.
Keccak256
(
encodeU64
(
a
))
...
)
diff
=
append
(
diff
,
crypto
.
Keccak256
(
encodeU64
(
b
))
...
)
preHash
:=
crypto
.
Keccak256Hash
(
encodeU64
(
s
))
diffHash
:=
crypto
.
Keccak256Hash
(
diff
)
images
:=
make
(
map
[[
32
]
byte
][]
byte
)
images
[
preimage
.
LocalIndexKey
(
0
)
.
PreimageKey
()]
=
preHash
[
:
]
images
[
preimage
.
LocalIndexKey
(
1
)
.
PreimageKey
()]
=
diffHash
[
:
]
images
[
preimage
.
LocalIndexKey
(
2
)
.
PreimageKey
()]
=
encodeU64
(
s
*
a
+
b
)
oracle
:=
&
testOracle
{
hint
:
func
(
v
[]
byte
)
{
parts
:=
strings
.
Split
(
string
(
v
),
" "
)
require
.
Len
(
t
,
parts
,
2
)
p
,
err
:=
hex
.
DecodeString
(
parts
[
1
])
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
p
,
32
)
h
:=
common
.
Hash
(
*
(
*
[
32
]
byte
)(
p
))
switch
parts
[
0
]
{
case
"fetch-state"
:
require
.
Equal
(
t
,
h
,
preHash
,
"expecting request for pre-state pre-image"
)
images
[
preimage
.
Keccak256Key
(
preHash
)
.
PreimageKey
()]
=
encodeU64
(
s
)
case
"fetch-diff"
:
require
.
Equal
(
t
,
h
,
diffHash
,
"expecting request for diff pre-images"
)
images
[
preimage
.
Keccak256Key
(
diffHash
)
.
PreimageKey
()]
=
diff
images
[
preimage
.
Keccak256Key
(
crypto
.
Keccak256Hash
(
encodeU64
(
a
)))
.
PreimageKey
()]
=
encodeU64
(
a
)
images
[
preimage
.
Keccak256Key
(
crypto
.
Keccak256Hash
(
encodeU64
(
b
)))
.
PreimageKey
()]
=
encodeU64
(
b
)
default
:
t
.
Fatalf
(
"unexpected hint: %q"
,
parts
[
0
])
}
},
getPreimage
:
func
(
k
[
32
]
byte
)
[]
byte
{
p
,
ok
:=
images
[
k
]
if
!
ok
{
t
.
Fatalf
(
"missing pre-image %s"
,
k
)
}
return
p
},
}
var
stdOutBuf
,
stdErrBuf
bytes
.
Buffer
us
,
err
:=
NewUnicornState
(
mu
,
state
,
oracle
,
io
.
MultiWriter
(
&
stdOutBuf
,
os
.
Stdout
),
io
.
MultiWriter
(
&
stdErrBuf
,
os
.
Stderr
))
require
.
NoError
(
t
,
err
,
"hook unicorn to state"
)
for
i
:=
0
;
i
<
2000
_000
;
i
++
{
if
us
.
state
.
Exited
{
break
}
us
.
Step
(
false
)
}
require
.
True
(
t
,
state
.
Exited
,
"must complete program"
)
require
.
Equal
(
t
,
uint8
(
0
),
state
.
ExitCode
,
"exit with 0"
)
require
.
Equal
(
t
,
fmt
.
Sprintf
(
"computing %d * %d + %d
\n
claim %d is good!
\n
"
,
s
,
a
,
b
,
s
*
a
+
b
),
stdOutBuf
.
String
(),
"stdout says hello"
)
require
.
Equal
(
t
,
"started!"
,
stdErrBuf
.
String
(),
"stderr silent"
)
}
mipsevm/unicorn.go
View file @
c96647f5
...
...
@@ -32,7 +32,7 @@ type UnicornState struct {
preimageOracle
PreimageOracle
// cached pre-image data
// cached pre-image data
, including 8 byte length prefix
lastPreimage
[]
byte
// key for above preimage
lastPreimageKey
[
32
]
byte
...
...
@@ -70,10 +70,16 @@ func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, std
readPreimage
:=
func
(
key
[
32
]
byte
,
offset
uint32
)
(
dat
[
32
]
byte
,
datLen
uint32
)
{
preimage
:=
m
.
lastPreimage
if
key
!=
m
.
lastPreimageKey
{
preimage
=
po
.
GetPreimage
(
key
)
m
.
lastPreimageKey
=
key
data
:=
po
.
GetPreimage
(
key
)
// add the length prefix
preimage
=
make
([]
byte
,
0
,
8
+
len
(
data
))
preimage
=
binary
.
BigEndian
.
AppendUint64
(
preimage
,
uint64
(
len
(
data
)))
preimage
=
append
(
preimage
,
data
...
)
m
.
lastPreimage
=
preimage
}
m
.
lastPreimageOffset
=
offset
datLen
=
uint32
(
copy
(
dat
[
:
],
preimage
))
datLen
=
uint32
(
copy
(
dat
[
:
],
preimage
[
offset
:
]
))
return
}
...
...
@@ -130,8 +136,10 @@ func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, std
case
fdStdin
:
// leave v0 and v1 zero: read nothing, no error
case
fdPreimageRead
:
// pre-image oracle
mem
:=
st
.
Memory
.
GetMemory
(
a1
&
0xFFffFFfc
)
effAddr
:=
a1
&
0xFFffFFfc
mem
:=
st
.
Memory
.
GetMemory
(
effAddr
)
dat
,
datLen
:=
readPreimage
(
st
.
PreimageKey
,
st
.
PreimageOffset
)
fmt
.
Printf
(
"reading pre-image data: addr: %08x, offset: %d, datLen: %d, data: %x, key: %s count: %d
\n
"
,
a1
,
st
.
PreimageOffset
,
datLen
,
dat
[
:
datLen
],
st
.
PreimageKey
,
a2
)
alignment
:=
a1
&
3
space
:=
4
-
alignment
if
space
<
datLen
{
...
...
@@ -143,9 +151,13 @@ func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, std
var
outMem
[
4
]
byte
binary
.
BigEndian
.
PutUint32
(
outMem
[
:
],
mem
)
copy
(
outMem
[
alignment
:
],
dat
[
:
datLen
])
st
.
Memory
.
SetMemory
(
a1
&
0xFFffFFfc
,
binary
.
BigEndian
.
Uint32
(
outMem
[
:
]))
st
.
Memory
.
SetMemory
(
effAddr
,
binary
.
BigEndian
.
Uint32
(
outMem
[
:
]))
if
err
:=
mu
.
MemWrite
(
uint64
(
effAddr
),
outMem
[
:
]);
err
!=
nil
{
log
.
Fatalf
(
"failed to write pre-image data to memory: %v"
,
err
)
}
st
.
PreimageOffset
+=
datLen
v0
=
datLen
fmt
.
Printf
(
"read %d pre-image bytes, new offset: %d, eff addr: %08x mem: %08x
\n
"
,
datLen
,
st
.
PreimageOffset
,
effAddr
,
outMem
)
case
fdHintRead
:
// hint response
// don't actually read into memory, just say we read it all, we ignore the result anyway
v0
=
a2
...
...
@@ -164,9 +176,19 @@ func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, std
_
,
_
=
io
.
Copy
(
stdErr
,
st
.
Memory
.
ReadMemoryRange
(
a1
,
a2
))
v0
=
a2
case
fdHintWrite
:
hint
,
_
:=
io
.
ReadAll
(
st
.
Memory
.
ReadMemoryRange
(
a1
,
a2
))
v0
=
a2
hintData
,
_
:=
io
.
ReadAll
(
st
.
Memory
.
ReadMemoryRange
(
a1
,
a2
))
st
.
LastHint
=
append
(
st
.
LastHint
,
hintData
...
)
for
len
(
st
.
LastHint
)
>=
4
{
// process while there is enough data to check if there are any hints
hintLen
:=
binary
.
BigEndian
.
Uint32
(
st
.
LastHint
[
:
4
])
if
hintLen
>=
uint32
(
len
(
st
.
LastHint
[
4
:
]))
{
hint
:=
st
.
LastHint
[
4
:
4
+
hintLen
]
// without the length prefix
st
.
LastHint
=
st
.
LastHint
[
4
+
hintLen
:
]
po
.
Hint
(
hint
)
}
else
{
break
// stop processing hints if there is incomplete data buffered
}
}
v0
=
a2
case
fdPreimageWrite
:
mem
:=
st
.
Memory
.
GetMemory
(
a1
&
0xFFffFFfc
)
key
:=
st
.
PreimageKey
...
...
@@ -181,6 +203,7 @@ func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, std
copy
(
key
[
32
-
a2
:
],
tmp
[
:
])
st
.
PreimageKey
=
key
st
.
PreimageOffset
=
0
fmt
.
Printf
(
"updating pre-image key: %s
\n
"
,
st
.
PreimageKey
)
v0
=
a2
default
:
v0
=
0xFFffFFff
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment