From 1252efcd18a845a7c2641354838c26ece3d6d873 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 26 Nov 2017 21:39:28 +0100
Subject: Increased the reference counter for provided operands and updated
 code.

---
 plugins/androhelpers/params.c       |  2 ++
 plugins/androhelpers/switch.c       |  2 ++
 plugins/dalvik/fetch.c              |  2 ++
 plugins/dalvik/link.c               |  2 ++
 plugins/dalvik/operand.c            |  2 ++
 plugins/fmtp/parser.c               |  4 ++--
 plugins/pychrysa/arch/instruction.c |  2 ++
 plugins/stackvars/stackvars.c       |  2 ++
 src/analysis/db/items/switcher.c    | 20 ++++++++++++++++++--
 src/analysis/disass/links.c         |  8 ++++++--
 src/arch/arm/v7/fetch.c             | 14 +++++++++++++-
 src/arch/arm/v7/link.c              |  4 ++++
 src/arch/arm/v7/post.c              |  2 ++
 src/arch/instruction.c              | 13 ++++++++++++-
 src/arch/link.c                     | 14 ++++++++------
 src/arch/post.c                     |  2 ++
 src/arch/raw.c                      |  6 ++++++
 17 files changed, 87 insertions(+), 14 deletions(-)

diff --git a/plugins/androhelpers/params.c b/plugins/androhelpers/params.c
index ea85b89..f5c22b9 100644
--- a/plugins/androhelpers/params.c
+++ b/plugins/androhelpers/params.c
@@ -163,6 +163,8 @@ static void visit_all_method_operands(const GDexMethod *method, GArchInstruction
             else if (G_IS_DALVIK_ARGS_OPERAND(operand))
                 process_args_operand(method, G_DALVIK_ARGS_OPERAND(operand));
 
+            g_object_unref(G_OBJECT(operand));
+
         }
 
         g_arch_instruction_unlock_operands(iter);
diff --git a/plugins/androhelpers/switch.c b/plugins/androhelpers/switch.c
index 20e6037..0e8b6ed 100644
--- a/plugins/androhelpers/switch.c
+++ b/plugins/androhelpers/switch.c
@@ -89,6 +89,8 @@ static bool load_dex_switch(const GArchInstruction *instr, GArchInstruction *ins
 
     imm = NULL; //g_dalvik_target_operand_get_value(G_DALVIK_TARGET_OPERAND(operand));
 
+    g_object_unref(G_OBJECT(operand));
+
     if (!g_imm_operand_to_vmpa_t(imm, &addr))
         return false;
 
diff --git a/plugins/dalvik/fetch.c b/plugins/dalvik/fetch.c
index aa17a9f..1ac6fa2 100644
--- a/plugins/dalvik/fetch.c
+++ b/plugins/dalvik/fetch.c
@@ -56,6 +56,8 @@ void help_fetching_with_dalvik_instruction(GArchInstruction *instr, GArchProcess
     status = g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &target);
     assert(status);
 
+    g_object_unref(G_OBJECT(op));
+
     if (status)
         g_proc_context_push_drop_point(G_PROC_CONTEXT(context), DPL_OTHER, target);
 
diff --git a/plugins/dalvik/link.c b/plugins/dalvik/link.c
index 5fa0c26..502b7a3 100644
--- a/plugins/dalvik/link.c
+++ b/plugins/dalvik/link.c
@@ -127,6 +127,8 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *
         }
     }
 
+    g_object_unref(G_OBJECT(op));
+
     if (defined)
     {
         switch_ins = g_arch_processor_find_instr_by_address(proc, &addr);
diff --git a/plugins/dalvik/operand.c b/plugins/dalvik/operand.c
index e37a0bb..12fcca5 100644
--- a/plugins/dalvik/operand.c
+++ b/plugins/dalvik/operand.c
@@ -749,4 +749,6 @@ void dalvik_mark_first_operand_as_written(GArchInstruction *instr)
 
     g_dalvik_register_operand_mark_as_written(G_DALVIK_REGISTER_OPERAND(operand));
 
+    g_object_unref(G_OBJECT(operand));
+
 }
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c
index fe41e9b..994b7b4 100644
--- a/plugins/fmtp/parser.c
+++ b/plugins/fmtp/parser.c
@@ -116,7 +116,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
 
             g_imm_operand_set_default_display(imm, def->disp_rules[i]);
 
-            // TODO : unref(imm)
+            g_object_unref(G_OBJECT(imm));
 
         }
 
@@ -139,7 +139,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
 
             imm = G_IMM_OPERAND(g_arch_instruction_get_operand(instr, 0));
             raw = g_imm_operand_get_raw_value(imm);
-            // TODO : unref(imm)
+            g_object_unref(G_OBJECT(imm));
 
             for (i = 0; i < def->comment.ccount; i++)
             {
diff --git a/plugins/pychrysa/arch/instruction.c b/plugins/pychrysa/arch/instruction.c
index 61d1987..bb977ce 100644
--- a/plugins/pychrysa/arch/instruction.c
+++ b/plugins/pychrysa/arch/instruction.c
@@ -341,6 +341,8 @@ static PyObject *py_arch_instruction_get_operands(PyObject *self, void *unused)
         ret = PyTuple_SetItem(result, i, Py_BuildValue("O", opobj));
         assert(ret == 0);
 
+        g_object_unref(G_OBJECT(operand));
+
     }
 
     g_arch_instruction_unlock_operands(instr);
diff --git a/plugins/stackvars/stackvars.c b/plugins/stackvars/stackvars.c
index ce9d539..1b5a188 100644
--- a/plugins/stackvars/stackvars.c
+++ b/plugins/stackvars/stackvars.c
@@ -223,6 +223,8 @@ static bool replace_stack_vars_in_instruction(GArchInstruction *instr, GBinRouti
 
         }
 
+        g_object_unref(G_OBJECT(operand));
+
     }
 
     g_arch_instruction_unlock_operands(instr);
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 35acf5f..1863098 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -269,6 +269,7 @@ GDbSwitcher *g_db_switcher_new(GArchInstruction *instr, const GImmOperand *imm,
     GDbSwitcher *result;                    /* Instance à retourner        */
     size_t count;                           /* Nombre d'opérandes à visiter*/
     size_t i;                               /* Boucle de parcours          */
+    GArchOperand *op;                       /* Opérande manipulé           */
     const mrange_t *range;                  /* Localisation de l'instruct° */
 
     /* Recherche de la position de l'opérande */
@@ -278,8 +279,19 @@ GDbSwitcher *g_db_switcher_new(GArchInstruction *instr, const GImmOperand *imm,
     count = _g_arch_instruction_count_operands(instr);
 
     for (i = 0; i < count; i++)
-        if (G_ARCH_OPERAND(imm) == _g_arch_instruction_get_operand(instr, i))
+    {
+        op = _g_arch_instruction_get_operand(instr, i);
+
+        if (G_ARCH_OPERAND(imm) == op)
+        {
+            g_object_unref(G_OBJECT(op));
             break;
+        }
+
+        else
+            g_object_unref(G_OBJECT(op));
+
+    }
 
     g_arch_instruction_unlock_operands(instr);
 
@@ -523,7 +535,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
     if (op == NULL)
     {
         result = false;
-        goto exit_instr;
+        goto exit_without_operand;
     }
 
     result = G_IS_IMM_OPERAND(op);
@@ -561,6 +573,10 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO
 
  exit_operand:
 
+    g_object_unref(G_OBJECT(op));
+
+ exit_without_operand:
+
     g_object_unref(G_OBJECT(instr));
 
  exit_instr:
diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c
index 640d266..09f8d1b 100644
--- a/src/analysis/disass/links.c
+++ b/src/analysis/disass/links.c
@@ -237,7 +237,7 @@ static void convert_immediate_into_target(GArchInstruction *instr, size_t index,
 
  ciit_done:
 
-    ;
+    g_object_unref(G_OBJECT(op));
 
 }
 
@@ -280,7 +280,7 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format
             convert_immediate_into_target(instr, i, format);
 
         op = _g_arch_instruction_get_operand(instr, i);
-        if (!G_IS_TARGET_OPERAND(op)) continue;
+        if (!G_IS_TARGET_OPERAND(op)) goto next_op;
 
         g_target_operand_get_addr(G_TARGET_OPERAND(op), &addr);
 
@@ -295,6 +295,10 @@ void establish_links_for_instruction(GArchInstruction *instr, GBinFormat *format
 
         }
 
+    next_op:
+
+        g_object_unref(G_OBJECT(op));
+
     }
 
     g_arch_instruction_unlock_operands(instr);
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c
index a1ddd3e..dee9aa2 100644
--- a/src/arch/arm/v7/fetch.c
+++ b/src/arch/arm/v7/fetch.c
@@ -94,6 +94,8 @@ void help_fetching_with_instruction_b_with_orig(GArchInstruction *instr, GArchPr
 
     else assert(0);
 
+    g_object_unref(G_OBJECT(op));
+
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
@@ -157,6 +159,8 @@ void help_fetching_with_instruction_bl_with_orig(GArchInstruction *instr, GArchP
 
     else assert(0);
 
+    g_object_unref(G_OBJECT(op));
+
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
@@ -210,6 +214,8 @@ void help_fetching_with_instruction_blx_with_dest(GArchInstruction *instr, GArch
 
     else assert(0);
 
+    g_object_unref(G_OBJECT(op));
+
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, iset);
@@ -284,7 +290,7 @@ void help_fetching_with_instruction_bx_with_orig(GArchInstruction *instr, GArchP
 
  hfwibwo_no_pc:
 
-    ;
+    g_object_unref(G_OBJECT(op));
 
 }
 
@@ -329,6 +335,8 @@ void help_fetching_with_instruction_cb_n_z(GArchInstruction *instr, GArchProcess
 
     else assert(0);
 
+    g_object_unref(G_OBJECT(op));
+
     target = pc + offset;
 
     //g_armv7_context_define_encoding(context, target, AV7IS_THUMB);
@@ -405,6 +413,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
     if (!ret)
     {
         assert(0);
+        g_object_unref(G_OBJECT(op));
         g_arch_instruction_unlock_operands(instr);
         return;
     }
@@ -416,6 +425,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
     if (!g_exe_format_translate_offset_into_vmpa(format, val_offset, &loaded_addr))
     {
         assert(0);
+        g_object_unref(G_OBJECT(op));
         g_arch_instruction_unlock_operands(instr);
         return;
     }
@@ -433,6 +443,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
 
     if (!ret)
     {
+        g_object_unref(G_OBJECT(op));
         g_arch_instruction_unlock_operands(instr);
         return;
     }
@@ -484,6 +495,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst
     new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target);
     _g_arch_instruction_replace_operand(instr, op, new);
 
+    g_object_unref(G_OBJECT(op));
     g_arch_instruction_unlock_operands(instr);
 
 
diff --git a/src/arch/arm/v7/link.c b/src/arch/arm/v7/link.c
index 63fb3ae..68cde7b 100644
--- a/src/arch/arm/v7/link.c
+++ b/src/arch/arm/v7/link.c
@@ -65,6 +65,8 @@ void handle_armv7_conditional_branch_from_register(GArchInstruction *instr, GArc
 
     g_object_unref(G_OBJECT(reg));
 
+    g_object_unref(G_OBJECT(op));
+
 }
 
 
@@ -107,4 +109,6 @@ void handle_armv7_return_from_pop(GArchInstruction *instr, GArchProcessor *proc,
 
     }
 
+    g_object_unref(G_OBJECT(op));
+
 }
diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c
index 7d8ecb3..46a1792 100644
--- a/src/arch/arm/v7/post.c
+++ b/src/arch/arm/v7/post.c
@@ -92,6 +92,8 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc
 
  ppli_release:
 
+    g_object_unref(G_OBJECT(op));
+
     g_arch_instruction_unlock_operands(instr);
 
 }
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index c11f253..7e1e646 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -191,6 +191,10 @@ static void g_arch_instruction_dispose(GArchInstruction *instr)
 
         rem_item_from_flat_array(&instr->operands, 0, sizeof(GArchOperand *));
 
+        /**
+         * Une fois pour l'obtention, une autre pour la libération !
+         */
+        g_object_unref(G_OBJECT(op));
         g_object_unref(G_OBJECT(op));
 
     }
@@ -564,7 +568,7 @@ GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, siz
 
     result = *ptr;
 
-    /* TODO : incrémenter la référence ! */
+    g_object_ref(G_OBJECT(result));
 
     return result;
 
@@ -635,6 +639,8 @@ bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *
             break;
         }
 
+        g_object_unref(G_OBJECT(op));
+
     }
 
     if (result)
@@ -678,6 +684,8 @@ void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *t
         if (op == target)
             break;
 
+        g_object_unref(G_OBJECT(op));
+
     }
 
     rem_item_from_flat_array(&instr->operands, i, sizeof(GArchOperand *));
@@ -1192,6 +1200,7 @@ static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line
     {
         op = _g_arch_instruction_get_operand(instr, 0);
         g_arch_operand_print(op, line, 0/*syntax*/);
+        g_object_unref(G_OBJECT(op));
 
         for (i = 1; i < count; i++)
         {
@@ -1202,6 +1211,8 @@ static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line
 
             g_arch_operand_print(op, line, 0/*syntax*/);
 
+            g_object_unref(G_OBJECT(op));
+
         }
 
     }
diff --git a/src/arch/link.c b/src/arch/link.c
index fbcd391..2e8e455 100644
--- a/src/arch/link.c
+++ b/src/arch/link.c
@@ -61,9 +61,7 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
 
     g_arch_instruction_unlock_operands(instr);
 
-    if (!G_IS_IMM_OPERAND(op)) return;
-
-    if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+    if (G_IS_IMM_OPERAND(op) && g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
     {
         init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
 
@@ -77,6 +75,8 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
 
     }
 
+    g_object_unref(G_OBJECT(op));
+
 }
 
 
@@ -131,6 +131,8 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
         }
     }
 
+    g_object_unref(G_OBJECT(op));
+
     if (defined)
     {
         target = g_arch_processor_find_instr_by_address(proc, &addr);
@@ -191,9 +193,7 @@ void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
 
     g_arch_instruction_unlock_operands(instr);
 
-    if (!G_IS_IMM_OPERAND(op)) return;
-
-    if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
+    if (G_IS_IMM_OPERAND(op) && g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &virt))
     {
         init_vmpa(&addr, VMPA_NO_PHYSICAL, virt);
 
@@ -207,4 +207,6 @@ void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon
 
     }
 
+    g_object_unref(G_OBJECT(op));
+
 }
diff --git a/src/arch/post.c b/src/arch/post.c
index 59522bf..f3d1fd6 100644
--- a/src/arch/post.c
+++ b/src/arch/post.c
@@ -119,6 +119,8 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro
 
     }
 
+    g_object_unref(G_OBJECT(op));
+
     g_arch_instruction_unlock_operands(instr);
 
 }
diff --git a/src/arch/raw.c b/src/arch/raw.c
index 8ab788f..e85d865 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -468,6 +468,8 @@ static const char *g_raw_instruction_get_keyword(const GRawInstruction *instr, A
     else
         size = g_imm_operand_get_size(G_IMM_OPERAND(operand));
 
+    g_object_unref(G_OBJECT(operand));
+
     return defines[MDS_RANGE(size)];
 
 }
@@ -585,6 +587,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
 
             string[iter++] = byte;
 
+            g_object_unref(G_OBJECT(op));
+
             continue;
 
  grip_fallback:
@@ -621,6 +625,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
 
             g_arch_operand_print(op, line, 0/*syntax*/);
 
+            g_object_unref(G_OBJECT(op));
+
         }
 
         /* Si au final une chaîne traine encore */
-- 
cgit v0.11.2-87-g4458