1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
-- Sample code to demonstrate how to emulate Sparc code
import Unicorn
import Unicorn.Hook
import qualified Unicorn.CPU.Sparc as Sparc
import qualified Data.ByteString as BS
import Data.Word
import qualified Numeric as N (showHex)
-- Code to be emulated
--
-- add %g1, %g2, %g3
sparcCode :: BS.ByteString
sparcCode = BS.pack [0x86, 0x00, 0x40, 0x02]
-- Memory address where emulation starts
address :: Word64
address = 0x10000
-- Pretty-print integral as hex
showHex :: (Integral a, Show a) => a -> String
showHex =
flip N.showHex ""
-- Calculate code length
codeLength :: Num a => BS.ByteString -> a
codeLength =
fromIntegral . BS.length
hookBlock :: BlockHook ()
hookBlock _ addr size _ =
putStrLn $ ">>> Tracing basic block at 0x" ++ showHex addr ++
", block size = 0x" ++ (maybe "0" showHex size)
hookCode :: CodeHook ()
hookCode _ addr size _ =
putStrLn $ ">>> Tracing instruction at 0x" ++ showHex addr ++
", instruction size = 0x" ++ (maybe "0" showHex size)
testSparc :: IO ()
testSparc = do
putStrLn "Emulate SPARC code"
result <- runEmulator $ do
-- Initialize emulator in Sparc mode
uc <- open ArchSparc [ModeSparc32, ModeBigEndian]
-- Map 2MB memory for this emulation
memMap uc address (2 * 1024 * 1024) [ProtAll]
-- Write machine code to be emulated to memory
memWrite uc address sparcCode
-- Initialize machine registers
regWrite uc Sparc.G1 0x1230
regWrite uc Sparc.G2 0x6789
regWrite uc Sparc.G3 0x5555
-- Tracing all basic blocks with customized callback
blockHookAdd uc hookBlock () 1 0
-- Tracing all instructions with customized callback
codeHookAdd uc hookCode () 1 0
-- Emulate machine code in infinite time (last param = Nothing), or
-- when finishing all the code
let codeLen = codeLength sparcCode
start uc address (address + codeLen) Nothing Nothing
-- Return results
g3 <- regRead uc Sparc.G3
return g3
case result of
Right g3 -> do
-- Now print out some registers
putStrLn ">>> Emulation done. Below is the CPU context"
putStrLn $ ">>> G3 = 0x" ++ showHex g3
Left err -> putStrLn $ "Failed with error: " ++ show err ++ " (" ++
strerror err ++ ")"
main :: IO ()
main =
testSparc
|