Here is what could happen when I try to retrieve the IL of a function:
It is immediately available
It is not yet available, but can be retrieved briefly
It cannot be retrieved
Now think of the case of func.mlil, it will work for case 1 & 2, but it will throw an exception in case 3. If I use func.mlil_if_available, then it will work for case 1 & 3, but not for case 2 according to my test. I had to use this code pattern to handle all cases:
try:
mlil = f.mlil
except ILException:
return
if mlil is None:
return
for mlil_bb in mlil.basic_blocks:
pass
Which is quite ugly and inconvenient. It would be great if we can devise a way to retrieve the IL without needing to write code in the above pattern. Potentially we could just create a new API that wraps the above code logic
While working on the binja backend for capa, I noticed a few outstanding crashes: https://github.com/mandiant/capa/issues/2406#issuecomment-2490171179, and https://github.com/mandiant/capa/issues/2249. After troubleshooting this, I realized that to reliably get the IL of a function, we have to use try/catch for now.
Here is what could happen when I try to retrieve the IL of a function:
Now think of the case of
func.mlil
, it will work for case 1 & 2, but it will throw an exception in case 3. If I usefunc.mlil_if_available
, then it will work for case 1 & 3, but not for case 2 according to my test. I had to use this code pattern to handle all cases:Which is quite ugly and inconvenient. It would be great if we can devise a way to retrieve the IL without needing to write code in the above pattern. Potentially we could just create a new API that wraps the above code logic