diff options
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | src/analysis/disass/fetch.c | 16 | ||||
-rw-r--r-- | src/analysis/disass/limit.c | 2 | ||||
-rw-r--r-- | src/analysis/disass/output.c | 14 | ||||
-rw-r--r-- | src/analysis/routine.c | 64 | ||||
-rw-r--r-- | src/analysis/routine.h | 17 | ||||
-rw-r--r-- | src/arch/instruction-int.h | 7 | ||||
-rw-r--r-- | src/arch/instruction.c | 25 | ||||
-rw-r--r-- | src/arch/instruction.h | 10 | ||||
-rw-r--r-- | src/arch/raw.c | 11 | ||||
-rw-r--r-- | src/arch/vmpa.c | 231 | ||||
-rw-r--r-- | src/arch/vmpa.h | 59 | ||||
-rw-r--r-- | src/format/dex/method.c | 10 | ||||
-rw-r--r-- | src/format/elf/helper_x86.c | 4 | ||||
-rw-r--r-- | src/format/elf/symbols.c | 6 | ||||
-rw-r--r-- | src/format/format.c | 2 | ||||
-rw-r--r-- | src/format/symbol.c | 48 | ||||
-rw-r--r-- | src/format/symbol.h | 7 | ||||
-rw-r--r-- | src/glibext/gbufferline.c | 24 | ||||
-rw-r--r-- | src/glibext/gbufferline.h | 6 | ||||
-rw-r--r-- | src/glibext/gcodebuffer.c | 49 | ||||
-rw-r--r-- | src/glibext/gcodebuffer.h | 5 | ||||
-rw-r--r-- | src/gui/panels/symbols.c | 10 |
23 files changed, 441 insertions, 212 deletions
@@ -1,3 +1,29 @@ +14-09-17 Cyrille Bagard <nocbos@gmail.com> + + * src/analysis/disass/fetch.c: + * src/analysis/disass/limit.c: + * src/analysis/disass/output.c: + * src/analysis/routine.c: + * src/analysis/routine.h: + * src/arch/instruction.c: + * src/arch/instruction.h: + * src/arch/instruction-int.h: + * src/arch/raw.c: + * src/arch/vmpa.c: + * src/arch/vmpa.h: + * src/format/dex/method.c: + * src/format/elf/helper_x86.c: + * src/format/elf/symbols.c: + * src/format/format.c: + * src/format/symbol.c: + * src/format/symbol.h: + * src/glibext/gbufferline.c: + * src/glibext/gbufferline.h: + * src/glibext/gcodebuffer.c: + * src/glibext/gcodebuffer.h: + * src/gui/panels/symbols.c: + Introduce memory ranges. + 14-09-16 Cyrille Bagard <nocbos@gmail.com> * src/format/elf/elf.c: diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 55ea1d4..763b37a 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -70,6 +70,7 @@ GArchInstruction *load_raw_binary(const GLoadedBinary *binary, const vmpa2t *bas off_t old_phy; /* Ancienne position physique */ GArchInstruction *instr; /* Instruction décodée */ off_t new_phy; /* Nouvelle position physique */ + mrange_t range; /* Couverture de l'instruction */ result = NULL; @@ -90,8 +91,10 @@ GArchInstruction *load_raw_binary(const GLoadedBinary *binary, const vmpa2t *bas if (instr == NULL) break; new_phy = get_phy_addr(&pos); + init_mrange(&range, &prev, new_phy - old_phy); + + g_arch_instruction_set_range(instr, &range); - g_arch_instruction_set_location(instr, &prev, new_phy - old_phy); g_arch_instruction_add_to_list(&result, instr); copy_vmpa(&prev, &pos); @@ -146,7 +149,7 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt size_t i; /* Boucle de parcours */ - + const mrange_t *range; /* Couverture d'un symbole */ const vmpa2t *border; /* Nouvelle bordure rencontrée */ off_t length; /* Taille d'une partie traitée */ @@ -183,7 +186,14 @@ GArchInstruction *disassemble_binary_content(const GLoadedBinary *binary, GtkExt - border = g_binary_symbol_get_location(symbols[i], &length); + + range = g_binary_symbol_get_range(symbols[i]); + + border = get_mrange_addr(range); + length = get_mrange_length(range); + + + switch (g_binary_symbol_get_target_type(symbols[i])) { diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c index 8501251..6d5bc35 100644 --- a/src/analysis/disass/limit.c +++ b/src/analysis/disass/limit.c @@ -87,7 +87,7 @@ void limit_all_routines(GArchInstruction *list, GBinRoutine **routines, size_t c lengths[i] = find_best_ending_address_for_routine(instr, i, starts, lengths, count); lengths[i] -= starts[i]; - g_binary_routine_set_size(routines[i], lengths[i]); + /////////g_binary_routine_set_size(routines[i], lengths[i]); lar_next: diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index f368796..a6d7845 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -55,8 +55,14 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form GArchProcessor *proc; /* Architecture du binaire */ MemoryDataSize msize; /* Taille du bus d'adresses */ const bin_t *content; /* Contenu binaire global */ + +#if 0 + const mrange_t *range; /* Cou + vmpa_t start; /* Adresse de départ */ vmpa_t end; /* Adresse de fin */ +#endif + const GArchInstruction *iter; /* Boucle de parcours #1 */ size_t i; /* Boucle de parcours #2 */ const vmpa2t *iaddr; /* Adresse d'instruction */ @@ -100,9 +106,13 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form content = g_binary_format_get_content(G_BIN_FORMAT(format), NULL); +#if 0 g_arch_instruction_get_location(instrs, NULL, NULL, &start); + start = + iter = g_arch_instruction_find_last(instrs); g_arch_instruction_get_location(iter, NULL, NULL, &end); +#endif for (iter = instrs, i = 0; iter != NULL; @@ -129,8 +139,8 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form if (sym_index < sym_count) { - iaddr = g_arch_instruction_get_location2(iter, NULL); - saddr = g_binary_symbol_get_location(symbols[sym_index], NULL); + iaddr = get_mrange_addr(g_arch_instruction_get_range(iter)); + saddr = get_mrange_addr(g_binary_symbol_get_range(symbols[sym_index])); if (cmp_vmpa_by_phy(iaddr, saddr) == 0) { diff --git a/src/analysis/routine.c b/src/analysis/routine.c index eebcb69..a91e53a 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -38,8 +38,7 @@ struct _GBinRoutine { GObject parent; /* A laisser en premier */ - vmpa2t addr; /* Position physique/mémoire */ - off_t size; /* Taille du code associé */ + mrange_t range; /* Couverture mémoire */ RoutineType type; /* Type de routine */ @@ -214,7 +213,7 @@ void g_binary_routine_finalize(GBinRoutine *routine) int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b) { - return cmp_vmpa(&(*a)->addr, &(*b)->addr); + return cmp_mrange(&(*a)->range, &(*b)->range); } @@ -234,7 +233,7 @@ int g_binary_routine_compare(const GBinRoutine **a, const GBinRoutine **b) int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b) { - return (-1) * cmp_vmpa(&(*a)->addr, &(*b)->addr); + return (-1) * cmp_mrange(&(*a)->range, &(*b)->range); } @@ -242,9 +241,9 @@ int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * -* addr = position mémoire ou physique déclarée. * +* range = plage mémoire ou physique déclarée. * * * -* Description : Définit la position physique / en mémoire d'une routine. * +* Description : Définit la couverture physique / en mémoire d'une routine. * * * * Retour : - * * * @@ -252,67 +251,28 @@ int g_binary_routine_rcompare(const GBinRoutine **a, const GBinRoutine **b) * * ******************************************************************************/ -void g_binary_routine_set_address(GBinRoutine *routine, const vmpa2t *addr) +void g_binary_routine_set_range(GBinRoutine *routine, const mrange_t *range) { - copy_vmpa(&routine->addr, addr); + copy_mrange(&routine->range, range); } /****************************************************************************** * * -* Paramètres : routine = routine à mettre à jour. * -* * -* Description : Fournit la position physique / en mémoire d'une routine. * -* * -* Retour : Position mémoire ou physique déclarée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const vmpa2t *g_binary_routine_get_address(const GBinRoutine *routine) -{ - return &routine->addr; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * -* size = taille du code associé. * -* * -* Description : Définit la taille du code d'une routine. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_routine_set_size(GBinRoutine *routine, off_t size) -{ - routine->size = size; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * +* Paramètres : routine = routine à consulter. * * * -* Description : Fournit la taille du code associé à une routine. * +* Description : Fournit la couverture physique / en mémoire d'une routine. * * * -* Retour : Taille du code associée. * +* Retour : Plage mémoire ou physique déclarée. * * * * Remarques : - * * * ******************************************************************************/ -off_t g_binary_routine_get_size(const GBinRoutine *routine) +const mrange_t *g_binary_routine_get_range(const GBinRoutine *routine) { - return routine->size; + return &routine->range; } diff --git a/src/analysis/routine.h b/src/analysis/routine.h index 29f6e63..3aa33ac 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -86,17 +86,26 @@ int g_binary_routine_compare(const GBinRoutine **, const GBinRoutine **); /* Etablit la comparaison descendante entre deux routines. */ int g_binary_routine_rcompare(const GBinRoutine **, const GBinRoutine **); -/* Définit la position physique / en mémoire d'une routine. */ -void g_binary_routine_set_address(GBinRoutine *, const vmpa2t *); +/* Définit la couverture physique / en mémoire d'une routine. */ +void g_binary_routine_set_range(GBinRoutine *, const mrange_t *); + +/* Fournit la couverture physique / en mémoire d'une routine. */ +const mrange_t *g_binary_routine_get_range(const GBinRoutine *); + + /* Fournit la position physique / en mémoire d'une routine. */ -const vmpa2t *g_binary_routine_get_address(const GBinRoutine *); +//const vmpa2t *g_binary_routine_get_address(const GBinRoutine *); +#define g_binary_routine_get_address(r) 0 /* Définit la taille du code d'une routine. */ void g_binary_routine_set_size(GBinRoutine *, off_t); /* Fournit la taille du code associé à une routine. */ -off_t g_binary_routine_get_size(const GBinRoutine *); +//off_t g_binary_routine_get_size(const GBinRoutine *); +#define g_binary_routine_get_size(r) 0 + + /* Définit le type d'une routine. */ void g_binary_routine_set_type(GBinRoutine *, RoutineType); diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 28caf78..958a5bd 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -55,12 +55,19 @@ struct _GArchInstruction DL_LIST_ITEM(flow); /* Maillon de liste chaînée */ + mrange_t range; /* Emplacement en mémoire */ + + /* ------- %< ----------- */ + vmpa2t address2; /* Position associée */ off_t offset; /* Position physique de départ */ off_t length; /* Taille de l'instruction */ vmpa_t address; /* Position associée */ + /* ------- %< ----------- */ + + GArchOperand **operands; /* Liste des opérandes */ size_t operands_count; /* Nbre. d'opérandes utilisées */ diff --git a/src/arch/instruction.c b/src/arch/instruction.c index ea713cd..402b0f5 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -159,15 +159,9 @@ static void g_arch_instruction_finalize(GArchInstruction *instr) * * ******************************************************************************/ -void g_arch_instruction_set_location(GArchInstruction *instr, const vmpa2t *address, off_t length) +void g_arch_instruction_set_range(GArchInstruction *instr, const mrange_t *range) { - copy_vmpa(&instr->address2, address); - - /* FIXME */ - instr->offset = get_phy_addr(address); - instr->address = get_virt_addr(address); - - instr->length = length; + copy_mrange(&instr->range, range); } @@ -175,23 +169,18 @@ void g_arch_instruction_set_location(GArchInstruction *instr, const vmpa2t *addr /****************************************************************************** * * * Paramètres : instr = instruction quelconque à consulter. * -* offset = position physique dans le code binaire/NULL. [OUT] * -* length = taille de l'instruction ou NULL. [OUT] * -* address = adresse virtuelle ou position physique/NULL. [OUT] * * * -* Description : Fournit la localisation d'une instruction. * +* Description : Fournit la place mémoire d'une instruction. * * * -* Retour : - * +* Retour : Zone mémoire couverte par l'instruction. * * * * Remarques : - * * * ******************************************************************************/ -const vmpa2t *g_arch_instruction_get_location2(const GArchInstruction *instr, off_t *length) +const mrange_t *g_arch_instruction_get_range(const GArchInstruction *instr) { - if (length != NULL) *length = instr->length; - - return &instr->address2; + return &instr->range; } @@ -699,7 +688,7 @@ static GBufferLine *_g_arch_instruction_print(const GArchInstruction *instr, GCo size_t klen; /* Taille de ce mot clef */ size_t i; /* Boucle de parcours */ - result = g_code_buffer_append_new_line(buffer, &instr->address2); + result = g_code_buffer_append_new_line(buffer, &instr->range); g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, instr->length, true); diff --git a/src/arch/instruction.h b/src/arch/instruction.h index f04a458..4fe0569 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -57,18 +57,18 @@ typedef struct _GArchInstructionClass GArchInstructionClass; GType g_arch_instruction_get_type(void); /* Définit la localisation d'une instruction. */ -void g_arch_instruction_set_location(GArchInstruction *, const vmpa2t *, off_t); +void g_arch_instruction_set_range(GArchInstruction *, const mrange_t *); - - -/* Fournit la localisation d'une instruction. */ -const vmpa2t *g_arch_instruction_get_location2(const GArchInstruction *, off_t *); +/* Fournit la place mémoire d'une instruction. */ +const mrange_t *g_arch_instruction_get_range(const GArchInstruction *); /* Fournit la localisation d'une instruction. */ void g_arch_instruction_get_location(const GArchInstruction *, off_t *, off_t *, vmpa_t *); + + /* Attache un opérande supplémentaire à une instruction. */ void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *); diff --git a/src/arch/raw.c b/src/arch/raw.c index 842c2b4..e127f91 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -187,16 +187,17 @@ static void g_raw_instruction_finalize(GRawInstruction *instr) GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize size, size_t count, vmpa2t *addr, off_t end, SourceEndian endian) { GArchInstruction *result; /* Instruction à retourner */ - vmpa2t *old; /* Sauvegarde de la position */ + vmpa2t old; /* Sauvegarde de la position */ size_t i; /* Boucle de parcours */ GArchOperand *operand; /* Octet non décodé à afficher */ + mrange_t range; /* Couverture de l'instruction */ /* Par soucis de cohérence */ if (count == 0) return NULL; result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); - old = dup_vmpa(addr); + copy_vmpa(&old, addr); for (i = 0; i < count; i++) { @@ -208,9 +209,9 @@ GArchInstruction *g_raw_instruction_new_array(const bin_t *data, MemoryDataSize g_arch_instruction_attach_extra_operand(result, operand); } - g_arch_instruction_set_location(result, old, compute_vmpa_diff(addr, old)); + init_mrange(&range, &old, compute_vmpa_diff(addr, &old)); - delete_vmpa(old); + g_arch_instruction_set_range(result, &range); return result; @@ -251,7 +252,7 @@ static GBufferLine *g_raw_instruction_print(const GRawInstruction *instr, GCodeB else { - result = g_code_buffer_append_new_line(buffer, &base->address2); + result = g_code_buffer_append_new_line(buffer, &base->range); g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, base->length, true); diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index c3cf17e..6f305fb 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -34,9 +34,14 @@ +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UNE POSITION EN MEMOIRE */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * -* Paramètres : addr = élément à initialiser. * +* Paramètres : addr = élément à initialiser. [OUT] * * phy = position dans la mémoire physique. * * virt = adresse dans la mémoire virtuelle. * * * @@ -48,7 +53,7 @@ * * ******************************************************************************/ -void init_vmpa(vmpa2t *addr, off_t phy, uint64_t virt) +void init_vmpa(vmpa2t *addr, phys_t phy, virt_t virt) { addr->physical = phy; addr->virtual = virt; @@ -69,7 +74,7 @@ void init_vmpa(vmpa2t *addr, off_t phy, uint64_t virt) * * ******************************************************************************/ -vmpa2t *make_vmpa(off_t phy, uint64_t virt) +vmpa2t *make_vmpa(phys_t phy, virt_t virt) { vmpa2t *result; /* Structure à retourner */ @@ -212,7 +217,6 @@ int cmp_vmpa(const vmpa2t *a, const vmpa2t *b) } - /****************************************************************************** * * * Paramètres : addr = élément à modifier. * @@ -226,7 +230,7 @@ int cmp_vmpa(const vmpa2t *a, const vmpa2t *b) * * ******************************************************************************/ -void advance_vmpa(vmpa2t *addr, off_t qty) +void advance_vmpa(vmpa2t *addr, phys_t qty) { if (addr->physical != VMPA_NO_PHYSICAL) addr->physical += qty; @@ -250,9 +254,9 @@ void advance_vmpa(vmpa2t *addr, off_t qty) * * ******************************************************************************/ -off_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b) +phys_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b) { - off_t result; /* Valeur à retourner */ + phys_t result; /* Valeur à retourner */ result = VMPA_NO_PHYSICAL; @@ -260,7 +264,7 @@ off_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b) result = (b->physical > a->physical ? b->physical - a->physical : a->physical- b->physical); else if (a->virtual != VMPA_NO_VIRTUAL && b->virtual != VMPA_NO_VIRTUAL) - result = (off_t)(b->virtual > a->virtual ? b->virtual - a->virtual : a->virtual- b->virtual); + result = (phys_t)(b->virtual > a->virtual ? b->virtual - a->virtual : a->virtual- b->virtual); return result; @@ -283,15 +287,15 @@ off_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b) bool recv_vmpa(vmpa2t *addr, int fd, int flags) { - uint64_t val64; /* Valeur sur 64 bits */ + virt_t val64; /* Valeur sur 64 bits */ bool status; /* Bilan d'une réception */ - status = safe_recv(fd, &val64, sizeof(uint64_t), flags); + status = safe_recv(fd, &val64, sizeof(virt_t), flags); if (!status) return false; addr->physical = be64toh(val64); - status = safe_recv(fd, &val64, sizeof(uint64_t), flags); + status = safe_recv(fd, &val64, sizeof(virt_t), flags); if (!status) return false; addr->virtual = be64toh(val64); @@ -319,10 +323,10 @@ bool send_vmpa(const vmpa2t *addr, int fd, int flags) { bool status; /* Bilan d'une émission */ - status = safe_send(fd, (uint64_t []) { htobe64(addr->physical) }, sizeof(uint64_t), flags); + status = safe_send(fd, (virt_t []) { htobe64(addr->physical) }, sizeof(virt_t), flags); if (!status) return false; - status = safe_send(fd, (uint64_t []) { htobe64(addr->virtual) }, sizeof(uint64_t), flags); + status = safe_send(fd, (virt_t []) { htobe64(addr->virtual) }, sizeof(virt_t), flags); if (!status) return false; return true; @@ -446,7 +450,7 @@ char *vmpa2_virt_to_string(const vmpa2t *addr, MemoryDataSize msize, char buffer vmpa2t *string_to_vmpa_phy(const char *buffer) { - off_t physical; /* Position à retrouver */ + phys_t physical; /* Position à retrouver */ physical = strtoull(buffer, NULL, 16); @@ -469,10 +473,207 @@ vmpa2t *string_to_vmpa_phy(const char *buffer) vmpa2t *string_to_vmpa_virt(const char *buffer) { - uint64_t virtual; /* Adresse à retrouver */ + virt_t virtual; /* Adresse à retrouver */ virtual = strtoull(buffer, NULL, 16); return make_vmpa(VMPA_NO_PHYSICAL, virtual); } + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UNE ZONE EN MEMOIRE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : range = plage à initialiser. [OUT] * +* addr = position de départ dans la mémoire. * +* length = taille de la plage à constituer. * +* * +* Description : Initialise une plage dans l'espace mémoire/physique. * +* * +* Retour : Place définie en mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +void init_mrange(mrange_t *range, const vmpa2t *addr, phys_t length) +{ + copy_vmpa(&range->addr, addr); + + range->length = length; + +} + + +/****************************************************************************** +* * +* Paramètres : dest = structure de destination pour la copie. * +* src = structure de source pour la copie. * +* * +* Description : Copie la définition d'une plage mémoire dans une autre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void copy_mrange(mrange_t *dest, const mrange_t *src) +{ + copy_vmpa(&dest->addr, &src->addr); + + dest->length = src->length; + +} + + +/****************************************************************************** +* * +* Paramètres : a = première définition à analyser. * +* b = seconde définition à analyser. * +* * +* Description : Compare deux couvertures mémoire selon leurs propriétés. * +* * +* Retour : Bilan de la comparaison : -1, 0 ou 1 (-1 par défaut). * +* * +* Remarques : - * +* * +******************************************************************************/ + +int cmp_mrange(const mrange_t *a, const mrange_t *b) +{ + int result; /* Bilan à retourner */ + + result = cmp_vmpa(&a->addr, &b->addr); + + if (result == 0) + { + if (a->length < b->length) + result = -1; + else if (a->length > b->length) + result = 1; + else + result = 0; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : range = zone mémoire à consulter. * +* addr = localisation mémoire à analyser. * +* * +* Description : Indique si une localisation est incluse dans une zone ou non.* +* * +* Retour : Bilan de la consultation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool mrange_contains_addr(const mrange_t *range, const vmpa2t *addr) +{ + bool result; /* Bilan à retourner */ + int ret; /* Bilan d'une comparaison */ + phys_t diff; /* Espace entre deux adresses */ + + ret = cmp_vmpa(&range->addr, addr); + + if (ret <= -1) + { + diff = compute_vmpa_diff(&range->addr, addr); + result = (diff < range->length); + } + + else if (ret == 0) + result = true; + + else + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : rane = emplacement virtuel ou physique à traiter. * +* msize = taille de cette adresse, réelle ou désirée. * +* start = indique si le début ou la fin est à imprimer. * +* buffer = tampon de sortie utilisé à constituer. [OUT] * +* length = transmission de la taille du résultat ou NULL. [OUT]* +* * +* Description : Transforme un emplacement physique en chaîne de caractères. * +* * +* Retour : Chaîne de caractères constituée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *mrange_phys_to_string(const mrange_t *range, MemoryDataSize msize, bool start, char buffer[VMPA_MAX_LEN], size_t *length) +{ + vmpa2t tmp; + + if (start) + vmpa2_phys_to_string(&range->addr, msize, buffer, length); + + else + { + copy_vmpa(&tmp, &range->addr); + advance_vmpa(&tmp, range->length); + + vmpa2_phys_to_string(&tmp, msize, buffer, length); + + } + + return buffer; + +} + + +/****************************************************************************** +* * +* Paramètres : rane = emplacement virtuel ou physique à traiter. * +* msize = taille de cette adresse, réelle ou désirée. * +* start = indique si le début ou la fin est à imprimer. * +* buffer = tampon de sortie utilisé à constituer. [OUT] * +* length = transmission de la taille du résultat ou NULL. [OUT]* +* * +* Description : Transforme un emplacement virtuel en chaîne de caractères. * +* * +* Retour : Chaîne de caractères constituée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *mrange_virt_to_string(const mrange_t *range, MemoryDataSize msize, bool start, char buffer[VMPA_MAX_LEN], size_t *length) +{ + vmpa2t tmp; + + if (start) + vmpa2_virt_to_string(&range->addr, msize, buffer, length); + + else + { + copy_vmpa(&tmp, &range->addr); + advance_vmpa(&tmp, range->length); + + vmpa2_virt_to_string(&tmp, msize, buffer, length); + + } + + return buffer; + +} diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 85ff6b4..52c5d6a 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -37,6 +37,9 @@ +/* ---------------------- DEFINITION D'UNE POSITION EN MEMOIRE ---------------------- */ + + /* Taille de la plus longue chaîne de représentation */ #define VMPA_MAX_LEN (sizeof(STR(ULLONG_MAX)) + 1) @@ -44,24 +47,28 @@ #define VMPA_BUFFER(name) char name[VMPA_MAX_LEN] -#define VMPA_NO_PHYSICAL ((off_t)-1) -#define VMPA_NO_VIRTUAL ((uint64_t)-2) +/* Types pour respectivement une position physique et une adresse virtuelle */ +#define phys_t off_t +#define virt_t uint64_t + +#define VMPA_NO_PHYSICAL ((phys_t)-1) +#define VMPA_NO_VIRTUAL ((virt_t)-2) /* Adresse mémoire ou position physique */ typedef struct _vmpa2t { - off_t physical; /* Position physique */ - uint64_t virtual; /* Adresse virtuelle */ + phys_t physical; /* Position physique */ + virt_t virtual; /* Adresse virtuelle */ } vmpa2t; /* Initialise une localisation dans l'espace mémoire/physique. */ -void init_vmpa(vmpa2t *, off_t, uint64_t); +void init_vmpa(vmpa2t *, phys_t, virt_t); /* Crée une localisation dans l'adressage mémoire. */ -vmpa2t *make_vmpa(off_t, uint64_t); +vmpa2t *make_vmpa(phys_t, virt_t); #define delete_vmpa(a) free(a) @@ -87,10 +94,10 @@ int cmp_vmpa(const vmpa2t *, const vmpa2t *); make_vmpa(get_phy_addr(src), get_virt_addr(src)) /* Décalle une position d'une certaine quantité. */ -void advance_vmpa(vmpa2t *, off_t); +void advance_vmpa(vmpa2t *, phys_t); /* Calcule au mieux la distance entre deux coordonnées. */ -off_t compute_vmpa_diff(const vmpa2t *, const vmpa2t *); +phys_t compute_vmpa_diff(const vmpa2t *, const vmpa2t *); /* Lit la définition d'une adresse depuis un flux réseau. */ bool recv_vmpa(vmpa2t *, int, int); @@ -112,4 +119,40 @@ vmpa2t *string_to_vmpa_virt(const char *); +/* ------------------------ DEFINITION D'UNE ZONE EN MEMOIRE ------------------------ */ + + +/* Couverture mémoire */ +typedef struct _mrange_t +{ + vmpa2t addr; /* Adresse physique/virtuelle */ + phys_t length; /* Taille de la couverture */ + +} mrange_t; + + +#define get_mrange_addr(r) &(r)->addr +#define get_mrange_length(r) (r)->length + + +/* Initialise une plage dans l'espace mémoire/physique. */ +void init_mrange(mrange_t *, const vmpa2t *, phys_t ); + +/* Copie la définition d'une plage mémoire dans une autre. */ +void copy_mrange(mrange_t *, const mrange_t *); + +/* Compare deux couvertures mémoire selon leurs propriétés. */ +int cmp_mrange(const mrange_t *, const mrange_t *); + +/* Indique si une localisation est incluse dans une zone ou non. */ +bool mrange_contains_addr(const mrange_t *, const vmpa2t *); + +/* Transforme un emplacement physique en chaîne de caractères. */ +char *mrange_phys_to_string(const mrange_t *, MemoryDataSize, bool, char [VMPA_MAX_LEN], size_t *); + +/* Transforme un emplacement virtuel en chaîne de caractères. */ +char *mrange_virt_to_string(const mrange_t *, MemoryDataSize, bool, char [VMPA_MAX_LEN], size_t *); + + + #endif /* _ARCH_VMPA_H */ diff --git a/src/format/dex/method.c b/src/format/dex/method.c index d7900f8..22e7039 100644 --- a/src/format/dex/method.c +++ b/src/format/dex/method.c @@ -131,6 +131,10 @@ GDexMethod *g_dex_method_new(const GDexFormat *format, const encoded_method *see GBinRoutine *routine; + vmpa2t addr; + mrange_t range; + + offset = seed->code_off; if (!read_dex_code_item(format, &offset, &item)) @@ -168,9 +172,11 @@ GDexMethod *g_dex_method_new(const GDexFormat *format, const encoded_method *see //printf(" method off :: 0x%08x\n", result->offset); + init_vmpa(&addr, result->offset, VMPA_NO_VIRTUAL); + init_mrange(&range, &addr, item.insns_size * sizeof(uint16_t)); + - g_binary_routine_set_address(routine, result->offset); - g_binary_routine_set_size(routine, item.insns_size * sizeof(uint16_t)); + g_binary_routine_set_range(routine, &range); result->routine = routine; diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c index d921592..af733a2 100644 --- a/src/format/elf/helper_x86.c +++ b/src/format/elf/helper_x86.c @@ -293,7 +293,7 @@ void translate_exe_elf_relocations(GElfFormat *format, GArchInstruction **instru routine = try_to_demangle_routine(g_binary_symbol_to_string(symbols[j])); - g_binary_routine_set_address(routine, address); + ///g_binary_routine_set_address(routine, address); ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); @@ -401,7 +401,7 @@ void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instru routine = try_to_demangle_routine(name); - g_binary_routine_set_address(routine, address); + ////g_binary_routine_set_address(routine, address); ///// reactiver g_binary_format_add_routine(G_BIN_FORMAT(format), routine); diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index 06d7cab..15c3a6b 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -1296,6 +1296,7 @@ static bool load_elf_internal_symbols(GElfFormat *format) off_t iter; /* Boucle de parcours */ elf_sym sym; /* Symbole aux infos visées */ vmpa2t addr; /* Localisation d'une routine */ + mrange_t range; /* Couverture mémoire associée */ const char *name; /* Nom du symbole trouvé */ char alt_name[5 + VMPA_MAX_LEN]; /* Nom abstrait de substitution*/ GBinRoutine *routine; /* Nouvelle routine trouvée */ @@ -1320,6 +1321,8 @@ static bool load_elf_internal_symbols(GElfFormat *format) init_vmpa(&addr, ELF_SYM(format, sym, st_value), VMPA_NO_VIRTUAL); + init_mrange(&range, &addr, ELF_SYM(format, sym, st_size)); + /* Première ébauche de nom */ @@ -1373,8 +1376,7 @@ static bool load_elf_internal_symbols(GElfFormat *format) routine = try_to_demangle_routine(name); - g_binary_routine_set_address(routine, &addr); - g_binary_routine_set_size(routine, ELF_SYM(format, sym, st_size)); + g_binary_routine_set_range(routine, &range); /* Symbole uniquement */ diff --git a/src/format/format.c b/src/format/format.c index 4b5dfb5..4fec391 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -374,7 +374,7 @@ bool g_binary_format_resolve_symbol(const GBinFormat *format, const char **label for (i = 0; i < format->symbols_count && !result; i++) { addr = g_binary_symbol_get_address(format->symbols[i]); - size = g_binary_symbol_get_size(format->symbols[i]); + size = 0;//////g_binary_symbol_get_size(format->symbols[i]); if (addr <= *address && *address < (addr + size)) { diff --git a/src/format/symbol.c b/src/format/symbol.c index 5b80555..0875e1f 100644 --- a/src/format/symbol.c +++ b/src/format/symbol.c @@ -192,32 +192,29 @@ vmpa_t g_binary_symbol_get_address(const GBinSymbol *symbol) /****************************************************************************** * * * Paramètres : symbol = symbole à venir consulter. * -* length = taille de l'instruction ou NULL. [OUT] * * * * Description : Fournit l'emplacement où se situe un symbole. * * * -* Retour : Adresse virtuelle ou physique associée. * +* Retour : Zone mémoire couverte par le symbole. * * * * Remarques : - * * * ******************************************************************************/ -const vmpa2t *g_binary_symbol_get_location(const GBinSymbol *symbol, off_t *length) +const mrange_t *g_binary_symbol_get_range(const GBinSymbol *symbol) { - const vmpa2t *result; /* Localisation à retourner */ + const mrange_t *result; /* Plage à retourner */ result = NULL; switch (symbol->type) { case STP_DATA: - result = g_arch_instruction_get_location2(symbol->extra.instr, length); + result = g_arch_instruction_get_range(symbol->extra.instr); break; case STP_ROUTINE: - result = g_binary_routine_get_address(symbol->extra.routine); - if (length != NULL) - *length = g_binary_routine_get_size(symbol->extra.routine); + result = g_binary_routine_get_range(symbol->extra.routine); break; default: @@ -234,41 +231,6 @@ const vmpa2t *g_binary_symbol_get_location(const GBinSymbol *symbol, off_t *leng /****************************************************************************** * * * Paramètres : symbol = symbole à venir consulter. * -* * -* Description : Fournit la taille officielle d'un symbole. * -* * -* Retour : Taille de symbole. * -* * -* Remarques : - * -* * -******************************************************************************/ - -off_t g_binary_symbol_get_size(const GBinSymbol *symbol) -{ - off_t result; /* Taille à renvoyer */ - - switch (symbol->type) - { - case STP_OBJECT: - result = 1; /* FIXME */ - break; - case STP_FUNCTION: - /* FIXME */if (symbol->extra.routine == NULL) result = 1; else - result = g_binary_routine_get_size(symbol->extra.routine); - break; - case STP_STRING: - result = strlen(g_binary_symbol_to_string(symbol)); - break; - } - - return result;; - -} - - -/****************************************************************************** -* * -* Paramètres : symbol = symbole à venir consulter. * * alt = désignation humaine alternative à favoriser. * * * * Description : Définit un autre nom pour le symbole. * diff --git a/src/format/symbol.h b/src/format/symbol.h index 8d27f97..91268f1 100644 --- a/src/format/symbol.h +++ b/src/format/symbol.h @@ -72,13 +72,10 @@ SymbolType g_binary_symbol_get_target_type(const GBinSymbol *); const char *g_binary_symbol_to_string(const GBinSymbol *); /* Fournit l'adresse associée à un symbole. */ -vmpa_t g_binary_symbol_get_address(const GBinSymbol *); +vmpa_t g_binary_symbol_get_address(const GBinSymbol *); /////////////////// /* Fournit l'emplacement où se situe un symbole. */ -const vmpa2t *g_binary_symbol_get_location(const GBinSymbol *, off_t *); - -/* Fournit la taille officielle d'un symbole. */ -off_t g_binary_symbol_get_size(const GBinSymbol *); +const mrange_t *g_binary_symbol_get_range(const GBinSymbol *); /* Définit un autre nom pour le symbole. */ void g_binary_symbol_set_alt_name(GBinSymbol *, char *); diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index ac6dc23..758dff7 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -80,7 +80,7 @@ struct _GBufferLine { GObject parent; /* A laisser en premier */ - const vmpa2t *addr; /* Emplacement geographique */ + mrange_t range; /* Couverture geographique */ BufferLineColumn main_column; /* Colonne principale */ buffer_line_column columns[BLC_COUNT]; /* Répartition du texte */ @@ -354,8 +354,8 @@ static void g_buffer_line_init(GBufferLine *line) /****************************************************************************** * * -* Paramètres : addr = emplacement où va se situer la ligne. * -* main = colonne à référencer comme étant la principale. * +* Paramètres : range = emplacement où va se situer la ligne. * +* main = colonne à référencer comme étant la principale. * * * * Description : Crée une nouvelle représentation de fragments de texte. * * * @@ -365,13 +365,13 @@ static void g_buffer_line_init(GBufferLine *line) * * ******************************************************************************/ -GBufferLine *g_buffer_line_new(const vmpa2t *addr, BufferLineColumn main) +GBufferLine *g_buffer_line_new(const mrange_t *range, BufferLineColumn main) { GBufferLine *result; /* Composant à retourner */ result = g_object_new(G_TYPE_BUFFER_LINE, NULL); - result->addr = addr; + copy_mrange(&result->range, range); result->main_column = main; return result; @@ -383,17 +383,17 @@ GBufferLine *g_buffer_line_new(const vmpa2t *addr, BufferLineColumn main) * * * Paramètres : line = ligne à venir consulter. * * * -* Description : Indique l'adresse à laquelle se situe la ligne. * +* Description : Indique la zone mémoire où se situe la ligne. * * * -* Retour : Adresse mémoire ou physique. * +* Retour : Emplacement mémoire virtuel ou physique. * * * * Remarques : - * * * ******************************************************************************/ -const vmpa2t *g_buffer_line_get_address(const GBufferLine *line) +const mrange_t *g_buffer_line_get_range(const GBufferLine *line) { - return line->addr; + return &line->range; } @@ -433,10 +433,10 @@ void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, Memor /* Adresse physique puis virtuelle */ - vmpa2_phys_to_string(line->addr, psize, address, &len); + mrange_phys_to_string(&line->range, psize, true, address, &len); g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW); - vmpa2_virt_to_string(line->addr, vsize, address, &len); + mrange_virt_to_string(&line->range, vsize, true, address, &len); g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_RAW); /* Détermination du réceptacle */ @@ -450,7 +450,7 @@ void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, Memor /* Code brut */ - start = get_phy_addr(line->addr); + start = get_phy_addr(get_mrange_addr(&line->range)); end = start + length; for (i = start, iter = bin_code; i < end; i++, iter += ret) diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 4ca07ca..b96f7a6 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -83,10 +83,10 @@ typedef enum _BufferLineColumn GType g_buffer_line_get_type(void); /* Crée une nouvelle représentation de fragments de texte. */ -GBufferLine *g_buffer_line_new(const vmpa2t *, BufferLineColumn); +GBufferLine *g_buffer_line_new(const mrange_t *, BufferLineColumn); -/* Indique l'adresse à laquelle se situe la ligne. */ -const vmpa2t *g_buffer_line_get_address(const GBufferLine *); +/* Indique la zone mémoire où se situe la ligne. */ +const mrange_t *g_buffer_line_get_range(const GBufferLine *); /* Construit le tronc commun d'une ligne d'instruction. */ void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize, const bin_t *, off_t, bool); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index 6a21222..0ac3bb3 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -416,6 +416,11 @@ static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, v /* TODO : coder un parcours plus optimal ! */ + return (first ? 0 : buffer->used - 1); + + +#if 0 + for (result = 0; result < buffer->used; result++) if (g_buffer_line_get_address(buffer->lines[result]) == addr) break; @@ -425,6 +430,8 @@ static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, v if (g_buffer_line_get_address(buffer->lines[result + 1]) != addr) break; +#endif + return result; } @@ -466,7 +473,7 @@ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t a /****************************************************************************** * * * Paramètres : buffer = composant GTK à mettre à jour. * -* addr = emplacement où va se situer la ligne. * +* range = emplacement où va se situer la ligne. * * * * Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. * * * @@ -476,7 +483,7 @@ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t a * * ******************************************************************************/ -GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const vmpa2t *addr) +GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t *range) { GBufferLine *result; /* Instance à retourner */ size_t i; /* Boucle de parcours */ @@ -488,7 +495,7 @@ GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const vmpa2t *ad buffer->count * sizeof(GBufferLine *)); } - result = g_buffer_line_new(addr, buffer->main_column); + result = g_buffer_line_new(range, buffer->main_column); buffer->lines[buffer->used++] = result; for (i = 0; i < buffer->indent; i++) @@ -1111,7 +1118,7 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, caret->width = 2; caret->height = view->line_height; - return g_buffer_line_get_address(line); + return NULL;///g_buffer_line_get_address(line); } @@ -1303,17 +1310,6 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y) line = g_buffer_view_find_line_at(view, y, NULL); if (line == NULL) return; - - do - { - vmpa_t addr; - addr = g_buffer_line_get_address(line); - - printf(" ... x2 clic at 0x%08lx\n", addr); - - } - while (0); - x -= view->left_text; if (x < 0) return; @@ -1463,8 +1459,7 @@ bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr size_t first; /* Première ligne intégrée */ size_t last; /* Dernière ligne intégrée */ size_t i; /* Boucle de parcours */ - const vmpa2t *current; /* Adresse parcourue */ - int ret; /* Bilan d'une comparaison */ + const mrange_t *range; /* Emplacement parcouru */ result = false; @@ -1479,11 +1474,21 @@ bool g_buffer_view_get_address_coordinates(GBufferView *view, const vmpa2t *addr if (view->buffer->used > 0) for (i = first; i <= last; i++) { - current = g_buffer_line_get_address(view->buffer->lines[i]); - ret = cmp_vmpa(current, addr); - - result = (ret == 0); - if (ret >= 0) break; + /** + * Si l'adresse recherchée est plus petite que l'adresse de départ, + * on va effectuer un parcours complet pour rien. + * + * On considère cependant que le seul cas où celà peut arriver + * est lorsque que des découpages en blocs sont impliqués. + * + * Les découpages conduisent alors à la formation de petites zones, + * rapides à parcourir. + */ + + range = g_buffer_line_get_range(view->buffer->lines[i]); + + result = mrange_contains_addr(range, addr); + if (result) break; *y += lheight; diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h index 5be0084..472d403 100644 --- a/src/glibext/gcodebuffer.h +++ b/src/glibext/gcodebuffer.h @@ -57,10 +57,11 @@ GType g_code_buffer_get_type(void); GCodeBuffer *g_code_buffer_new(BufferLineColumn); /* FIXME */ -#define g_code_buffer_append_new_line_fixme(b) g_code_buffer_append_new_line(b, make_vmpa(VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL)) +#define g_code_buffer_append_new_line_fixme(b) \ + g_code_buffer_append_new_line(b, (mrange_t []){ { 0, 0 }, 0 }) /* Ajoute une nouvelle ligne à un tampon pour code désassemblé. */ -GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *, const vmpa2t *); +GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *, const mrange_t *); /* Ajoute une nouvelle ligne à un tampon pour code désassemblé. */ GBufferLine *g_code_buffer_insert_at(GCodeBuffer *, vmpa_t, bool); diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index c106881..cb10a54 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -553,17 +553,17 @@ static void on_symbols_selection_change(GtkTreeSelection *selection, GSymbolsPan GtkTreeIter iter; /* Point de sélection */ GtkTreeModel *model; /* Modèle de gestion */ GBinSymbol *symbol; /* Symbole à traiter */ - const vmpa2t *addr; /* Localisation dudit symbole */ + const mrange_t *range; /* Couverture dudit symbole */ GtkViewPanel *vpanel; /* Afficheur effectif de code */ if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, SBC_SYMBOL, &symbol, -1); - addr = g_binary_symbol_get_location(symbol, NULL); + range = g_binary_symbol_get_range(symbol); vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(panel)); - gtk_view_panel_scroll_to_address(vpanel, addr); + gtk_view_panel_scroll_to_address(vpanel, get_mrange_addr(range)); g_object_unref(G_OBJECT(symbol)); @@ -670,7 +670,7 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel) break; } - addr = g_binary_symbol_get_location(symbols[i], NULL); + addr = get_mrange_addr(g_binary_symbol_get_range(symbols[i])); vmpa2_virt_to_string(addr, size, virt, NULL); gtk_tree_store_append(panel->store, &iter, NULL); @@ -850,7 +850,7 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel) break; } - addr = g_binary_symbol_get_location(symbols[i], NULL); + addr = get_mrange_addr(g_binary_symbol_get_range(symbols[i])); vmpa2_virt_to_string(addr, size, virt, NULL); gtk_tree_store_set(panel->store, &iter, |