import struct
import math
import libanalyze
RD_CHAR = "*"
FD_CHAR ="-"
#get max end function
def func_max_end(imm, addr):
fun = libanalyze.Function(imm, addr)
end1 = fun.getFunctionEnd()
if len(end1) == 0:
return 0
end_max = end1[0]
for e in end1:
if e>end_max:
end_max = e
return end_max
#search asmcode in function
#["mov byte ptr ss:[R32+100], R8", 3,"mov byte ptr ss:[R32+101], R8"] R32 R_32 R16 R_16 R8 R_8
#ret []
def search_asmcode_infun(imm, fun_begin_addr, c_list):
end_max = func_max_end(imm, fun_begin_addr)
if end_max==0 :
return []
ret_addr = []
space = -1
begin_addr = fun_begin_addr
imm.log("")
imm.log("start to search asm !", highlight = 1)
imm.log("-----------------------------------------------------")
for c in c_list:
if type(c)== type(1):
space = c
else:
s_ret = search_asmcode(imm, begin_addr, end_max, c, space)
if len(s_ret) !=0:
begin_addr = s_ret[0]
imm.log("get address at 0x%x" % begin_addr)
ret_addr.append(begin_addr)
space = -1
imm.log("-----------------------------------------------------")
return ret_addr
#"lea eax, dword ptr ds:[ecx+edx-FA]" --> "lea eax, dword ptr ds:[ecx+edx-0xFA]"
def change_special(asm_code):
def change_list_chrsp(st, chr_sp):
st_tmp = st
for chr_elt in chr_sp:
l_flt = change_hex(st_tmp, chr_elt)
st_tmp= l_flt
return st_tmp
def change_hex(st, chr_sp):
l = st.split(chr_sp)
xx = []
for ii in l:
try:
xx.append("0x%x" %int(ii, 16))
except (ValueError, TypeError):
xx.append("%s" % ii)
return chr_sp.join(xx)
fit = asm_code.find("[")
sec = asm_code.find("]")
aft = ""
if (fit!=-1) and (sec !=-1) and (sec>fit):
ll = asm_code[fit+1: sec]
aft += change_list_chrsp(ll, "+-*")
asm_code = asm_code.replace(asm_code[fit+1: sec], aft)
asm_code = change_list_chrsp(asm_code, ", ")
if asm_code.startswith("0x"):
asm_code = asm_code[2:]
return asm_code
def search_asmcode(imm, start_addr, end_addr, asmcode, space = -1):
imm.log("asmreg to search: %s space: %d addr: 0x%x" % (asmcode, space, start_addr), highlight = 1)
register_32 = ["EAX", "EBX", "ECX", "EDX", "EBP", "ESI", "EDI", "ESP"]
register_16 = ["AX", "BX", "CX", "DX", "BP", "SI", "DI", "SP"]
register_8 = ["AH", "AL", "BH", "BL", "CL", "CH", "DL", "DH"]
ret_list = []
ret_list.append(asmcode)
ret_list.extend([xx.replace("R32", r) for r in register_32 for xx in ret_list if (xx.find("R32")!= -1)])
ret_list.extend([xx.replace("R_32", r) for r in register_32 for xx in ret_list if (xx.find("R_32")!= -1)])
ret_list.extend([xx.replace("R16", r) for r in register_16 for xx in ret_list if (xx.find("R16")!= -1)])
ret_list.extend([xx.replace("R_16", r) for r in register_16 for xx in ret_list if (xx.find("R_16")!= -1)])
ret_list.extend([xx.replace("R_8", r) for r in register_8 for xx in ret_list if (xx.find("R_8")!= -1)])
ret_list.extend([xx.replace("R8", r) for r in register_8 for xx in ret_list if (xx.find("R8")!= -1)])
ret_list = [r for r in ret_list if ((r.find("R32")==-1) and (r.find("R_32")==-1) and (r.find("R16")==-1) \
and (r.find("R_16")==-1) and (r.find("R8")==-1) and (r.find("R_8")==-1))]
code = ""
for r in ret_list :
code += imm.assemble(change_special(r)) # get code list
cnt = 0
while True:
op = imm.disasm(start_addr)
start_addr = start_addr + op.getSize()
new_asm = change_special(op.getDisasm())
this_code = imm.assemble(new_asm)
if (this_code in code) and (cnt<=space if space>0 else True):
imm.log("hit addr 0x%x asm:%s"%(op.getAddress(), op.getDisasm()), highlight = 1)
return [op.getAddress(), op.getDisasm()]
if start_addr > end_addr:
break
cnt = cnt +1
return []
#list[0x12345678, 0x12345678]
def search_code_Long(imm, begin, end, code_list, min, max):
st = ""
if (min<0) or (min>max):
return []
if type(code_list) != type([]):
return []
for i in range(len(code_list)-1):
st += "%02X%02X%02X%02X"%(code_list[i]&0xff, (code_list[i]>>0x8)&0xff, (code_list[i]>>0x10)&0xff, (code_list[i]>>0x18)&0xff)
st += "%s%02x%02x" % (RD_CHAR, min, max) if max>0 else ""
last_num = code_list[len(code_list)-1]
st += "%02X%02X%02X%02X"%(last_num&0xff, (last_num>>0x8)&0xff, (last_num>>0x10)&0xff, (last_num>>0x18)&0xff)
return search_code_string(imm, begin, end, st)
#list[0x1234, 0x1234]
def search_code_short(imm, begin, end, code_list, min, max):
st = ""
if (min<0) or (min>max):
return []
if type(code_list) != type([]):
return []
for i in range(len(code_list)-1):
st += "%02X%02X"%(code_list[i]&0xff, (code_list[i]>>0x8)&0xff)
st += "%s%02x%02x" % (RD_CHAR, min, max) if max>0 else ""
last_num = code_list[len(code_list)-1]
st += "%02X%02X"%(last_num&0xff, (last_num>>0x8)&0xff)
return search_code_string(imm, begin, end, st)
#list[0x34, 0x34]
def search_code_byte(imm, begin, end, code_list, min, max):
st = ""
if (min<0) or (min>max):
return []
if type(code_list) != type([]):
return []
for i in range(len(code_list)-1):
st += "%02X"%(code_list[i]&0xff)
st += "%s%02x%02x" % (RD_CHAR, min, max) if max>0 else ""
last_num = code_list[len(code_list)-1]
st += "%02X"%(last_num&0xff)
return search_code_string(imm, begin, end, st)
#str "GUOJICHONGYUN" "\xff\xff\xff\xff"
def search_data_str(imm, begin, end, str_search, min, max):
st = ""
if (min<0) or (min>max):
return []
if type(str_search) != type(""):
return []
for i in range(len(str_search)-1):
st += "%02X"%(ord(str_search[i]))
st += "%s%02x%02x"%(RD_CHAR, min, max) if max>0 else ""
st += "%02X"%(ord(str_search[len(str_search)-1]))
return search_code_string(imm, begin, end, st)
#search code string
#ef00*0209EabA*0304eeaa FF00-04AA 53f966*0000E000008ab70183C40899F7*00007C24
def search_code_string(imm, begin, end, code_str):
st1 = code_str.upper()
ret_error = 0
ret = []
imm.log("the code to search:%s"%st1, highlight = 1)
start = 0
x = 0
for aa in st1:
if (aa ==RD_CHAR) or (aa == FD_CHAR):
break
else:
x += 1
y = 0
min_n = []
max_n = []
s1 = []
s2 = []
if x == len(st1):
s1.append(st1)
else:
count_ = 0
while True:
count_ = 0
if st1[x] == FD_CHAR:
min_max_tmp = int(st1[x+1:x+3], 16)
min_n.append(min_max_tmp*2)
max_n.append(min_max_tmp*2)
count_ = 3
else:
min_tmp = int(st1[x+1:x+3], 16)
max_tmp = int(st1[x+3:x+5], 16)
if (min_tmp>max_tmp) or (min_tmp<0):
return []
min_n.append(min_tmp*2)
max_n.append(max_tmp*2)
count_ = 5
if start != x:
s1.append(st1[start:x])
y = 0
for aa in st1[x+count_:]:
if (aa ==RD_CHAR) or (aa == FD_CHAR):
break
else:
y += 1
if y == len(st1[x+count_:]):
s2.append(st1[x+count_:])
break
else:
s2.append(st1[x+count_:y+x+count_])
x = y + x + count_
start = x
#'''
imm.log("min_n %s " % min_n, highlight = 1)
imm.log("max_n %s " % max_n, highlight = 1)
imm.log("s1 %s " % s1, highlight = 1)
imm.log("s2 %s " % s2, highlight = 1) #'''
len1 = len(s1[0])
mun1_str = ""
for i in range(len1/2):
x = ((int(s1[0][2*i])) if s1[0][2*i].isdigit() else (int(s1[0][2*i], 16)))*math.pow(16, 1)
x += ((int(s1[0][2*i+1])) if s1[0][2*i+1].isdigit() else (int(s1[0][2*i+1], 16)))*math.pow(16, 0)
mun1_str += struct.pack("B", x)
first_ = imm.search(mun1_str)
byte_num = 0
for i in max_n:
byte_num += i
for si in s2:
byte_num += len(si)
for fx in first_:
if (fx<begin) or (fx>end):
continue
buf = imm.readMemory(fx, byte_num)
mem_read_str = ''.join(['%02X' % ord(x) for x in buf[0:]])
imm.log("addr 0x%x mem_read_str %s" %(fx, mem_read_str), highlight = 1)
start = len(s1[0])
i = 0
flag = 0
for s2_tmp in s2:
y = mem_read_str[start:].find(s2_tmp)
if y == -1:
flag = 0
break
elif (y>=min_n[i]) and (y<=max_n[i]):
flag += 1
start = start + y + len(s2_tmp)
else:
break
i = i +1
#imm.log("flag %d len1 %d i %d"%(flag, len1, i))
#imm.log("flag %d len1%d"%(flag, len1))
if flag == len(min_n):
ret.append(fx)
return ret