Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
16d8d95
update readme
wtdcode Apr 10, 2025
b94ff99
add UC_CTL go bindings
Jun 21, 2025
2da916c
glib_compat/glib_compact: Clear the buffer in g_hash_table_resize (#2…
MarsDoge Jul 22, 2025
052f33e
Enable install for rust bindings (#2224)
wtdcode Aug 4, 2025
cdf38b9
Remove ninja installation from macos runners (#2225)
scribam Aug 6, 2025
8803d46
Fix `read_sprr_perm` for Apple real CPUs and GitHub Actions; enable A…
patryk4815 Aug 8, 2025
2e76a45
Fix cmake deprecation warning (#2226)
scribam Aug 8, 2025
e9e2d3f
Add support for clangarm64 (#2228)
scribam Aug 16, 2025
869969f
Revert "glib_compat/glib_compact: Clear the buffer in g_hash_table_re…
wtdcode Aug 30, 2025
3132d29
Python bindings: Use ABI3 wheels (#2223)
Antelox Sep 9, 2025
8f29cc9
concurrent control (#2235)
wtdcode Sep 9, 2025
667febe
Sync FAQ
wtdcode Sep 9, 2025
bd8dd78
bump 2.1.4
wtdcode Sep 9, 2025
72a37ac
bump consts
wtdcode Sep 9, 2025
d515023
Update ChangeLog
wtdcode Sep 9, 2025
c0915a7
fix rust bindings
wtdcode Sep 9, 2025
efb1354
Also add bindings.rs wrapper
wtdcode Sep 9, 2025
231df7d
update changelog
wtdcode Sep 9, 2025
12d7a52
refactor rust packages
wtdcode Sep 9, 2025
d51e192
refactor rust directories
wtdcode Sep 9, 2025
1017230
add a comment
wtdcode Sep 9, 2025
d891611
update release ci
wtdcode Sep 9, 2025
1da40fe
Fix incorrect folder name under release
wtdcode Sep 9, 2025
5cc267d
implement glib_random_bytes for msvc
wtdcode Sep 9, 2025
2a2bcc8
fix again
wtdcode Sep 9, 2025
b1893ab
add UC_CTL go bindings
Sep 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Contact
[Contact us](http://www.unicorn-engine.org/contact/) via mailing list, email or twitter for any questions.


Join [our group](https://t.me/+lnNl0fPpyCYzZmVh) for instant feedback.

Contribute
----------

Expand All @@ -55,5 +57,4 @@ We also maintain a list of more challenged problems in [milestones](https://gith

Please send pull request to our [dev branch](https://github.com/unicorn-engine/unicorn/tree/dev).

[CREDITS.TXT](CREDITS.TXT) records important contributors of our project.

[CREDITS.TXT](CREDITS.TXT) records important contributors of our project.
78 changes: 77 additions & 1 deletion bindings/go/unicorn/uc.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,82 @@ uc_err uc_reg_write_batch_helper(uc_engine *handle, int *regs, uint64_t *val_in,
return ret;
}

uc_err uc_ctl_get_mode_helper(uc_engine *handle, int *mode) {
return uc_ctl(handle, UC_CTL_READ(UC_CTL_UC_MODE, 1), (mode));
}

uc_err uc_ctl_get_page_size_helper(uc_engine *handle, uint32_t *ptr) {
return uc_ctl(handle, UC_CTL_READ(UC_CTL_UC_PAGE_SIZE, 1), (ptr));
}

uc_err uc_ctl_set_page_size_helper(uc_engine *handle, uint32_t page_size) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_UC_PAGE_SIZE, 1), (page_size));
}

uc_err uc_ctl_get_arch_helper(uc_engine *handle, int *arch) {
return uc_ctl(handle, UC_CTL_READ(UC_CTL_UC_ARCH, 1), (arch));
}

uc_err uc_ctl_get_timeout_helper(uc_engine *handle, uint64_t *ptr) {
return uc_ctl(handle, UC_CTL_READ(UC_CTL_UC_TIMEOUT, 1), (ptr));
}

uc_err uc_ctl_exits_enable_helper(uc_engine *handle) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_UC_USE_EXITS, 1), 1);
}

uc_err uc_ctl_exits_disable_helper(uc_engine *handle) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_UC_USE_EXITS, 1), 0);
}

uc_err uc_ctl_get_exits_cnt_helper(uc_engine *handle, size_t *ptr) {
return uc_ctl(handle, UC_CTL_READ(UC_CTL_UC_EXITS_CNT, 1), (ptr));
}

uc_err uc_ctl_get_exits_helper(uc_engine *handle, uint64_t *exits, size_t len) {
return uc_ctl(handle, UC_CTL_READ(UC_CTL_UC_EXITS, 2), (exits), (len));
}

uc_err uc_ctl_set_exits_helper(uc_engine *handle, uint64_t *exits, size_t len) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_UC_EXITS, 2), (exits), (len));
}

uc_err uc_ctl_get_cpu_model_helper(uc_engine *handle, int *model) {
return uc_ctl(handle, UC_CTL_READ(UC_CTL_CPU_MODEL, 1), (model));
}

uc_err uc_ctl_set_cpu_model_helper(uc_engine *handle, int model) {
return uc_ctl_set_cpu_model(handle, model);
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_CPU_MODEL, 1), (model));
}

uc_err uc_ctl_remove_cache_helper(uc_engine *handle, uint64_t address, uint64_t end) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_TB_REMOVE_CACHE, 2), (address), (end));
}

uc_err uc_ctl_request_cache_helper(uc_engine *handle, uint64_t address, uc_tb *tb) {
return uc_ctl(handle, UC_CTL_READ_WRITE(UC_CTL_TB_REQUEST_CACHE, 2), (address), (tb));
}

uc_err uc_ctl_flush_tb_helper(uc_engine *handle) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_TB_FLUSH, 0));
}

uc_err uc_ctl_flush_tlb_helper(uc_engine *handle) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_TLB_FLUSH, 0));
}

uc_err uc_ctl_tlb_mode_helper(uc_engine *handle, int mode) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_TLB_TYPE, 1), (mode));
}

uc_err uc_ctl_get_tcg_buffer_size_helper(uc_engine *handle, uint32_t *size) {
return uc_ctl(handle, UC_CTL_READ(UC_CTL_TCG_BUFFER_SIZE, 1), (size));
}

uc_err uc_ctl_set_tcg_buffer_size_helper(uc_engine *handle, uint32_t size) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_TCG_BUFFER_SIZE, 1), (size));
}

uc_err uc_ctl_context_mode_helper(uc_engine *handle, int mode) {
return uc_ctl(handle, UC_CTL_WRITE(UC_CTL_CONTEXT_MODE, 1), (mode));
}
19 changes: 19 additions & 0 deletions bindings/go/unicorn/uc.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
uc_err uc_reg_read_batch_helper(uc_engine *handle, int *regs, uint64_t *val_out, int count);
uc_err uc_reg_write_batch_helper(uc_engine *handle, int *regs, uint64_t *val_in, int count);
uc_err uc_ctl_get_mode_helper(uc_engine *handle, int *mode);
uc_err uc_ctl_get_page_size_helper(uc_engine *handle, uint32_t *ptr);
uc_err uc_ctl_set_page_size_helper(uc_engine *handle, uint32_t page_size);
uc_err uc_ctl_get_arch_helper(uc_engine *handle, int *arch);
uc_err uc_ctl_get_timeout_helper(uc_engine *handle, uint64_t *ptr);
uc_err uc_ctl_exits_enable_helper(uc_engine *handle);
uc_err uc_ctl_exits_disable_helper(uc_engine *handle);
uc_err uc_ctl_get_exits_cnt_helper(uc_engine *handle, size_t *ptr);
uc_err uc_ctl_get_exits_helper(uc_engine *handle, uint64_t *exits, size_t len);
uc_err uc_ctl_set_exits_helper(uc_engine *handle, uint64_t *exits, size_t len);
uc_err uc_ctl_get_cpu_model_helper(uc_engine *handle, int *model);
uc_err uc_ctl_set_cpu_model_helper(uc_engine *handle, int model);
uc_err uc_ctl_remove_cache_helper(uc_engine *handle, uint64_t address, uint64_t end);
uc_err uc_ctl_request_cache_helper(uc_engine *handle, uint64_t address, uc_tb *tb);
uc_err uc_ctl_flush_tb_helper(uc_engine *handle);
uc_err uc_ctl_flush_tlb_helper(uc_engine *handle);
uc_err uc_ctl_tlb_mode_helper(uc_engine *handle, int mode);
uc_err uc_ctl_get_tcg_buffer_size_helper(uc_engine *handle, uint32_t *size);
uc_err uc_ctl_set_tcg_buffer_size_helper(uc_engine *handle, uint32_t size);
uc_err uc_ctl_context_mode_helper(uc_engine *handle, int mode);
175 changes: 174 additions & 1 deletion bindings/go/unicorn/unicorn.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,27 @@ type Unicorn interface {
Handle() *C.uc_engine
RegWriteX86Msr(reg uint64, val uint64) error
RegReadX86Msr(reg uint64) (uint64, error)

GetMode() (int, error)
GetPageSize() (uint32, error)
SetPageSize(pageSize uint32) error
GetArch() (int, error)
GetTimeout() (uint64, error)
ExitsEnable() error
ExitsDisable() error
GetExitsCnt() (uint32, error)
GetExits() ([]uint64, error)
SetExits(exits []uint64) error
GetCPUModel() (int, error)
SetCPUModel(model int) error
RemoveCache(address, end uint64) error
RequestCache(address uint64) (UcTb, error)
FlushTB() error
FlushTLB() error
TLBMode(mode int) error
GetTCGBufferSize() (uint32, error)
SetTCGBufferSize(size uint32) error
ContextMode(mode int) error
}

type uc struct {
Expand All @@ -72,6 +92,12 @@ type UcOptions struct {
Timeout, Count uint64
}

type UcTb struct {
Pc uint64
Icount uint16
Size uint16
}

func Version() (int, int) {
var major, minor C.uint
C.uc_version(&major, &minor)
Expand Down Expand Up @@ -107,7 +133,13 @@ func (u *uc) Close() (err error) {
}

func (u *uc) StartWithOptions(begin, until uint64, options *UcOptions) error {
ucerr := C.uc_emu_start(u.handle, C.uint64_t(begin), C.uint64_t(until), C.uint64_t(options.Timeout), C.size_t(options.Count))
ucerr := C.uc_emu_start(
u.handle,
C.uint64_t(begin),
C.uint64_t(until),
C.uint64_t(options.Timeout),
C.size_t(options.Count),
)
return errReturn(ucerr)
}

Expand Down Expand Up @@ -187,14 +219,26 @@ func (u *uc) MemWrite(addr uint64, data []byte) error {
if len(data) == 0 {
return nil
}
<<<<<<< HEAD
return errReturn(C.uc_mem_write(u.handle, C.uint64_t(addr), unsafe.Pointer(&data[0]), C.uint64_t(len(data))))
=======
return errReturn(
C.uc_mem_write(u.handle, C.uint64_t(addr), unsafe.Pointer(&data[0]), C.size_t(len(data))),
)
>>>>>>> 11cedbec (add UC_CTL go bindings)
}

func (u *uc) MemReadInto(dst []byte, addr uint64) error {
if len(dst) == 0 {
return nil
}
<<<<<<< HEAD
return errReturn(C.uc_mem_read(u.handle, C.uint64_t(addr), unsafe.Pointer(&dst[0]), C.uint64_t(len(dst))))
=======
return errReturn(
C.uc_mem_read(u.handle, C.uint64_t(addr), unsafe.Pointer(&dst[0]), C.size_t(len(dst))),
)
>>>>>>> 11cedbec (add UC_CTL go bindings)
}

func (u *uc) MemRead(addr, size uint64) ([]byte, error) {
Expand All @@ -211,7 +255,13 @@ func (u *uc) MemMap(addr, size uint64) error {
}

func (u *uc) MemMapPtr(addr, size uint64, prot int, ptr unsafe.Pointer) error {
<<<<<<< HEAD
return errReturn(C.uc_mem_map_ptr(u.handle, C.uint64_t(addr), C.uint64_t(size), C.uint32_t(prot), ptr))
=======
return errReturn(
C.uc_mem_map_ptr(u.handle, C.uint64_t(addr), C.size_t(size), C.uint32_t(prot), ptr),
)
>>>>>>> 11cedbec (add UC_CTL go bindings)
}

func (u *uc) MemProtect(addr, size uint64, prot int) error {
Expand All @@ -232,7 +282,130 @@ func (u *uc) Handle() *C.uc_engine {
return u.handle
}

func (u *uc) GetMode() (int, error) {
var mode C.int
ucerr := C.uc_ctl_get_mode_helper(u.handle, &mode)
return int(mode), errReturn(ucerr)
}

func (u *uc) GetPageSize() (uint32, error) {
var ptr C.uint32_t
ucerr := C.uc_ctl_get_page_size_helper(u.handle, &ptr)
return uint32(ptr), errReturn(ucerr)
}

func (u *uc) SetPageSize(pageSize uint32) error {
ucerr := C.uc_ctl_set_page_size_helper(u.handle, C.uint32_t(pageSize))
return errReturn(ucerr)
}

func (u *uc) GetArch() (int, error) {
var arch C.int
ucerr := C.uc_ctl_get_arch_helper(u.handle, &arch)
return int(arch), errReturn(ucerr)
}

func (u *uc) GetTimeout() (uint64, error) {
var timeout C.uint64_t
ucerr := C.uc_ctl_get_timeout_helper(u.handle, &timeout)
return uint64(timeout), errReturn(ucerr)
}

func (u *uc) ExitsEnable() error {
return errReturn(C.uc_ctl_exits_enable_helper(u.handle))
}

func (u *uc) ExitsDisable() error {
return errReturn(C.uc_ctl_exits_disable_helper(u.handle))
}

func (u *uc) GetExitsCnt() (uint32, error) {
var count C.size_t
ucerr := C.uc_ctl_get_timeout_helper(u.handle, &count)
return uint32(count), errReturn(ucerr)
}

func (u *uc) GetExits() ([]uint64, error) {
count, err := u.GetExitsCnt()
if err != nil {
return nil, err
}
exits := make([]C.uint64_t, count)
ucerr := C.uc_ctl_get_exits_helper(u.handle, &exits[0], C.size_t(count))

res := make([]uint64, count)
for i := 0; i < int(count); i++ {
res[i] = uint64(exits[i])
}
return res, errReturn(ucerr)
}

func (u *uc) SetExits(exits []uint64) error {
cExits := make([]C.uint64_t, len(exits))
for i := 0; i < len(exits); i++ {
cExits[i] = C.uint64_t(exits[i])
}
ucerr := C.uc_ctl_set_exits_helper(u.handle, &cExits[0], C.size_t(len(exits)))
return errReturn(ucerr)
}

func (u *uc) GetCPUModel() (int, error) {
var model C.int
ucerr := C.uc_ctl_get_cpu_model_helper(u.handle, &model)
return int(model), errReturn(ucerr)
}

func (u *uc) SetCPUModel(model int) error {
ucerr := C.uc_ctl_set_cpu_model_helper(u.handle, C.int(model))
return errReturn(ucerr)
}

func (u *uc) RemoveCache(address, end uint64) error {
ucerr := C.uc_ctl_remove_cache_helper(u.handle, C.uint64_t(address), C.uint64_t(end))
return errReturn(ucerr)
}

func (u *uc) RequestCache(address uint64) (UcTb, error) {
var tb C.uc_tb
ucerr := C.uc_ctl_request_cache_helper(u.handle, C.uint64_t(address), &tb)
err := errReturn(ucerr)
if err != nil {
return UcTb{}, err
}
return UcTb{
Pc: uint64(tb.pc),
Icount: uint16(tb.icount),
Size: uint16(tb.size),
}, nil
}

func (u *uc) FlushTB() error {
ucerr := C.uc_ctl_flush_tb_helper(u.handle)
return errReturn(ucerr)
}

func (u *uc) FlushTLB() error {
ucerr := C.uc_ctl_flush_tlb_helper(u.handle)
return errReturn(ucerr)
}

func (u *uc) TLBMode(mode int) error {
ucerr := C.uc_ctl_tlb_mode_helper(u.handle, C.int(mode))
return errReturn(ucerr)
}

func (u *uc) GetTCGBufferSize() (uint32, error) {
var size C.uint32_t
ucerr := C.uc_ctl_get_tcg_buffer_size_helper(u.handle, &size)
return uint32(size), errReturn(ucerr)
}

func (u *uc) SetTCGBufferSize(size uint32) error {
ucerr := C.uc_ctl_set_tcg_buffer_size_helper(u.handle, C.uint32_t(size))
return errReturn(ucerr)
}

func (u *uc) ContextMode(mode int) error {
ucerr := C.uc_ctl_context_mode_helper(u.handle, C.int(mode))
return errReturn(ucerr)
}