AIL is the angr intermediate language.
Project repository: https://github.com/angr/ailment
Documentation: https://api.angr.io/projects/ailment/en/latest/
AIL: The angr Intermediate Language.
License: BSD 2-Clause "Simplified" License
AIL is the angr intermediate language.
Project repository: https://github.com/angr/ailment
Documentation: https://api.angr.io/projects/ailment/en/latest/
What is the status of this IR? It looks like it has some potential, but has no development effort.
Not sure if this is an angr bug or an ailment bug, but I got it when I hit tab in a-m:
Traceback (most recent call last):
File "/home/audrey/angr/ailment/ailment/tagged_object.py", line 23, in __getattr__
return self.tags[item]
KeyError: 'copy'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/audrey/angr/angr-management/angrmanagement/ui/views/disassembly_view.py", line 206, in keyReleaseEvent
self.decompile_current_function()
File "/home/audrey/angr/angr-management/angrmanagement/ui/views/disassembly_view.py", line 399, in decompile_current_function
self.workspace.decompile_function(self._current_function.am_obj, curr_ins=curr_ins)
File "/home/audrey/angr/angr-management/angrmanagement/ui/workspace.py", line 305, in decompile_function
view.function = func
File "/home/audrey/angr/angr-management/angrmanagement/ui/views/code_view.py", line 82, in function
self.decompile()
File "/home/audrey/angr/angr-management/angrmanagement/ui/views/code_view.py", line 46, in decompile
d = self.workspace.instance.project.analyses.Decompiler(
File "/home/audrey/angr/angr/angr/analyses/analysis.py", line 115, in __call__
oself.__init__(*args, **kwargs)
File "/home/audrey/angr/angr/angr/analyses/decompiler/decompiler.py", line 30, in __init__
self._decompile()
File "/home/audrey/angr/angr/angr/analyses/decompiler/decompiler.py", line 47, in _decompile
clinic = self.project.analyses.Clinic(self.func,
File "/home/audrey/angr/angr/angr/analyses/analysis.py", line 115, in __call__
oself.__init__(*args, **kwargs)
File "/home/audrey/angr/angr/angr/analyses/decompiler/clinic.py", line 74, in __init__
self._analyze()
File "/home/audrey/angr/angr/angr/analyses/decompiler/clinic.py", line 145, in _analyze
ail_graph = self._simplify_blocks(ail_graph, stack_pointer_tracker=spt)
File "/home/audrey/angr/angr/angr/utils/timing.py", line 28, in timed_func
return func(*args, **kwargs)
File "/home/audrey/angr/angr/angr/analyses/decompiler/clinic.py", line 305, in _simplify_blocks
simplified = self._simplify_block(ail_block, stack_pointer_tracker=stack_pointer_tracker)
File "/home/audrey/angr/angr/angr/analyses/decompiler/clinic.py", line 321, in _simplify_block
simp = self.project.analyses.AILBlockSimplifier(
File "/home/audrey/angr/angr/angr/analyses/analysis.py", line 115, in __call__
oself.__init__(*args, **kwargs)
File "/home/audrey/angr/angr/angr/analyses/decompiler/block_simplifier.py", line 52, in __init__
self._analyze()
File "/home/audrey/angr/angr/angr/analyses/decompiler/block_simplifier.py", line 66, in _analyze
new_block = self._simplify_block_once(block)
File "/home/audrey/angr/angr/angr/analyses/decompiler/block_simplifier.py", line 82, in _simplify_block_once
propagator = self.project.analyses.Propagator(block=block, stack_pointer_tracker=self._stack_pointer_tracker)
File "/home/audrey/angr/angr/angr/analyses/analysis.py", line 115, in __call__
oself.__init__(*args, **kwargs)
File "/home/audrey/angr/angr/angr/analyses/propagator/propagator.py", line 375, in __init__
self._analyze()
File "/home/audrey/angr/angr/angr/analyses/propagator/propagator.py", line 515, in _analyze
self._analysis_core_graph()
File "/home/audrey/angr/angr/angr/analyses/forward_analysis/forward_analysis.py", line 240, in _analysis_core_graph
changed, output_state = self._run_on_node(n, job_state)
File "/home/audrey/angr/angr/angr/analyses/propagator/propagator.py", line 422, in _run_on_node
state = engine.process(state, block=block, project=self.project, base_state=self._base_state,
File "/home/audrey/angr/angr/angr/analyses/propagator/engine_base.py", line 28, in process
self._process(state, None, block=kwargs.pop('block', None))
File "/home/audrey/angr/angr/angr/engines/light/engine.py", line 649, in _process
self._process_Stmt(whitelist=whitelist)
File "/home/audrey/angr/angr/angr/engines/light/engine.py", line 666, in _process_Stmt
self._handle_Stmt(stmt)
File "/home/audrey/angr/angr/angr/engines/light/engine.py", line 712, in _handle_Stmt
getattr(self, old_handler)(stmt)
File "/home/audrey/angr/angr/angr/analyses/propagator/engine_ail.py", line 102, in _ail_handle_Return
self._expr(ret_expr)
File "/home/audrey/angr/angr/angr/engines/light/engine.py", line 687, in _expr
return h(expr)
File "/home/audrey/angr/angr/angr/analyses/propagator/engine_ail.py", line 143, in _ail_handle_Register
new_expr = self.state.get_variable(expr)
File "/home/audrey/angr/angr/angr/analyses/propagator/propagator.py", line 263, in get_variable
v = first_obj.copy()
File "/home/audrey/angr/ailment/ailment/tagged_object.py", line 25, in __getattr__
return super(TaggedObject, self).__getattribute__(item)
AttributeError: 'Const' object has no attribute 'copy'
Does this fall under the BSD license, too? Thanks.
When vex statements contain a div operation, IRSBConverter doesn't come out with a correct result.
import angr
import ailment
import sys
p = angr.Project(sys.argv[1])
block = p.factory.block(0x400000,0xe)
ail_manager = ailment.Manager(arch=p.factory.project.arch)
ail_block = ailment.IRSBConverter.convert(block.vex, ail_manager)
print(ail_block.statements)
test_div.o.zip
The result looks like this
Ijk_SigFPE_IntDiv
, which generates a ConditionalJump without false node in ail block. Should it be skipped?pyvex.expr.Binop
, but its operation is Iop_64HLto128
which looks like a convent operation. So its type should be pyvex.expr.Unop
. ail_manager
can't handle this operation and return None, so ail_block
gets this statement Assignment (t18, (0x0<64> None t9))
.Hi,
I'm currently using ailment in a project and I have 2 questions, since I'm not certain if certain things are oversights or working as intended.
I'd like to check if the address of a store and the value of a register from the same basic block coincide.
Currently, I'm comparing the hash of the store address with the source of the register assignment.
Equality (==
, __eq__
) does not work since the index of an expression is also considered when evaluating equality.
The hash function however, does not consider the index and can thus be used. Is not passing the index to the hash function an oversight or intended?
Reading the commit that introduced this index comparison (bb6dc19) also gave me the impression that likes
ought to preserve the old equality check that ignores indices. But for binary operators likes
also checks if self.operands == other.operands
, which invokes __eq__
and thus compares indices. The consequence is that e.g. in my case (x0 + 2).likes((x0 + 2))
evaluates to false, since the constants have different indices. Is this working as intended?
There's an error importing ailment on some distributions that don't have _md5. In my case, Python 3.6 on RHEL 7.
See here.
I'll open a PR where we fall back to the slower hashlib version of md5.
I'm trying to convert an irsb of custom arch (eBPF example in angr-platforms) to AILBlock
diff --git a/tests/test_ebpf.py b/tests/test_ebpf.py
index 0d23ec8..8aa10a5 100644
--- a/tests/test_ebpf.py
+++ b/tests/test_ebpf.py
@@ -2,6 +2,7 @@ import unittest
from pathlib import Path
import angr
+import ailment
from angr_platforms.ebpf import ArchExtendedBPF, LifterEbpf
@@ -36,8 +37,12 @@ class TestEbpf(unittest.TestCase):
state = proj.factory.entry_state()
block = proj.factory.block(state.addr)
lifter = LifterEbpf(proj.arch, block.addr)
- lifter.lift(block.bytes)
+ irsb = lifter.lift(block.bytes)
assert len(lifter.disassemble()) == 2
+
+ manager = ailment.Manager(arch=proj.arch)
+ ailblock = ailment.IRSBConverter.convert(irsb, manager)
+ assert isinstance(ailblock.statements[0], ailment.statement.Assignment)
if __name__ == "__main__":
but the converter raises NotImplementedError
.
To my understanding, If a irsb ends with a Ijk_Exit
, we can simply do nothing, right? Maybe we can modify converter_vex.py as following:
diff --git a/ailment/converter_vex.py b/ailment/converter_vex.py
index 6523695..dc9bf5e 100644
--- a/ailment/converter_vex.py
+++ b/ailment/converter_vex.py
@@ -753,6 +753,9 @@ class VEXIRSBConverter(Converter):
vex_stmt_idx=DEFAULT_STATEMENT,
)
)
+ elif irsb.jumpkind == "Ijk_Exit":
+ # exit
+ pass
else:
raise NotImplementedError("Unsupported jumpkind")
No response
No response
Not sure if this is an AIL bug or intended behavior, but I am losing context as to what some temp variables hold. Attaching sample Capstone/VEX/AIL/AILBlockSimplfier(ail).result_block.
The simplified AIL block uses t0 without ever specifying where that comes from.
Capstone
0x400000: imul eax, eax, 2
0x400003: add eax, 3
0x400006: nop
VEX (opt_level=1)
t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I32 t4:Ity_I32 t5:Ity_I32 t6:Ity_I32
00 | ------ IMark(0x400000, 3, 0) ------
01 | t0 = GET:I32(eax)
02 | t2 = Mul32(t0,0x00000002)
03 | ------ IMark(0x400003, 3, 0) ------
04 | t3 = Add32(t2,0x00000003)
05 | PUT(cc_op) = 0x00000003
06 | PUT(cc_dep1) = t2
07 | PUT(cc_dep2) = 0x00000003
08 | PUT(cc_ndep) = 0x00000000
09 | PUT(eax) = t3
10 | ------ IMark(0x400006, 1, 0) ------
NEXT: PUT(eip) = 0x00400007; Ijk_Boring
}
AIL
## Block 400000
00 | 400000 | t0 = eax<4>
01 | 400000 | t2 = (t0 Mul 0x2<32>)
02 | 400003 | t3 = (t2 + 0x3<32>)
03 | 400003 | cc_op<4> = 0x3<32>
04 | 400003 | cc_dep1<4> = t2
05 | 400003 | cc_dep2<4> = 0x3<32>
06 | 400003 | cc_ndep<4> = 0x0<32>
07 | 400003 | eax<4> = t3
08 | 400006 | Goto(0x400007<32>)
AIL Simplified
## Block 400000
00 | 400000 | t2 = (t0 Mul 0x2<32>)
01 | 400003 | eax<4> = (t2 + 0x3<32>)
02 | 400006 | Goto(0x400007<32>)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.