Missing export function - memcmp

I’ve just had an issue with a KMDF driver (built with VS2015 update 1) that would load fine on Win7 x64 and on later versions of Windows but would not load on Win7 x86. The error logged was ‘the specified procedure could not be found’.

Looking at the Win7/x86 build of the driver in Dependency Walker, I got ‘Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module’. After scouring project settings to identify differences and finding nothing, I started stripping code out of the driver and eventually pinpointed a memcmp call as the culprit; replacing this with RtlCompareMemory solved the problem.

What confused me is why this driver would load on Win7/x64 and on Windows 8 etc., but not Win7/x86. Also, I see that Doron Holan has stated on another thread that ‘RtlCompareMemory redirects as a define to memcmp’ which makes me question why switching to RtlCompareMemory has solved my problem.

Can anyone shed any light on this?

xxxxx@gmail.com wrote:

I’ve just had an issue with a KMDF driver (built with VS2015 update 1) that would load fine on Win7 x64 and on later versions of Windows but would not load on Win7 x86. The error logged was ‘the specified procedure could not be found’.

Looking at the Win7/x86 build of the driver in Dependency Walker, I got ‘Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module’. After scouring project settings to identify differences and finding nothing, I started stripping code out of the driver and eventually pinpointed a memcmp call as the culprit; replacing this with RtlCompareMemory solved the problem.

What confused me is why this driver would load on Win7/x64 and on Windows 8 etc., but not Win7/x86. Also, I see that Doron Holan has stated on another thread that ‘RtlCompareMemory redirects as a define to memcmp’ which makes me question why switching to RtlCompareMemory has solved my problem.

It shouldn’t have made any difference. Here is the literal code in <wdm.h>:

#define RtlCopyMemory(Destination,Source,Length)
memcpy((Destination),(Source),(Length))

Are you using the standard settings? Usually, the C compiler settings
have intrinsics turned on, so that memcpy compiles to a “rep movsd” and
doesn’t involve an external call at all. If you do “link /dump
/imports” on your driver, do you actually see a reference to memcpy?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</wdm.h>

> #define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))

Ishan mentions memcmp, not memcpy. I’m not sure what is causing his problem but RtlCompareMemory is not a #define to memcmp, it’s it’s own function.
J

Tim Roberts wrote:

Usually, the C compiler settings have intrinsics turned on,
so that memcpy compiles to a “rep movsd” and doesn’t
involve an external call at all.

Up to a certain size, correct?

On Apr 17, 2016, at 8:29 AM, xxxxx@gmail.com wrote:

Tim Roberts wrote:

> Usually, the C compiler settings have intrinsics turned on,
> so that memcpy compiles to a “rep movsd” and doesn’t
> involve an external call at all.

Up to a certain size, correct?

BELOW a certain size it uses individual register moves. But there is no upper limit on the “rep moved”. After all, once it gets rolling, that does 4 bytes per cycle, and it’s hard to beat that without using custom instruction sets.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks for the response Tim, although as Jason says my issue is with memcmp, not memcpy. As far as I know, I’m using the standard settings to compile and link.

I’ve dumped the imports and do indeed see a reference to memcmp, abridged output below. When I dump the imports for the Win8 build configuration (which loads without issue) the memcmp is also present.

File Type: EXECUTABLE IMAGE

Section contains the following imports:

ntoskrnl.exe
407090 Import Address Table
409144 Import Name Table
0 time date stamp
0 Index of first forwarder reference

385 IoWriteErrorLogEntry
740 RtlEnumerateGenericTableAvl
79E RtlInitializeGenericTableAvl
7A4 RtlInsertElementGenericTableAvl
72A RtlDeleteElementGenericTableAvl
6FD RtlCompareMemory
7B8 RtlIpv4StringToAddressA
A64 memcmp

Run depends.exe on your driver image.

Tim Roberts wrote:

After all, once it gets rolling, that does 4 bytes per cycle, and
it?s hard to beat that without using custom instruction sets.

That’s what I meant. Like, I feel like I remember ending up in memcpy.asm at some point and seeing some SSE stuff going on. But this was on a larger copy.