| VirtualMethodCall Bool
| InterfaceMethodCall Bool
| InstanceOfMiss B.ByteString
+ | NewObjectTrap B.ByteString
+ | NoKnownTrap String
getTrapType :: TrapMap -> CPtrdiff -> CPtrdiff -> TrapType
getTrapType tmap signal_from from2 =
(Just (StaticMethod _)) -> StaticMethodCall
(Just (StaticField _)) -> StaticFieldAccess
(Just (InstanceOf cn)) -> InstanceOfMiss cn
- (Just _) -> error "getTrapMap: doesn't happen"
+ (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
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