tenable/ghidra_tools

Duplicate var names causes issues

Closed this issue · 3 comments

Hi Olivia. Fun little script you have here. Also, just realized you wrote 'Secrets of the Ooze' which made my jaw drop because it was opened in another tab from a totally unrelated thing.

Anyway, a duplicate name exception prevented the function from being renamed. Perhaps a try - except clause added in the renaming logic would prevent a clash like this from killing the rest of the script.

`g3po.py> Running...
INFO:root:Current address is at 7ff6eec46720
INFO:root:Decompiling function: FUN_7ff6eec46720 at 7ff6eec46720
INFO:root:Length of decompiled C code: 2155 characters, guessing 1077 tokens
Prompt:

Below is some C code that Ghidra decompiled from a binary that I'm trying to reverse engineer.


LPSTR * FUN_7ff6eec46720(int param_1,longlong param_2)

{
  int iVar1;
  LPSTR *ppCVar2;
  LPSTR lpMultiByteStr;
  char *pcVar3;
  char *pcVar4;
  ulonglong uVar5;
  ulonglong uVar6;
  LPSTR *ppCVar7;
  LPCWSTR pWVar8;
  LPCWSTR lpWideCharStr;
  undefined8 uVar9;
  uint uVar10;
  ulonglong uVar11;
  
  ppCVar2 = (LPSTR *)_calloc_base((longlong)param_1 + 1,8);
  if (ppCVar2 == (LPSTR *)0x0) {
    return (LPSTR *)0x0;
  }
  uVar5 = 0;
  if (0 < param_1) {
    uVar6 = uVar5;
    ppCVar7 = ppCVar2;
    uVar11 = uVar5;
    do {
      lpWideCharStr = *(LPCWSTR *)((longlong)ppCVar7 + (param_2 - (longlong)ppCVar2));
      uVar9 = 0xffffffff;
      pWVar8 = lpWideCharStr;
      iVar1 = WideCharToMultiByte(0xfde9,0,lpWideCharStr,-1,(LPSTR)0x0,0,(LPCSTR)0x0,(LPBOOL)0x0);
      if (iVar1 == 0) {
        pcVar4 = "Failed to get UTF-8 buffer size.\n";
LAB_7ff6eec46858:
        pcVar3 = "WideCharToMultiByte";
LAB_7ff6eec4685f:
        FUN_7ff6eec41cb0(pcVar3,(ulonglong)pcVar4,pWVar8,uVar9);
        *ppCVar7 = (LPSTR)0x0;
        if (-1 < (longlong)uVar6) {
          do {
            FUN_7ff6eec53ed8(ppCVar2[uVar5]);
            uVar5 = uVar5 + 1;
          } while ((longlong)uVar5 <= (longlong)uVar6);
        }
        FUN_7ff6eec53ed8(ppCVar2);
        return (LPSTR *)0x0;
      }
      lpMultiByteStr = (LPSTR)_calloc_base((longlong)iVar1 + 1,1);
      if (lpMultiByteStr == (LPSTR)0x0) {
        pcVar4 = "Out of memory.\n";
        pcVar3 = "win32_utils_to_utf8";
        goto LAB_7ff6eec4685f;
      }
      uVar9 = 0xffffffff;
      iVar1 = WideCharToMultiByte(0xfde9,0,lpWideCharStr,-1,lpMultiByteStr,iVar1,(LPCSTR)0x0,
                                  (LPBOOL)0x0);
      if (iVar1 == 0) {
        pcVar4 = "Failed to encode wchar_t as UTF-8.\n";
        pWVar8 = lpWideCharStr;
        goto LAB_7ff6eec46858;
      }
      *ppCVar7 = lpMultiByteStr;
      uVar10 = (int)uVar11 + 1;
      uVar11 = (ulonglong)uVar10;
      ppCVar7 = ppCVar7 + 1;
      uVar6 = uVar6 + 1;
    } while ((int)uVar10 < param_1);
  }
  ppCVar2[param_1] = (LPSTR)0x0;
  return ppCVar2;
}


Please provide a detailed explanation of what this code does, in English, that might be useful to a reverse engineer. Explain your reasoning as much as possible. Finally, suggest a suitable name for this function and for each variable bearing a default name, offer a more informative name, if the purpose of that variable is unambiguous. Print each suggested variable name on its own line in the form old_name -> new_name, and print the suggested function name on its own line in the form old_name :: new_name.

INFO:root:OpenAI request succeeded!
INFO:root:Response: {u'created': 1673344054, u'usage': {u'completion_tokens': 227, u'prompt_tokens': 1164, u'total_tokens': 1391}, u'model': u'text-davinci-003', u'id': u'cmpl-6X5WAU81DFKdBGEWDthzL5nXpXglK', u'choices': [{u'index': 0, u'logprobs': None, u'finish_reason': u'stop', u'text': u'\nThis code is a function that allocates memory for a given number of strings, converts them from wide characters to multi-byte characters, and stores them in the allocated memory. It then adds a null terminator at the end of the allocated memory and returns a pointer to the allocated memory. \n\nparam_1 -> num_strings\nparam_2 -> wide_char_ptr\niVar1 -> wide_char_to_multi_byte_ret\nppCVar2 -> multi_byte_str_ptr\nlpMultiByteStr -> multi_byte_str\npcVar3 -> func_name\npcVar4 -> err_msg\nuVar5 -> i\nuVar6 -> j\nppCVar7 -> multi_byte_str_ptr_ptr\npWVar8 -> wide_char_str\nlpWideCharStr -> wide_char_str\nuVar9 -> ret\nuVar10 -> k\nuVar11 -> k\n\nFUN_7ff6eec46720 :: wide_char_to_multi_byte_str_array'}], u'object': u'text_completion'}
This code is a function that allocates memory for a given number of strings, converts them from wide characters to multi-byte characters, and stores them in the allocated memory. It then adds a null terminator at the end of the allocated memory and returns a pointer to the allocated memory.

param_1 -> num_strings
param_2 -> wide_char_ptr
iVar1 -> wide_char_to_multi_byte_ret
ppCVar2 -> multi_byte_str_ptr
lpMultiByteStr -> multi_byte_str
pcVar3 -> func_name
pcVar4 -> err_msg
uVar5 -> i
uVar6 -> j
ppCVar7 -> multi_byte_str_ptr_ptr
pWVar8 -> wide_char_str
lpWideCharStr -> wide_char_str
uVar9 -> ret
uVar10 -> k
uVar11 -> k

FUN_7ff6eec46720 :: wide_char_to_multi_byte_str_array
INFO:root:Added comment to function: FUN_7ff6eec46720
INFO:root:Applying gpt-3 variable names
Traceback (most recent call last):
File "C:\Users\Administrator\Desktop\RE project\ghidra_10.2.2_PUBLIC\Ghidra\Features\Python\ghidra_scripts\g3po.py", line 353, in
apply_variable_predictions(comment)
File "C:\Users\Administrator\Desktop\RE project\ghidra_10.2.2_PUBLIC\Ghidra\Features\Python\ghidra_scripts\g3po.py", line 341, in apply_variable_predictions
rename_high_variable(symbols[old], new)
File "C:\Users\Administrator\Desktop\RE project\ghidra_10.2.2_PUBLIC\Ghidra\Features\Python\ghidra_scripts\g3po.py", line 299, in rename_high_variable
return HighFunctionDBUtil.updateDBVariable(hv,
at ghidra.program.database.symbol.SymbolManager.checkDuplicateSymbolName(SymbolManager.java:485)
at ghidra.program.database.symbol.SymbolDB.doSetNameAndNamespace(SymbolDB.java:611)
at ghidra.program.database.symbol.SymbolDB.setNameAndNamespace(SymbolDB.java:674)
at ghidra.program.database.symbol.SymbolDB.setName(SymbolDB.java:538)
at ghidra.program.database.function.VariableDB.setName(VariableDB.java:165)
at ghidra.program.model.pcode.HighFunctionDBUtil.updateDBVariable(HighFunctionDBUtil.java:589)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
ghidra.util.exception.DuplicateNameException: ghidra.util.exception.DuplicateNameException: A Local Var symbol with name wide_char_str already exists in namespace FUN_7ff6eec46720
g3po.py> Finished!
`

ah good catch! thanks! i'll add that fix. glad you enjoyed the Ooze post, too! i should get back to blogging there sometime soon.

Alright, PR #7 should sort this out.

fixed in PR #7