diff --git a/bindings/go/unicorn/context.go b/bindings/go/unicorn/context.go new file mode 100644 index 00000000..bf5ced9b --- /dev/null +++ b/bindings/go/unicorn/context.go @@ -0,0 +1,28 @@ +package unicorn + +import ( + "runtime" +) + +// #include +import "C" + +type Context **C.uc_context + +func (u *uc) ContextSave(reuse Context) (Context, error) { + ctx := reuse + if ctx == nil { + ctx = new(*C.uc_context) + } + if err := errReturn(C.uc_context_alloc(u.handle, ctx)); err != nil { + return nil, err + } + runtime.SetFinalizer(ctx, func(p Context) { C.uc_context_free(*p) }) + if err := errReturn(C.uc_context_save(u.handle, *ctx)); err != nil { + } + return ctx, nil +} + +func (u *uc) ContextRestore(ctx Context) error { + return errReturn(C.uc_context_restore(u.handle, *ctx)) +} diff --git a/bindings/go/unicorn/context_test.go b/bindings/go/unicorn/context_test.go new file mode 100644 index 00000000..3231ef43 --- /dev/null +++ b/bindings/go/unicorn/context_test.go @@ -0,0 +1,26 @@ +package unicorn + +import ( + "testing" +) + +func TestContext(t *testing.T) { + u, err := NewUnicorn(ARCH_X86, MODE_32) + if err != nil { + t.Fatal(err) + } + u.RegWrite(X86_REG_EBP, 100) + ctx, err := u.ContextSave(nil) + if err != nil { + t.Fatal(err) + } + u.RegWrite(X86_REG_EBP, 200) + err = u.ContextRestore(ctx) + if err != nil { + t.Fatal(err) + } + val, _ := u.RegRead(X86_REG_EBP) + if val != 100 { + t.Fatal("context restore failed") + } +} diff --git a/bindings/go/unicorn/unicorn.go b/bindings/go/unicorn/unicorn.go index 59ad50e5..58e28939 100644 --- a/bindings/go/unicorn/unicorn.go +++ b/bindings/go/unicorn/unicorn.go @@ -55,6 +55,9 @@ type Unicorn interface { HookDel(hook Hook) error Query(queryType int) (uint64, error) Close() error + + ContextSave(reuse Context) (Context, error) + ContextRestore(Context) error } type uc struct {