avast / avast/retdec

Bug report & Question about functions which cannot be lifted into LLVM IR

Open
#666 2 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

Dear, RetDec developers.

I really appreciate that you make this tool.
But, I found some problems. I am not sure whether this is ARM's THUMB architecture specific.

Based on my guess, the problem is that some functions are not lifted into LLVM.
This function is "not explicitly" called by other function because it is run by "pthread_create".
However, this is not a standard pthread create. That means that my target binary running on the embedded device w/ RTOS (RIOT) - not Linux.
Therefore, pthead_create is included in the binary codes as a normal function.

Specifically, the problem is that.
1) This function is not called by the other functions. That's why I think RetDec didn't lift it.

2) Also, when this function's pointer value is passed into an argument to "pthread_create". This function pointer value should be "actual function pointer value + 1".
When a function is executed with ARM's Thumb mode, its pointer value must be +1; otherwise, that function will be executed in the ARM's "ARM mode". (I strongly believe you know ARM architecture supports both ARM and Thumb modes which is the unique ARM scheme. But, I put this description just in case.)

3) As I mentioned, my target firmware is not an application binary for Linux. It is a bare-metal firmware including RTOS (+ pthread related functions).
That's why pthread functions are considered as a just normal function.
Then, RetDec may not take special processing to pthread functions I guess

In this context, could you help me to solve this problem?
Even if that is not possible (at least very soon), is there a way to "forcibly" convert such "unlifted" functions?
I think the fundamental reason why that function is not lifted is related to optimization.
For example, I guess that function is considered as garbage since it is not called by any other functions during some analysis (e.g., a sort of points-to analysis I guess...?)
If that is possible, I am fine with it at this time since I need to emergently solve this problem.

Or at this time, I can assume my firmware has a symbol against the target unlifted function temporarily.

Thank you for your help :)

PS. the converted "pthread_create" call looks like this
%v9_80015a4 = call i32 @pthread_create(i32* nonnull %th_id1_-44, i32 %v2_8001596, i8* (i8*)* inttoptr (i32 134222901 to i8* (i8*)*), i8* null)

i8* (i8*)* inttoptr (i32 134222901 to i8* (i8*)*) -> this was originally a function pointer to thread handler function. But, since the last bit is set (13422290"1"), it was not recognized as a function pointer maybe....

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the converted pthread_create call and trace how its inttoptr callback is handled during ARM Thumb lifting into LLVM IR. Check whether the +1 function pointer and an otherwise unreferenced thread handler are recognized; done means the handler is lifted or the supported limitation and a usable workaround are documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers, embedded-iot, reverse-engineering
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.