| 1660 | | for ( i=0;i<sizeof(tests)/sizeof(struct instr_test);i++ ) |
|---|
| 1661 | | { |
|---|
| 1662 | | if ( n != -1 && i != n && !opts.from_stdin ) |
|---|
| 1663 | | continue; |
|---|
| 1664 | | |
|---|
| 1665 | | // int failed = 0; |
|---|
| 1666 | | if (!opts.from_stdin) |
|---|
| 1667 | | printf("testing (#%d) '%s' \t", i, tests[i].instr); |
|---|
| 1668 | | |
|---|
| 1669 | | int j=0; |
|---|
| 1670 | | |
|---|
| 1671 | | /* set the registers to the initial values */ |
|---|
| 1672 | | for ( j=0;j<8;j++ ) |
|---|
| 1673 | | { |
|---|
| 1674 | | emu_cpu_reg32_set(cpu,j ,tests[i].in_state.reg[j]); |
|---|
| 1675 | | } |
|---|
| 1676 | | |
|---|
| 1677 | | |
|---|
| 1678 | | /* set the flags */ |
|---|
| 1679 | | emu_cpu_eflags_set(cpu,tests[i].in_state.eflags); |
|---|
| 1680 | | |
|---|
| 1681 | | |
|---|
| 1682 | | /* write the code to the offset */ |
|---|
| 1683 | | int static_offset = CODE_OFFSET; |
|---|
| 1684 | | if (!opts.from_stdin) |
|---|
| 1685 | | emu_memory_write_block(mem, static_offset, tests[i].code, tests[i].codesize); |
|---|
| 1686 | | else |
|---|
| 1687 | | emu_memory_write_block(mem, static_offset, opts.scode, opts.size); |
|---|
| 1688 | | |
|---|
| 1689 | | |
|---|
| 1690 | | |
|---|
| 1691 | | /* set eip to the code */ |
|---|
| 1692 | | emu_cpu_eip_set(emu_cpu_get(e), static_offset + opts.offset); |
|---|
| 1693 | | |
|---|
| 1694 | | /* run the code */ |
|---|
| | 1681 | int j=0; |
|---|
| | 1682 | |
|---|
| | 1683 | |
|---|
| | 1684 | /* run the code */ |
|---|
| | 1685 | if ( opts.verbose >= 2 ) |
|---|
| | 1686 | { |
|---|
| | 1687 | emu_log_level_set(emu_logging_get(e),EMU_LOG_DEBUG); |
|---|
| | 1688 | emu_cpu_debug_print(cpu); |
|---|
| | 1689 | emu_log_level_set(emu_logging_get(e),EMU_LOG_NONE); |
|---|
| | 1690 | } |
|---|
| | 1691 | |
|---|
| | 1692 | |
|---|
| | 1693 | struct emu_vertex *last_vertex = NULL; |
|---|
| | 1694 | struct emu_graph *graph = NULL; |
|---|
| | 1695 | struct emu_hashtable *eh = NULL; |
|---|
| | 1696 | struct emu_hashtable_item *ehi = NULL; |
|---|
| | 1697 | |
|---|
| | 1698 | if ( opts.graphfile != NULL ) |
|---|
| | 1699 | { |
|---|
| | 1700 | graph = emu_graph_new(); |
|---|
| | 1701 | eh = emu_hashtable_new(2047, hash, cmp); |
|---|
| | 1702 | } |
|---|
| | 1703 | |
|---|
| | 1704 | |
|---|
| | 1705 | int ret; //= emu_cpu_run(emu_cpu_get(e)); |
|---|
| | 1706 | |
|---|
| | 1707 | |
|---|
| | 1708 | |
|---|
| | 1709 | uint32_t eipsave = 0; |
|---|
| | 1710 | for ( j=0;j<opts.steps;j++ ) |
|---|
| | 1711 | { |
|---|
| | 1712 | |
|---|
| 1782 | | if ( eipsave > env->loaded_dlls[numdlls]->baseaddr && |
|---|
| 1783 | | eipsave < env->loaded_dlls[numdlls]->baseaddr + env->loaded_dlls[numdlls]->imagesize ) |
|---|
| 1784 | | { |
|---|
| 1785 | | iv->dll = env->loaded_dlls[numdlls]; |
|---|
| 1786 | | } |
|---|
| 1787 | | numdlls++; |
|---|
| 1788 | | } |
|---|
| 1789 | | |
|---|
| 1790 | | } |
|---|
| 1791 | | |
|---|
| 1792 | | if ( dllhook->fnhook == NULL ) |
|---|
| 1793 | | break; |
|---|
| 1794 | | |
|---|
| 1795 | | } |
|---|
| 1796 | | else |
|---|
| 1797 | | { |
|---|
| 1798 | | |
|---|
| 1799 | | ret = emu_cpu_parse(emu_cpu_get(e)); |
|---|
| 1800 | | |
|---|
| 1801 | | if ( opts.verbose >= 1 ) |
|---|
| 1802 | | { |
|---|
| 1803 | | emu_log_level_set(emu_logging_get(e),EMU_LOG_DEBUG); |
|---|
| 1804 | | logDebug(e, "%s\n", cpu->instr_string); |
|---|
| 1805 | | emu_log_level_set(emu_logging_get(e),EMU_LOG_NONE); |
|---|
| 1806 | | } |
|---|
| 1807 | | |
|---|
| 1808 | | struct emu_env_linux_syscall *syscall =NULL; |
|---|
| 1809 | | if ( ret != -1 ) |
|---|
| 1810 | | { |
|---|
| 1811 | | |
|---|
| 1812 | | if ( ( syscall = emu_env_linux_syscall_check(lenv)) != NULL) |
|---|
| 1813 | | { |
|---|
| 1814 | | if ( opts.graphfile != NULL && ev->data == NULL ) |
|---|
| 1815 | | { |
|---|
| 1816 | | iv = instr_vertex_new(eipsave, syscall->name); |
|---|
| 1817 | | emu_vertex_data_set(ev, iv); |
|---|
| 1818 | | iv->syscall = syscall; |
|---|
| 1819 | | } |
|---|
| 1820 | | }else |
|---|
| 1821 | | { |
|---|
| 1822 | | |
|---|
| 1823 | | if ( opts.graphfile != NULL && ev->data == NULL ) |
|---|
| 1824 | | { |
|---|
| 1825 | | iv = instr_vertex_new(eipsave, emu_cpu_get(e)->instr_string); |
|---|
| 1826 | | emu_vertex_data_set(ev, iv); |
|---|
| 1827 | | } |
|---|
| | 1806 | iv = instr_vertex_new(eipsave, syscall->name); |
|---|
| | 1807 | emu_vertex_data_set(ev, iv); |
|---|
| | 1808 | iv->syscall = syscall; |
|---|
| 1872 | | } |
|---|
| 1873 | | |
|---|
| 1874 | | printf("stepcount %i\n",j); |
|---|
| 1875 | | |
|---|
| 1876 | | |
|---|
| 1877 | | if ( opts.graphfile != NULL ) |
|---|
| 1878 | | { |
|---|
| 1879 | | |
|---|
| 1880 | | struct emu_vertex *ev; |
|---|
| 1881 | | struct instr_vertex *iv; |
|---|
| 1882 | | |
|---|
| 1883 | | FILE *f = fopen(opts.graphfile,"w+"); |
|---|
| 1884 | | |
|---|
| 1885 | | struct emu_graph *sgraph = emu_graph_new(); |
|---|
| 1886 | | struct emu_hashtable *ht = emu_hashtable_new(2047, hash, cmp); |
|---|
| 1887 | | |
|---|
| 1888 | | struct emu_vertex *nev; |
|---|
| 1889 | | struct instr_vertex *niv=NULL; |
|---|
| 1890 | | |
|---|
| 1891 | | printf("copying vertexes\n"); |
|---|
| 1892 | | for ( ev = emu_vertexes_first(graph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) |
|---|
| 1893 | | { |
|---|
| 1894 | | iv = (struct instr_vertex *)ev->data; |
|---|
| 1895 | | |
|---|
| 1896 | | nev = emu_vertex_new(); |
|---|
| 1897 | | emu_graph_vertex_add(sgraph, nev); |
|---|
| 1898 | | |
|---|
| 1899 | | niv = instr_vertex_copy(iv); |
|---|
| 1900 | | nev->data = niv; |
|---|
| 1901 | | |
|---|
| 1902 | | emu_hashtable_insert(ht, (void *)iv->eip, nev); |
|---|
| 1903 | | ev->color = white; |
|---|
| 1904 | | } |
|---|
| 1905 | | |
|---|
| 1906 | | printf("optimizing graph\n"); |
|---|
| 1907 | | for ( ev = emu_vertexes_first(graph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) |
|---|
| 1908 | | { |
|---|
| 1909 | | // ignore known |
|---|
| 1910 | | if ( ev->color == black ) |
|---|
| 1911 | | continue; |
|---|
| 1912 | | |
|---|
| 1913 | | |
|---|
| 1914 | | printf("vertex %08x\n", (unsigned int)ev); |
|---|
| 1915 | | |
|---|
| 1916 | | // find the first in a chain |
|---|
| 1917 | | iv = (struct instr_vertex *)ev->data; |
|---|
| 1918 | | while ( emu_edges_length(ev->backedges) == 1 && emu_edges_length(ev->edges) <= 1 && ev->color == white && iv->dll == NULL && iv->syscall == NULL ) |
|---|
| 1919 | | { |
|---|
| 1920 | | ev->color = grey; |
|---|
| 1921 | | |
|---|
| 1922 | | struct emu_vertex *xev = emu_edges_first(ev->backedges)->destination; |
|---|
| 1923 | | iv = (struct instr_vertex *)xev->data; |
|---|
| 1924 | | if ( emu_edges_length(xev->backedges) > 1 || emu_edges_length(xev->edges) > 1 || iv->dll != NULL || iv->syscall != NULL ) |
|---|
| 1925 | | break; |
|---|
| 1926 | | |
|---|
| 1927 | | ev = xev; |
|---|
| 1928 | | printf(" -> vertex %08x\n",(unsigned int)ev); |
|---|
| 1929 | | } |
|---|
| 1930 | | |
|---|
| 1931 | | |
|---|
| 1932 | | iv = (struct instr_vertex *)ev->data; |
|---|
| 1933 | | |
|---|
| 1934 | | // create the new vertex |
|---|
| 1935 | | nev = (struct emu_vertex *)emu_hashtable_search(ht, (void *)iv->eip)->value; |
|---|
| 1936 | | niv = (struct instr_vertex *)nev->data; |
|---|
| 1937 | | |
|---|
| 1938 | | iv = (struct instr_vertex *)ev->data; |
|---|
| 1939 | | |
|---|
| 1940 | | printf("going forwards from %08x\n", (unsigned int)ev); |
|---|
| 1941 | | while ( emu_edges_length(ev->edges) == 1 && emu_edges_length(ev->backedges) <= 1 && ev->color != black && iv->dll == NULL && iv->syscall == NULL ) |
|---|
| 1942 | | { |
|---|
| 1943 | | ev->color = black; |
|---|
| 1944 | | struct emu_vertex *xev = emu_edges_first(ev->edges)->destination; |
|---|
| 1945 | | iv = (struct instr_vertex *)xev->data; |
|---|
| 1946 | | |
|---|
| 1947 | | if ( emu_edges_length(xev->backedges) > 1 || emu_edges_length(xev->edges) > 1 || |
|---|
| 1948 | | iv->dll != NULL || iv->syscall != NULL ) |
|---|
| 1949 | | break; |
|---|
| 1950 | | |
|---|
| 1951 | | ev = xev; |
|---|
| 1952 | | |
|---|
| 1953 | | iv = (struct instr_vertex *)ev->data; |
|---|
| 1954 | | emu_string_append_char(niv->instr_string, emu_string_char(iv->instr_string)); |
|---|
| 1955 | | printf(" -> vertex %08x\n",(unsigned int)ev); |
|---|
| 1956 | | } |
|---|
| 1957 | | |
|---|
| 1958 | | ev->color = black; |
|---|
| 1959 | | |
|---|
| 1960 | | printf("copying edges for %08x\n",(unsigned int)ev); |
|---|
| 1961 | | struct emu_edge *ee; |
|---|
| 1962 | | for ( ee = emu_edges_first(ev->edges); !emu_edges_attail(ee); ee = emu_edges_next(ee) ) |
|---|
| 1963 | | { |
|---|
| 1964 | | struct instr_vertex *ivto = emu_vertex_data_get(ee->destination); |
|---|
| 1965 | | struct emu_hashtable_item *ehi = emu_hashtable_search(ht, (void *)ivto->eip); |
|---|
| 1966 | | struct emu_vertex *to = (struct emu_vertex *)ehi->value; |
|---|
| 1967 | | if (1)// nev != to )//&& to->color != black ) |
|---|
| 1968 | | { |
|---|
| 1969 | | struct emu_edge *nee = emu_vertex_edge_add(nev, to); |
|---|
| 1970 | | nee->count = ee->count; |
|---|
| 1971 | | nee->data = ee->data; |
|---|
| 1972 | | printf(" -> %08x\n", (unsigned int)to); |
|---|
| 1973 | | } |
|---|
| 1974 | | } |
|---|
| 1975 | | |
|---|
| 1976 | | } |
|---|
| 1977 | | |
|---|
| 1978 | | graph->vertex_destructor = instr_vertex_destructor; |
|---|
| 1979 | | emu_graph_free(graph); |
|---|
| 1980 | | graph = sgraph; |
|---|
| 1981 | | |
|---|
| 1982 | | emu_hashtable_free(ht); |
|---|
| 1983 | | fprintf(f, "digraph G {\n\trankdir=LR\n"); |
|---|
| 1984 | | |
|---|
| 1985 | | #if 0 |
|---|
| 1986 | | int numdlls=0; |
|---|
| 1987 | | while ( env->loaded_dlls[numdlls] != NULL ) |
|---|
| 1988 | | { |
|---|
| 1989 | | int has_dll = 0; |
|---|
| 1990 | | struct emu_string *fs = emu_string_new(); |
|---|
| 1991 | | emu_string_append_format(fs, "\t subgraph cluster%i {\n\t\t node [shape=box, style=filled, color=\".7 .3 1.0\"];\n\t\tstyle=filled;\n\t\tcolor=lightgrey;\n\t\tlabel=\"%s\"\n\t\t", numdlls, env->loaded_dlls[numdlls]->dllname); |
|---|
| 1992 | | for ( ev = emu_vertexes_first(graph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) |
|---|
| 1993 | | { |
|---|
| 1994 | | struct instr_vertex *iv = emu_vertex_data_get(ev); |
|---|
| 1995 | | if ( iv->dll == env->loaded_dlls[numdlls] ) |
|---|
| 1996 | | { |
|---|
| 1997 | | emu_string_append_format(fs, "\t\%i [label = \"%s\"];\n", iv->eip, emu_string_char(iv->instr_string)); |
|---|
| 1998 | | |
|---|
| 1999 | | has_dll = 1; |
|---|
| 2000 | | } |
|---|
| 2001 | | |
|---|
| 2002 | | } |
|---|
| 2003 | | |
|---|
| 2004 | | emu_string_append_char(fs, "\t}\n"); |
|---|
| 2005 | | |
|---|
| 2006 | | fprintf(f, "%s", emu_string_char(fs)); |
|---|
| 2007 | | numdlls++; |
|---|
| 2008 | | } |
|---|
| 2009 | | #endif // 0 |
|---|
| 2010 | | for ( ev = emu_vertexes_first(graph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) |
|---|
| 2011 | | { |
|---|
| 2012 | | if ( emu_edges_length(ev->edges) == 0 && emu_edges_length(ev->backedges) == 0 ) |
|---|
| 2013 | | continue; |
|---|
| 2014 | | |
|---|
| 2015 | | struct instr_vertex *iv = emu_vertex_data_get(ev); |
|---|
| 2016 | | #if 0 |
|---|
| 2017 | | if ( iv->dll != NULL ) |
|---|
| 2018 | | continue; |
|---|
| 2019 | | #endif // 0 |
|---|
| 2020 | | if ( iv->dll != NULL || iv->syscall != NULL ) |
|---|
| 2021 | | fprintf(f, "\t %i [shape=box, style=filled, color=\".7 .3 1.0\", label = \"%s\"]\n",iv->eip, emu_string_char(iv->instr_string)); |
|---|
| 2022 | | else |
|---|
| 2023 | | fprintf(f, "\t %i [shape=box, label = \"%s\"]\n",iv->eip, emu_string_char(iv->instr_string)); |
|---|
| 2024 | | } |
|---|
| 2025 | | |
|---|
| 2026 | | for ( ev = emu_vertexes_first(graph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) |
|---|
| 2027 | | { |
|---|
| 2028 | | struct instr_vertex *ivfrom = emu_vertex_data_get(ev); |
|---|
| 2029 | | |
|---|
| 2030 | | struct emu_edge *ee; |
|---|
| 2031 | | for ( ee = emu_edges_first(ev->edges); !emu_edges_attail(ee); ee = emu_edges_next(ee) ) |
|---|
| 2032 | | { |
|---|
| 2033 | | struct instr_vertex *ivto = emu_vertex_data_get(ee->destination); |
|---|
| 2034 | | struct emu_string *fs = emu_string_new(); |
|---|
| 2035 | | |
|---|
| 2036 | | if ( ee->data != (void *)0x0 ) |
|---|
| 2037 | | emu_string_append_format(fs, "\t %i -> %i [style = dashed", ivfrom->eip, ivto->eip); |
|---|
| 2038 | | else |
|---|
| 2039 | | emu_string_append_format(fs, "\t %i -> %i [style = bold", ivfrom->eip, ivto->eip); |
|---|
| 2040 | | |
|---|
| 2041 | | if ( ee->count > 100 ) |
|---|
| 2042 | | emu_string_append_char(fs, ", color=red"); |
|---|
| 2043 | | else |
|---|
| 2044 | | if ( ee->count > 50 ) |
|---|
| 2045 | | emu_string_append_char(fs, ", color=blue"); |
|---|
| 2046 | | else |
|---|
| 2047 | | if ( ee->count > 25 ) |
|---|
| 2048 | | emu_string_append_char(fs, ", color=green"); |
|---|
| 2049 | | else |
|---|
| 2050 | | if ( ee->count > 1 ) |
|---|
| 2051 | | emu_string_append_char(fs, ", color=orange"); |
|---|
| 2052 | | |
|---|
| 2053 | | |
|---|
| 2054 | | |
|---|
| 2055 | | emu_string_append_char(fs, " ]\n"); |
|---|
| 2056 | | |
|---|
| 2057 | | fprintf(f, "%s", emu_string_char(fs)); |
|---|
| 2058 | | emu_string_free(fs); |
|---|
| 2059 | | } |
|---|
| 2060 | | |
|---|
| 2061 | | } |
|---|
| 2062 | | |
|---|
| 2063 | | |
|---|
| 2064 | | fprintf(f, "}"); |
|---|
| 2065 | | fclose(f); |
|---|
| 2066 | | |
|---|
| 2067 | | } |
|---|
| 2068 | | if ( opts.verbose >= 2 ) |
|---|
| 2069 | | { |
|---|
| 2070 | | emu_log_level_set(emu_logging_get(e),EMU_LOG_DEBUG); |
|---|
| 2071 | | emu_cpu_debug_print(cpu); |
|---|
| 2072 | | emu_log_level_set(emu_logging_get(e),EMU_LOG_NONE); |
|---|
| 2073 | | } |
|---|
| 2074 | | |
|---|
| 2075 | | if ( opts.graphfile != NULL ) |
|---|
| 2076 | | { |
|---|
| 2077 | | graph->vertex_destructor = instr_vertex_destructor; |
|---|
| 2078 | | emu_graph_free(graph); |
|---|
| 2079 | | emu_hashtable_free(eh); |
|---|
| 2080 | | } |
|---|
| 2081 | | |
|---|
| 2082 | | if (opts.from_stdin) |
|---|
| 2083 | | break; |
|---|
| 2090 | | |
|---|
| | 1887 | int graph_draw(struct emu_graph *graph) |
|---|
| | 1888 | { |
|---|
| | 1889 | struct emu_vertex *ev; |
|---|
| | 1890 | struct instr_vertex *iv; |
|---|
| | 1891 | |
|---|
| | 1892 | FILE *f = fopen(opts.graphfile,"w+"); |
|---|
| | 1893 | |
|---|
| | 1894 | struct emu_graph *sgraph = emu_graph_new(); |
|---|
| | 1895 | struct emu_hashtable *ht = emu_hashtable_new(2047, hash, cmp); |
|---|
| | 1896 | |
|---|
| | 1897 | struct emu_vertex *nev; |
|---|
| | 1898 | struct instr_vertex *niv=NULL; |
|---|
| | 1899 | |
|---|
| | 1900 | printf("copying vertexes\n"); |
|---|
| | 1901 | for ( ev = emu_vertexes_first(graph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) |
|---|
| | 1902 | { |
|---|
| | 1903 | iv = (struct instr_vertex *)ev->data; |
|---|
| | 1904 | |
|---|
| | 1905 | nev = emu_vertex_new(); |
|---|
| | 1906 | emu_graph_vertex_add(sgraph, nev); |
|---|
| | 1907 | |
|---|
| | 1908 | niv = instr_vertex_copy(iv); |
|---|
| | 1909 | nev->data = niv; |
|---|
| | 1910 | |
|---|
| | 1911 | emu_hashtable_insert(ht, (void *)iv->eip, nev); |
|---|
| | 1912 | ev->color = white; |
|---|
| | 1913 | } |
|---|
| | 1914 | |
|---|
| | 1915 | printf("optimizing graph\n"); |
|---|
| | 1916 | for ( ev = emu_vertexes_first(graph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) |
|---|
| | 1917 | { |
|---|
| | 1918 | // ignore known |
|---|
| | 1919 | if ( ev->color == black ) |
|---|
| | 1920 | continue; |
|---|
| | 1921 | |
|---|
| | 1922 | |
|---|
| | 1923 | printf("vertex %08x\n", (unsigned int)ev); |
|---|
| | 1924 | |
|---|
| | 1925 | // find the first in a chain |
|---|
| | 1926 | iv = (struct instr_vertex *)ev->data; |
|---|
| | 1927 | while ( emu_edges_length(ev->backedges) == 1 && emu_edges_length(ev->edges) <= 1 && ev->color == white && iv->dll == NULL && iv->syscall == NULL ) |
|---|
| | 1928 | { |
|---|
| | 1929 | ev->color = grey; |
|---|
| | 1930 | |
|---|
| | 1931 | struct emu_vertex *xev = emu_edges_first(ev->backedges)->destination; |
|---|
| | 1932 | iv = (struct instr_vertex *)xev->data; |
|---|
| | 1933 | if ( emu_edges_length(xev->backedges) > 1 || emu_edges_length(xev->edges) > 1 || iv->dll != NULL || iv->syscall != NULL ) |
|---|
| | 1934 | break; |
|---|
| | 1935 | |
|---|
| | 1936 | ev = xev; |
|---|
| | 1937 | printf(" -> vertex %08x\n",(unsigned int)ev); |
|---|
| | 1938 | } |
|---|
| | 1939 | |
|---|
| | 1940 | |
|---|
| | 1941 | iv = (struct instr_vertex *)ev->data; |
|---|
| | 1942 | |
|---|
| | 1943 | // create the new vertex |
|---|
| | 1944 | nev = (struct emu_vertex *)emu_hashtable_search(ht, (void *)iv->eip)->value; |
|---|
| | 1945 | niv = (struct instr_vertex *)nev->data; |
|---|
| | 1946 | |
|---|
| | 1947 | iv = (struct instr_vertex *)ev->data; |
|---|
| | 1948 | |
|---|
| | 1949 | printf("going forwards from %08x\n", (unsigned int)ev); |
|---|
| | 1950 | while ( emu_edges_length(ev->edges) == 1 && emu_edges_length(ev->backedges) <= 1 && ev->color != black && iv->dll == NULL && iv->syscall == NULL ) |
|---|
| | 1951 | { |
|---|
| | 1952 | ev->color = black; |
|---|
| | 1953 | struct emu_vertex *xev = emu_edges_first(ev->edges)->destination; |
|---|
| | 1954 | iv = (struct instr_vertex *)xev->data; |
|---|
| | 1955 | |
|---|
| | 1956 | if ( emu_edges_length(xev->backedges) > 1 || emu_edges_length(xev->edges) > 1 || |
|---|
| | 1957 | iv->dll != NULL || iv->syscall != NULL ) |
|---|
| | 1958 | break; |
|---|
| | 1959 | |
|---|
| | 1960 | ev = xev; |
|---|
| | 1961 | |
|---|
| | 1962 | iv = (struct instr_vertex *)ev->data; |
|---|
| | 1963 | emu_string_append_char(niv->instr_string, emu_string_char(iv->instr_string)); |
|---|
| | 1964 | printf(" -> vertex %08x\n",(unsigned int)ev); |
|---|
| | 1965 | } |
|---|
| | 1966 | |
|---|
| | 1967 | ev->color = black; |
|---|
| | 1968 | |
|---|
| | 1969 | printf("copying edges for %08x\n",(unsigned int)ev); |
|---|
| | 1970 | struct emu_edge *ee; |
|---|
| | 1971 | for ( ee = emu_edges_first(ev->edges); !emu_edges_attail(ee); ee = emu_edges_next(ee) ) |
|---|
| | 1972 | { |
|---|
| | 1973 | struct instr_vertex *ivto = emu_vertex_data_get(ee->destination); |
|---|
| | 1974 | struct emu_hashtable_item *ehi = emu_hashtable_search(ht, (void *)ivto->eip); |
|---|
| | 1975 | struct emu_vertex *to = (struct emu_vertex *)ehi->value; |
|---|
| | 1976 | if ( 1 )// nev != to )//&& to->color != black ) |
|---|
| | 1977 | { |
|---|
| | 1978 | struct emu_edge *nee = emu_vertex_edge_add(nev, to); |
|---|
| | 1979 | nee->count = ee->count; |
|---|
| | 1980 | nee->data = ee->data; |
|---|
| | 1981 | printf(" -> %08x\n", (unsigned int)to); |
|---|
| | 1982 | } |
|---|
| | 1983 | } |
|---|
| | 1984 | |
|---|
| | 1985 | } |
|---|
| | 1986 | |
|---|
| | 1987 | graph->vertex_destructor = instr_vertex_destructor; |
|---|
| | 1988 | emu_graph_free(graph); |
|---|
| | 1989 | graph = sgraph; |
|---|
| | 1990 | |
|---|
| | 1991 | emu_hashtable_free(ht); |
|---|
| | 1992 | fprintf(f, "digraph G {\n\t//rankdir=LR\n\tnode [fontname=Courier, labeljust=r];\n"); |
|---|
| | 1993 | |
|---|
| | 1994 | #if 0 |
|---|
| | 1995 | int numdlls=0; |
|---|
| | 1996 | while ( env->loaded_dlls[numdlls] != NULL ) |
|---|
| | 1997 | { |
|---|
| | 1998 | int has_dll = 0; |
|---|
| | 1999 | struct emu_string *fs = emu_string_new(); |
|---|
| | 2000 | emu_string_append_format(fs, "\t subgraph cluster%i {\n\t\t node [shape=box, style=filled, color=\".7 .3 1.0\"];\n\t\tstyle=filled;\n\t\tcolor=lightgrey;\n\t\tlabel=\"%s\"\n\t\t", numdlls, env->loaded_dlls[numdlls]->dllname); |
|---|
| | 2001 | for ( ev = emu_vertexes_first(graph->vertexes); !emu_vertexes_attail(ev); ev = emu_vertexes_next(ev) ) |
|---|
| | 2002 | { |
|---|
| | 2003 | struct instr_vertex *iv = emu_vertex_data_get(ev); |
|---|
| | 2004 | |
|---|