W10 -> W7 Compatibility Layer

Discussion in 'Windows 7' started by kebabstorm, Feb 26, 2023.

  1. kebabstorm

    kebabstorm MDL Junior Member

    Aug 3, 2016
    94
    120
    0
    Does a simple W10 -> W7 compatibility layer project exist?
    Similar to how DXVK can be used to make D3D12 to work in Windows 7, but for system calls.

    Translating simple calls like USER32:SystemParametersInfoForDPI -> USER32:SystemParametersInfo.
    I couldn't find anything by searching but nowadays it's increasingly hard to find anything useful with search engines and while such a project might exist in GitHub, its' search is also notoriously terrible.

    Running a full blown emulation layer like winevdm would be unnecessary for such a simple task. Where the limitations are only arbitrary because some missing API function was used or a GetVersionEx() check applied.

    This is very easy to implement by myself but as I am pretty sure such a thing already exists, I'd rather not reinvent the wheel.

    If it really doesn't exist though, I'll make it myself and publish the project. I just can't imagine it hasn't been done already.
     
  2. abbodi1406

    abbodi1406 MDL KB0000001

    Feb 19, 2011
    16,141
    84,318
    340
    Even W8.1 -> W7 don't exist
     
  3. acer-5100

    acer-5100 MDL Guru

    Dec 8, 2018
    3,644
    2,620
    120
    #3 acer-5100, Feb 26, 2023
    Last edited: Feb 26, 2023

    In short you want kernelex for w7

    Variations of it exist for w98/w2k/xp and vista but AFAIK no one has botered (yet) to make one for w7.
     
  4. kebabstorm

    kebabstorm MDL Junior Member

    Aug 3, 2016
    94
    120
    0
  5. kebabstorm

    kebabstorm MDL Junior Member

    Aug 3, 2016
    94
    120
    0
    If a simple hook hasn't been made, from top of my head I can think of a few methods using avrf

    a) Remove the missing function from import address table, decrease iat size, search executable memory for all references to it and make them point to our func, resume process
    b) Relocate export address table, increase size, add function, point it to wherever (won't be used) and make avrf thunk descriptor to point to our func
    c) Rename the dll in import address table to point to our dll which contains the needed func

    probably b would be the cleanest option of these, and maybe there are better methods. but these ones wouldn't be too hard
     
  6. kebabstorm

    kebabstorm MDL Junior Member

    Aug 3, 2016
    94
    120
    0
    Okay regarding option B i'm back with some increased knowledge, but please correct me if I'm wrong.

    As a part of the PE loading process, when IAT is walked, ntdll:LdrLoadDll is used on each one.
    LdrLoadDll -> ... -> LdrpFindOrMapDll -> ... ->
    branches to A/B whether it's already loaded or not, opens either the file or the mapped memory NtCreateFile/NtOpenFile, bunch of other stuff, not important -> ...
    CreateSection -> NtMapViewOfSection ->
    then from my understanding , this is been like this since windows XP that the nt header and export address table isn't read raw like earlier windows version, but uses these helper funcs
    RtlImageNtHeaderEx -> RtlImageDirectoryEntryToData

    This returns the pointer to the directory entries, one of which is is the export address table we want (IMAGE_DIRECTORY_ENTRY_EXPORT)
    As avrf is loaded directly after ntdll and before everything else, we could trampoline this func , copy the existing EAT to somewhere else, add our missing func to the copied eat and point to our func. This way you wouldn't even need to write in memory of the loaded modules as the old eat would still be in place, but just never used as we made the func return the copied eat ptr.
    The func pointers of the originals would need to be updated to match the change in relative address, this could be a problem if the disp32 is too large (target dll and our dll mapped > 0xffffffff ~ 2GB apart, but in practice this doesn't happen?)
    This way it would appear as if the function never was missing. Functions like ntdll:LdrGetProcedureAddress/Ex also use the RtlImageDirectoryEntryToData to read the exports so it seems it'd be enough to hook only this single func and it would work with all regular imports / delay-load / dynamic getprocaddr loads without needing to seperately hook them. Obviously software could dynamically load a dll without using the windows api funcs but in practice this never happens.

    I find this should be relatively easy to implement. Only problem I can think of is when x86 apps run under x64 and wow64 is added into the mix, increasing complexity. Idk whether it would be easier to hook the 64bit version of ntdll and mix 64-bit and 32-bit code or hook the 32-bit one in 32-bit apps and maybe bypassing this complexity.

    Thoughts?