include "../include/PT8-Main.h" // Enum representing tree view types, these are embedded in collumn // number 4 (hidden) in every data view treeview. enum { DV_TYPE_NONE, DV_TYPE_HEX, DV_TYPE_DISASM, DV_TYPE_HEAP, DV_TYPE_ANALYSIS }; // The data viewer display, and data viewer widgets are used // to view process information. // Widget Types: // Data Viewer DISPLAY == Modified Tree Store Widget // Data Viewer == Window containing tree store widget // All functions pertaining to the dataviewer are found here // any dataviewer functions must be portable in the sense that // the data viwer source and header may be removed and used in // other applications utilizing GTK. // What is a data viewer:? // A data viewer is a GTK window which is dynamically created to // display data in a variety of formats. The formats supported // are Hex, Assembly, Heap, Stack, and Analysis Mode. // The dataviewer display handles large sets of data by utilizing callbacks // that act on various build in lists. The callbacks are built into // the scrolling mechanism. // Main Range Callback: This range represents the vscrollbar in the // nested window. What needs to happen is void DV_MainRangeCallback(GtkRange *range, gpointer user_data){ // Retrieve parent scrolled window from range GtkWidget * parentHbox = (GtkWidget *) gtk_widget_get_parent((GtkWidget *) range); if(parentHbox == NULL) return; // Retrieve a widget list from the hbox container GList * childWidgetList = gtk_container_get_children((GtkContainer *) parentHbox); if(childWidgetList == NULL) return; // Extract child widgets from the hbox GtkWidget * packedScrollWindow = (GtkWidget *) childWidgetList->data; if(packedScrollWindow == NULL) return; GtkWidget * treeView = (GtkWidget *) gtk_bin_get_child((GtkBin *) packedScrollWindow); if(treeView == NULL) return; GtkWidget * treeModel = (GtkWidget *) gtk_tree_view_get_model((GtkTreeView *) treeView); if(treeModel == NULL) return; // Get the top iter GtkTreeIter topIter; int success = gtk_tree_model_get_iter_first((GtkTreeModel *) treeModel, &topIter); // false if the tree is empty if(success == false) return; // Get the model type first unsigned int modelType = 0; gtk_tree_model_get((GtkTreeModel *) treeModel, &topIter, 4, &modelType, -1); // retrieve new range and round it off long roundedRange = (long) gtk_range_get_value(range); printf("\n RANGE = %u", roundedRange); // Main switch to pass information off to update functions switch(modelType){ case DV_TYPE_HEX: printf("\n woo, got hex type"); break; case DV_TYPE_DISASM: printf("\n hehe, got asm type"); DV_AsmUpdateDisplay(parentHbox, roundedRange, 100, NULL); break; case DV_TYPE_HEAP: break; case DV_TYPE_ANALYSIS: break; default: g_print("\n DataView Callback: Erroneous type."); break; } // We are done with the list, so it can be free'd g_list_free(childWidgetList); // Ok, now get the tree store's top instruction. // First, get list first pointer. // Get scroll window tree view first // unsigned int instructionCount = X86_32_GetInstructionCount(P_X86_32_DECODED_INSTRUCTION_LIST instructions); // Extract tree view from the scrolled window } // Destroys a data viewer that was created with CreateDataViewer unsigned int DestroyDataViewer(GtkWidget *dataViewer){ return ERR_SUCCESS; } // Create a new data viewer window packed with toolbar to display data // on the fly. GtkWidget * CreateDataViewer(unsigned char *data, unsigned int length, unsigned int initialDisplayType, P_DV_HIGHLIGHT_RANGE initialHighlight){ if(data == NULL || length == 0) return NULL; // -------------------------------------------------------------- // Window Initialization // Sets upa lookup path to the default dv window icon char lookupPath[sizeof(DV_DEFAULT_ICON_PATH) + 500]; memset(lookupPath, 0x00, sizeof(lookupPath)); strncat(lookupPath, DV_DEFAULT_ICON_PATH, sizeof(DV_DEFAULT_ICON_PATH)); strncat(lookupPath, "/dv-icon.png", strlen("/dv-icon.png")); // Retrieve the windows custom icon gtk_window_set_default_icon_from_file(lookupPath, NULL); // create the new window (perhaps proxy function when // logc is completed) GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_object_set(G_OBJECT(window), "title", "[Prototype-8: Data Viewer]", NULL); gdk_window_set_back_pixmap(window->window, NULL, FALSE); // set border width gtk_container_set_border_width(GTK_CONTAINER(window), 0); // Connect window to destroy an delete events g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(DestroyDataViewer), NULL); // ----------------------------------------------------------- // Create top toolbar // Create the default HBox (non-homogenous, 0px spacing) GtkWidget *outermostVbox = gtk_vbox_new(FALSE, 0); // Create a new toolbar GtkToolbar *toolBar = (GtkToolbar *) gtk_toolbar_new(); /* * "expand", false, "fill", false, */ /* g_object_set(G_OBJECT(toolBar), "icon-size", GTK_ICON_SIZE_SMALL_TOOLBAR, "icon-size-set", true, NULL); */ // ----------------------------------------------------------- // Create toolbar buttons // Icon pointer used to set icons GtkWidget *winIcon; // Set Disassemble Button----------------------------------------- memset(lookupPath, 0x00, sizeof(lookupPath)); strncat(lookupPath, DV_DEFAULT_ICON_PATH, sizeof(DV_DEFAULT_ICON_PATH)); strncat(lookupPath, "/dv-disassemble.png", strlen("/dv-disassemble.png")); winIcon = gtk_image_new_from_file (lookupPath); GtkToolItem * disassembleButton = gtk_tool_button_new(winIcon, NULL); gtk_toolbar_insert(toolBar, disassembleButton, 0); // Set hex view button------------------------------------- memset(lookupPath, 0x00, sizeof(lookupPath)); strncat(lookupPath, DV_DEFAULT_ICON_PATH, sizeof(DV_DEFAULT_ICON_PATH)); strncat(lookupPath, "/dv-hex.png", strlen("/dv-hex.png")); winIcon = gtk_image_new_from_file (lookupPath); GtkToolItem * hexButton = gtk_tool_button_new(winIcon, NULL); gtk_toolbar_insert(toolBar, hexButton, 0); // Set analysis button------------------------------------- memset(lookupPath, 0x00, sizeof(lookupPath)); strncat(lookupPath, DV_DEFAULT_ICON_PATH, sizeof(DV_DEFAULT_ICON_PATH)); strncat(lookupPath, "/dv-analysis.png", strlen("/dv-analysis.png")); winIcon = gtk_image_new_from_file (lookupPath); GtkToolItem * analysisButton = gtk_tool_button_new(winIcon, NULL); gtk_toolbar_insert(toolBar, analysisButton, 0); // ------------------------------------------------------------ // Create mainview in conjunction with the init type GtkWidget * dataViewMain = NULL; unsigned int scaleTopVal = 0; switch(initialDisplayType){ case DV_INIT_HEX: // Create the new image, this is effectively our pixmap // END ATTEMPT dataViewMain = DV_HexCreateDisplay(data, length, 0x00, initialHighlight); break; case DV_INIT_DISASM: // fifty rows by default dataViewMain = DV_AsmCreateDisplay(data, length, 50, 0x00, initialHighlight); // If the data view is not null, retrieve the total number // of instructions to be used with the range. if(dataViewMain != NULL){ printf("\n Retrieved proper data view"); // DV_AsmGetInstructionCount(dataViewMain); } // unsigned int X86_32_GetInstructionCount(P_X86_32_DECODED_INSTRUCTION_LIST instructions){ break; case DV_INIT_HEAP: break; case DV_INIT_STACK: break; case DV_INIT_ANALYSIS: break; } // ------------------------------------------------------------- // Apply custom widget settings g_object_set(G_OBJECT(outermostVbox), "height-request", 400, "hscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); // gtk_image_get_pixmap((GtkImage*) bgImage, bgPixmap, NULL); // ATTEMPT TO PAINT WIDGET BACKGROUND // 1. gtk_widget_realize(widget) // gtk_widget_realize(dataViewMain); // 2. gtk_widget_set_app_paintable(widget) // gtk_widget_set_app_paintable(dataViewMain,TRUE); // 3. gtk_window_set_back_pixmap(window, winIcon, FALSE); // gdk_window_set_back_pixmap(dataViewMain->window, *bgPixmap, FALSE); // ------------------------------------------------------------ // Finish up and Show the Widgets // Pack Toolbar gtk_box_pack_start((GtkBox *) outermostVbox, (GtkWidget *) toolBar, FALSE, FALSE, 0); // pack custom dataview into window gtk_box_pack_start((GtkBox *) outermostVbox, dataViewMain, false, false, 0); gtk_widget_show(dataViewMain); // Add the VBox to the window gtk_container_add(GTK_CONTAINER(window), outermostVbox); // Show widget and return gtk_widget_show_all(window); return window; } // --------------------------------------------------------------- // HEX DISPLAY FUNCTIONS // Default rows for the hex tree store (row 5 is always type) enum { DV_HEX_ADDR, DV_HEX_DATA, DV_HEX_ASCII, DV_HEX_PTR, DV_HEX_TYPE }; // Number of bytes to display at a time in 4 byte increments // must be divisible by 4. #define HEX_DISPLAY_COUNT 24 // Retrieves Hex Display suitable for a data viewer widget, set as treeview // DO NOT DESTROY DATA AFTER CREATING DISPLAY. Pointers from the data // are stored within the hex display itself. GtkWidget * DV_HexCreateDisplay(unsigned char *data, unsigned int length, unsigned int base, P_DV_HIGHLIGHT_RANGE initialHighlight){ // ----------------------------------------------------------- // Overall widget creation guidelines: // ----------------------------------------------------------- // Step one, create tree view // ------------------------------------------------------------ // Step two, create scale representing the total number of 64 // byte increments found in the hex buffer + 64bytes if // a remainder is found. // --------------------------------------------------------------- // Step three, create custom hBox and pack the scale and tree // view. // --------------------------------------------------------------- // ----------------------------------------------------------- // Step one, create tree view GtkWidget *view; GtkTreeModel *model; GtkTreeStore * store; GtkTreeModel *mode; GtkCellRenderer *renderer; GtkTreeIter iter, child; // set up an new tree store (5 elements) store = gtk_tree_store_new(5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT, NULL); // derive new model off of store model = GTK_TREE_MODEL(store); // Create new tree view based off the model view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); g_object_set(G_OBJECT(view), "enable-search", false, "enable-grid-lines", true, "reorderable", false, "app-paintable", true, NULL); gdk_window_set_back_pixmap(view->window, NULL, FALSE); // set view and model gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); renderer = gtk_cell_renderer_text_new (); g_object_set(G_OBJECT(renderer), "foreground", "#045E00", NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Address", renderer, "text", DV_HEX_ADDR, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set(G_OBJECT(renderer), "foreground", "#070098", "size", 9000, "family", "Monospace", NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Data", renderer, "text", DV_HEX_DATA, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set(G_OBJECT(renderer), "foreground", "#070098", "size", 9000, "family", "Monospace", NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Ascii", renderer, "text", DV_HEX_ASCII, NULL); // Create hidden pointer collumn for data row pointer (dependent on // initial data) renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "PTR", renderer, "text", DV_HEX_PTR, NULL); // Create hidden integer collumn to represent the data type renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "TYPE", renderer, "text", DV_HEX_TYPE, NULL); // Block size is natively 24 bytes per row unsigned int blocks = 0; unsigned int remainder = 0; // counts blocks in main loop unsigned int i = 0; // inner loop vars unsigned int x = 0, y = 0; // If the length is greater then 64, set remainder as if(length < HEX_DISPLAY_COUNT){ // set remainder to length, as length is less then one line // block. remainder = length; length = 0; } else { // Set blocks and remainder blocks = length / HEX_DISPLAY_COUNT; remainder = length % HEX_DISPLAY_COUNT; } // Loop through the data and print available data // Addr string used to print out the occuring address of the data char addrStr[16]; memset(addrStr, 0x00, 16); // Data Str is used to actually append data to the tree store // it is 84 bytes to represent 64 bytes plus 20 bytes of additional // padding. char dataStr[200]; memset(dataStr, 0x00, 200); // Ascii String (64bytes + 20 for padding) char asciiStr[200]; memset(dataStr, 0x00, 200); // Data holder for translations (need to memcpy bytes into this // variable to get correct translatoins) unsigned int dwData; // total offset for entire buffer read unsigned int totalOffset = 0; for(i = 0; i < blocks; i++){ sprintf(addrStr, "0x%.08x: ", (unsigned int) base); // assign data string (+base on loop to move string forward memset(dataStr, 0x00, 200); memset(asciiStr, 0x00, 200); for(x = 0; x < 32; x+=4){ memcpy((void *) &dwData, (void *) &data[totalOffset+x], 4); sprintf(&dataStr[strnlen(dataStr, 83)], "%.08x ", dwData); memcpy(&asciiStr[x], &dwData, 4); } //DV_HEX_ADDR, // DV_HEX_DATA, // DV_HEX_ASCII // Add strings to store and loop gtk_tree_store_append (store, &iter, NULL); gtk_tree_store_set (store, &iter, DV_HEX_ADDR, addrStr, DV_HEX_DATA, dataStr, DV_HEX_ASCII, asciiStr, DV_HEX_PTR, &data[totalOffset], DV_HEX_TYPE, DV_TYPE_HEX, -1); // Advance offset for total read totalOffset += HEX_DISPLAY_COUNT; base += HEX_DISPLAY_COUNT; } // Add last row for remainder if exists if(remainder > 0){ // Set the entire data string to spaces for alignment // assign data string memset(dataStr, 0x00, 200); memset(asciiStr, 0x00, 200); for(i = 0; i < remainder; i+=4){ memcpy((void *) &dwData, (void *) &data[totalOffset+i], 4); sprintf(&dataStr[strnlen(dataStr, 83)], "%.08x ", dwData); memcpy(&asciiStr[i], &dwData, 4); } sprintf(addrStr, "0x%.08x: ", (unsigned int) base); gtk_tree_store_append (store, &iter, NULL); gtk_tree_store_set (store, &iter, DV_HEX_ADDR, addrStr, DV_HEX_DATA, dataStr, DV_HEX_ASCII, asciiStr, -1); } // ------------------------------------------------------------ // Step two, create scale representing the total number of instructions // in the instruction list. // the vScale for our new widget: Blocks plus 1 = 64bytes[x]+64bytes GtkWidget * vScale = gtk_vscale_new_with_range(0, blocks+1, 1); // set scale callback g_signal_connect(G_OBJECT(vScale), "value-changed", G_CALLBACK(DV_MainRangeCallback), NULL); // --------------------------------------------------------------- // Step three, create custom hBox and pack the scale and tree // view. // Testing, create new hbox GtkWidget * customHbox = gtk_hbox_new(false, 0); // create scrolled window to hold the tree widget GtkWidget * treeScrollWindow = gtk_scrolled_window_new(NULL, NULL); gtk_container_add((GtkContainer *) treeScrollWindow, view); // may have to re-add "width-request", 700, g_object_set(G_OBJECT(customHbox), "height-request", 400, "hscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); g_object_set(G_OBJECT(treeScrollWindow), "vscrollbar-policy", GTK_POLICY_NEVER, "hscrollbar-policy", GTK_POLICY_ALWAYS, NULL); // Pack Data View gtk_box_pack_start((GtkBox *) customHbox, (GtkWidget *) treeScrollWindow, true, true, 0); // pack the box with scale next gtk_box_pack_start((GtkBox *) customHbox, vScale, false, false, 0); // Return the populated tree view, ready for display return customHbox; // Return the populated tree view, ready for display return view; } // ---------------------------------------------------------- // ASM VIEW SPECIFIC FUNCTIONS AND DATA // Default rows for the disasm tree store enum { DV_DISASM_ADDR, DV_DISASM_INST, DV_DISASM_OPERANDS, DV_DISASM_PTR, DV_DISASM_TYPE, DV_DISASM_NOTES, }; // Retrieves ASM Display suitable for a data viewer widget, set as treeview GtkWidget * DV_AsmCreateDisplay(unsigned char *data, unsigned int length, unsigned int maxDisplayRows, unsigned int base, P_DV_HIGHLIGHT_RANGE initialHighlight){ // ----------------------------------------------------------- // Overall widget creation guidelines: // ----------------------------------------------------------- // Step one, create tree view // ------------------------------------------------------------ // Step two, create scale representing the total number of instructions // in the instruction list. // --------------------------------------------------------------- // Step three, create custom hBox and pack the scale and tree // view. // --------------------------------------------------------------- // --------------------------------------------------- // Step 1) Create Tree View // New base tree view to create GtkWidget *view; // New base tree model GtkTreeModel *model; GtkTreeStore * store; GtkTreeModel *mode; GtkCellRenderer *renderer; // Cell iters GtkTreeIter iter, child; // set up an new tree store (4 elements) store = gtk_tree_store_new(6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_STRING, -1); // derive new model off of store model = GTK_TREE_MODEL(store); // Create new tree view based off the model view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); g_object_set(G_OBJECT(view), "enable-search", false, "enable-grid-lines", true, "reorderable", false, NULL); // dereference model and set to null (speed hack) g_object_ref(model); gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); renderer = gtk_cell_renderer_text_new (); g_object_set(G_OBJECT(renderer), "foreground", "#045E00", NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Address", renderer, "text", DV_DISASM_ADDR, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set(G_OBJECT(renderer), "foreground", "#5D5858", NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Data", renderer, "text", DV_DISASM_INST, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set(G_OBJECT(renderer), "foreground", "#000000", "size", 9000, "family", "Sans", NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Operands", renderer, "text", DV_DISASM_OPERANDS, NULL); // Hidden collumn to contain the instruction list pointer // corresponding to the widget. When the row is moved, the // whole list will be updated but GtkWidget * columnPtr = NULL; renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "List Pointer", renderer, NULL); columnPtr = (GtkWidget *) gtk_tree_view_get_column((GtkTreeView *) view, DV_DISASM_PTR); gtk_tree_view_column_set_visible((GtkTreeViewColumn *) columnPtr, false); // Second hidden collumnl, represents the data type in the row renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Data Type", renderer, NULL); columnPtr = (GtkWidget *) gtk_tree_view_get_column((GtkTreeView *) view, DV_DISASM_TYPE); gtk_tree_view_column_set_visible((GtkTreeViewColumn *) columnPtr, false); renderer = gtk_cell_renderer_text_new (); g_object_set(G_OBJECT(renderer), "foreground", "#070098", "size", 9000, "family", "Monospace", NULL); // Last row, is notes.. its not hidden. Its placed last because of // the way that the collums are set up. 3'rd and 4th are always taken // by ptr and type, so this 5th collumn represents the notes. gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Notes", renderer, "text", DV_DISASM_NOTES, "width", 20, NULL); // columnPtr = (GtkWidget *) gtk_tree_view_get_column((GtkTreeView *) view, DV_DISASM_NOTES); // gtk_tree_view_column_set_visible((GtkTreeViewColumn *) columnPtr, false); // Retrieve instruction table for global session debugger if not there // as it is used for disassembly. if(globals.session.Debugger.instructionTable == NULL){ // THREAD SAFTEY NEEDED globals.session.Debugger.instructionTable = X86_32_GetX86InstructionTable(); } // THREAD SAFTEY NEEDED P_X86_32_DECODED_INSTRUCTION_LIST decodedList = globals.session.Debugger.DbgDecodeInstructionsNL(data, length, base); P_X86_32_DECODED_INSTRUCTION_LIST decodedListFirst = decodedList->first; char *instStr = NULL; char *operStr = NULL; char *noteStr = NULL; char addrStr[20]; unsigned int rows = 0; // Walk the list and fill the treeview for(decodedList = decodedList->first; decodedList != NULL; decodedList = decodedList->next){ memset(addrStr, 0x00, 20); // Check instruction first if(decodedList->instruction == NULL){ instStr = "[bad]"; noteStr = " "; } else { instStr = decodedList->instruction->instructionStr; noteStr = decodedList->instruction->description; } // check operands next if(decodedList->intelDecode == NULL){ operStr = " "; } else { operStr = decodedList->intelDecode; } sprintf(addrStr, "0x%p:", decodedList->address); gtk_tree_store_append (store, &iter, NULL); gtk_tree_store_set (store, &iter, DV_DISASM_ADDR, addrStr, DV_DISASM_INST, instStr, DV_DISASM_OPERANDS, operStr, DV_DISASM_PTR, decodedList, DV_DISASM_TYPE, DV_TYPE_DISASM, DV_DISASM_NOTES, noteStr, -1); // Break if we're on the next element if(decodedList->next == NULL) break; // break to only display maxDisplayRows at a time. if(rows >= maxDisplayRows) break; rows++; } columnPtr = (GtkWidget *) gtk_tree_view_get_column((GtkTreeView *) view, DV_DISASM_NOTES); g_object_set(G_OBJECT(columnPtr), "max-width", 10 ,"resizable", true, NULL); // set view and model gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); // ------------------------------------------------------------ // Step two, create scale representing the total number of instructions // in the instruction list. // Get top of the list unsigned int scaleTopVal = X86_32_GetInstructionCount(decodedList->first); // the vScale for our new widget GtkWidget * vScale = gtk_vscale_new_with_range(0, scaleTopVal, 1); // set scale callback g_signal_connect(G_OBJECT(vScale), "value-changed", G_CALLBACK(DV_MainRangeCallback), NULL); // --------------------------------------------------------------- // Step three, create custom hBox and pack the scale and tree // view. // Testing, create new hbox GtkWidget * customHbox = gtk_hbox_new(false, 0); // create scrolled window to hold the tree widget GtkWidget * treeScrollWindow = gtk_scrolled_window_new(NULL, NULL); gtk_container_add((GtkContainer *) treeScrollWindow, view); // May need to make a width request g_object_set(G_OBJECT(customHbox), "height-request", 400, "hscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); g_object_set(G_OBJECT(treeScrollWindow), "vscrollbar-policy", GTK_POLICY_NEVER, "hscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); // Pack Data View gtk_box_pack_start((GtkBox *) customHbox, (GtkWidget *) treeScrollWindow, true, true, 0); // pack the box with scale next gtk_box_pack_start((GtkBox *) customHbox, vScale, false, false, 0); printf("\n CONFIRMED SCROLLWINDOW PTR: %p", treeScrollWindow); printf("\n CONFIRMED HBOX PTR: %p", customHbox); // Working test call // DV_UpdateAsmDisplay(view, decodedListFirst, 3, NULL); // Return the populated tree view, ready for display return customHbox; } // Updates the assembly view to render instructions in unison with the current range value // as the range value increases or decreases, the contents of the treeview change within a // respective +- threshold. void DV_AsmUpdateDisplay(GtkWidget *dataView, unsigned int currentRangeValue, unsigned int maxDisplayRows, P_DV_HIGHLIGHT_RANGE initialHighlight){ if(dataView == NULL) return; // ----------------------------------------------------- // Steps to take to create the updated window // ----------------------------------------------------- // Step 1) Extract the treestore from the packed hbox. Get a // list pointer from the hidden collumns. // ------------------------------------------------------ // Step 2) Get total list length. The store will be refilled // along a max value of baseWidgetStoreHeight. Which // effectively represents the nuber of rows to have in // the store, total. // ------------------------------------------------------ // Step 3) move the top of tree store to the value of the // current range and fill with the remainder of the list // with baseWidgetStoreHeight number of instructions. // ------------------------------------------------------- // Remember that dataView is simply a hBox in disguise. // Retrieve a widget list from the hbox container GList * childWidgetList = gtk_container_get_children((GtkContainer *) dataView); if(childWidgetList == NULL) return; // Extract child widgets from the hbox GtkWidget * packedScrollWindow = (GtkWidget *) childWidgetList->data; if(packedScrollWindow == NULL) return; GtkWidget * treeView = (GtkWidget *) gtk_bin_get_child((GtkBin *) packedScrollWindow); if(treeView == NULL) return; GtkWidget * treeModel = (GtkWidget *) gtk_tree_view_get_model((GtkTreeView *) treeView); if(treeModel == NULL) return; // Get the top iter GtkTreeIter topIter; unsigned int success = gtk_tree_model_get_iter_first((GtkTreeModel *) treeModel, &topIter); // false represents an empty tree if(success == false) return; // Get the model type and list pointer from the top of the list unsigned int modelType = 0; P_X86_32_DECODED_INSTRUCTION_LIST topList = NULL; gtk_tree_model_get((GtkTreeModel *) treeModel, &topIter, 4, &modelType, -1); gtk_tree_model_get((GtkTreeModel *) treeModel, &topIter, 3, &topList, -1); // Get the list item that represents the current level printf("\n Got update range: %i", currentRangeValue); printf("\n Got type: %i", modelType); printf("\n Got instruction list current top: %p", topList); printf("\n Got update range: %p", topList->first); topList = X86_32_GetInstructionAtListPosition(topList->first, currentRangeValue); if(topList == NULL){ printf("\n toplist is null?"); return; } char *instStr = NULL; char *operStr = NULL; char *noteStr = NULL; char addrStr[20]; gtk_tree_store_clear((GtkTreeStore *) treeModel); unsigned int rows = 0; // Walk the list and fill the treeview for(; topList != NULL; topList = topList->next){ memset(addrStr, 0x00, 20); // Check instruction first if(topList->instruction == NULL){ instStr = "[bad]"; noteStr = " "; } else { instStr = topList->instruction->instructionStr; noteStr = topList->instruction->description; } // check operands next if(topList->intelDecode == NULL){ operStr = " "; } else { operStr = topList->intelDecode; } sprintf(addrStr, "0x%p:", topList->address); gtk_tree_store_append ((GtkTreeStore *) treeModel, &topIter, NULL); gtk_tree_store_set ((GtkTreeStore *) treeModel, &topIter, DV_DISASM_ADDR, addrStr, DV_DISASM_INST, instStr, DV_DISASM_OPERANDS, operStr, DV_DISASM_PTR, topList, DV_DISASM_TYPE, DV_TYPE_DISASM, DV_DISASM_NOTES, noteStr, -1); // Break if we've displayed the total appropriate number // of rows. if(rows == maxDisplayRows) break; rows++; // Break if we're on the next element if(topList->next == NULL) break; } // Now that we've retrieved all relevant data, clear the model // to get it ready for a redraw. } // Retrieves a total instruction count from a Data viewer assembly type // widget. 0 for failure or none. The dataviewer widget is not // the window itself, but the hbox corresponding to the scale and // tree view. unsigned int DV_AsmGetInstructionCount(GtkWidget * dataViewer){ if(dataViewer == NULL) return 0; // Retrieve a widget list for the widget GList * childWidgetList = gtk_container_get_children((GtkContainer *) dataViewer); // Extract child widgets from the hbox GtkWidget * packedScrollWindow = (GtkWidget *) childWidgetList->data; GtkWidget * treeView = (GtkWidget *) gtk_bin_get_child((GtkBin *) packedScrollWindow); GtkWidget * treeModel = (GtkWidget *) gtk_tree_view_get_model((GtkTreeView *) treeView); // Get the top iter GtkTreeIter topIter; gtk_tree_model_get_iter_first((GtkTreeModel *) treeModel, &topIter); // Get the model type from the model next unsigned int modelType = 0; gtk_tree_model_get((GtkTreeModel *) treeModel, &topIter, 4, &modelType, -1); // Exit if the views type is not assembly if(modelType != DV_TYPE_DISASM){ return 0; } // set first instruction and get total count from first instruction P_X86_32_DECODED_INSTRUCTION_LIST first = NULL; gtk_tree_model_get((GtkTreeModel *) treeModel, &topIter, 3, &first, -1); first = first->first; // get the total instruction count from first pointer unsigned int retVal = X86_32_GetInstructionCount(first); return retVal; }