Skip to content

Update comment in pseudocode table when use a ea = <func entry addr> #25

@singleghost2

Description

@singleghost2

I execute following commands in IDA's idasql commandline window.

idasql>SELECT printf(“0x%x”, ea), line_num, line, comment, comment_placement FROM pseudocode
   WHERE func_addr = 0x140010780 LIMIT 5;
printf(“0x%x”, ea) | Line Number | Code Line | Comment | Comment Position
------------ ------+----------+------+---------+------------------
0x140010780 | 0 | __int64 __fastcall VpuEscape(int *DeferredContext, __int64 a2) |  | Semi-fixed
0x0 | 1 | { |  | Semi-auto
0x0 | 2 |   int v4; // ebx |  | Semi-auto
0x0 | 3 |   _DWORD *v5; // r14 |  | Semi-automatic
0x0 | 4 |   unsigned int v6; // edx |  | Semi-automatic
idasql>UPDATE pseudocode SET comment_placement = ‘block1’, comment =
‘test’
         WHERE func_addr = 0x140010780 and ea = 0x140010780;
(0 rows)
idasql>SELECT printf(“0x%x”,ea), line_num, line, comment, comment_placement FROM pseudocode
   WHERE func_addr = 0x140010780 LIMIT 5;
printf(“0x%x”,ea) | line_num | line | comment | comment_placement
------------ - -----+----------+------+---------+------------------
0x140010780 | 0 | __int64 __fastcall VpuEscape(int *DeferredContext, __int64 a2) | test | block1
0x0 | 1 | { |  | Semi-automatic
0x0 | 2 |   int v4; // ebx |  | Semi-automatic
0x0 | 3 |   _DWORD *v5; // r14 |  | Semi-automatic
0x0 | 4 |   unsigned int v6; // edx |  | Semi-automatic
(5 rows)

The comment on line 0 is successfully updated to “test”, but IDA's pseucode windows is not affected at all.

__int64 __fastcall VpuEscape(int *DeferredContext, __int64 a2)
{
  int v4; // ebx
  _DWORD *v5; // r14
  unsigned int v6; // edx
  bool v7; // cl
  unsigned int v8; // edx

I debugged the idasql code and set_decompiler_comment function is executed and returns true.

bool set_decompiler_comment(ea_t func_addr, ea_t target_ea, const char* comment, item_preciser_t itp) {
    if (!hexrays_available()) return false;
    if (target_ea == BADADDR || target_ea == 0) return false;

    func_t* f = get_func(func_addr);
    if (!f) return false;

    hexrays_failure_t hf;
    cfuncptr_t cfunc = decompile(f, &hf);
    if (!cfunc) return false;

    treeloc_t loc;
    loc.ea = target_ea;
    loc.itp = itp;

    // set_user_cmt with empty/null pointer deletes comment
    cfunc->set_user_cmt(loc, (comment && comment[0]) ? comment : nullptr);

    cfunc->save_user_cmts();
    invalidate_decompiler_cache(func_addr);
    return true;
}

I tried with other ea values which is not equal to function's entry address, the pseudocode window is successfully updated with the new comment.
I recall that I once wrote a set_comment function using idapython that adds comments simultaneously in both the disassembly and pseudo-code windows:

    
def set_comment(
    address: Union[str, int],
    comment: Annotated[str, “Comment text”],
    append = False, 
    cfunc = None 
):
    “”‘Sets a comment at the specified address in function disassembly and pseudo-code’“”
    if type(address) is str:
        address = parse_address(address)

    if append is True:
        ...
            
    if not idaapi.set_cmt(address, comment, False):
        raise IDAError(f“Failed to set disassembly comment at {hex(address)}”)

    # Reference: https://cyber.wtf/2019/03/22/using-ida-python-to-analyze-trickbot/
    # Check if address corresponds to code line
    if cfunc is None:
        cfunc = decompile_checked(address)

    # Special handling for function entry comments
    if address == cfunc.entry_ea:
        idc.set_func_cmt(address, comment, True)
        cfunc.refresh_func_ctext()
        return

    eamap = cfunc.get_eamap() # Obtain the ea -> cinsn_t mapping table (cinsn_t.opname == return or block or expr or ...)
    if address not in eamap:
        print(f“Failed to set decompiler comment at {hex(address)}”)
        return
    insn = eamap[address][0]
    nearest_ea = insn.ea
    # Remove existing orphan comments
    if cfunc.has_orphan_cmts():
        cfunc.del_orphan_cmts()
        cfunc.save_user_cmts()

    # Attempt to set comment for all possible item types
    tl = idaapi.treeloc_t()
    tl.ea = nearest_ea
    for itp in range(idaapi.ITP_SEMI, idaapi.ITP_COLON):
        tl.itp = itp
        cfunc.set_user_cmt(tl, comment)
        cfunc.save_user_cmts()
        cfunc.refresh_func_ctext()
        if not cfunc.has_orphan_cmts():
            return
        cfunc.del_orphan_cmts()
        cfunc.save_user_cmts()
    print(f“Failed to set decompiler comment at {hex(address)}”)

If address == cfunc.entry_ea, the comment is set via idc.set_func_cmt(address, comment, True). Therefore, I suppose IDASQL should also detect this scenario to set the comment like this.

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