# Untitled

a guest
Sep 6th, 2018
139
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
2. Documentation for this module.
3. This is a IDA script file built to output Section, Symbol, and Xref information
4.
5.
6. If run as script in IDA should create csv files called Xref, Symbols, and Sections
7. """
8. import json
9. from idautils import *
10. from idc import *
11. from idaapi import *
12. import sqlite3
13. import sys
14.
15. #Python Quicksort from interactivepython.org/courselib/static/pythonds/SortSearch/TheQuickSort.html
16. def quickSort(alist, blist):
17.     """Documentation for a function.
18.    @param alist list to be sorted
19.    @param blist an additional list that is to be sorted not by its order but by lista's order
20.    @brief Simple function that sorts both lists in the order of lowest to highest based on the first list
21.    """
22.     quickSortHelper(alist,0,len(alist)-1, blist)
23.
24. def quickSortHelper(alist,first,last, blist):
25.     """Documentation for a function.
26.    @param alist list to be sorted
27.    @param first is the index of first value in quicksort
28.    @param last is the index of last value in quicksort
29.    @param blist an additional list that is to be sorted not by its order but by lista's order
30.    @brief Helper Function that can be called recursively
31.    """
32.     if first<last:
33.
34.         splitpoint = partition(alist,first,last, blist)
35.
36.         quickSortHelper(alist,first,splitpoint-1, blist)
37.         quickSortHelper(alist,splitpoint+1,last, blist)
38.
39.
40. def partition(alist,first,last, blist):
41.     """Documentation for a function.
42.    @param alist list to be sorted
43.    @param first is the index of first value in quicksort
44.    @param last is the index of last value in quicksort
45.    @param blist an additional list that is to be sorted not by its order but by lista's order
46.    @brief Partitions and sorts per quicksort rules. Pivotvalue just chosen as first right now
47.    """
48.     pivotvalue = alist[first]
49.
50.     leftmark = first+1
51.     rightmark = last
52.
53.     done = False
54.     while not done:
55.
56.         while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
57.             leftmark = leftmark + 1
58.
59.         while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
60.             rightmark = rightmark -1
61.
62.         if rightmark < leftmark:
63.             done = True
64.         else:
65.             temp = alist[leftmark]
66.             alist[leftmark] = alist[rightmark]
67.             alist[rightmark] = temp
68.             temp = blist[leftmark]
69.             blist[leftmark] = blist[rightmark]
70.             blist[rightmark] = temp
71.
72.     temp = alist[first]
73.     alist[first] = alist[rightmark]
74.     alist[rightmark] = temp
75.     temp = blist[first]
76.     blist[first] = blist[rightmark]
77.     blist[rightmark] = temp
78.
79.     return rightmark
80.
81. def write_all(cur):
82.     """Documentation for a function.
83.    @param cur Cursor to the sqlite database to write to
84.    @brief Discovers xrefs and symbols and gets information to print them. Calls print sections
85.    """
86.     #Random Declarations
87.     funcs = Functions()
88.     #Record all xref.to's to symbol list and their type to corresponding index in symbolListType
89.     symbolList = []
90.     symbolListType = []
91.     ptrList = []
92.
93.     #Prints the section
95.
96.     #Make sure all functions are added to symbol list. Must be prior so funcs don't get identified as objects
97.     for x in funcs:
98.         func = get_func(x)
99.         if not func is None:
100.             symbolList.append(func.startEA)
101.             symbolListType.append(17)
102.     funcs = Functions()
103.     #This main loop goes through all functions discovering all xrefs
104.     for x in funcs:
105.         func = get_func(x)
106.         if not func is None:
107.             fname = Name(func.startEA)
108.             items = FuncItems(func.startEA)
109.             #Every item is a line of assembly
110.             for i in items:
111.                 #There can be multiple xrefs in a line of assembly if two pointers are referenced
112.                 for xref in XrefsFrom(i, 0):
114.                     #Detecting if this is a symbol and has not been added to symbol table yet
115.                     if xref.to not in symbolList and int(xref.type) != 21:
116.                         symbolList.append(xref.to)
117.                         symbolListType.append(int(xref.type))
118.
119.                 #Both the next two if statements are for detecting pointer's intial values
120.                 if(get_operand_type(i, 0) == 2):
121.                     #we don't need to store its intial value more than once so created a list
122.                     if int(GetOperandValue(i, 0)) not in ptrList:
123.                         ptrList.append(int(GetOperandValue(i,0)))
124.                         for xrefHidden in XrefsFrom(GetOperandValue(i, 0), 0):
125.                             #add the new xref to xref file
126.                             add_xref_info_to_db(cur, GetOperandValue(i, 0), xrefHidden, 1)
127.                             #add the xref.to to the symbol file
128.                             if xrefHidden.to not in symbolList and int(xrefHidden.type) != 21:
129.                                 symbolList.append(xrefHidden.to)
130.                                 symbolListType.append(int(xrefHidden.type))
131.                 #Same as above but with second operand
132.                 if(get_operand_type(i, 1) == 2):
133.                     if int(GetOperandValue(i, 1)) not in ptrList:
134.                         ptrList.append(int(GetOperandValue(i, 1)))
135.                         for xrefHidden in XrefsFrom(GetOperandValue(i, 1), 0):
136.                             add_xref_info_to_db(cur, GetOperandValue(i, 1), xrefHidden, 1)
137.                             if xrefHidden.to not in symbolList and int(xrefHidden.type) != 21:
138.                                 symbolList.append(xrefHidden.to)
139.                                 symbolListType.append(int(xrefHidden.type))
140.
141.
142.     #Use xrefs to calculate size of symbols if they are data
143.     quickSort(symbolList, symbolListType)
144.     i = 0
145.     #Calculates the size of each symbol by subtraction
146.     while i < len(symbolList):
147.         #Either subtracts next Xref or Seg End, whichever comes first
148.         segEnd = get_segm_end(symbolList[i])
149.         #Last xref has to be linked against segment because no xref after it
150.         if i != len(symbolList)-1:
151.             nextXref = symbolList[i + 1]
152.         else:
153.             nextXref = segEnd
154.         if(nextXref < segEnd):
155.             diff = nextXref - symbolList[i]
156.         else:
157.             diff = segEnd - symbolList[i]
159.         i += 1
160.
161. #    fileX.close()
162. #    fileS.close()
163.     return;
164.
165. def create_tables(cur):
166.     """Documentation for a function.
167.    @param cur Cursor to the sqlite database to write to
168.    @brief Clears any existing database information and sets up new tables
169.    """
170.     #Purge any old data.
171.     #SQLite will not create new tables if there are existing tables with the same name.
172.     cur.execute("DROP TABLE IF EXISTS XREF")
173.     cur.execute("DROP TABLE IF EXISTS SYMBOLS")
174.     cur.execute("DROP TABLE IF EXISTS SECTIONS")
176.     cur.execute("CREATE TABLE SYMBOLS(ADDRESS INTEGER, SIZE INTEGER, TYPE STRING, NAME STRING)")
177.     cur.execute("CREATE TABLE SECTIONS(NAME STRING, PERM INTEGER, VADDR INTEGER, VSIZE INTEGER)")
178.
179. #Replacement for write_sections_csv
181.     """Documentation for a function.
182.    @param cur Cursor to the sqlite database to write to
183.    @brief Ouput section information to section.csv
184.    """
185.     for s in Segments():
186.         seg_name = get_segm_name(getseg(s))
188.             sqlString = "INSERT INTO SECTIONS VALUES('{}',{}, {}, {})"
189.             sqlString = sqlString.format(seg_name, get_segm_attr(s, SEGATTR_PERM), get_segm_start(s), get_segm_end(s) - get_segm_start(s))
190.             cur.execute(sqlString)
191.
194.     """Documentation for a function.
195.    @param cur Cursor to the sqlite database to write to
197.    @param xrefType Is an integer representing the type of xref the symbol was
198.    @param size Is the size of the symbol
199.    @brief should output symbol at address information to a symbols.txt file
200.    """
201.     if(xrefType != 21):
203.         if(funcInside is None or int(funcInside.startEA) == int(address)):
204.             if(xrefType == 17 and funcInside is not None):
205.                 size = funcInside.endEA - funcInside.startEA;
206.             if(xrefType == 1 or xrefType == 2 or xrefType == 3):
207.                 typeChanged = "object"
208.             else:
209.                 typeChanged = "func"
210.             sqlString = "INSERT INTO SYMBOLS VALUES({}, {}, '{}', '{}')"
212.             cur.execute(sqlString)
213.
214. #Replacement for printXrefInfo
216.     """Documentation for a function.
217.    @param cur Cursor to the sqlite database to write to
219.    @param xref the xref object from idapython
220.    @param ptr Is 1 if ptr is 0 if not
221.    @brief It will then output to the xref file (Xref.csv) all the information about that xref.
222.    """
223.     #xref type 21 is some sort of dataFlow xref that is not legit
224.     if(xref.type != 21):
225.         size = 4
226.         typeChanged = ""
227.         if (int(xref.to) == int(GetOperandValue(address, 0))):
228.             size = len(str(hex(GetOperandValue(address, 0)))) - 1
230.                 typeChanged = "disp"
233.                     typeChanged = "imm"
234.                 else:
235.                     typeChanged = "imm_alone"
237.             size = len(str(hex(GetOperandValue(address, 1)))) - 1
239.                 typeChanged = "disp"
242.                     typeChanged = "imm"
243.                 else:
244.                     typeChanged = "imm_alone"
245.         if(xref.type == 17):
246.             typeChanged = "call"
247.         elif(xref.type == 19):
248.             typeChanged = "jmp"
249.         #Passed in whether this is a pointer
250.         if(ptr == 1):
251.             typeChanged = "ptr"
252.         sqlString = "INSERT INTO XREF VALUES({}, {}, {}, '{}')"
253.         sqlString = sqlString.format(address, size, xref.to, typeChanged)
254.         cur.execute(sqlString)
255.
256.
257.
258. #Technically this is the main function:
259. print("\n\n\n\nBegin script call")
260. #fileName = "database.sqlite"+sys.argv[1]
261. #fileName = "database.sqlite"
262. targetNum = get_root_filename()[-1]