MeanDiff
MeanDiff copied to clipboard
Operand address changed - `sub`
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
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.
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
.
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!