avast / avast/retdec

Stack string information in decompiled output

Open
#849 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
8.6k
Forks
1k
PR merge metrics
No merged PRs in 30d

Description

When running a simple sample through Retdec, I had noticed that only the first value (byte, word, dword, qword, etc..) of a stack string is displayed in the decompiled output. I wanted to know if it's possible to display the full value of the stack string in the decompiled output.

Consider the following source code
```c
#include

int main()
{
char str[] = {'h','e','l','l','o',' ','w','o','r','l','d','\0'};
printf("%s", str);
return 0;
}
```

Using RetDec from R2, the only value that is shown in the decompiled output is the qword value of `ow olleh`

```c
#include
#include

// ------------------------ Functions -------------------------

// Address range: 0x401126 - 0x401160
int main() {
int64_t var_4h = 0x6f77206f6c6c6568; // bp-20, 0x401138
printf("%s", &var_4h);
return 0;
}
```

The Ghidra decompiled output will show the second-half of the string that is moved to the stack.
```c
undefined8 main(void)

{
undefined8 local_14;
undefined4 local_c;

local_14 = 0x6f77206f6c6c6568;
local_c = 0x646c72;
printf("%s",&local_14);
return 0;
}
```

This becomes more noticeable when the values are single byte.
Consider the following example:
```c
#include

int main(int argc, char **argv)
{
char str[20];
str[0] = 0x68;
str[1] = 0x65;
str[2] = 0x6c;
str[3] = 0x6c;
str[4] = 0x6f;
str[5] = 0x20;
str[6] = 0x77;
str[7] = 0x6f;
str[8] = 0x72;
str[9] = 0x6c;
str[10] = 0x64;
str[11] = '\0';
printf("%s", &str);
return 0;
}
```
The retdec output (showing the first char value of the stack string)
```c
#include
#include

// ------------------------ Functions -------------------------

// Address range: 0x401126 - 0x401182
int main(int argc, char ** argv) {
int64_t var_18h = 104; // bp-40, 0x401135
printf("%s", &var_18h);
return 0;
}
```
The Ghidra output will display the string in full.
```c
undefined8 main(void)

{
undefined local_28;
undefined local_27;
undefined local_26;
undefined local_25;
undefined local_24;
undefined local_23;
undefined local_22;
undefined local_21;
undefined local_20;
undefined local_1f;
undefined local_1e;
undefined local_1d;

local_28 = 0x68;
local_27 = 0x65;
local_26 = 0x6c;
local_25 = 0x6c;
local_24 = 0x6f;
local_23 = 0x20;
local_22 = 0x77;
local_21 = 0x6f;
local_20 = 0x72;
local_1f = 0x6c;
local_1e = 100;
local_1d = 0;
printf("%s",&local_28);
return 0;
}
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reproducing the issue with the two C examples in the report and inspect RetDec's decompiled output for each. Compare the results with the Ghidra examples; done means the output displays the full stack string rather than only its first value.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.