Changeset 1591

Show
Ignore:
Timestamp:
03/06/08 17:40:30 (6 months ago)
Author:
common
Message:

libemu

  • slightly smarter traversal
    if traversal fails due to stack operations which are not track(ed|able), or something different
    bruteforce the instructions 'infront' of the known, taking the static tree as input
    from the result, take the first offset doing 256 steps
    one might be able to speed this up, caching already tested positions using the hashtable which is given as parameter to run_and_track
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libemu/trunk/src/emu_shellcode.c

    r1359 r1591  
    7171        if ( ((struct emu_stats *)a->data)->cpu.steps > ((struct emu_stats *)b->data)->cpu.steps ) 
    7272                return 0; 
     73        else 
     74        if ( ((struct emu_stats *)a->data)->cpu.steps == ((struct emu_stats *)b->data)->cpu.steps ) 
     75        if ( ((struct emu_stats *)a->data)->eip <= ((struct emu_stats *)b->data)->eip ) 
     76                        return 0; 
     77 
    7378        return 1; 
    7479} 
     
    8388                                                                                struct emu_track_and_source *etas, 
    8489                                                                                struct emu_hashtable *known_positions, 
    85                                                                                 struct emu_stats **running_stats 
     90                                                                                struct emu_list_root *stats_tested_positions_list, 
     91                                                                                bool brute_force 
    8692                                                                           ) 
    8793{ 
     
    9399        emu_queue_enqueue(eq, (void *)((uint32_t)eipoffset+STATIC_OFFSET)); 
    94100 
    95       struct emu_list_root *tested_positions = emu_list_create(); 
     101//    struct emu_list_root *tested_positions = emu_list_create(); 
    96102 
    97103        while ( !emu_queue_empty(eq) ) 
     
    106112                        logDebug(e, "running at offset %i %08x\n", current_offset, current_offset); 
    107113 
     114                        emu_memory_clear(mem); 
     115 
    108116                        /* write the code to the offset */ 
    109117                        emu_memory_write_block(mem, STATIC_OFFSET, data, datasize); 
     118                         
    110119 
    111120                        /* set the registers to the initial values */ 
     
    126135                for ( j=0;j<steps;j++ ) 
    127136                { 
     137//                      emu_cpu_debug_print(cpu); 
    128138                        uint32_t eipsave; 
    129139                        eipsave = emu_cpu_eip_get(cpu); 
     
    153163                                { 
    154164                                        logDebug(e, "error at %s\n", cpu->instr_string); 
    155                                         break; 
     165                                        if (brute_force) 
     166                                        { 
     167                                                logDebug(e, "goto traversal\n"); 
     168                                                goto traversal; 
     169                                        } 
     170                                        else 
     171                                                break; 
    156172                                } 
    157173 
    158174                                if ( emu_track_instruction_check(e, etas) == -1 ) 
    159175                                { 
     176traversal: 
    160177                                        logDebug(e, "failed instr %s\n", cpu->instr_string); 
    161178                                        logDebug(e, "tracking at eip %08x\n", eipsave); 
     
    215232                                                        current_pos_v->color = red; 
    216233 
    217                                                         while ( !emu_tracking_info_covers(&current_pos_satii->track.init, current_pos_ti_diff)
     234                                                        while ( !emu_tracking_info_covers(&current_pos_satii->track.init, current_pos_ti_diff) || brute_force
    218235                                                        { 
    219236                                                                logDebug(e, "loop %s:%i\n", __FILE__, __LINE__); 
     
    252269                                                        } 
    253270 
    254                                                         if ( emu_tracking_info_covers(&current_pos_satii->track.init, current_pos_ti_diff)
     271                                                        if ( emu_tracking_info_covers(&current_pos_satii->track.init, current_pos_ti_diff) || brute_force
    255272                                                        { 
    256273                                                                logDebug(e, "found position which satiesfies the requirements %i %08x\n", current_pos_satii->eip, current_pos_satii->eip); 
     
    279296                struct emu_list_item *eli = emu_list_item_create(); 
    280297                eli->data = es; 
    281                 emu_list_insert_last(tested_positions, eli); 
     298                emu_list_insert_last(stats_tested_positions_list, eli); 
    282299        } 
    283300 
     
    286303 
    287304        /* sort all tested positions by the number of steps ascending */ 
    288         emu_list_qsort(tested_positions, tested_positions_cmp); 
    289  
    290  
    291 #if 0 
    292         { 
    293                 struct emu_list_item *eli; 
    294                 for ( eli = emu_list_first(tested_positions); !emu_list_attail(eli); eli = emu_list_next(eli) ) 
    295                 { 
    296                         struct emu_stats *es = (struct emu_stats *)eli->data; 
    297                         printf("a offset 0x%08x steps %i\n",es->eip, es->cpu.steps); 
    298                 } 
    299         } 
    300 #endif // 0 
    301  
    302         struct emu_list_item *eli = emu_list_first(tested_positions); 
     305        emu_list_qsort(stats_tested_positions_list, tested_positions_cmp); 
     306 
     307        struct emu_list_item *eli = emu_list_first(stats_tested_positions_list); 
    303308        struct emu_stats *es = (struct emu_stats *)eli->data; 
    304309        uint32_t best_offset = es->eip; 
    305310 
    306         *running_stats = es; 
    307         eli->data = NULL; 
    308  
    309         for (eli = emu_list_first(tested_positions); !emu_list_attail(eli); eli = emu_list_next(eli)) 
    310         { 
    311                 if (eli->data != NULL) 
    312                 { 
    313                         emu_stats_free((struct emu_stats *)eli->data); 
    314                 } 
    315         } 
    316  
    317  
    318  
    319311        return best_offset - STATIC_OFFSET; 
    320312} 
    321  
    322313 
    323314enum 
     
    399390        { 
    400391                logDebug(e, "testing offset %i %08x\n", eli->uint32, eli->uint32); 
    401  
    402                 struct emu_list_item *xeli = emu_list_item_create(); 
    403                 void **v = &xeli->data; 
    404                 struct emu_stats **stats = (struct emu_stats **)v; 
    405  
    406                 int32_t this_offset = emu_shellcode_run_and_track(e, data, size, eli->uint32, 256, env, etas, eh, stats); 
    407  
    408                 ((struct emu_stats *)xeli->data)->eip = this_offset; 
    409                 emu_list_insert_last(results, xeli); 
    410         } 
     392                emu_shellcode_run_and_track(e, data, size, eli->uint32, 256, env, etas, eh, 
     393                                                                        results, false); 
     394        } 
     395 
     396        /* for all positions we got, take the best, maybe take memory access into account later */ 
     397        emu_list_qsort(results, tested_positions_cmp); 
     398        if ( ((struct emu_stats *)emu_list_first(results)->data)->cpu.steps != 256 ) 
     399        { 
     400                logDebug(e, "brute force!\n"); 
     401                struct emu_list_root *new_results = emu_list_create(); 
     402                for ( eli = emu_list_first(results); !emu_list_attail(eli); eli = emu_list_next(eli) ) 
     403                { 
     404                        struct emu_stats *es = (struct emu_stats *)eli->data; 
     405                        logDebug(e, "brute at offset 0x%08x \n",es->eip - STATIC_OFFSET); 
     406                        emu_shellcode_run_and_track(e, data, size, es->eip - STATIC_OFFSET, 256, env, etas, eh, 
     407                                                                                new_results, true); 
     408                         
     409                } 
     410 
     411                emu_list_concat(results, new_results); 
     412                emu_list_qsort(results, tested_positions_cmp); 
     413 
     414                /* uniq */ 
     415                for ( eli = emu_list_first(results); !emu_list_attail(eli); eli = emu_list_next(eli) ) 
     416                { 
     417                        struct emu_list_item *next = emu_list_next(eli); 
     418                        if (next != NULL && 
     419                ((struct emu_stats *)eli->data)->eip == ((struct emu_stats *)next->data)->eip ) 
     420                                emu_list_remove(next); 
     421                } 
     422        } 
     423 
     424         
    411425 
    412426        emu_hashtable_free(eh); 
     
    415429        emu_track_and_source_free(etas); 
    416430 
    417         /* for all positions we got, take the best, maybe take memory access into account later */ 
    418         emu_list_qsort(results, tested_positions_cmp); 
    419  
    420 #if 0 
     431 
    421432        { 
    422433                struct emu_list_item *eli; 
     
    424435                { 
    425436                        struct emu_stats *es = (struct emu_stats *)eli->data; 
    426                         printf("b offset 0x%08x steps %i\n",es->eip, es->cpu.steps); 
    427                 } 
    428         } 
    429 #endif // 0 
     437                        logDebug(e, "b offset 0x%08x steps %i\n",es->eip, es->cpu.steps); 
     438                } 
     439        } 
    430440 
    431441        eli = emu_list_first(results); 
     
    447457        emu_list_destroy(results); 
    448458 
    449         return offset
     459        return offset - STATIC_OFFSET
    450460} 
    451461