http://bugs.winehq.org/show_bug.cgi?id=15649
--- Comment #13 from Anastasius Focht focht@gmx.net 2009-06-17 17:30:11 --- Hello,
after looking at Razor's injector code it seems indeed to rely on fixed base address for kernel32.dll in both Razor and game client process space - needed to write the thunk instructions that call LoadLibrary() and GetProcAddress().
The following code snippets are called from "loader.dll", export "Load":
Params:
"C:\Program Files\EA Games\Ultima Online 2D Client\client.exe" -> the remote process where the dll will be injected/loaded "Crypt.dll" -> the library to be injected "OnAttach" -> export that will be called from remote thunk code when library got loaded
--- snip --- 0009:Call KERNEL32.CreateProcessA(0033f170 "C:\Program Files\EA Games\Ultima Online 2D Client\client.exe",00000000,00000000,00000000,00000000,00000004,00000000,0033ecec "C:\Program Files\EA Games\Ultima Online 2D Client",0033edf0,0033ec8c) ret=031d118f 0022:trace:relay:load_list L"RelayExclude" = L"ntdll.RtlEnterCriticalSection;ntdll.RtlLeaveCriticalSection;kernel32.48;kernel32.49;kernel32.94;kernel32.95;kernel32.96;kernel32.97;kernel32.98" 0022:trace:relay:load_list L"RelayFromExclude" = L"winex11.drv;user32;gdi32;advapi32;kernel32" 0022:Call KERNEL32.__wine_kernel_init() ret=7ef94483 0009:Ret KERNEL32.CreateProcessA() retval=00000001 ret=031d118f --- snip ---
Remote process is created suspended.
--- snip --- ... 0009:Call KERNEL32.VirtualAllocEx(00000184,00000000,00000066,00003000,00000040) ret=031d120e 0009:Ret KERNEL32.VirtualAllocEx() retval=00340000 ret=031d120e 0009:Call ntdll.RtlAllocateHeap(03890000,00000000,00000066) ret=031d1be6 0009:Ret ntdll.RtlAllocateHeap() retval=03891e18 ret=031d1be6 0009:Call KERNEL32.VirtualProtectEx(00000184,00554b3c,00000008,00000040,0033ec88) ret=031d1297 0009:Ret KERNEL32.VirtualProtectEx() retval=00000001 ret=031d1297 0009:Call KERNEL32.ReadProcessMemory(00000184,00554b3c,0033ecec,00000008,0033ec88) ret=031d12cd 0009:Ret KERNEL32.ReadProcessMemory() retval=00000001 ret=031d12cd 0009:Call KERNEL32.WriteProcessMemory(00000184,00554b3c,0033eca4,00000008,0033ec88) ret=031d1315 0009:Ret KERNEL32.WriteProcessMemory() retval=00000001 ret=031d1315 0009:Call KERNEL32.LoadLibraryA(031d816c "Kernel32") ret=031d13a8 0009:Ret KERNEL32.LoadLibraryA() retval=7edb0000 ret=031d13a8 0009:Call KERNEL32.GetProcAddress(7edb0000,031d815c "LoadLibraryA") ret=031d13bd 0009:Ret KERNEL32.GetProcAddress() retval=7edc1f40 ret=031d13bd 0009:Call KERNEL32.GetProcAddress(7edb0000,031d814c "GetProcAddress") ret=031d13de 0009:Ret KERNEL32.GetProcAddress() retval=7edc1118 ret=031d13de 0009:Call KERNEL32.FreeLibrary(7edb0000) ret=031d13f2 0009:Ret KERNEL32.FreeLibrary() retval=00000001 ret=031d13f2 0009:Call KERNEL32.WriteProcessMemory(00000184,00340000,03891e18,00000066,0033ec88) ret=031d149c 0009:Ret KERNEL32.WriteProcessMemory() retval=00000001 ret=031d149c 0009:Call ntdll.RtlFreeHeap(03890000,00000000,03891e18) ret=031d1b77 0009:Ret ntdll.RtlFreeHeap() retval=00000001 ret=031d1b77 0009:Call KERNEL32.ResumeThread(00000188) ret=031d14cb 0009:Ret KERNEL32.ResumeThread() retval=00000001 ret=031d14cb --- snip ---
The dll injection mechanism. Along with the thunk, code is written to remote process entry point (0x00554b3c -> PE entry point) to jump to the thunk code which loads the library and calls the export. Remote process execution is resumed which should ideally load the dll (and restore the entry).
The anomaly with your trace log is here:
"Razor.exe":
--- snip --- ... 0009:Call PE DLL (proc=0x7ef41110,module=0x7ef30000 L"mscoree.dll",reason=WINE_PREATTACH,res=(nil)) 0009:Ret PE DLL (proc=0x7ef41110,module=0x7ef30000 L"mscoree.dll",reason=WINE_PREATTACH,res=(nil)) retval=0 0009:Call PE DLL (proc=0x7efc8e30,module=0x7ef60000 L"ntdll.dll",reason=PROCESS_ATTACH,res=0x1) 0009:Ret PE DLL (proc=0x7efc8e30,module=0x7ef60000 L"ntdll.dll",reason=PROCESS_ATTACH,res=0x1) retval=1 0009:Call PE DLL (proc=0x7ee3a490,module=0x7edb0000 L"KERNEL32.dll",reason=PROCESS_ATTACH,res=0x1) 0009:Ret PE DLL (proc=0x7ee3a490,module=0x7edb0000 L"KERNEL32.dll",reason=PROCESS_ATTACH,res=0x1) retval=1 0009:Call PE DLL (proc=0x79002c77,module=0x79000000 L"mscoree.dll",reason=PROCESS_ATTACH,res=0x1) ... --- snip ---
"C:\Program Files\EA Games\Ultima Online 2D Client\client.exe":
--- snip --- ... 0022:Call PE DLL (proc=0x7efc8e30,module=0x7ef60000 L"ntdll.dll",reason=PROCESS_ATTACH,res=0x1) 0022:Ret PE DLL (proc=0x7efc8e30,module=0x7ef60000 L"ntdll.dll",reason=PROCESS_ATTACH,res=0x1) retval=1 0022:Call PE DLL (proc=0x7ee46490,module=0x7edc0000 L"KERNEL32.dll",reason=PROCESS_ATTACH,res=0x1) 0022:Ret PE DLL (proc=0x7ee46490,module=0x7edc0000 L"KERNEL32.dll",reason=PROCESS_ATTACH,res=0x1) retval=1 0022:Call PE DLL (proc=0x7e98a490,module=0x7e950000 ... --- snip ---
Kernel32.dll gets different image bases in different virtual address spaces and additionally it's not getting its preferred base at all (along with ntdll). Do you run a Linux distribution which has virtual address space randomization enabled by chance?
"cat /proc/sys/kernel/randomize_va_space"
Also try to attach to Razor process with "winedbg" and do "info share". Attach output to bug to have the usual virtual address space layout on your system reviewed.
Regards