Comments (7)
Thanks for the report. In fact this is not a bug, the target address computation is based on the concrete address of the instruction itself as you indicated. Do you have any specific reason why RIP should appear in the lifted IR? IMHO, it will complicate the formula anyways.
from b2r2.
Thanks you for the response.
There're cases where we need a symbolique RIP, for example in the snippet:
0x0 e8 fb ff ff ff call -0x5
0x5 58 pop rax
which is more or less mov rax, rip
.
Because of RIP
is always concrete, then it's not possible to prove rax == rip
in LowIR
; and it has effects on optimization and caching.
For example, in implementing a DBI we may get several the same basic block at different addresses, a method to accelerate DBI is to optimize this basic block and put the result into a cache. Given the basic block (well, it's not because of call
and ret
but just an example)
0x0 53 push rbx
0x1 c3 ret
0x2 e8 f4 ff ff ff call -0xc
0x7 58 pop rax
0x8 48 31 d8 xor rax, rbx
an optimizer would be able to know that rax = 0
at the end of the block; but it's not possible yet in current B2R2.
from b2r2.
0x0 e8 fb ff ff ff call -0x5
0x5 58 pop rax
From your example above, the call instruction will jump to itself, and it will go infinite loop. So I think you wanted to say something like:
0x0 e8 00 00 00 00 call 0x5
0x5 58 pop rax
Now, this is effectively the same asmov rax, 0
, where 0 is the address of the first instruction. If the first instruction is at 0x42, then the above snippet will be lifted as mov rax, 0x42
, and so on.
We still know that rax
will be always the same as the address of the first instruction (call instr), and an optimizer can benefit from it regardless of the fact that we have the symbolic RIP or not. Let me know if I am missing something.
from b2r2.
Thanks you for the response.
...the call instruction will jump to itself, and it will go infinite loop. So I think you wanted to say something like:
I feel ashamed :(, your example is correct, this is indeed call 0x5
(or call 0
under Intel's assembly).
Yes, the optimizer will reduce this snippet into mov rax, 0x5
(instead of mov rax, rip + 0x5
). But that's the problem that I want to say about: if we have many blocks of:
call 0x5
pop rax
at different base addresses, then we can not reduce them into a general formula rax = rip + 0x5
: the only way we can do is to enumerate one by one so that the optimizer will re-optimize each block with corresponding base rip
.
from b2r2.
Sorry but I am not still sure about "reducing multiple of those call-pop pairs".
Suppose we have consecutive call-pop pairs like this:
0 call 5
5 pop rax
6 call 11
11 pop rax
12 call 17
17 pop rax
Now, we can translate this into
mov rax, 5
mov rax, 11
mov rax, 17
Now, with what you have mentioned, we would have:
mov rax, rip
mov rax, rip
mov rax, rip
But this is wrong, because RIP will change as you convert the instruction to mov rax, rip
. The address of the instruction will change, and the corresponding RIP will also change. This means, after executing the above three instructions, we will have different a value in rax
. So, to me, it is more accurate to use concrete addresses.
from b2r2.
Thanks you for the response, I really appreciate that.
Sorry for my bad explanation, this is not what I mean in saying replace the "call-pop" by the single mov rax, rip + 0x5
, and your example
mov rax, rip
mov rax, rip
mov rax, rip
is indeed a very good example to say that it will not work.
What I mean is by symbolizing RIP
, we get a general formula rax = base_address + 0x5
. Though "call-pop" is a too trivial example to see the effect, we can imagine a more sophisticated basic block where the result on of registers depending on the base address, and there are many copies of it with different base addresses.
An emulator (using LowIR
as internal IR and optimizing with symbolic PC
) will have chance to directly compute the result without replaying each concrete basic block.
from b2r2.
Thank you for the explanation. I now see what you mean. I think such a global optimization can definitely benefit, but we may not change our design decision at this point for several reasons:
- Having explicit RIP for every relative branch instructions makes ASTs unnecessarily big. It is just one more node for one instruction, but overall there are too many relative branches in a program.
- The optimization you mentioned is difficult to implement in reality, and we are not sure if the optimization is critical for the efficiency of an analyzer or an emulator.
- Making RIP explicit is never difficult, but requires some carefully modification on the entire front-end of our system.
So all in all, If we see more needs on this, we may resurrect this issue and the PR, but for now, we will not handle this issue. Hope this makes sense to you, and thanks for the fruitful discussion.
from b2r2.
Related Issues (20)
- x86/64 lifting loop instruction HOT 7
- Incorrect disassembly HOT 2
- [BinHandler] Error in section reading HOT 11
- Error in parse EAT HOT 2
- Error in getRawOffset HOT 2
- Bug in GetSymbols HOT 7
- Behavior change of FormatDetector.Detect() HOT 4
- pcmpistri lifting infine loop HOT 4
- [Question] Any plan for supporting a SMT? HOT 2
- ARMv7: incorrect disassembly of VCVT HOT 6
- Improve function detection algorithm HOT 2
- Updates? HOT 1
- [Question] Dose the newest version B2R2 v0.5.0 support python? HOT 4
- [Question] Question on analyzing the ARMv8 aarch32 binary HOT 1
- [Question] Assembling LowUIR to Assembly (x86/x64/...) HOT 1
- Error when import function does not exist in wasm binary HOT 3
- Does the B2R2 support PPC32 or Sparc? HOT 2
- Does it take three to four seconds for each instruction to be decompiled? Is there any way to improve the efficiency? HOT 7
- I want to lift .so file but an error occurs HOT 4
- I think I found a B2R2 LowUIR bug. HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from b2r2.