1#!/usr/bin/env ruby 2# Sample code for SPARC of Unicorn. Nguyen Anh Quynh <aquynh@gmail.com> 3# Ruby sample ported by Sascha Schirra <sashs82@gmail.com> 4require 'unicorn_engine' 5require 'unicorn_engine/sparc_const' 6 7include UnicornEngine 8 9# code to be emulated 10SPARC_CODE = "\x86\x00\x40\x02" # add %g1, %g2, %g3; 11# memory address where emulation starts 12ADDRESS = 0x10000 13 14 15# callback for tracing basic blocks 16$hook_block = Proc.new do |uc, address, size, user_data| 17 puts(">>> Tracing basic block at 0x%x, block size = 0x%x" % [address, size]) 18end 19 20 21# callback for tracing instructions 22$hook_code = Proc.new do |uc, address, size, user_data| 23 puts(">>> Tracing instruction at 0x%x, instruction size = %u" % [address, size]) 24end 25 26# Test SPARC 27def test_sparc() 28 puts("Emulate SPARC code") 29 begin 30 # Initialize emulator in SPARC EB mode 31 mu = Uc.new UC_ARCH_SPARC, UC_MODE_SPARC32|UC_MODE_BIG_ENDIAN 32 33 # map 2MB memory for this emulation 34 mu.mem_map(ADDRESS, 2 * 1024 * 1024) 35 36 # write machine code to be emulated to memory 37 mu.mem_write(ADDRESS, SPARC_CODE) 38 39 # initialize machine registers 40 mu.reg_write(UC_SPARC_REG_G1, 0x1230) 41 mu.reg_write(UC_SPARC_REG_G2, 0x6789) 42 mu.reg_write(UC_SPARC_REG_G3, 0x5555) 43 44 # tracing all basic blocks with customized callback 45 mu.hook_add(UC_HOOK_BLOCK, $hook_block) 46 47 # tracing all instructions with customized callback 48 mu.hook_add(UC_HOOK_CODE, $hook_code) 49 50 # emulate machine code in infinite time 51 mu.emu_start(ADDRESS, ADDRESS + SPARC_CODE.bytesize) 52 53 # now puts out some registers 54 puts(">>> Emulation done. Below is the CPU context") 55 56 g3 = mu.reg_read(UC_SPARC_REG_G3) 57 puts(">>> G3 = 0x%x" %g3) 58 59 rescue UcError => e 60 puts("ERROR: %s" % e) 61 end 62end 63 64 65test_sparc() 66