├── README.md └── ida2neo.py /README.md: -------------------------------------------------------------------------------- 1 | # ida2neo 2 | -------------------------------------------------------------------------------- /ida2neo.py: -------------------------------------------------------------------------------- 1 | ''' 2 | _ _ ____ 3 | (_) __| | __ _|___ \ _ __ ___ ___ 4 | | |/ _` |/ _` | __) | '_ \ / _ \/ _ \ 5 | | | (_| | (_| |/ __/| | | | __/ (_) | 6 | |_|\__,_|\__,_|_____|_| |_|\___|\___/ 7 | 8 | vectra networks 9 | http://www.vectranetworks.com 10 | Export IDB callgraph to Neo4j for maximum query excellence 11 | ''' 12 | 13 | import idaapi 14 | import idautils 15 | import json 16 | import urllib2 17 | 18 | ''' 19 | Cypher Queries 20 | 21 | Regex match 22 | Match (n) where n.name =~ '.*memmove.*' RETURN n 23 | 24 | Find one shortest path from _DriverEntry to _McGenControlCallbackV2 25 | MATCH (q:Function) WHERE q.name = '_DriverEntry_at_8' 26 | MATCH (r:Function) WHERE r.name = '_McGenControlCallbackV2_at_36' 27 | MATCH p = shortestPath((q)-[*..15]->(r)) 28 | RETURN p 29 | 30 | Find all shortest path from _DriverEntry to _McGenControlCallbackV2 31 | MATCH (q:Function) WHERE q.name = '_DriverEntry_at_8' 32 | MATCH (r:Function) WHERE r.name = '_McGenControlCallbackV2_at_36' 33 | MATCH p = allShortestPaths((q)-[*..15]->(r)) 34 | RETURN p 35 | 36 | Find callers of memset 37 | MATCH (n:Function)-[:CALLS]->(a:Function) WHERE a.name = '_memset' RETURN n LIMIT 1000 38 | 39 | Find Callers of Callers of memset 40 | MATCH (q:Function)-[:CALLS]->(n:Function)-[:CALLS]->(a:Function) WHERE a.name = '_memset' RETURN q LIMIT 1000 41 | 42 | Set bulletin of _DiskFdoQueryWmiRegInfoEx_at_16 43 | MATCH (n { name: '_DiskFdoQueryWmiRegInfoEx_at_16' }) SET n.bulletin = 'MS15-007' RETURN n 44 | 45 | ''' 46 | 47 | URL = r'http://localhost:7474/db/data/transaction/commit' 48 | STATEMENT = '{\"statements\":[%s]}' 49 | SUB_STATEMENT = '{\"statement\":\"CREATE (p:Function {name:{name},bulletin:{bulletin},notes:{notes}}) RETURN p\",\"parameters\":{\"name\":\"%s\",\"bulletin\":\"%s\",\"notes\":\"%s\"}}' 50 | SUB_STATEMENT2 = '{\"statement\":\"MATCH (a:Function {name:{name}}), (b:Function {name:{name2}}) CREATE (a)-[:CALLS {bulletin:{bull}}]->(b)\",\"parameters\":{\"name\":\"%s\",\"name2\":\"%s\",\"bull\":\"%s\"}}' 51 | MAX_BATCH = 400 52 | 53 | 54 | def MakeRestReq(sBatch, uCnt): 55 | req = urllib2.Request(URL, STATEMENT % (sBatch.rstrip(',')), { 56 | 'Content-Type': 'application/json'}) 57 | f = urllib2.urlopen(req) 58 | response = f.read() 59 | print 'Iteration - [%d]' % (uCnt) 60 | f.close() 61 | 62 | # Create dummy node 63 | MakeRestReq(SUB_STATEMENT % ('indirect_call', 'BASE_IMPORT', 'BASE_IMPORT'), 0) 64 | 65 | # Save Nodes 66 | sBatch = '' 67 | uCnt = 1 68 | for _ in Functions(): 69 | sFunctionName = GetFunctionName(_).replace( 70 | '@', '_at_').replace('?', '_qm_') 71 | sQuery = SUB_STATEMENT % (sFunctionName, 'BASE_IMPORT', 'BASE_IMPORT') 72 | 73 | if uCnt % MAX_BATCH == 0: 74 | MakeRestReq(sBatch, uCnt) 75 | sBatch = '' 76 | else: 77 | sBatch += sQuery + ',' 78 | 79 | uCnt += 1 80 | 81 | if sBatch != '': 82 | MakeRestReq(sBatch, uCnt) 83 | sBatch = '' 84 | 85 | print '[i] Finished Node Import' 86 | 87 | # Save Relations 88 | sBatch = '' 89 | uCnt = 1 90 | 91 | # for each defined function 92 | for z in Functions(): 93 | # for each xref to that function 94 | for xref in XrefsTo(z): 95 | sCaller = GetFunctionName(xref.frm).replace( 96 | '@', '_at_').replace('?', '_qm_') 97 | sCallee = GetFunctionName(z).replace('@', '_at_').replace('?', '_qm_') 98 | if sCaller == '': 99 | sCaller = 'indirect_call' 100 | if sCallee == '': 101 | sCallee = 'indirect_call' 102 | sQuery = SUB_STATEMENT2 % (sCaller, sCallee, 'BASE_IMPORT') 103 | if uCnt % MAX_BATCH == 0: 104 | MakeRestReq(sBatch, uCnt) 105 | sBatch = '' 106 | else: 107 | sBatch += sQuery + ',' 108 | uCnt += 1 109 | 110 | if sBatch != '': 111 | MakeRestReq(sBatch, uCnt) 112 | sBatch = '' 113 | 114 | print '[i] Finished Edge Import' 115 | --------------------------------------------------------------------------------