X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=Mate%2FX86TrapHandling.hs;h=493a3ceaf1b1a3a4a45c2d29bcacbeb6034a7a2e;hb=094e3cea9aa9d638b071fb52a12f04f6ddd80dc1;hp=f89e2b8f77493ac5b6d3df60b802aaac5688220f;hpb=3c1c1355bc77bf53846255a628416aa36a730e23;p=mate.git diff --git a/Mate/X86TrapHandling.hs b/Mate/X86TrapHandling.hs index f89e2b8..493a3ce 100644 --- a/Mate/X86TrapHandling.hs +++ b/Mate/X86TrapHandling.hs @@ -8,6 +8,7 @@ module Mate.X86TrapHandling ( ) where import qualified Data.Map as M +import qualified Data.ByteString.Lazy as B import Foreign import Foreign.C.Types @@ -24,30 +25,41 @@ data TrapType = | StaticFieldAccess | VirtualMethodCall Bool | InterfaceMethodCall Bool + | InstanceOfMiss B.ByteString + | NewObjectTrap B.ByteString + | NoKnownTrap String getTrapType :: TrapMap -> CPtrdiff -> CPtrdiff -> TrapType getTrapType tmap signal_from from2 = case M.lookup (fromIntegral signal_from) tmap of (Just (StaticMethod _)) -> StaticMethodCall (Just (StaticField _)) -> StaticFieldAccess - (Just _) -> error "getTrapMap: doesn't happen" + (Just (InstanceOf cn)) -> InstanceOfMiss cn + (Just (NewObject cn)) -> NewObjectTrap cn + (Just _) -> NoKnownTrap "getTrapMap: doesn't happen" -- maybe we've a hit on the second `from' value Nothing -> case M.lookup (fromIntegral from2) tmap of (Just (VirtualMethod imm8 _)) -> VirtualMethodCall imm8 (Just (InterfaceMethod imm8 _)) -> InterfaceMethodCall imm8 - (Just _) -> error "getTrapType: abort #1 :-(" - Nothing -> error $ "getTrapType: abort #2 :-(" ++ show signal_from ++ ", " ++ show from2 ++ ", " ++ show tmap + (Just _) -> NoKnownTrap "getTrapType: abort #1 :-(" + Nothing -> NoKnownTrap $ "getTrapType: abort #2 :-(" ++ show signal_from ++ ", " ++ show from2 ++ ", " ++ show tmap -foreign export ccall mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff -mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff -mateHandler eip eax ebx esp = do +foreign export ccall mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff +mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff +mateHandler eip eax ebx esp esi = do callerAddr <- callerAddrFromStack esp tmap <- getTrapMap case getTrapType tmap eip callerAddr of StaticMethodCall -> staticCallHandler eip StaticFieldAccess -> staticFieldHandler eip + (InstanceOfMiss cn) -> instanceOfMissHandler eip cn + (NewObjectTrap cn) -> newObjectHandler eip cn VirtualMethodCall imm8 -> invokeHandler eax eax esp imm8 InterfaceMethodCall imm8 -> invokeHandler eax ebx esp imm8 + NoKnownTrap err -> + case esi of + 0x13371234 -> return (-1) + _ -> error err staticCallHandler :: CPtrdiff -> IO CPtrdiff staticCallHandler eip = do @@ -81,6 +93,37 @@ staticFieldHandler eip = do return eip else error "staticFieldHandler: something is wrong here. abort.\n" +instanceOfMissHandler :: CPtrdiff -> B.ByteString -> IO CPtrdiff +instanceOfMissHandler eip classname = do + -- first byte is going to be the opcode + let insn_ptr = intPtrToPtr (fromIntegral eip) :: Ptr CUChar + -- the next four bytes are the immediate + let imm_ptr = intPtrToPtr (fromIntegral (eip + 1)) :: Ptr CPtrdiff + checkMe <- peek imm_ptr + if checkMe == 0x909090ff then -- safety check... + do + mtable <- getMethodTable classname + poke imm_ptr (fromIntegral mtable) + poke insn_ptr 0xba -- `mov edx' opcode + return eip + else error "instanceOfMissHandler: something is wrong here. abort.\n" + +newObjectHandler :: CPtrdiff -> B.ByteString -> IO CPtrdiff +newObjectHandler eip classname = do + let push_insn_ptr = intPtrToPtr (fromIntegral eip) :: Ptr CUChar + let push_imm_ptr = intPtrToPtr (fromIntegral (eip + 1)) :: Ptr CPtrdiff + let mov_imm_ptr = intPtrToPtr (fromIntegral (eip + 16)) :: Ptr CPtrdiff + checkMe <- peek mov_imm_ptr + if checkMe == 0x13371337 + then do + objsize <- getObjectSize classname + mtable <- getMethodTable classname + poke push_insn_ptr 0x68 -- push_imm insn + poke push_imm_ptr (fromIntegral objsize) + poke mov_imm_ptr (fromIntegral mtable) + return eip + else error "newObjectHandler: something is wrong here. abort.\n" + invokeHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> Bool -> IO CPtrdiff invokeHandler method_table table2patch esp imm8 = do -- table2patch: note, that can be a method-table or a interface-table