2012年8月10日 星期五

Hook CreateFile by pydbg


For malware analysis , file access is an important factor to understand what malware do. Therefore in this article, I write a small program that can hook windows createfile API.

TOOL
 I use pydbg to develop this program. pydbg is an subproject of paimei which is a well-known reverse engineering tool.
It is not easy to install pydbg. During installing pydbg, I have encountered following error, and there are some articles solve those problems.
1.      pydasm not found
        Because pydbg need a decompiler, so we need to install pydasm first. Pydasm source can be found here. https://code.google.com/p/libdasm/. Then remove pydasm.pyd in pydbg source.

2.      unable to find vcvarsall.bat
This is due to lower version of VS compiler. We can solve this problem by install higher version of VS or use mingw instead.
3.  gcc: error: unrecognized command line option '-mno-cygwin'
   Option '-mno-cygwin' has been removed in gcc options.So we just remove '-mno-cygwin' in ‘distutils\cygwinccompiler.py’


program review

Due to dynamic link of createfile API, we cannot resolve address of createfile at program start. Therefore we need to hook createfile API once kernel32.dll loaded.
We write a call back function load_dll () which is triggered when dll load. And we use dbg.set_callback(LOAD_DLL_DEBUG_EVENT, load_dll) to register callback of DLL loading. In function load_dll (), we should check if kernel32.dll was loaded and hook createfile API(CreateFileW) .

file_hook.py

from pydbg import *
from pydbg.defines import *

import utils
import sys
import os
from ctypes import *

is_hook = 0

def FileCreateHook( dbg, args ):
    buffer  = ""
    offset  = 0
    while 1:
        byte = dbg.read_process_memory( args[0] + offset, 2 )
        if not ( ord(byte[0])==0 and ord(byte[1])==0) :
            buffer  += byte
            offset  += 2
            continue
        else:
            break
    print unicode(buffer,"utf-16")
    return DBG_CONTINUE

########################################################################################################################
def load_dll (pydbg):
    last_dll = pydbg.system_dlls[-1]
    print "loading:%s into:%08x size:%d" % (last_dll.name, last_dll.base, last_dll.size)
    global is_hook
    if is_hook==0 :
        
        global hooks   
        hooks = utils.hook_container()
        hook_address  = pydbg.func_resolve_debuggee("kernel32.dll","CreateFileW")
        print hook_address
        if hook_address:
            res = hooks.add( pydbg, hook_address, 7, FileCreateHook, None)
            is_hook =1
            print res
            print "[*] CreateFileW hooked at: 0x%08x" % hook_address
        else:
            print "[*] Error: Couldn't resolve hook address."
    return DBG_CONTINUE

dbg = pydbg()
dbg.set_callback(LOAD_DLL_DEBUG_EVENT, load_dll)
dbg.load(sys.argv[1])

is_hook =0
hooks=None

dbg.debug_event_loop()


reference

1 則留言: