반응형
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
86
87
88
import sys, struct
import pefile
from pydbg import *
from pydbg.defines import *
 
def log(str):
    global fpp
    print str
    fpp.write(str)
    fpp.write("\n")
    return 
    
def addr_handler(dbg):               
    global func_name
    ret_addr = dbg.context.Eax
    if ret_addr:
        dict[ret_addr] = func_name
        dbg.bp_set(ret_addr, handler=generic)
    return DBG_CONTINUE
 
def generic(dbg):
    global func_name
    eip = dbg.context.Eip
    esp = dbg.context.Esp
    paddr = dbg.read_process_memory(esp, 4)
    addr = struct.unpack("L", paddr)[0]
    addr = int(addr)
    if addr < 70000000:
        log("RETURN ADDRESS: 0x%.8x\tCALL: %s" % (addr, dict[eip])) 
    if dict[eip] == "KERNEL32!GetProcAddress" or dict[eip] == "GetProcAddress"
        try:
            esp = dbg.context.Esp
            addr = esp + 0x8
            size = 50
            pstring = dbg.read_process_memory(addr, 4)
            pstring = struct.unpack("L", pstring)[0]
            pstring = int(pstring)
            if pstring > 500:
                data = dbg.read_process_memory(pstring, size)
                func_name = dbg.get_ascii_string(data)
            else:
                func_name = "Ordinal entry"
            paddr = dbg.read_process_memory(esp, 4)
            addr = struct.unpack("L", paddr)[0]
            addr = int(addr)
            dbg.bp_set(addr, handler=addr_handler)
        except:
            pass
    return DBG_CONTINUE
 
 
def entryhandler(dbg):
    getaddr = dbg.func_resolve("kernel32.dll""GetProcAddress")  
    dict[getaddr] = "kernel32!GetProcAddress"
    dbg.bp_set(getaddr, handler=generic)
    for entry in pe.DIRECTORY_ENTRY_IMPORT:
        DllName = entry.dll
        for imp in entry.imports:                  
            api = imp.name
            address = dbg.func_resolve(DllName, api)
            if address:
                try:
                    Dllname = DllName.split(".")[0]
                    dll_func = Dllname + "!" + api
                    dict[address] = dll_func
                    dbg.bp_set(address, handler=generic)
                except:
                    pass
    
    return DBG_CONTINUE        
 
def main():
    global pe, DllName, func_name, fpp
    global dict
    dict = {}
    file = sys.argv[1]
    fpp = open("API Calls List.txt"'a')
    pe = pefile.PE(file)
    dbg = pydbg()
    dbg.load(file)
    entrypoint = pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.AddressOfEntryPoint
    dbg.bp_set(entrypoint, handler=entryhandler)
    dbg.run()
    log('\n'
    fpp.close()
 
if __name__ == '__main__':
    main()
cs


출처 : http://securityxploded.com/api-call-tracing-with-pefile-pydbg-and-idapython.php

exe 파일등의 PE file을 pydbg() 기능을 통해 API를 분석해오는 과정이다.

정확히 이해는 못했지만 IAT 테이블에 저장되어있는 API들에 hooking을 하여 실행될 때 사용되는 API들을 출력해주는 함수라고 알고 있다.

정확한 이해를 하기 위해서는 출처에 들어가서 확인해 보는 편이 좋을 듯 하다.


명령어 입력으로는 '>> python   파이썬파일.py    대상 파일.exe'   형식이다.



반응형

+ Recent posts