Instead of analyzing the test result in the Windbg log file I decided to do it in IDA. I took the errors from the Windbg log and simply highlighted the instructions causing read-before-write in IDA. The highlight idea was borrowed from team ZDI (thanks).
Below is the code snippet wherein an error detected that appears to be a false positive.
There are two questions need answering:
- Why is it a false positive detection?
- Why the detection was mistakenly issued?
void*
is pushed onto the stack that is a parameter for delete()
. delete()
uses cdecl
calling convention so it doesn't clean-up void*
on the stack but pop ecx
in the red line does. pop ecx
reads void*
. The memory address void*
read from has been written by push
instruction. So the red line cannot be a read-before-write access.Answering the second question: why the detection was mistakenly issued is a bit more complex and requires knowledge how my Windbg plugin extension works - read the principles here if you like. When
push [ebp+var_78]
is executed it does the followings. First, it reads var_78
local variable, then it writes (pushes) var_78
onto the stack. The address of the read access and the address of the write access are both stack memory addresses. In this example, the protection flags were set on stack memory region by the Windbg command extension. As mentioned above when push
is executed read access occurs first. We handle this by removing the protection flags and let the push execute. Since the memory protection flags removed push
didn't have a chance to cause a write access exception, therefore the address is not added to the list of written addresses. Later on the execution, pop
causes a read access violation and the plugin checks if the address has been written. Since the address is not on the list of written addresses it issues a read-before-write notification, mistakenly. The answer in short is because we didn't catch the write access of push
.The current implementation wrongly assumes that an instruction could cause either read or write access. As seen above, in fact, an instruction could cause both read and write accesses. A possible fix would be to deal with the situation of multiple accesses. However, I don't think it's a priority to implement at the moment because it's possible to do a post process on the output log to mark or to remove these situations when showed in IDA.