avast / avast/retdec

Bad type in decompiled .c file: uint32_t should be int32_t

Open
#924 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

Hi,

There is a bug when decompiling a simple program that checks the sign of a number.
In the outputed C file, the function get_sign returns an int32_t but the variable where the return value is saved is an uint32_t and should be an int32_t.

File: get_sign.c
```c
#include

int get_sign(int x) {
if (x == 0)
return 0;

if (x < 0)
return -1;
else
return 1;
}

int main() {
int a;

scanf("%d", &a);

int res = get_sign(a);

if(res > 0)
printf("%d is positive\n", a);
else if(res < 0)
printf("%d is negative\n", a);
else
printf("%d is zero\n", a);

return 0;
}
```

```bash
> clang -g -O0 -fno-stack-protector -no-pie -Wall get_sign.c -o get_sign
> retdec-decompiler --select-functions main,get_sign get_sign -o get_sign_ret.c
```

File: get_sign_ret.c
```c
//
// This file was generated by the Retargetable Decompiler
// Website: https://retdec.com
//

#include
#include

// ------------------- Function Prototypes --------------------

int32_t get_sign(int32_t x);

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

// From module: /home/fredyr4zox/Builds/Thesis/get_sign.c
// Address range: 0x401140 - 0x40117f
// Line range: 3 - 11
int32_t get_sign(int32_t x) {
int32_t result = 0; // 0x40114b
if (x != 0) {
// 0x40115d
result = x >= 0 ? 1 : -1;
}
// 0x40117a
return result;
}

// From module: /home/fredyr4zox/Builds/Thesis/get_sign.c
// Address range: 0x401180 - 0x40120d
// Line range: 13 - 27
int main() {
// 0x401180
int32_t a; // bp-16, 0x401180
scanf("%d", &a);
uint32_t v1 = get_sign(a); // 0x4011a7
if (v1 >= 1) {
// 0x4011b9
printf("%d is positive\n", (int64_t)a);
// 0x401205
return 0;
}
int64_t v2 = a;
if (v1 == 0) {
// 0x4011ef
printf("%d is zero\n", v2);
} else {
// 0x4011d9
printf("%d is negative\n", v2);
}
// 0x401205
return 0;
}

// --------------- Dynamically Linked Functions ---------------

// int printf(const char * restrict format, ...);
// int scanf(const char * restrict format, ...);

// --------------------- Meta-Information ---------------------

// Detected compiler/packer: llvm (11.0.1)
// Detected functions: 2
```

If i compile the original binary without debug info (without -g), the output is the following:
```c
// This file was generated by the Retargetable Decompiler
// Website: https://retdec.com
//

#include
#include

// ------------------- Function Prototypes --------------------

int64_t get_sign(int64_t a1);

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

// Address range: 0x401140 - 0x40117f
int64_t get_sign(int64_t a1) {
int32_t v1 = a1; // 0x401144
int64_t result = 0; // 0x40114b
if (v1 != 0) {
// 0x40115d
result = v1 >= 0 ? 1 : 0xffffffff;
}
// 0x40117a
return result;
}

// Address range: 0x401180 - 0x40120d
int main(int argc, char ** argv) {
// 0x401180
int64_t v1; // bp-16, 0x401180
scanf("%d", &v1);
uint32_t v2 = (int32_t)get_sign(v1 & 0xffffffff); // 0x4011ac
if (v2 >= 1) {
// 0x4011b9
printf("%d is positive\n", v1 & 0xffffffff);
// 0x401205
return 0;
}
int64_t v3 = v1 & 0xffffffff;
if (v2 == 0) {
// 0x4011ef
printf("%d is zero\n", v3);
} else {
// 0x4011d9
printf("%d is negative\n", v3);
}
// 0x401205
return 0;
}

// --------------- Dynamically Linked Functions ---------------

// int printf(const char * restrict format, ...);
// int scanf(const char * restrict format, ...);

// --------------------- Meta-Information ---------------------

// Detected compiler/packer: gcc (10.2.0)
// Detected functions: 2
```

"uint32_t v1 = get_sign(a);" should be "int32_t v1 = get_sign(a);"

The .ll and .bc files are correct. Only the .c file is not.

Contributor guide

No contributing guide indexed for this repository

Research direction

Reproduce the issue with get_sign.c using the retdec-decompiler command and compare the generated get_sign_ret.c with the mentioned .ll and .bc files. Trace the C decompilation path for the get_sign return value in both debug and non-debug cases. Done when the generated variable uses int32_t consistently and the resulting C preserves the sign checks.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.