http://www.codeguru.com/Cpp/W-P/system/processesmodules/article.php/c5767/ says:
When creating a process, the loader on Win 2000, Win XP and Win 2003 checks if kernel32.dll and user32.dll (their names are hardcoded into the loader) are mapped at their preferred bases; if not, a hard error is raised. In WinNT 4 ole32.dll was also checked. In WinNT 3.51 and lower such checks were not present, so kernel32.dll and user32.dll could be anywhere. Anyway, the only module that is always at its base is ntdll.dll. The loader doesn't check it, but if ntdll.dll is not at its base, the process just can't be created.
It's a common technique to rely on the fact that exports from kernel32 reside at the same address to use CreateRemoteThread calling LoadLibrary for remote code injection (this is not what Vitaliy's App is doing here but the assertions are the same).
OK, fair enough.
It's hard to implement that in Wine, because dlls are loaded using dlopen() and there's no way to specify which address to load the dll at.
You might be able to do it by staticly linking ntdll, kernel32 and user32 with wine-pthread/wine-kthread, and fixing the binary's address in memory, though that would probably be quite a bit of work.
Mike