📄 search.c
字号:
/*************************************************************************** * * Gtk+ Game Cheater * Copyright (C) 2005 Alf <h980501427@hotmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * **************************************************************************/#include <string.h>#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "gamecheater.h"#ifndef G_MAXUINT8#define G_MAXUINT8 0xFF#endiftypedef struct { pid_t pid; guint64 value; value_type type; GSList* result; /* GUI widget tree */ GladeXML* xml;} cheater_t;static void addr_cell_func(GtkTreeViewColumn* column, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter, gpointer data){ unsigned long addr = 0; gchar* text = NULL; gtk_tree_model_get(model, iter, RESULT_ADDRESS_COLUMN, &addr, -1); text = g_strdup_printf("0x%0*lX", sizeof(unsigned long)*2, addr); g_object_set(renderer, "text", text, NULL); g_free(text); return;}static GtkListStore* get_store_map(GtkListStore* store_map, pid_t pid){ GtkListStore* store = store_map; if (store == NULL) { store = gtk_list_store_new(N_MAP_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_ULONG); } else { gtk_list_store_clear(store); } GtkTreeIter iter; FILE* fmaps = NULL; char buf[1024]; char fname[1024]; gboolean check = FALSE; long process = 0; int len = 0; snprintf(buf, sizeof(buf), "/proc/%ld/maps", (long) pid); fmaps = fopen(buf, "rb"); if (fmaps == NULL) return store; while (fgets(buf, sizeof(buf), fmaps) != NULL) { unsigned long begin, end, offset, inode; int dev_major, dev_minor; char perms[8]; len = sscanf(buf, "%lx-%lx %s %lx %d:%d %lu %s", &begin, &end, perms, &offset, &dev_major, &dev_minor, &inode, fname); if (len <= 0) g_warning("sscanf function is dangerous! return %d\n", len); /* skip read only mem */ if (perms[1] != 'w') continue; check = TRUE; len = strlen(fname); /* skip device mem */ if (strncmp(fname, "/dev/", 5) == 0) check = FALSE; /* skip system library mem */ if (strncmp(fname, "/lib/", 5) == 0) check = FALSE; if (strncmp(fname, "/usr/X11R6/", 11) == 0) check = FALSE; /* skip system library mem */ if (strncmp(fname, "/usr/lib/", 9) == 0) check = FALSE; /* skip font mem */ if (strncmp(fname + len - 4, ".ttf", 4) == 0) check = FALSE; /* skip mo mem */ if (strncmp(fname + len - 3, ".mo", 3) == 0) check = FALSE; gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, MAP_CHECK_COLUMN, check, MAP_NAME_COLUMN, fname, MAP_PROCESS_COLUMN, process, MAP_ADDRESS_START_COLUMN, begin, MAP_ADDRESS_END_COLUMN, end, -1); } if (fmaps != NULL) fclose(fmaps); return store;}static GtkListStore* get_store_result(GtkListStore* store_result, cheater_t* cheater){ GtkListStore* store = store_result; if (store == NULL) { store = gtk_list_store_new(N_RESULT_COLUMNS, G_TYPE_ULONG, G_TYPE_STRING); } else { gtk_list_store_clear(store); } if (cheater == NULL) return store; if (cheater->result == NULL) return store; long i = 0; void* p = NULL; GtkTreeIter iter; unsigned char preview[PREVIEW_LENGTH]; unsigned char buf[PREVIEW_LENGTH * 3]; while (i < MAX_RESULT_VIEW) { p = g_slist_nth_data(cheater->result, i); if (p == NULL) break; if (gc_get_memory(cheater->pid, p, preview, sizeof(preview)) != 0) { g_warning("get memory addr[0x%0*lX] len[%u] error!\n", sizeof(unsigned long)*2, (unsigned long) p, sizeof(preview)); } unsigned char t[4]; long j = 0; for (j = 0; j < sizeof(preview); j++) { if (3*j >= sizeof(buf)) break; snprintf((char*) t, sizeof(t), "%02X ", preview[j]); memcpy(buf + j*3, t, 3); } buf[sizeof(buf)-1] = '\0'; gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, RESULT_ADDRESS_COLUMN, (unsigned long) p, RESULT_MEMORY_COLUMN, buf, -1); i++; } return store;}static void* search_memory(cheater_t* cheater){ if (cheater == NULL) return NULL; if (cheater->xml == NULL) return NULL; GladeXML* xml = cheater->xml;/* GtkWidget* window = glade_xml_get_widget(xml, "window");*/ /* stop the process. */ pid_t pid = cheater->pid; if (gc_ptrace_stop(pid) != 0) { g_warning("ptrace %ld error!\n", (long) pid); return NULL; } GtkWidget* treeview_lib = glade_xml_get_widget(xml, "treeview_lib"); GtkWidget* treeview_result = glade_xml_get_widget(xml, "treeview_result"); GtkWidget* progressbar = glade_xml_get_widget(xml, "progressbar"); GtkWidget* entry = glade_xml_get_widget(xml, "entry"); gtk_widget_set_sensitive(entry, FALSE); gtk_widget_set_sensitive(treeview_lib, FALSE); char buf[MEMORY_BLOCK_SIZE]; void* addr = NULL; unsigned long len = 0; unsigned long per = 0; long i = 0; unsigned long j = 0; unsigned long k = 0; /* No results. */ if (cheater->result == NULL) { GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_lib)); GtkTreeIter iter; gboolean valid = FALSE; gboolean check = FALSE; unsigned long begin = 0; unsigned long end = 0; double pro_total = 0.0; double pro_searched = 0.0; valid = gtk_tree_model_get_iter_first (model, &iter); while (valid) { check = FALSE; gtk_tree_model_get (model, &iter, MAP_CHECK_COLUMN, &check, MAP_ADDRESS_START_COLUMN, &begin, MAP_ADDRESS_END_COLUMN, &end, -1); if (check) pro_total = pro_total + (end - begin); gtk_list_store_set(GTK_LIST_STORE (model), &iter, MAP_PROCESS_COLUMN, 0, -1); valid = gtk_tree_model_iter_next (model, &iter); } /* end of while (valid) */ valid = gtk_tree_model_get_iter_first (model, &iter); while (valid) { i = j = k = 0; check = FALSE; gtk_tree_model_get (model, &iter, MAP_CHECK_COLUMN, &check, MAP_ADDRESS_START_COLUMN, &begin, MAP_ADDRESS_END_COLUMN, &end, -1); if ((!check) || (end <= begin)) { valid = gtk_tree_model_iter_next (model, &iter); continue; } addr = (void*) begin; per = (end - begin) / 100; while ((unsigned long)addr < end) { while (gtk_events_pending ()) gtk_main_iteration (); if (model == NULL || !GTK_IS_LIST_STORE (model)) goto out; if ((unsigned long) addr + MEMORY_BLOCK_SIZE <= end) len = MEMORY_BLOCK_SIZE; else len = end - (unsigned long) addr; if (gc_get_memory(pid, addr, (void*)buf, len) != 0) { g_warning("get memory addr[0x%0*lX] len[%lu] error!\n", sizeof(unsigned long)*2, (unsigned long) addr, len); goto out; } switch (cheater->type) { case TYPE_U8 : { guint8* pu8 = (guint8*) buf; guint8 u8 = (guint8) cheater->value; for (i = 0; i < len / sizeof(guint8); i++) { if (pu8[i] == u8) { cheater->result = g_slist_append(cheater->result, addr + sizeof(guint8) * i); } } break; } case TYPE_U16 : { guint16* pu16 = (guint16*) buf; guint16 u16 = (guint16) cheater->value; for (i = 0; i < len / sizeof(guint16); i++) { if (pu16[i] == u16) { cheater->result = g_slist_append(cheater->result, addr + sizeof(guint16) * i); } } break; } case TYPE_U32 : { guint32* pu32 = (guint32*) buf; guint32 u32 = (guint32) cheater->value; for (i = 0; i < len / sizeof(guint32); i++) { if (pu32[i] == u32) { cheater->result = g_slist_append(cheater->result, addr + sizeof(guint32) * i); } } break; } case TYPE_U64 : { guint64* pu64 = (guint64*) buf; guint64 u64 = (guint64) cheater->value; for (i = 0; i < len / sizeof(guint64); i++) { if (pu64[i] == u64) { cheater->result = g_slist_append(cheater->result, addr + sizeof(guint64) * i); } } break; } default : break; } /* end of switch(cheater->type) */ addr += len; pro_searched += len; k = ((unsigned long)addr - begin) / per; if ( k > j) { j = k; if (j > 100) j = 100; /* update progressbar */ if (model == NULL || !GTK_IS_LIST_STORE (model)) goto out; gtk_list_store_set(GTK_LIST_STORE (model), &iter, MAP_PROCESS_COLUMN, j, -1); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progressbar), pro_searched / pro_total); } } /* end of while ((unsigned long)addr < end) */ if (j != 100) { gtk_list_store_set(GTK_LIST_STORE (model), &iter, MAP_PROCESS_COLUMN, 100, -1); } valid = gtk_tree_model_iter_next (model, &iter); } /* end of while (valid) */ } else { GSList* list = cheater->result; k = 0; len = g_slist_length(cheater->result); while (1) { while (gtk_events_pending ()) gtk_main_iteration (); addr = list->data; switch (cheater->type) { case TYPE_U8 : { guint8 u8 = (guint8) cheater->value; guint8 tu8 = 0; if (gc_get_memory(pid, addr, (void*)&tu8, sizeof(guint8)) != 0) { g_warning("get memory addr[0x%0*lX] error!\n", sizeof(unsigned long)*2, (unsigned long) addr); goto out; } if (u8 != tu8) { list->data = NULL; } break; } case TYPE_U16 : { guint16 u16 = (guint16) cheater->value; guint16 tu16 = 0; if (gc_get_memory(pid, addr, (void*)&tu16, sizeof(guint16)) != 0) { g_warning("get memory addr[0x%0*lX] error!\n", sizeof(unsigned long)*2, (unsigned long) addr); goto out; } if (u16 != tu16) { list->data = NULL; } break; } case TYPE_U32 : { guint32 u32 = (guint32) cheater->value; guint32 tu32 = 0; if (gc_get_memory(pid, addr, (void*)&tu32, sizeof(guint32)) != 0) { g_warning("get memory addr[0x%0*lX] error!\n", sizeof(unsigned long)*2, (unsigned long) addr); goto out; } if (u32 != tu32) { list->data = NULL; } break; } case TYPE_U64 : { guint64 u64 = (guint64) cheater->value; guint64 tu64 = 0; if (gc_get_memory(pid, addr, (void*)&tu64, sizeof(guint64)) != 0) { g_warning("get memory addr[0x%0*lX] error!\n", sizeof(unsigned long)*2, (unsigned long) addr); goto out; } if (u64 != tu64) { list->data = NULL; } break; } default : break; } /* end of switch(cheater->type) */ list = list->next; if (list == NULL) break; k++; if (k % MEMORY_BLOCK_SIZE == 0) { if (GTK_IS_PROGRESS_BAR (progressbar)) goto out; gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progressbar), (double) k / len); } } /* end of while (1) */ cheater->result = g_slist_remove_all(cheater->result, NULL); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progressbar), 0.0); } GtkListStore* store = GTK_LIST_STORE (gtk_tree_view_get_model(GTK_TREE_VIEW (treeview_result))); store = get_store_result(store, cheater); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progressbar), 0.0); snprintf(buf, sizeof(buf), _("%u matched"), g_slist_length(cheater->result)); gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progressbar), buf); gtk_widget_set_sensitive(treeview_lib, TRUE); gtk_widget_set_sensitive(entry, TRUE);out: gc_ptrace_continue(pid); return NULL;}static void map_check_clicked(GtkCellRendererToggle* cell, gchar* path_str, gpointer data){ GtkTreeIter iter; GtkListStore* store = GTK_LIST_STORE (data); GtkTreeModel* model = GTK_TREE_MODEL (data); GtkTreePath *path = gtk_tree_path_new_from_string (path_str); gboolean check; gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, MAP_CHECK_COLUMN, &check, -1); gtk_tree_path_free (path); if (check) { gtk_list_store_set(store, &iter, MAP_CHECK_COLUMN, FALSE, MAP_PROCESS_COLUMN, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -