Skip to content

Retyping arrays silently fails #52

Description

@rcaragea

Testing idasql with an LLM workflow, I noticed that the models fail a couple times to retype an array, then switch to introducing a typedef due to a limitation in UPDATE ctree_lvars. It would be nice to have it working properly from the start.

Here's what I mean:

  • In a function there is a variable detected as _DWORD v4[50];
  • After supplying the following instructions: change v4 to a wchar_t array, it tries a few approaches which all fail with "cannot set lvar type: failed to parse type...":
    • UPDATE ctree_lvars SET type = 'wchar_t[100]' WHERE func_addr = 0x4014FA AND idx = 4
    • UPDATE ctree_lvars SET type = 'wchar_t v4[100]' WHERE func_addr = 0x4014FA AND idx = 4;
    • UPDATE ctree_lvars SET type = 'wchar_t[100]' WHERE func_addr = 0x4014FA AND idx = 4;
  • I added a debug print after
    decl.sprnt("%s __x;", type_str);
    to the console plugin and, as inferred from the code, the problem is that the declarations aren't well formed:
Running parse_decl on: wchar_t[100] __x;
Running parse_decl on: wchar_t v4[100] __x;
Running parse_decl on: wchar_t[100] __x;
  • Eventually it takes another approach and adds a typedef with:
    • SELECT parse_decls('typedef wchar_t wchar_array_100[100];');
    • UPDATE ctree_lvars SET type = 'wchar_array_100' WHERE func_addr = 0x4014FA AND idx = 4;

This approach works but it's kind of ugly to have to retry a couple times and add typedefs for each array size encountered.

I made a quick fix which seems to work but I'm unsure whether this is ideal:

diff --git a/src/lib/src/decompiler.cpp b/src/lib/src/decompiler.cpp
index c2073e2..f52f74f 100644
--- a/src/lib/src/decompiler.cpp
+++ b/src/lib/src/decompiler.cpp
@@ -2209,7 +2209,17 @@ bool set_lvar_type_at(ea_t func_addr, int lvar_idx, const char* type_str) {
     if (!tif.get_named_type(nullptr, type_str)) {
         // Use parse_decl for C declaration parsing
         qstring decl;
-        decl.sprnt("%s __x;", type_str);
+        if  (type_str && strchr(type_str, '[')) {
+            // Split the type string at the first '['
+            const char* bracket_pos = strchr(type_str, '[');
+            qstring base_type(type_str, bracket_pos - type_str);
+            qstring array_part(bracket_pos);  // includes the '[' and everything after
+            decl.sprnt("%s __x%s;", base_type.c_str(), array_part.c_str());
+        } else {
+                decl.sprnt("%s __x;", type_str);
+        }
+        // log the decl for debugging
+        msg("Running parse_decl on: %s\n", decl.c_str());
         qstring out_name;
         if (!parse_decl(&tif, &out_name, nullptr, decl.c_str(), PT_SIL)) {
             xsql::set_vtab_error(

Example input file attached test.zip

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions