def stage2(data): read_data = analyse_read() ret_addr = idc.DbgDword(idautils.cpu.esp) idautils.cpu.esp += 0x14 + 4 idautils.cpu.eip = ret_addr data += '\r\n' idc.DbgWrite(read_data.read_buf, data) idc.DbgWrite(read_data.nread_out, struct.pack('<I', len(data))) return read_data
def handler(self): if 1: b1 = 'sn00gle-fl00gle-p00dlekins' dst = idautils.cpu.esp + 0x100 dstsize = 0x102 idc.DbgWrite(dst, '\x00'*dstsize) buf = dst - len(b1)-10 idc.DbgWrite(buf, b1+'\x00') gen_perm_ea = idc.LocByName('generate_perm') mix_ea = idc.LocByName('mix_things') pass1_ea = idc.LocByName('PASSWORD1') pass1_len = read_u32(idc.LocByName('PASSWORD1_LEN')) finalsize = pass1_len finaldest = idautils.cpu.esp - 2*finalsize idc.DbgWrite(finaldest, '\x00'*(finalsize+1)) self.call(gen_perm_ea, dst, buf, len(b1)) yield print(hex(dst), hex(pass1_ea), hex(finaldest), hex(pass1_len)) #self.done = 1 #return self.call(mix_ea, dst, pass1_ea, finaldest, pass1_len) yield with open('./final.data', 'wb') as f: f.write(idc.DbgRead(finaldest, pass1_len)) else: stride = 0x24 nseg = read_u32(self.rx_seg_count) base_addr = self.rx_seg_desc print('HANDLER', nseg) for i in range(nseg): seg_addr = base_addr + stride * i for data in self.decode_seg(seg_addr, False): yield nseg = read_u32(self.rw_seg_count) base_addr = self.rw_seg_desc for i in range(nseg): seg_addr = base_addr + stride * i for data in self.decode_seg(seg_addr, True): yield print('dumping handler') json.dump(self.segs, open('./dump.json', 'w')) self.done = 1
def strcpy(self, dst, src=''): ''' Monitors, reports and simulates the strcpy function. ''' print 'strcpy(0x%X, "%s")' % (dst, src) idc.DbgWrite(dst, src + "\x00") return dst
def dbg_bpt(self, tid, ea): try: if self.done: print('should be done') return 0 if ea == self.send_req_ea: print('ON SEND REQ') self.reqid += 1 a = read_u32(idautils.cpu.esp + 4) b = read_u32(idautils.cpu.esp + 8) print(a, b) a = get_str(a) b = get_str(b) print(a, b) content = req_web(a, b) do_ret() ea = self.bufs[self.reqid - 1] idautils.cpu.eax = ea idc.DbgWrite(ea, content) print('GOT CONTENT >> ', content) if self.reqid >= 4: self.done = 1 elif ea == self.decrypt_end_ea: tmp = read_u32(idautils.cpu.eax) rem = idc.DbgRead(idautils.cpu.eax + 4, 0x3000) print('DECRYPTING >>>', tmp, rem) except Exception as e: tb.print_exc() self.done = 1 print('FAILURE') return 0
def malloc(self, data=None, size=0): ''' Allocates space for data in the debugger's memory and populates it. @data - Data to place into memory. If None, NULL bytes will be used. @size - Size of memory to allocate. If 0, len(data) bytes will be allocated. Returns the address of the allocated memory. ''' if size == 0 and data is not None: size = len(data) if data is None: data = "\x00" * size if self.use_native_malloc: addr = self.app.Call('malloc', arguments=[size], retaddr=self.cpu.ReturnAddress()) else: self._detect_membase() addr = self.MP self.MP += size # This ensures memory addresses are 4-byte aligned. This is important for some architectures. if (self.MP % self.ALIGN) > 0: self.MP += (self.ALIGN - (self.MP % self.ALIGN)) # Keep a dictionary of allocated addresses and their sizes self.allocated_addresses[addr] = size idc.DbgWrite(addr, data) return addr
def strcat(self, dst, src=''): ''' Monitors, reports and simulates the strcat function. ''' print 'strcat(0x%X, "%s")' % (dst, src) addr = dst + len(idc.GetString(dst)) idc.DbgWrite(addr, src + "\x00") return dst
def __stack_dword(self, n, value=None): addr = self.StackPointer() + self.cpu['spoffset'] + (n * self.bsize) if value is not None: sval = self.ToString(value, size=self.bsize) idc.DbgWrite(addr, sval) return idc.DbgDword(addr)
def generate_random_buf_handler(self, bufaddr, ngen, key=None): dx = self.curkey if self.count == 1: if key is None: dx = self.v2c.read0(0x30) else: dx = self.v2c.read0(ngen, off=0x2a) self.last_gen_rand = dx idc.DbgWrite(bufaddr, self.last_gen_rand)
def sprintf(self, dst, fmt=''): ''' Monitors, reports and simulates sprintf. ''' data = self.sim.vsprintf(ftm, 2) print 'sprintf(0x%X, "%s")' % (dst, data) idc.DbgWrite(dst, data + "\x00") return len(data)
def fgets(self, dst, size, fd): if self.file_descriptors.has_key(fd): while not data.endswith('\n') and len(data) < (size - 1): data += self._read(fd, 1) data += "\x00" idc.DbgWrite(dst, data, len(data)) return dst
def read_csman(self, fd, key, value, size, default): if self.config.has_key(key): print "read_csman(%s)" % self.config[key]['name'] idc.DbgWrite(value, self.config[key]['value']) else: print "UNKNOWN CSID: 0x%.8X called from 0x%.8X" % ( key, self.idasim.cpu.ReturnAddress()) return 0
def recv_fixed_handler(self, bufaddr, n, data=None): if data is None: cx = self.c2v.read(n) else: cx = data.read(n) print('RECXEIVED ', cx, len(cx), n) assert len(cx) == n idc.DbgWrite(bufaddr, cx) return 1
def __reg_value(self, reg, value=None): if value is not None: if reg.startswith('*'): idc.DbgWrite(idc.GetRegValue(reg[1:]), self.ToString(value)) else: idc.SetRegValue(value, reg) if reg.startswith('*'): return idc.DbgDword(idc.GetRegValue(reg[1:])) else: return idc.GetRegValue(reg)
def dbg_bpt(self, tid, ea): #if ea == self.cond_ea: # self.done = True # self.res_val = idc.DbgDword(idautils.cpu.esi) print('ON >> ', hex(ea), 'want ', hex(self.fill_obj)) if ea == self.fill_obj: idc.DbgWrite(idautils.cpu.edx + 0x638, struct.pack('<I', 0xc0000000)) idc.DbgWrite(idautils.cpu.edx, open('/tmp/data.out', 'rb').read()) idautils.cpu.eip = self.fill_ret print('JUMPING') elif ea == self.choose_item: idautils.cpu.eax = self.item elif ea == self.file_ea: buf = idc.DbgRead(idautils.cpu.edi, idautils.cpu.esi) x = open('/tmp/chall11_out_%d.out' % self.item, 'wb') x.write(buf) x.close() self.done = 1 return 0
def dbg_bpt(self, tid, ea): #if ea == self.cond_ea: # self.done = True # self.res_val = idc.DbgDword(idautils.cpu.esi) print('ON >> ', hex(ea), 'want ') if ea == self.fgets_ea: next_addr = 0x40e1fa idautils.cpu.rip = next_addr idautils.cpu.rax = len(self.buf) idc.DbgWrite(idautils.cpu.rdi, self.buf) elif ea == self.check_ea: eax = idautils.cpu.eax ecx = idautils.cpu.ecx print('GOT >>> ', self.pos, self.round, hex(eax), hex(ecx), self.buf) if eax != ecx or self.round == self.pos: self.got = [eax, ecx] self.done = 1 self.pos += 1 return 0
def memset(self, buf, c, n): idc.DbgWrite(buf, (chr(c) * n)) return buf
def write_u16(addr, v): idc.DbgWrite(addr, struct.pack('<H', v))
def write_u32(addr, v): idc.DbgWrite(addr, struct.pack('<I', v))
def snprintf(self, dst, n, fmt=''): idc.DbgWrite(dst, self.sim.vsprintf(fmt, 3)[:n] + "\x00") return dst
def strncat(self, dst, src='', n=0): addr = dst + len(idc.GetString(dst)) idc.DbgWrite(addr, src + "\x00", length=n) return dst
def fread(self, ptr, size, nmemb, fd): data = self._read(fd, (size * nmemb)) idc.DbgWrite(ptr, data) return len(data)
def dbg_bpt(self, tid, ea): #if ea == self.cond_ea: # self.done = True # self.res_val = idc.DbgDword(idautils.cpu.esi) #print('ON >> ', hex(ea), 'want ') try: if ea == self.push_screen_ea: tmp=idc.DbgRead(self.screen_buf_ea, 6) self.screen_data.append(tmp) print('pushing screen here', tmp) self.count += 1 if 0 and self.count == 10000: self.done = 1 if self.count%10==0: self.save_screen() elif ea == self.deque_ea: recv_word = idautils.cpu.eax mask=idc.DbgDword(idautils.cpu.ebp-0x6070) self.dec_data.append([recv_word, mask]) if 1 and len(self.dec_data)==0x1000/8: self.done=1 print('DEQUE >> ', hex(recv_word), hex(mask)) elif ea == self.prepare_reg_send: if 1: return idc.DbgWrite(idautils.cpu.esp+0x3c-0x1d, chr(self.cur_byte)) abc=idc.DbgRead(idautils.cpu.esp+0x3c-0x1d, 1) print('SENDING CHAR >> ', abc, self.cur_byte) self.tmp_tb=[] self.last_edi=idautils.cpu.edi elif ea == self.enqueue_func: print('SKIPPING ENQUEUE') if 0: return do_ret() elif ea == self.enqueue_ea: #if 0: return if self.tmp_tb is not None: nedi=idautils.cpu.edi send_word=(nedi-self.last_edi)%8 self.last_edi=nedi self.tmp_tb.append(send_word) self.tb2.append([nedi, hex(idautils.cpu.eax)]) print('GOT TB LEN ', self.tmp_tb) if len(self.tmp_tb)==3: self.enc_data.append(self.tmp_tb) self.tmp_tb=None self.cur_byte+=1 self.last_edi=None if self.cur_byte==256: self.done=1 print('ENQUEUE >> ', send_word) elif ea == self.prepare_str_ea: if 1: return buf_len = idc.DbgDword(idautils.cpu.esi + 0x38) buf_addr = idc.DbgDword(idautils.cpu.esi + 0x34) buf = idc.DbgRead(buf_addr, buf_len) print(buf_len, buf_addr, buf) assert len(self.want_str) <= buf_len idc.DbgWrite(buf_addr, self.want_str) idc.DbgWrite(idautils.cpu.esi + 0x38, struct.pack('<I', len(self.want_str))) print('string is set') #self.done = 1 elif ea==self.test_time_end: if self.time>=3600*24: self.done=1 #entre 23h et 1h else: idautils.cpu.eip=self.test_time_start resv=idautils.cpu.eax h,m,s=self.get_time(self.time) print 'REsult: %d:%d:%d >> %d'%(h,m,s,resv) self.time+=60 elif ea==self.test_time_mod: h,m,s=self.get_time(self.time) addr=idautils.cpu.ebx write_u16(addr+4*2, h) write_u16(addr+5*2, m) write_u16(addr+6*2, s) except: traceback.print_exc() print('FAILED here') self.done=1 return 0
def memcpy(self, dst, src, n): idc.DbgWrite(dst, idc.GetManyBytes(src, n, use_dbg=False)) return dst
def go(addr): while idc.GetRegValue('eip') != addr: idc.GetDebuggerEvent(idc.WFNE_CONT | idc.WFNE_SUSP, -1) idc.AddBpt(func_end) idc.AddBpt(func_start) go(func_end) n = 0x25 buf_addr = idc.DbgDword(idautils.cpu.ebp + 0xc) data_addr = idc.DbgDword(idautils.cpu.ebp + 0x8) len_addr = idautils.cpu.ebp + 0x10 assert idc.DbgWrite(len_addr, struct.pack('<I', n)) print 'steaaart', hex(buf_addr) res = '' for i in range(n): for c in range(256): assert idc.DbgWrite(buf_addr + i, chr(c)) == 1 idc.RefreshDebuggerMemory() idautils.cpu.eip = func_start go(func_end) if idautils.cpu.edi != data_addr + n - i: print 'FOUND ONE', c print 'have ', hex(idautils.cpu.edi), hex(data_addr + n - i) res += chr(c) break
def nvram_get_ex(self, key='', dst=0, size=0): idc.DbgWrite(dst, self.nvram_bufget(0, key)[:size]) return 0
def strncpy(self, dst, src='', n=0): idc.DbgWrite(dst, src + "\x00", length=n) return dst