MeanDiff icon indicating copy to clipboard operation
MeanDiff copied to clipboard

Operand address changed - `sub`

Open mfaerevaag opened this issue 6 years ago • 3 comments

Description

Destination address, specified in the first operand, is changed before being written to.

Reference: Ref. Intel 64 and IA-32 Architecture Software Developer's Manual Vol. 2B 4-652

Affected instructions:

0x2a00
0x2b00

NOTE: All combinations of prefixes and operands are omitted.

Reproduction guide

Instruction:

00000000  2A00              sub al,[eax]

Input:

bap-mc "2a00" --show-bil --arch=X86

Observed output:

{
  v1 := low:8[low:32[EAX]]
  EAX := (extract: 31:8[EAX]).((low:8[low:32[EAX]]) - (mem32[pad:32[low:32[EAX]], el]:u8))
  CF := v1 < (mem32[pad:32[low:32[EAX]], el]:u8)
  OF := high:1[(v1 ^ (mem32[pad:32[low:32[EAX]], el]:u8)) & (v1 ^ (low:8[low:32[EAX]]))]
  AF := 0x10:8 = (0x10:8 & (((low:8[low:32[EAX]]) ^ v1) ^ (mem32[pad:32[low:32[EAX]], el]:u8)))
  PF := ~(low:1[let v2 = ((low:8[low:32[EAX]]) >> 0x4:8) ^ (low:8[low:32[EAX]]) in
    let v2 = (v2 >> 0x2:8) ^ v2 in
    (v2 >> 0x1:8) ^ v2])
  SF := high:1[low:8[low:32[EAX]]]
  ZF := 0x0:8 = (low:8[low:32[EAX]])
}

Expected output: Not to change address in destination operand before write.

System Info

OS:

# uname -a
Linux ubuntu 4.10.0-28-generic #32-Ubuntu SMP Fri Jun 30 05:32:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=17.04
DISTRIB_CODENAME=zesty
DISTRIB_DESCRIPTION="Ubuntu 17.04"

BAP:

# bap-mc --version
1.0.0
# bap --version
1.2.0

mfaerevaag avatar Aug 22 '17 10:08 mfaerevaag

Can you elaborate a little bit more? I don't see any changes to the addresses. Here is the output of the newer bap, that is more readable:

$ bap-mc "2a00" --show-bil --arch=X86 --show-insn=asm
subb (%eax), %al
{
  v1 := low:8[EAX]
  EAX := extract:31:8[EAX].low:8[EAX] - mem[EAX]
  CF := v1 < mem[EAX]
  OF := high:1[(v1 ^ mem[EAX]) & (v1 ^ low:8[EAX])]
  AF := 0x10 = (0x10 & (low:8[EAX] ^ v1 ^ mem[EAX]))
  PF := ~low:1[let v2 = low:8[EAX] >> 4 ^ low:8[EAX] in
    let v2 = v2 >> 2 ^ v2 in
    v2 >> 1 ^ v2]
  SF := high:1[low:8[EAX]]
  ZF := 0 = low:8[EAX]
}

And without the flag calculation (that are irrelevant to this issue):

$ bap-mc "2a00" --show-bil --arch=X86 --show-insn=asm
subb (%eax), %al
{
  EAX := extract:31:8[EAX].low:8[EAX] - mem[EAX]
}

That means that a value of eax is a concatenation of whatever was in the higher 3 bytes of eax and a difference between the low byte of eax and a byte that is stored in at the location pointed by eax. BIL expressions are side-effect free, so the value of EAX doesn't change during the expression evaluation. The semantics of BIL is formally specified here.

ivg avatar Sep 19 '17 02:09 ivg

Sorry, maybe Expected output does not have our intention.

I think BAP executes the BIL statements in sequantial way. That is, the value of EAX is changed after the 2nd statement. So in the flag calculation of CF or AF, memory is accessed with newly assigned EAX value.

I think assignment of EAX should go to the end of statements, or CF or AF calculation should be done with v1.

soomin-kim avatar Sep 19 '17 03:09 soomin-kim

Aha! Now I totally see your point. It looks like a family of bugs where we use the original variable instead of the temporal. I will create an issue in our repo, to track these issues.

Thanks again!

ivg avatar Sep 19 '17 12:09 ivg