Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: error in translating the "sbb" instruction #1196

Open
zyt755 opened this issue Mar 26, 2024 · 1 comment
Open

BUG: error in translating the "sbb" instruction #1196

zyt755 opened this issue Mar 26, 2024 · 1 comment

Comments

@zyt755
Copy link

zyt755 commented Mar 26, 2024

There is an error in lifting the x86 instruction "sbb" to IRs while calculating the AF flag.

Since %32 and 15 perform unsigned greater than calculations, %33 will only become true when %32 is greater than 15 or less than 0. Therefore, Retdec will only set AF to 1 when the least significant 4 bits of eax is 0xf. However, in a real CPU, if CF is 1 after this instruction is executed, AF will be set to 1. Otherwise, AF will be 0.

The original instruction is sbb %eax, %eax
The following is how IRs of "sbb" calculate the AF flag, where an error exists.

store volatile i64 4195574, i64* @_asm_program_counter
%19 = load i64, i64* @rax
%20 = trunc i64 %19 to i32   ; %eax
%21 = load i64, i64* @rax
%22 = trunc i64 %21 to i32   ; %eax
%23 = load i1, i1* @cf
%24 = zext i1 %23 to i32      ; @cf 32bits
%25 = add i32 %22, %24     ; %eax + @cf
%27 = and i32 %20, 15        ; (%eax)_low 4bits
%28 = and i32 %25, 15        ; (%eax + @cf)_low 4bits
%29 = sub i32 %27, %28     ; (%eax)_low4bits - (%eax + @cf)_low4bits
%30 = load i1, i1* @cf
%31 = zext i1 %30 to i32      ; @cf 32bits
%32 = add i32 %29, %31     
%33 = icmp ugt i32 %32, 15
store i1 %33, i1* @az

The following are the completed IRs of "sbb".

store volatile i64 4195574, i64* @_asm_program_counter
%19 = load i64, i64* @rax
%20 = trunc i64 %19 to i32
%21 = load i64, i64* @rax
%22 = trunc i64 %21 to i32
%23 = load i1, i1* @cf
%24 = zext i1 %23 to i32
%25 = add i32 %22, %24
%26 = sub i32 %20, %25
%27 = and i32 %20, 15
%28 = and i32 %25, 15
%29 = sub i32 %27, %28
%30 = load i1, i1* @cf
%31 = zext i1 %30 to i32
%32 = add i32 %29, %31
%33 = icmp ugt i32 %32, 15
%34 = load i1, i1* @cf
%35 = zext i1 %34 to i32
%36 = sub i32 %26, %35
%37 = icmp ult i32 %20, %36
%38 = icmp ult i32 %25, -1
%39 = or i1 %37, %38
%40 = icmp ult i32 %20, %25
%41 = select i1 %34, i1 %39, i1 %40
%42 = load i1, i1* @cf
%43 = zext i1 %42 to i32
%44 = sub i32 %26, %43
%45 = xor i32 %20, %25
%46 = xor i32 %20, %44
%47 = and i32 %45, %46
%48 = icmp slt i32 %47, 0
store i1 %33, i1* @az
store i1 %41, i1* @cf
store i1 %48, i1* @of
%49 = icmp eq i32 %26, 0
store i1 %49, i1* @zf
%50 = icmp slt i32 %26, 0
store i1 %50, i1* @sf
%51 = trunc i32 %26 to i8
%52 = call i8 @llvm.ctpop.i8(i8 %51)
%53 = and i8 %52, 1
%54 = icmp eq i8 %53, 0
store i1 %54, i1* @pf
%55 = zext i32 %26 to i64
store i64 %55, i64* @rax
@zyt755
Copy link
Author

zyt755 commented Mar 28, 2024

Besides, In the case of sar, sal, shr, and shl instructions, Retdec overlooks the effect on the AF flag. Conversely, the physical CPU does take this flag into account.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant