From: Paul Baker [MVP, Windows Desktop Experience] on 9 Sep 2009 14:09 Even in OSes without ASLR, a base address can also vary between processes if they are loaded dynamically in a different order, because of a different execution path, can't it? The base address in the DLL file is only a "preferred" base address. Paul "Ben Voigt [C++ MVP]" <bvoigt(a)newsgroup.nospam> wrote in message news:OvkCY0aIKHA.1988(a)TK2MSFTNGP03.phx.gbl... > Alexander Grigoriev wrote: >> The address can be different in different processes. > > For most functions, but not for ntdll or kernel32, unless ASLR has been > updated to use different base addresses in different processes. > >> >> "Sanje�v" <swtbase(a)gmail.com> wrote in message >> news:dbf9fdbe-a054-4112-85a1-32716bb7e65c(a)p10g2000prm.googlegroups.com... >> On Aug 20, 4:34 am, "Ben Voigt [C++ MVP]" <bvo...(a)newsgroup.nospam> >> wrote: >> >>> Wrong in what way? You can't use the returned function pointer, or it >>> doesn't match another "correct" value you got a different way? Note >>> that &GetProcAddress in your source code may end up with the address >>> of a trampoline routine and not the real address of GetProcAddress. >> >> Wrong in the sense that the address it returns is of a protected >> memory probably used by the system (I cannot access the memory if I >> follow the address in WinDbg). If I use GetProcAddress for >> GetModuleHandle, the address it returns points correctly to the >> function where the memory is accessible (few scrolls up and the >> correct address of GetProcAddress can be seen). This can be checked by >> looking at the address it returned in WinDbg. No I am not using >> &GetProcAddress but GetProcAddress(GetModuleHandle("kernel32"), >> "GetProcAddress"). This means that there is no trampoline functions >> involved. If you are suspecting trampoline functions with C++ code >> then I should also note that I have disabled both security check >> functions and incremental linking. >> >> Here is the assembly for the binary function code (Please note that I >> will be inserting respective addresses in the 0x00000 and 0 fields >> before this binary is injected): >> >> >> PUSH EBP ; >> Start of function of type _stdcall >> MOV EBP,ESP >> SUB ESP,18 ; >> 18h bytes of local variables >> MOV DWORD PTR SS:[EBP-14], 0x00000 ; Address of dll >> name to be inserted here instead of zeros >> MOV DWORD PTR SS:[EBP-C], 0x00000 ; Address of dll >> function to call to be inserted here >> MOV DWORD PTR SS:[EBP-10], 0 ; Address to >> 'GetModuleHandleW' to be inserted here >> MOV DWORD PTR SS:[EBP-8], 0 ; Address to >> 'GetProcAddress' to be inserted here >> PUSH DWORD PTR SS:[EBP-14] ; wchar_t* >> lpModuleName >> CALL DWORD PTR SS:[EBP-10] ; Call to >> GetModuleHandleW >> PUSH DWORD PTR SS:[EBP-C] ; char* >> lpProcName >> PUSH EAX ; >> hDllHandle, value returned by 'GetModuleHandleW' >> CALL DWORD PTR SS:[EBP-8] ; Call to >> GetProcAddress >> MOV DWORD PTR SS:[EBP-4],EAX ; Save return >> value of GetProcAddress >> CALL DWORD PTR SS:[EBP-4] ; Call the >> function asked to call >> MOV DWORD PTR SS:[EBP-18],EAX ; Save its return >> value >> XOR EAX,EAX >> MOV ESP,EBP >> POP EBP >> RETN ; >> Return to caller >> >> >> Actual C++ code: >> >> >> DWORD WINAPI Func(LPVOID lpParameter) >> { >> wchar_t* lpDllName = L"<DllNameHere>"; // Dll >> name here >> char* lpFuncName = "<DllFunc2Call>"; // >> Dll func 2 call here >> void* lpFunc1 = reinterpret_cast<void*>(1); // >> Address to GetModuleHandleW >> void* lpFunc2 = reinterpret_cast<void*>(2); // >> Address to GetProcAddress >> LPINJDLLFUNC lpInjDllFunc; >> DWORD DllFuncRet; >> >> >> _asm >> { >> push lpDllName ;Push lpModuleName into stack >> call lpFunc1 ;Call GetModuleHandle >> >> >> push lpFuncName ;Push name of function to call in the >> dll into stack >> push eax ;Push ret value of >> GetModuleHandle into stack >> call lpFunc2 ;Call GetProcAddress >> >> >> mov lpInjDllFunc, eax ;Save ret value of >> GetProcAddress into memory >> >> >> call lpInjDllFunc ;Call the given function in >> the dll >> mov DllFuncRet, eax ;Save ret value of the >> function into variable >> } >> >> >> return DllFuncRet; >> } > >
From: Tim Roberts on 9 Sep 2009 23:14 "Paul Baker [MVP, Windows Desktop Experience]" <paulrichardbaker(a)community.nospam> wrote: > >Even in OSes without ASLR, a base address can also vary between processes if >they are loaded dynamically in a different order, because of a different >execution path, can't it? The base address in the DLL file is only a >"preferred" base address. Theoretically, yes. However, all of the system DLLs for a given version and service pack are specifically "rebased" so that their addresses do not overlap. So, without ASLR, your system DLLs will always be at the same address, regardless of load order, unless you load your own DLL in the system range (roughly 70000000 to 7fffffff). Futher, ntdll and kernel32 (which were the examples given) are the first two DLLs to be loaded. They will always get their preferred address. -- Tim Roberts, timr(a)probo.com Providenza & Boekelheide, Inc.
From: Paul Baker [MVP, Windows Desktop Experience] on 17 Sep 2009 08:55 Hence an even greater need for ASLR than I had imagined. Thanks! Paul "Tim Roberts" <timr(a)probo.com> wrote in message news:uirga5doju2qo86k3id963v2a1labrftn2(a)4ax.com... > "Paul Baker [MVP, Windows Desktop Experience]" > <paulrichardbaker(a)community.nospam> wrote: >> >>Even in OSes without ASLR, a base address can also vary between processes >>if >>they are loaded dynamically in a different order, because of a different >>execution path, can't it? The base address in the DLL file is only a >>"preferred" base address. > > Theoretically, yes. However, all of the system DLLs for a given version > and service pack are specifically "rebased" so that their addresses do not > overlap. So, without ASLR, your system DLLs will always be at the same > address, regardless of load order, unless you load your own DLL in the > system range (roughly 70000000 to 7fffffff). > > Futher, ntdll and kernel32 (which were the examples given) are the first > two DLLs to be loaded. They will always get their preferred address. > -- > Tim Roberts, timr(a)probo.com > Providenza & Boekelheide, Inc.
From: G�nter Prossliner on 17 Sep 2009 09:44 Hello Tim! Hello Paul! >> Even in OSes without ASLR, a base address can also vary between >> processes if they are loaded dynamically in a different order, >> because of a different execution path, can't it? The base address in >> the DLL file is only a "preferred" base address. > > Theoretically, yes. The only way I can imagine to cause kernel32 or ntdll to be relocated is to set the base-path of the exe into the range of this modules. But this causes the application to stop on initialization. For kernel32 (/base:0x7c800000) --------------------------- RebaseKernel32Test.exe - Illegal System DLL Relocation --------------------------- The system DLL kernel32.dll was relocated in memory. The application will not run properly. The relocation occurred because the DLL d:\Developing\Tests\RebaseKernel32Test\Debug\RebaseKernel32Test.exe occupied an address range reserved for Windows system DLLs. The vendor supplying the DLL should be contacted for a new DLL. --------------------------- OK --------------------------- For ntdll (/base:0x7c900000): The system cannot execute the specified program. Press any key to continue . . . GP
From: Tim Roberts on 17 Sep 2009 23:04 "G�nter Prossliner" <nospam(a)spam.com> wrote: > >The only way I can imagine to cause kernel32 or ntdll to be relocated is to >set the base-path of the exe into the range of this modules. > > >But this causes the application to stop on initialization. >... >For ntdll (/base:0x7c900000): > >The system cannot execute the specified program. >Press any key to continue . . . I believe ntdll.dll is actually loaded into the process BEFORE the executable; it's involved in loading and starting the program. -- Tim Roberts, timr(a)probo.com Providenza & Boekelheide, Inc.
|
Pages: 1 Prev: How to Communicate with chips on the ISA bus/SMBus? Next: which core does the __readmsr read? |