mirror of
https://github.com/JHUAPL/IDAPythonEmbeddedToolkit.git
synced 2026-01-09 07:08:05 -05:00
108 lines
5.1 KiB
Python
108 lines
5.1 KiB
Python
##############################################################################################
|
|
# Copyright 2017 The Johns Hopkins University Applied Physics Laboratory LLC
|
|
# All rights reserved.
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
# software and associated documentation files (the "Software"), to deal in the Software
|
|
# without restriction, including without limitation the rights to use, copy, modify,
|
|
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
# permit persons to whom the Software is furnished to do so.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
# OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
##############################################################################################
|
|
# define_code_functions.py
|
|
# Attempts to define the bytes in the user-entered address range as code and then as functions
|
|
# based on the user-define smart_prolog and smart_epilog regular expressions for that architecture.
|
|
#
|
|
# Inputs: start_addr: Start address for segment to define as data
|
|
# end_addr: End address for segment to define as data
|
|
# data_type: Type of data to set segment to (dependent on architecture)
|
|
#
|
|
##############################################################################################
|
|
import re
|
|
import idaapi
|
|
|
|
################### USER DEFINED VALUES ###################
|
|
# Enter a regular expression for how this architecture usually begins and ends functions.
|
|
# If the architecture does not dictate how to start or end a function use r".*" to allow
|
|
# for any instruction
|
|
|
|
processor_name = idaapi.get_inf_structure().procName
|
|
|
|
|
|
if processor_name == '8051':
|
|
# 8051 Architecture Prologue and Epilogue
|
|
smart_prolog = re.compile(r".*")
|
|
smart_epilog = re.compile(r"reti{0,1}")
|
|
|
|
elif processor_name == 'PIC18Cxx':
|
|
# PIC18 Architecture Prologue and Epilogue
|
|
smart_prolog = re.compile(r".*")
|
|
smart_epilog = re.compile(r"return 0")
|
|
|
|
elif processor_name == 'm32r':
|
|
# Mitsubishi M32R Architecutre Prologue and Epilogue
|
|
smart_prolog = re.compile(r"push +lr")
|
|
smart_epilog = re.compile(r"jmp +lr.*")
|
|
|
|
elif processor_name == 'TMS32028':
|
|
# Texas Instruments TMS320C28x
|
|
smart_prolog = re.compile(r".*")
|
|
smart_epilog = re.compile(r"lretr")
|
|
|
|
elif processor_name == 'AVR':
|
|
# AVR
|
|
smart_prolog = re.compile(r"push +r")
|
|
smart_epilog = re.compile(r"reti{0,1}")
|
|
|
|
else:
|
|
print "[define_code_functions.py] UNSUPPORTED PROCESSOR. Processor = %s is unsupported. Exiting." % processor_name
|
|
raise NotImplementedError('Unsupported Processor Type.')
|
|
|
|
print "[define_code_functions.py] Processor = %s -- Reg Expressions Selected. Proceeding." % processor_name
|
|
############################################################
|
|
|
|
start_addr = AskAddr(MinEA(), "Please enter the starting address for the data to be defined.")
|
|
end_addr = AskAddr(MaxEA(), "Please enter the ending address for the data to be defined.")
|
|
|
|
if ((start_addr is not None and end_addr is not None) and (start_addr != BADADDR and end_addr != BADADDR)):
|
|
do_make_unk = AskYN(0, "Do you want to make all of the code block UNKNOWN first?")
|
|
if (do_make_unk == 1):
|
|
curr_addr = start_addr
|
|
while (curr_addr < end_addr):
|
|
MakeUnkn(curr_addr,idc.DOUNK_SIMPLE)
|
|
curr_addr += 1
|
|
if (do_make_unk != -1):
|
|
curr_addr = start_addr
|
|
print "[make_code_functions.py] Running script to define code and functions on 0x%x to 0x%x" % (start_addr, end_addr)
|
|
while (curr_addr < end_addr):
|
|
next_unexplored = FindUnexplored(curr_addr, idaapi.BIN_SEARCH_FORWARD)
|
|
MakeCode(next_unexplored) # We don't care whether it succeeds or fails so not storing retval
|
|
curr_addr = next_unexplored
|
|
|
|
# Finished attempting to make all unexplored bytes into code
|
|
# Now, attempt to create functions of all code not currently in a function
|
|
print "[make_code_functions.py] Completed attempting to define bytes as code. Now trying to define functions."
|
|
curr_addr = start_addr
|
|
while (curr_addr != BADADDR and curr_addr < end_addr):
|
|
if (isCode(GetFlags(curr_addr)) and GetFunctionAttr(curr_addr, FUNCATTR_START) == BADADDR):
|
|
#print "Function Stuffs 0x%0x" % curr_addr
|
|
if(smart_prolog.match(GetDisasm(curr_addr)) or smart_epilog.match(GetDisasm(PrevHead(curr_addr)))):
|
|
#print "Smart Prolog match"
|
|
if (MakeFunction(curr_addr) != 0):
|
|
# MakeFunction(curr_addr) was successful so set curr_addr to next addr after the new function
|
|
curr_addr = GetFunctionAttr(curr_addr, FUNCATTR_END) # Returns first address AFTER the end of the function
|
|
continue
|
|
curr_addr = NextHead(curr_addr)
|
|
else:
|
|
print "[make_code_functions.py] Quitting. Entered address values are not valid."
|
|
|
|
|
|
|
|
|