Beispiel #1
0
    def memcmp(self, dp1, dp2, n):
        d1 = idc.DbgRead(dp1, n)
        d2 = idc.DbgRead(dp2, n)

        if d1 == d2:
            return 0
        else:
            return 1
Beispiel #2
0
    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
Beispiel #3
0
    def decode_seg(self, seg_addr, mem_seg):
      sz = read_u32(seg_addr + 0)
      addr = read_u32(seg_addr + 0x18)
      print('HAS SEG >> ', seg_addr, hex(addr), hex(sz), mem_seg)
      inspos_ptr = read_u32(seg_addr + 12)
      pos = 0
      inslst = []
      content = bytearray()
      self.call(self.virtual_protect_ea, addr, sz, 4, idautils.cpu.esp)
      yield

      while pos < sz:
        ipos = read_u32(inspos_ptr)
        if pos > ipos: break
        assert pos == ipos, '%s %s'%(pos, ipos)
        csize = read_u32(inspos_ptr + 4)
        inslst.append((pos, csize))
        pos += csize
        inspos_ptr += 8
      assert pos <= sz

      for ins, sz in inslst:
        target_addr = addr + ins
        push(mem_seg)
        push(target_addr)
        push(seg_addr-8)
        self.call(self.decode_seg_ea, seg_addr-8, target_addr, mem_seg)
        yield
        assert idautils.cpu.eip == self.ret_pad_ea
        content[ins:ins+sz] = idc.DbgRead(target_addr, sz)
      self.segs.append(dict(sz=sz, addr=addr, content=base64.b64encode(content), mem_seg=mem_seg, seg_addr=seg_addr))
Beispiel #4
0
        def send_fixed_handler(self, bufaddr, n):
            have = idc.DbgRead(bufaddr, n)

            expected = self.v2c.read(n)
            #print('EXPEcted ', expected)
            #print('have     ', have)
            #assert have == expected
            return 1
Beispiel #5
0
  def save_screen(self):
    w=1280
    h=720
    buf=idc.DbgRead(self.screen_buf_ea, w*h*4)
    filename='/tmp/imgs/f1_%05d.p7'%self.screen_count
    open(filename, 'wb').write(buf)

    self.screen_count+=1
    self.last_edi=None
Beispiel #6
0
    def memchr(self, dp, c, n):
        c = chr(c)
        data = idc.DbgRead(dp, n)

        offset = data.find(c)

        if offset == -1:
            return 0
        else:
            return dp + offset
Beispiel #7
0
def get_str(addr):
    s = ''
    n = 0x100
    while True:
        x = idc.DbgRead(addr, n)
        for j in range(len(x)):
            if ord(x[j]) == 0:
                s += x[:j]
                return s
        s += x
        addr += len(x)
    return s
Beispiel #8
0
    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
Beispiel #9
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 ', 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
Beispiel #10
0
 def getMemory(self, pos, l):
     return idc.DbgRead(pos, l)
Beispiel #11
0
 def read_u32(addr):
     return struct.unpack('<I', idc.DbgRead(addr, 4))[0]
Beispiel #12
0
 def fwrite(self, ptr, size, nmemb, fd):
     data = idc.DbgRead(ptr, (size * nmemb))
     self._write(fd, data)
     return len(data)
Beispiel #13
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 ')

    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
Beispiel #14
0
 def wcsncpy_handler(self, dest, src, n):
     print('WCSNCPY >> ', idc.DbgRead(src, n * 2))
     return RetAction('continue')
Beispiel #15
0
 def create_process_w_handler(self):
     print('CreateProcess >> ',
           make_print(idc.DbgRead(idautils.cpu.edx, 100)))
     #self.done = 1
     return RetAction('continue')
Beispiel #16
0
 def write_file_handler(self, handle, buf, n):
     print('WriteFile >> ', make_print(idc.DbgRead(buf, n)), n)
     return RetAction('continue')
Beispiel #17
0
 def memcpy_handler(self, dest, src, n):
     print('MEMCPY >> ', idc.DbgRead(src, n))
     return RetAction('continue')
Beispiel #18
0
    def Handler(self):
        '''
		Breakpoint condition handler, called by IDA to evaluate conditional brekpoints. It in turn calls the 
		appropriate function handler, populates the return value and puts execution back at the return address. 
	
		This is a (slight) abuse of IDA's conditional breakpoints; this function always returns 0, indicating that
		the breakpoint condition has not been met. However, it does ensure that every call to a given function
		can be intercepted and simulated, regardless of whether the process is running freely, or the function has 
		been stepped over, stepped into, etc.
		'''
        retval = 0
        retaddr = None

        if self.verbose:
            print self.FUNCTION_HANDLERS

        for (name, properties) in self.FUNCTION_HANDLERS.iteritems():
            if self.cpu.ProgramCounter() == properties["address"]:
                handler = properties["handler"]
                break

        # If no explicit handler was found, use the default handler
        if not handler and self.DEFAULT_HANDLER:
            handler = self.DEFAULT_HANDLER

        if handler:
            if self.verbose:
                print "Using function handler:", handler.__name__

            parameters = {}

            # Enumerate the arguments and default values for the handler
            args, varargs, keywords, defaults = inspect.getargspec(handler)
            try:
                defaults = dict(zip(reversed(args), reversed(defaults)))
            except:
                defaults = {}

            # Build the handler parameters
            try:
                i = 0
                for arg in args:
                    if arg != 'self':
                        parameters[arg] = self.cpu.Argument(i)

                        if defaults.has_key(arg):
                            # If default value is of type string, get the string automatically
                            if type(defaults[arg]) == type(''):
                                parameters[arg] = idc.GetString(
                                    parameters[arg])
                            # If default value is of type list, get an array of bytes
                            elif type(defaults[arg]) == type([]) and len(
                                    defaults[arg]) == 1:
                                parameters[arg] = [
                                    c for c in idc.DbgRead(
                                        parameters[arg], defaults[arg][0])
                                ]
                        i += 1
            except Exception, e:
                print "WARNING: Failed to parse handler parameters:", str(e)
                parameters = {}

            try:
                retval = handler(**parameters)
            except JumpTo, offset:
                retaddr = self.cpu.ReturnAddress() + offset.message
Beispiel #19
0
        def handler(self):
            assert_on_addr(self.run_call_addr)

            #PYALOD ENTRY: 00404000
            self.diff = idautils.cpu.ecx - idc.LocByName('PAYLOAD_ENTRY')
            self.find_sym_addr = self.sym('find_sym')  # 40b420

            self.mainloop_addr = self.add_bpt_on_sym('mainloop')
            print('MAINLOOP ', hex(self.mainloop_addr))
            yield
            assert_on_addr(self.mainloop_addr)
            print('INDEED ON ADDR, start get syms')

            if 1:
                self.replay_handlers[self.sym(
                    'generate_random_buf')] = self.generate_random_buf_handler
                self.replay_handlers[self.sym(
                    'send_fixed')] = self.send_fixed_handler
                self.replay_handlers[self.sym(
                    'recv_fixed_len')] = self.recv_fixed_handler
                self.replay_handlers[self.sym(
                    'initiate_conn')] = self.initiate_conn_handler

                self.replay_handlers[self.sym(
                    'do_recv')] = self.do_recv_handler
                self.replay_handlers[self.sym(
                    'listen_initiate')] = self.undefined_handler
                self.replay_handlers[self.sym(
                    'caller_ntdll_strncpy')] = self.memcpy_handler
                self.replay_handlers[self.sym(
                    'caller_ntdll_wcsncpy')] = self.wcsncpy_handler
                self.replay_handlers[self.sym(
                    'caller_ntdll_memcpy')] = self.memcpy_handler
                self.replay_handlers[
                    self.sym('caller_kernel32_CreateProcessW'
                             )] = self.create_process_w_handler
                self.replay_handlers[self.sym(
                    'caller_kernel32_WriteFile')] = self.write_file_handler
                self.replay_handlers[self.sym(
                    'caller_mpr_WNetOpenEnumW')] = self.wnet_open_enum_handler
                self.replay_handlers[self.sym('caller_mpr_WNetEnumResourceW'
                                              )] = self.wnet_enum_rsc_handler
                #self.replay_handlers[self.sym('caller_kernel32_FindNextFileW')] = self.find_next_filew_handler

                self.replay_handlers[self.sym(
                    'handle_conn_end')] = self.stop_handler
                self.replay_handlers[self.sym(
                    'caller_mpr_WNetAddConnection2W')] = self.stop_handler

                self.counts = defaultdict(lambda: 0)

                for silent_addr in self.syms_to_find.values():
                    if not silent_addr in self.replay_handlers:
                        self.replay_handlers[silent_addr] = self.silent_handler

                for k in self.replay_handlers.keys():
                    self.add_bpt(k)

                if 1:
                    xx = './conn2.packets.pickle'
                    data = pickle.load(open(xx, 'rb'))
                    self.c2v = io.BytesIO(data['c2v']['key'])

                    print('start try packets')
                    for _ in self.wait_until('generate_random_buf'):
                        yield
                    self.curkey = data['v2c']['key']
                    print('On generate_random_buf_handler')
                    self.replay_handler(self.ea, key=True)
                    yield

                    if 0:
                        for _ in self.wait_until('recv_packet'):
                            yield
                        pkts = data['c2v']['packets']
                        for i, pkt in enumerate(pkts):
                            print('============', i)
                            print('============', i)
                            print('============', i)
                            print('============', i)
                            print('============', i)
                            print('============', i)
                            print('============', i)
                            self.c2v = io.BytesIO(pkt[1])
                            self.curkey = pkt[1][0x2a:0x2a + 4]
                            for _ in self.wait_until('recv_packet_end'):
                                yield
                            for _ in self.wait_until('recv_packet'):
                                yield

                    else:
                        cnt = 0
                        for i, pkt in enumerate(data['c2v']['packets']):
                            for _ in self.wait_until('recv_packet'):
                                yield
                            self.c2v = io.BytesIO(pkt[1])
                            for _ in self.wait_until('recv_packet_end'):
                                yield
                            ptr = idautils.cpu.ebp - 8
                            data_ptr = read_u32(ptr)
                            with open('./output/' + xx + '_cmd_%04d.out' % i,
                                      'wb') as f:
                                if i == 11:
                                    f.write(idc.DbgRead(data_ptr, 0x8000))
                                else:
                                    f.write(idc.DbgRead(data_ptr, 0x2000))
                            idautils.cpu.eip = self.sym('recv_packet_start')
                            cnt += 1

                else:
                    self.do_replay = 1
                assert 0

            if 0:
                for cst, target_func in self.syms_to_find.items():
                    self.call1(self.find_sym_addr, cst)
                    yield
                    assert_on_addr(self.ret_pad_ea)
                    addr = idautils.cpu.eax
                    name = idc.Name(addr)
                    self.onames.append((target_func, 'caller_' + name))

            self.done = 1
            yield