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
cdeclcalling convention so it doesn't clean-up
void*on the stack but
pop ecxin the red line does.
void*. The memory address
void*read from has been written by
pushinstruction. 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_78local variable, then it writes (pushes)
var_78onto 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
pushis executed read access occurs first. We handle this by removing the protection flags and let the push execute. Since the memory protection flags removed
pushdidn'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,
popcauses 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
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.