Skip to content

Commit e1ebfcd

Browse files
committed
[Python] Fix copy_expr_to and add builder methods for recently-added instructions
1 parent 61b0683 commit e1ebfcd

4 files changed

Lines changed: 621 additions & 0 deletions

File tree

python/examples/pseudo_python.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,124 @@ def perform_get_expr_text(
889889
tokens.append_close_paren()
890890
if parens:
891891
tokens.append_close_paren()
892+
elif instr.operation == HighLevelILOperation.HLIL_BSWAP:
893+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
894+
if parens:
895+
tokens.append_open_paren()
896+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "bswap"))
897+
tokens.append_open_paren()
898+
self.perform_get_expr_text(instr.src, tokens, settings)
899+
tokens.append_close_paren()
900+
if parens:
901+
tokens.append_close_paren()
902+
elif instr.operation == HighLevelILOperation.HLIL_POPCNT:
903+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
904+
if parens:
905+
tokens.append_open_paren()
906+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "popcnt"))
907+
tokens.append_open_paren()
908+
self.perform_get_expr_text(instr.src, tokens, settings)
909+
tokens.append_close_paren()
910+
if parens:
911+
tokens.append_close_paren()
912+
elif instr.operation == HighLevelILOperation.HLIL_CLZ:
913+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
914+
if parens:
915+
tokens.append_open_paren()
916+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "clz"))
917+
tokens.append_open_paren()
918+
self.perform_get_expr_text(instr.src, tokens, settings)
919+
tokens.append_close_paren()
920+
if parens:
921+
tokens.append_close_paren()
922+
elif instr.operation == HighLevelILOperation.HLIL_CTZ:
923+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
924+
if parens:
925+
tokens.append_open_paren()
926+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "ctz"))
927+
tokens.append_open_paren()
928+
self.perform_get_expr_text(instr.src, tokens, settings)
929+
tokens.append_close_paren()
930+
if parens:
931+
tokens.append_close_paren()
932+
elif instr.operation == HighLevelILOperation.HLIL_RBIT:
933+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
934+
if parens:
935+
tokens.append_open_paren()
936+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "rbit"))
937+
tokens.append_open_paren()
938+
self.perform_get_expr_text(instr.src, tokens, settings)
939+
tokens.append_close_paren()
940+
if parens:
941+
tokens.append_close_paren()
942+
elif instr.operation == HighLevelILOperation.HLIL_CLS:
943+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
944+
if parens:
945+
tokens.append_open_paren()
946+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "cls"))
947+
tokens.append_open_paren()
948+
self.perform_get_expr_text(instr.src, tokens, settings)
949+
tokens.append_close_paren()
950+
if parens:
951+
tokens.append_close_paren()
952+
elif instr.operation == HighLevelILOperation.HLIL_ABS:
953+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
954+
if parens:
955+
tokens.append_open_paren()
956+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "abs"))
957+
tokens.append_open_paren()
958+
self.perform_get_expr_text(instr.src, tokens, settings)
959+
tokens.append_close_paren()
960+
if parens:
961+
tokens.append_close_paren()
962+
elif instr.operation == HighLevelILOperation.HLIL_MINS:
963+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
964+
if parens:
965+
tokens.append_open_paren()
966+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "mins"))
967+
tokens.append_open_paren()
968+
self.perform_get_expr_text(instr.left, tokens, settings)
969+
tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ", "))
970+
self.perform_get_expr_text(instr.right, tokens, settings)
971+
tokens.append_close_paren()
972+
if parens:
973+
tokens.append_close_paren()
974+
elif instr.operation == HighLevelILOperation.HLIL_MAXS:
975+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
976+
if parens:
977+
tokens.append_open_paren()
978+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "maxs"))
979+
tokens.append_open_paren()
980+
self.perform_get_expr_text(instr.left, tokens, settings)
981+
tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ", "))
982+
self.perform_get_expr_text(instr.right, tokens, settings)
983+
tokens.append_close_paren()
984+
if parens:
985+
tokens.append_close_paren()
986+
elif instr.operation == HighLevelILOperation.HLIL_MINU:
987+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
988+
if parens:
989+
tokens.append_open_paren()
990+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "minu"))
991+
tokens.append_open_paren()
992+
self.perform_get_expr_text(instr.left, tokens, settings)
993+
tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ", "))
994+
self.perform_get_expr_text(instr.right, tokens, settings)
995+
tokens.append_close_paren()
996+
if parens:
997+
tokens.append_close_paren()
998+
elif instr.operation == HighLevelILOperation.HLIL_MAXU:
999+
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
1000+
if parens:
1001+
tokens.append_open_paren()
1002+
tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "maxu"))
1003+
tokens.append_open_paren()
1004+
self.perform_get_expr_text(instr.left, tokens, settings)
1005+
tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ", "))
1006+
self.perform_get_expr_text(instr.right, tokens, settings)
1007+
tokens.append_close_paren()
1008+
if parens:
1009+
tokens.append_close_paren()
8921010
elif instr.operation == HighLevelILOperation.HLIL_ROUND_TO_INT:
8931011
parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence
8941012
if parens:

python/highlevelil.py

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3862,6 +3862,66 @@ def mult_double_prec_unsigned(
38623862
"""
38633863
return self.expr(HighLevelILOperation.HLIL_MULU_DP, a, b, size=size, source_location=loc)
38643864

3865+
def min_signed(
3866+
self, size: int, a: ExpressionIndex, b: ExpressionIndex, loc: Optional['ILSourceLocation'] = None
3867+
) -> ExpressionIndex:
3868+
"""
3869+
``min_signed`` signed minimum of expressions ``a`` and ``b`` returning an expression of ``size`` bytes
3870+
3871+
:param int size: the size of the result in bytes
3872+
:param ExpressionIndex a: LHS expression
3873+
:param ExpressionIndex b: RHS expression
3874+
:param ILSourceLocation loc: location of returned expression
3875+
:return: The expression ``mins.<size>(a, b)``
3876+
:rtype: ExpressionIndex
3877+
"""
3878+
return self.expr(HighLevelILOperation.HLIL_MINS, a, b, size=size, source_location=loc)
3879+
3880+
def max_signed(
3881+
self, size: int, a: ExpressionIndex, b: ExpressionIndex, loc: Optional['ILSourceLocation'] = None
3882+
) -> ExpressionIndex:
3883+
"""
3884+
``max_signed`` signed maximum of expressions ``a`` and ``b`` returning an expression of ``size`` bytes
3885+
3886+
:param int size: the size of the result in bytes
3887+
:param ExpressionIndex a: LHS expression
3888+
:param ExpressionIndex b: RHS expression
3889+
:param ILSourceLocation loc: location of returned expression
3890+
:return: The expression ``maxs.<size>(a, b)``
3891+
:rtype: ExpressionIndex
3892+
"""
3893+
return self.expr(HighLevelILOperation.HLIL_MAXS, a, b, size=size, source_location=loc)
3894+
3895+
def min_unsigned(
3896+
self, size: int, a: ExpressionIndex, b: ExpressionIndex, loc: Optional['ILSourceLocation'] = None
3897+
) -> ExpressionIndex:
3898+
"""
3899+
``min_unsigned`` unsigned minimum of expressions ``a`` and ``b`` returning an expression of ``size`` bytes
3900+
3901+
:param int size: the size of the result in bytes
3902+
:param ExpressionIndex a: LHS expression
3903+
:param ExpressionIndex b: RHS expression
3904+
:param ILSourceLocation loc: location of returned expression
3905+
:return: The expression ``minu.<size>(a, b)``
3906+
:rtype: ExpressionIndex
3907+
"""
3908+
return self.expr(HighLevelILOperation.HLIL_MINU, a, b, size=size, source_location=loc)
3909+
3910+
def max_unsigned(
3911+
self, size: int, a: ExpressionIndex, b: ExpressionIndex, loc: Optional['ILSourceLocation'] = None
3912+
) -> ExpressionIndex:
3913+
"""
3914+
``max_unsigned`` unsigned maximum of expressions ``a`` and ``b`` returning an expression of ``size`` bytes
3915+
3916+
:param int size: the size of the result in bytes
3917+
:param ExpressionIndex a: LHS expression
3918+
:param ExpressionIndex b: RHS expression
3919+
:param ILSourceLocation loc: location of returned expression
3920+
:return: The expression ``maxu.<size>(a, b)``
3921+
:rtype: ExpressionIndex
3922+
"""
3923+
return self.expr(HighLevelILOperation.HLIL_MAXU, a, b, size=size, source_location=loc)
3924+
38653925
def div_signed(
38663926
self, size: int, a: ExpressionIndex, b: ExpressionIndex, loc: Optional['ILSourceLocation'] = None
38673927
) -> ExpressionIndex:
@@ -4014,6 +4074,93 @@ def not_expr(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLoc
40144074
"""
40154075
return self.expr(HighLevelILOperation.HLIL_NOT, value, size=size, source_location=loc)
40164076

4077+
def byte_swap(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
4078+
"""
4079+
``byte_swap`` reverses the byte order of expression ``value`` of size ``size``
4080+
4081+
:param int size: the size of the result in bytes
4082+
:param ExpressionIndex value: the expression to byte swap
4083+
:param ILSourceLocation loc: location of returned expression
4084+
:return: The expression ``bswap.<size>(value)``
4085+
:rtype: ExpressionIndex
4086+
"""
4087+
return self.expr(HighLevelILOperation.HLIL_BSWAP, value, size=size, source_location=loc)
4088+
4089+
def population_count(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
4090+
"""
4091+
``population_count`` counts the number of set bits in expression ``value`` of size ``size``
4092+
4093+
:param int size: the size of the result in bytes
4094+
:param ExpressionIndex value: the expression to count set bits in
4095+
:param ILSourceLocation loc: location of returned expression
4096+
:return: The expression ``popcnt.<size>(value)``
4097+
:rtype: ExpressionIndex
4098+
"""
4099+
return self.expr(HighLevelILOperation.HLIL_POPCNT, value, size=size, source_location=loc)
4100+
4101+
def count_leading_zeros(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
4102+
"""
4103+
``count_leading_zeros`` counts the leading zero bits in expression ``value`` of size ``size``. The result is
4104+
``8 * size`` when ``value`` is zero.
4105+
4106+
:param int size: the size of the result in bytes
4107+
:param ExpressionIndex value: the expression to count leading zero bits in
4108+
:param ILSourceLocation loc: location of returned expression
4109+
:return: The expression ``clz.<size>(value)``
4110+
:rtype: ExpressionIndex
4111+
"""
4112+
return self.expr(HighLevelILOperation.HLIL_CLZ, value, size=size, source_location=loc)
4113+
4114+
def count_trailing_zeros(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
4115+
"""
4116+
``count_trailing_zeros`` counts the trailing zero bits in expression ``value`` of size ``size``. The result is
4117+
``8 * size`` when ``value`` is zero.
4118+
4119+
:param int size: the size of the result in bytes
4120+
:param ExpressionIndex value: the expression to count trailing zero bits in
4121+
:param ILSourceLocation loc: location of returned expression
4122+
:return: The expression ``ctz.<size>(value)``
4123+
:rtype: ExpressionIndex
4124+
"""
4125+
return self.expr(HighLevelILOperation.HLIL_CTZ, value, size=size, source_location=loc)
4126+
4127+
def reverse_bits(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
4128+
"""
4129+
``reverse_bits`` reverses the bit order of expression ``value`` of size ``size``
4130+
4131+
:param int size: the size of the result in bytes
4132+
:param ExpressionIndex value: the expression to reverse the bits of
4133+
:param ILSourceLocation loc: location of returned expression
4134+
:return: The expression ``rbit.<size>(value)``
4135+
:rtype: ExpressionIndex
4136+
"""
4137+
return self.expr(HighLevelILOperation.HLIL_RBIT, value, size=size, source_location=loc)
4138+
4139+
def count_leading_signs(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
4140+
"""
4141+
``count_leading_signs`` counts the leading sign bits in expression ``value`` of size ``size`` (the number of bits
4142+
below the sign bit that match it)
4143+
4144+
:param int size: the size of the result in bytes
4145+
:param ExpressionIndex value: the expression to count leading sign bits in
4146+
:param ILSourceLocation loc: location of returned expression
4147+
:return: The expression ``cls.<size>(value)``
4148+
:rtype: ExpressionIndex
4149+
"""
4150+
return self.expr(HighLevelILOperation.HLIL_CLS, value, size=size, source_location=loc)
4151+
4152+
def absolute_value(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
4153+
"""
4154+
``absolute_value`` signed absolute value of expression ``value`` of size ``size``
4155+
4156+
:param int size: the size of the result in bytes
4157+
:param ExpressionIndex value: the expression to take the absolute value of
4158+
:param ILSourceLocation loc: location of returned expression
4159+
:return: The expression ``abs.<size>(value)``
4160+
:rtype: ExpressionIndex
4161+
"""
4162+
return self.expr(HighLevelILOperation.HLIL_ABS, value, size=size, source_location=loc)
4163+
40174164
def sign_extend(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
40184165
"""
40194166
``sign_extend`` two's complement sign-extends the expression in ``value`` to ``size`` bytes

0 commit comments

Comments
 (0)