Changeset 1239

Show
Ignore:
Timestamp:
04/25/07 23:54:29 (2 years ago)
Author:
common
Message:

libemu

  • add emu_queue, emu_queue_{new,free,front,{en,de}queue,empty}
  • add emu_source, some parts of emu_source were already written in emu_track, and as emu_source and emu_track share a lot of data, they share the same struct now, emu_track_and_source, tracking functions use the emu_track_ prefix, sourcing functions the emu_source prefix
  • implement emu_source_bfs using emu_queue and some new emu_colors for backwards traversal, the end vertex gets the color red, on-the-way vertexes get the color black, starting vertexes get the color green, got to check what to do with all the other colors as well, cyan deserves a very special destiny
  • sctest move the getpc code to use the emu_source fns

  • may leak little mem for now in getpc mode
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libemu/trunk/include/emu/emu_graph.h

    r1229 r1239  
    2727header_list_functions(emu_vertexes,emu_vertex_root, emu_vertex, link); 
    2828 
    29 enum emu_vertex_color { white, grey, black }; 
     29 
     30 
     31 
     32enum emu_color { black, blue, cyan, green, grey, magenta, red, white, yellow }; 
    3033 
    3134struct emu_vertex 
     
    3538 
    3639        emu_vertex_link link; 
    37         enum emu_vertex_color color; 
     40        enum emu_color color; 
    3841 
    3942        emu_edge_root  *backedges; 
  • libemu/trunk/include/emu/emu_track.h

    r1225 r1239  
    11/* @header@ */ 
     2 
     3#ifndef HAVE_EMU_TRACK_H 
     4#define HAVE_EMU_TRACK_H 
    25 
    36#include <stdint.h> 
     
    710struct emu_graph; 
    811struct emu_instruction; 
     12struct emu_source; 
    913 
    1014 
    11 struct emu_track_instr_info 
     15struct emu_source_and_track_instr_info 
    1216{ 
    1317        uint32_t eip; 
     
    3236}; 
    3337 
    34 struct emu_track_instr_info *emu_track_instr_info_new(struct emu_cpu *cpu, uint32_t eip_before_instruction); 
    35 void emu_track_instr_info_free(); 
     38struct emu_source_and_track_instr_info *emu_source_and_track_instr_info_new(struct emu_cpu *cpu, uint32_t eip_before_instruction); 
     39void emu_source_track_instr_info_free(struct emu_source_and_track_instr_info *esantii); 
    3640 
    37 bool emu_track_instr_info_cmp(void *a, void *b); 
    38 uint32_t emu_track_instr_info_hash(void *key); 
     41bool emu_source_and_track_instr_info_cmp(void *a, void *b); 
     42uint32_t emu_source_and_track_instr_info_hash(void *key); 
    3943 
    4044 
    41 struct emu_track 
     45struct emu_track_and_source 
    4246{ 
    4347        uint32_t eflags; 
    4448        uint32_t reg[8]; 
    4549 
    46         struct emu_graph                *trackgraph; 
    47         struct emu_hashtable    *instrtable; 
     50        struct emu_graph                *instr_graph; 
     51        struct emu_hashtable    *instr_table; 
     52 
     53        struct emu_source               *source; 
    4854}; 
    4955 
    5056 
    51 struct emu_track *emu_track_new(); 
    52 void emu_track_free(struct emu_track *et); 
    53 uint32_t emu_track_tree_create(struct emu *e, struct emu_track *et, uint32_t datastart, uint32_t datasize); 
    54 int32_t emu_track_instruction_check(struct emu *e, struct emu_track *et); 
     57struct emu_track_and_source *emu_track_and_source_new(); 
     58void emu_track_and_source_free(struct emu_track_and_source *et); 
    5559 
     60int32_t emu_track_instruction_check(struct emu *e, struct emu_track_and_source *et); 
     61 
     62#endif 
  • libemu/trunk/src/Makefile.am

    r1225 r1239  
    2222libemu_la_SOURCES += emu_graph.c 
    2323libemu_la_SOURCES += emu_hashtable.c 
     24libemu_la_SOURCES += emu_queue.c 
     25libemu_la_SOURCES += emu_source.c 
    2426libemu_la_SOURCES += emu_track.c 
    2527libemu_la_SOURCES += functions/aaa.c 
  • libemu/trunk/src/emu_track.c

    r1236 r1239  
     1/* @header@ */ 
     2 
    13#include <string.h> 
    24 
     
    68#include "emu/emu_instruction.h" 
    79#include "emu/emu_track.h" 
     10#include "emu/emu_source.h" 
    811#include "emu/emu_hashtable.h" 
    912#include "emu/emu_graph.h" 
    1013 
    11 struct emu_track_instr_info *emu_track_instr_info_new(struct emu_cpu *cpu, uint32_t eip_before_instruction
     14struct emu_track_and_source *emu_track_and_source_new(
    1215{ 
    13         struct emu_track_instr_info *etii = (struct emu_track_instr_info *)malloc(sizeof(struct emu_track_instr_info)); 
    14         memset(etii, 0, sizeof(struct emu_track_instr_info)); 
    15  
    16         etii->eip = eip_before_instruction; 
    17         etii->instrstring = strdup(cpu->instr_string); 
    18  
    19         if ( cpu->instr.is_fpu ) 
    20         { 
    21                 etii->source.norm_pos           = cpu->instr.fpu.source.norm_pos;                
    22         }else 
    23         { 
    24                 etii->source.has_cond_pos       = cpu->instr.cpu.source.has_cond_pos; 
    25                 etii->source.cond_pos           = cpu->instr.cpu.source.cond_pos; 
    26                 etii->source.norm_pos           = cpu->instr.cpu.source.norm_pos; 
    27  
    28                 etii->track.init.eflags         = cpu->instr.cpu.track.init.eflags; 
    29                 memcpy(etii->track.init.reg, cpu->instr.cpu.track.init.reg, sizeof(uint32_t)*8); 
    30  
    31                 etii->track.need.eflags         = cpu->instr.cpu.track.need.eflags; 
    32                 memcpy(etii->track.need.reg, cpu->instr.cpu.track.need.reg, sizeof(uint32_t)*8); 
    33         } 
    34         return etii; 
    35 
    36  
    37 void emu_track_instr_info_free(struct emu_track_instr_info *etii) 
    38 
    39         if (etii->instrstring != NULL) 
    40                 free(etii->instrstring); 
    41  
    42         free(etii); 
    43 
    44  
    45 bool emu_track_instr_info_cmp(void *a, void *b) 
    46 
    47         if ((uint32_t)a == (uint32_t)b) 
    48                 return true; 
    49  
    50         return false; 
    51 
    52  
    53 uint32_t emu_track_instr_info_hash(void *key) 
    54 
    55         uint32_t ukey = (uint32_t)key; 
    56         ukey++; 
    57         return ukey; 
    58 
    59  
    60  
    61 struct emu_track *emu_track_new() 
    62 
    63         struct emu_track *et = (struct emu_track *)malloc(sizeof(struct emu_track)); 
    64         memset(et, 0, sizeof(struct emu_track)); 
     16        struct emu_track_and_source *et = (struct emu_track_and_source *)malloc(sizeof(struct emu_track_and_source)); 
     17        memset(et, 0, sizeof(struct emu_track_and_source)); 
    6518        et->reg[esp] = 0xffffffff; 
    6619        return et; 
    6720} 
    6821 
    69 void emu_track_free(struct emu_track *et) 
     22void emu_track_and_source_free(struct emu_track_and_source *et) 
    7023{ 
    71         if (et->instrtable != NULL) 
    72                 emu_hashtable_free(et->instrtable); 
     24        if (et->instr_table != NULL) 
     25                emu_hashtable_free(et->instr_table); 
    7326 
    74         if (et->trackgraph != NULL) 
    75                 emu_graph_free(et->trackgraph); 
     27        if (et->instr_graph != NULL) 
     28                emu_graph_free(et->instr_graph); 
    7629 
    7730        free(et); 
     
    7932} 
    8033 
    81 uint32_t emu_track_tree_create(struct emu *e, struct emu_track *et, uint32_t datastart, uint32_t datasize) 
    82 { 
    83         printf("tracking from %x to %x\n", datastart, datastart+datasize); 
    84         struct emu_cpu *c = emu_cpu_get(e); 
    85  
    86         et->trackgraph = emu_graph_new(); 
    87         et->instrtable = emu_hashtable_new(datasize/2, emu_track_instr_info_hash,  emu_track_instr_info_cmp); 
    88  
    89         uint32_t i; 
    90         for (i=datastart;i<datastart+datasize;i++) 
    91         { 
    92                 emu_cpu_eip_set(c, i); 
    93  
    94                 if ( emu_cpu_parse(c) != 0) 
    95                         continue; 
    96  
    97                 if ( emu_cpu_step(c) != 0) 
    98                         continue; 
    99  
    100         struct emu_track_instr_info *etii = emu_track_instr_info_new(c,i); 
    101                 struct emu_vertex *ev = emu_vertex_new(); 
    102                 ev->data = etii; 
    103                 emu_hashtable_insert(et->instrtable, (void *)i, ev); 
    104                 emu_graph_vertex_add(et->trackgraph, ev); 
    105         } 
    106  
    107         struct emu_vertex *ev; 
    108         for ( ev = emu_vertexes_first(et->trackgraph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) 
    109         { 
    110                 struct emu_track_instr_info *etii = (struct emu_track_instr_info *)ev->data; 
    111  
    112                 struct emu_hashtable_item *ehi = emu_hashtable_search(et->instrtable, (void *)etii->source.norm_pos); 
    113                 printf("NORM from %08x to %08x\n",((struct emu_track_instr_info *)ev->data)->eip, etii->source.norm_pos); 
    114                 if (ehi != NULL) 
    115                 { 
    116                         struct emu_vertex *to = (struct emu_vertex *)ehi->value; 
    117                         emu_vertex_edge_add(ev, to); 
    118                          
    119                 }else 
    120                 { 
    121                         printf("NORM IS UNKNOWN\n"); 
    122                 } 
    123  
    124                 if (etii->source.has_cond_pos == 1) 
    125                 { 
    126                         printf("COND from %08x to %08x\n",((struct emu_track_instr_info *)ev->data)->eip, etii->source.cond_pos); 
    127                         ehi = emu_hashtable_search(et->instrtable, (void *)etii->source.cond_pos); 
    128                         if (ehi != NULL) 
    129                         { 
    130                                 struct emu_vertex *to = (struct emu_vertex *)ehi->value; 
    131                                 emu_vertex_edge_add(ev, to); 
    132                                  
    133                         }else 
    134                         { 
    135                                 printf("COND IS UNKNOWN\n"); 
    136                         } 
    137                 } 
    138         } 
    139         return 0; 
    140 } 
    14134 
    14235void debug_instruction(struct emu_cpu_instruction *i); 
    14336 
    144 int32_t emu_track_instruction_check(struct emu *e, struct emu_track *et) 
     37int32_t emu_track_instruction_check(struct emu *e, struct emu_track_and_source *et) 
    14538{ 
    14639        struct emu_cpu *c = emu_cpu_get(e); 
     
    17972        return 0; 
    18073} 
     74 
     75 
     76struct emu_source_and_track_instr_info *emu_source_and_track_instr_info_new(struct emu_cpu *cpu, uint32_t eip_before_instruction) 
     77{ 
     78        struct emu_source_and_track_instr_info *etii = (struct emu_source_and_track_instr_info *)malloc(sizeof(struct emu_source_and_track_instr_info)); 
     79        memset(etii, 0, sizeof(struct emu_source_and_track_instr_info)); 
     80 
     81        etii->eip = eip_before_instruction; 
     82        etii->instrstring = strdup(cpu->instr_string); 
     83 
     84        if ( cpu->instr.is_fpu ) 
     85        { 
     86                etii->source.norm_pos           = cpu->instr.fpu.source.norm_pos;                
     87        }else 
     88        { 
     89                etii->source.has_cond_pos       = cpu->instr.cpu.source.has_cond_pos; 
     90                etii->source.cond_pos           = cpu->instr.cpu.source.cond_pos; 
     91                etii->source.norm_pos           = cpu->instr.cpu.source.norm_pos; 
     92 
     93                etii->track.init.eflags         = cpu->instr.cpu.track.init.eflags; 
     94                memcpy(etii->track.init.reg, cpu->instr.cpu.track.init.reg, sizeof(uint32_t)*8); 
     95 
     96                etii->track.need.eflags         = cpu->instr.cpu.track.need.eflags; 
     97                memcpy(etii->track.need.reg, cpu->instr.cpu.track.need.reg, sizeof(uint32_t)*8); 
     98        } 
     99        return etii; 
     100} 
     101 
     102void emu_source_and_track_instr_info_free(struct emu_source_and_track_instr_info *etii) 
     103{ 
     104        if (etii->instrstring != NULL) 
     105                free(etii->instrstring); 
     106 
     107        free(etii); 
     108} 
     109 
     110bool emu_source_and_track_instr_info_cmp(void *a, void *b) 
     111{ 
     112        if ((uint32_t)a == (uint32_t)b) 
     113                return true; 
     114 
     115        return false; 
     116} 
     117 
     118uint32_t emu_source_and_track_instr_info_hash(void *key) 
     119{ 
     120        uint32_t ukey = (uint32_t)key; 
     121        ukey++; 
     122        return ukey; 
     123} 
     124 
  • libemu/trunk/testsuite/sctest.c

    r1237 r1239  
    14201420 
    14211421#include <emu/emu_track.h> 
    1422  
    1423 void bfs_from_getpc(struct emu_vertex *ev) 
    1424 
    1425         printf("%08x %s\n", (unsigned int)ev, ((struct emu_track_instr_info *)ev->data)->instrstring); 
    1426  
    1427         struct emu_edge *ee; 
    1428 /*      for ( ee = emu_edges_first(ev->backedges); !emu_edges_attail(ee); ee = emu_edges_next(ee) ) 
    1429         { 
    1430                 if (ee->destination->color == white) 
    1431                         bfs_from_getpc(ee->destination); 
    1432         } 
    1433 */ 
    1434         if ( emu_edges_length(ev->backedges) == 0 ) 
    1435         { 
    1436                 ev->color = grey; 
    1437         } 
    1438         else 
    1439         { 
    1440                 ev->color = black; 
    1441         } 
    1442  
    1443         for ( ee = emu_edges_first(ev->backedges); !emu_edges_attail(ee); ee = emu_edges_next(ee) ) 
    1444         { 
    1445                 if ( ee->destination->color == white ) 
    1446                         bfs_from_getpc(ee->destination); 
    1447         } 
    1448  
    1449 
    1450  
    1451 int32_t run_and_track(struct emu *e, struct emu_track *et, struct emu_env_w32 *env) 
     1422#include <emu/emu_source.h> 
     1423 
     1424int32_t run_and_track(struct emu *e, struct emu_track_and_source *et, struct emu_env_w32 *env) 
    14521425{ 
    14531426        int ret = -1; 
     
    15121485        struct emu_memory *mem = emu_memory_get(e); 
    15131486        struct emu_env_w32 *env = emu_env_w32_new(e); 
    1514         struct emu_track *et = emu_track_new(); 
     1487        struct emu_track_and_source *et = emu_track_and_source_new(); 
    15151488 
    15161489        if ( env == 0 ) 
     
    16361609                                { 
    16371610                                        printf("FOX\n"); 
    1638                                         emu_track_tree_create(e, et, static_offset, tests[i].codesize); 
     1611                                        emu_source_instruction_graph_create(e, et, static_offset, tests[i].codesize); 
    16391612 
    16401613                                        struct emu_vertex *ev; 
    1641                                         for ( ev = emu_vertexes_first(et->trackgraph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) 
    1642                                         { 
    1643                                                 ev->color = white; 
    1644                                         } 
    1645  
    1646 /*                                      for ( ev = emu_vertexes_first(et->trackgraph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) 
    1647                                         { 
    1648                                                 bfs_from_getpc(ev); 
    1649                                         } 
    1650 */ 
    1651                                         struct emu_hashtable_item *ehi = emu_hashtable_search(et->instrtable, (void *)(static_offset+offset)); 
     1614 
     1615                                        struct emu_hashtable_item *ehi = emu_hashtable_search(et->instr_table, (void *)(static_offset+offset)); 
    16521616 
    16531617                                        if ( ehi != NULL ) 
    16541618                                        { 
    16551619                                                ev = (struct emu_vertex *)ehi->value; 
    1656                                                 bfs_from_getpc(ev); 
    1657  
    1658                                                 for ( ev = emu_vertexes_first(et->trackgraph->vertexes);  
     1620                                                emu_source_bfs(et, ev); 
     1621 
     1622                                                for ( ev = emu_vertexes_first(et->instr_graph->vertexes);  
    16591623                                                        !emu_vertexes_attail(ev) && found_good_candidate_after_getpc == false;  
    16601624                                                        ev = emu_vertexes_next(ev) ) 
    16611625                                                { 
    1662                                                         if ( ev->color == grey
     1626                                                        if ( ev->color == green
    16631627                                                        { 
    16641628                                                                printf("POSSIBLE\n"); 
    1665                                                                 struct emu_track_instr_info *etii = (struct emu_track_instr_info *)ev->data; 
     1629                                                                struct emu_source_and_track_instr_info *etii = (struct emu_source_and_track_instr_info *)ev->data; 
    16661630 
    16671631                                                                for ( j=0;j<8;j++ )