diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2015, Junji Hashimoto
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Junji Hashimoto nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,137 @@
+{-#LANGUAGE BangPatterns#-}
+
+import Numeric
+import Data.Word
+import Data.List
+import Data.Char (ord,isSpace)
+import Data.Bits
+import qualified Control.Exception as E
+import Control.Applicative
+import Control.Monad
+import System.Posix.Files
+import System.Posix.Types
+import System.Directory
+import System.FilePath
+import System.Environment
+import System.Exit
+import System.IO
+
+-- copy from https://github.com/haskell/cabal/blob/master/cabal-install/Distribution/Client/Sandbox.hs
+sandboxBuildDir :: FilePath -> FilePath
+sandboxBuildDir sandboxDir = "dist/dist-sandbox-" ++ showHex sandboxDirHash ""
+  where
+    sandboxDirHash = jenkins sandboxDir
+
+    -- See http://en.wikipedia.org/wiki/Jenkins_hash_function
+    jenkins :: String -> Word32
+    jenkins str = loop_finish $ foldl' loop 0 str
+      where
+        loop :: Word32 -> Char -> Word32
+        loop hash key_i' = hash'''
+          where
+            key_i   = toEnum . ord $ key_i'
+            hash'   = hash + key_i
+            hash''  = hash' + (shiftL hash' 10)
+            hash''' = hash'' `xor` (shiftR hash'' 6)
+
+        loop_finish :: Word32 -> Word32
+        loop_finish hash = hash'''
+          where
+            hash'   = hash + (shiftL hash 3)
+            hash''  = hash' `xor` (shiftR hash' 11)
+            hash''' = hash'' + (shiftL hash'' 15)
+
+
+
+-- copy from https://hackage.haskell.org/package/cab-0.2.14/docs/src/Distribution-Cab-Sandbox.html#getSandbox
+
+configFile :: String
+configFile = "cabal.sandbox.config"
+
+pkgDbKey :: String
+pkgDbKey = "package-db:"
+
+pkgDbKeyLen :: Int
+pkgDbKeyLen = length pkgDbKey
+
+-- | Find a sandbox config file by tracing ancestor directories,
+--   parse it and return the package db path
+getSandbox :: IO (Maybe FilePath)
+getSandbox = (Just <$> getPkgDb) `E.catch` handler
+  where
+    getPkgDb = getCurrentDirectory >>= getSandboxConfigFile >>= getPackageDbDir
+    handler :: E.SomeException -> IO (Maybe String)
+    handler _ = return Nothing
+
+-- | Find a sandbox config file by tracing ancestor directories.
+--   Exception is thrown if not found
+getSandboxConfigFile :: FilePath -> IO FilePath
+getSandboxConfigFile dir = do
+    let cfile = dir </> configFile
+    exist <- doesFileExist cfile
+    if exist then
+        return cfile
+      else do
+        let dir' = takeDirectory dir
+        if dir == dir' then
+            E.throwIO $ userError "sandbox config file not found"
+          else
+            getSandboxConfigFile dir'
+
+-- | Extract a package db directory from the sandbox config file.
+--   Exception is thrown if the sandbox config file is broken.
+getPackageDbDir :: FilePath -> IO FilePath
+getPackageDbDir sconf = do
+    -- Be strict to ensure that an error can be caught.
+    !path <- extractValue . parse <$> readFile sconf
+    return path
+  where
+    parse = head . filter ("package-db:" `isPrefixOf`) . lines
+    extractValue = fst . break isSpace . dropWhile isSpace . drop pkgDbKeyLen
+
+type ProjectRootDir = FilePath
+type BinaryName = FilePath
+
+
+getTimeStamp :: FilePath -> IO (Either E.SomeException EpochTime)
+getTimeStamp path = do
+  stat <- E.try $ getFileStatus path
+  return $ fmap modificationTime stat
+
+searchBinary :: ProjectRootDir -> BinaryName -> IO FilePath
+searchBinary rdir name = do
+  timeT <- getTimeStamp distTBin
+  msdir <- getSandbox
+  case msdir of
+    Just sdir -> do
+      let distS = sandboxBuildDir $ takeDirectory sdir
+      let distSBin = rdir </> distS </> "build" </> name </> name
+      timeS <- getTimeStamp distSBin
+      case (timeS,timeT) of
+        (Right s,Right t) -> return $ if t <= s then distSBin else distTBin
+        (Right _,Left _) -> return distSBin
+        (Left _,Right _) -> return distTBin
+        _ -> errorHandler [distSBin,distTBin]
+    Nothing -> do
+      case timeT of
+        (Right _) -> return distTBin
+        _ -> errorHandler [distTBin]
+  where
+    distTBin = rdir </> "dist" </> "build" </> name </> name
+    errorHandler paths = do
+      forM_ paths $ \path -> do
+        hPutStrLn stderr $ "Check:" ++ path
+      hPutStrLn stderr $ "Can not find exe-file:" ++ name
+      exitWith $ ExitFailure 2
+      
+main :: IO ()
+main = do
+  args <- getArgs
+  case args of
+    (dir:binName:[]) -> do
+      binPath <- searchBinary dir binName
+      putStrLn binPath
+      exitWith $ ExitSuccess
+    _ -> do
+      hPutStrLn stderr "Usage: cabal-test-bin \"project's root directory\" \"executable-program-name\""
+      exitWith $ ExitFailure 1
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/cabal-test-bin.cabal b/cabal-test-bin.cabal
new file mode 100644
--- /dev/null
+++ b/cabal-test-bin.cabal
@@ -0,0 +1,37 @@
+-- Initial cabal-temp-bin.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                cabal-test-bin
+version:             0.1.0
+synopsis:            A program for finding temporary build file during cabal-test.
+description:         cabal-test-bin finds exe-file for "cabal install --enable-tests --run-tests" or "cabal test".
+                     When a project uses cabal-sandbox, 
+                     cabal-test-bin checks both <project root>/dist/dist-sandbox-<hash>/build/<exe-file>/<exe-file> 
+                     and <project root>/dist/build/<exe-file>/<exe-file>.
+                     
+license:             BSD3
+license-file:        LICENSE
+author:              Junji Hashimoto
+maintainer:          junji.hashimoto@gmail.com
+-- copyright:           
+category:            Testing
+build-type:          Simple
+-- extra-source-files:  
+cabal-version:       >=1.10
+
+bug-reports:         https://github.com/junjihashimoto/cabal-test-bin/issues
+
+source-repository head
+  type:           git
+  location:       https://github.com/junjihashimoto/cabal-test-bin.git
+
+executable cabal-test-bin
+  main-is:             Main.hs
+  -- other-modules:       
+  -- other-extensions:    
+  build-depends:       base >=4.7 && <4.8
+                     , directory
+                     , filepath
+                     , unix
+  -- hs-source-dirs:      
+  default-language:    Haskell2010
