[+] AuFS::["Hooks"::]IPlatformFS::HookNamedMap for hooking file map requests - required for android OOBE mounts

This commit is contained in:
Reece Wilson 2024-12-05 15:12:29 +00:00
parent a79e63375d
commit df28df6772
8 changed files with 317 additions and 50 deletions

View File

@ -11,6 +11,18 @@ namespace Aurora::IO::FS
{
struct UpdateTimes;
struct NamedMapRequest
{
AuROString * pPath {};
AuOptional<EFileOpenMode> * pOpteMode {};
AuOptional<AuUInt64> * pOptuFileMapOffset {};
AuOptional<AuUInt64> * pOptuFileMapLength {};
AuOptional<AuInt64> * pOptiAdjustStreamOffset {};
AuOptional<EFileAdvisoryLockLevel> * pOpteAdvisoryLevel {};
AuOptional<bool> * pOptbLockEntireFile {};
AuIO::IIOHandle * pHandle {};
};
struct IPlatformFS
{
// Aurora::Win32Open-style API (not CreateFileW)
@ -28,6 +40,15 @@ namespace Aurora::IO::FS
int flags,
AuUInt64 uFlags) = 0;
// return: {} to ignore
// *although, argument pointers may still be updatable bc im too lazy to make a shadow copy of each*
// *you shouldn't rely on this. return true instead*
// return: {false} to fail/block the map
// return: {true} to acknowledge updatable NamedMapRequest.
// you may initialize NamedMapRequest::pHandle or update pPath.
// you may update any other argument pointer within NamedMapRequest.
virtual AuOptional<bool> HookNamedMap(NamedMapRequest &parameters) = 0;
virtual IFileStream *OpenExNew(const AuROString &path,
EFileOpenMode openMode,
EFileAdvisoryLockLevel lock,

View File

@ -8,6 +8,7 @@
#include <Source/RuntimeInternal.hpp>
#include "FSMemoryMappedFile.hpp"
#include <Source/IO/Adapters/AuIOAdapterAsyncDelegators.hpp>
#include <Aurora/IO/FS/Hook/FSPlatform.hpp>
namespace Aurora::IO::FS
{
@ -337,6 +338,41 @@ namespace Aurora::IO::FS
AuOptional<EFileAdvisoryLockLevel> opteAdvisoryLevel,
AuOptional<bool> optbLockEntireFile)
{
bool bHooked {};
AuROString path2 { path };
auto pReturn = _new MemoryMappedFile();
SysCheckNotNullMemory(pReturn, {});
{
NamedMapRequest req;
req.pPath = &path2;
req.pOpteMode = &opteMode;
req.pOptuFileMapOffset = &optuFileMapOffset;
req.pOptuFileMapLength = &optuFileMapLength;
req.pOptiAdjustStreamOffset = &optiAdjustStreamOffset;
req.pOpteAdvisoryLevel = &opteAdvisoryLevel;
req.pOptbLockEntireFile = &optbLockEntireFile;
req.pHandle = pReturn->handle.AsPointer();
if (auto optResult = AuFS::GetCurrentPlatform()->HookNamedMap(req))
{
if (optResult.Value())
{
bHooked = true;
}
else
{
return nullptr;
}
}
else
{
// nothing
}
}
auto eMode = opteMode.ValueOr(EFileOpenMode::eRead);
auto uFileMapOffset = optuFileMapOffset.ValueOr(0);
auto uFileLength = optuFileMapLength.ValueOr(0);
@ -344,19 +380,24 @@ namespace Aurora::IO::FS
auto bLockEntireFile = optbLockEntireFile.ValueOr(true);
auto eAdvisoryLevel = opteAdvisoryLevel.ValueOr(EFileAdvisoryLockLevel::eBlockReadWrite);
auto pReturn = _new MemoryMappedFile();
SysCheckNotNullMemory(pReturn, {});
auto createRequest = AuIO::IIOHandle::HandleCreate::Create(path);
auto createRequest = AuIO::IIOHandle::HandleCreate::Create(path2);
createRequest.eMode = eMode;
createRequest.eAdvisoryLevel = bLockEntireFile ? eAdvisoryLevel : EFileAdvisoryLockLevel::eNoSafety;
createRequest.bDirectIOMode = false;
if (bHooked && pReturn->handle->IsValid())
{
// do nothing
}
else
{
if (!pReturn->handle->InitFromPath(createRequest))
{
delete pReturn;
return nullptr;
}
}
if (!pReturn->Init(eMode, uFileMapOffset, uFileLength, iAdjustStreamOffset, !bLockEntireFile ? eAdvisoryLevel : EFileAdvisoryLockLevel::eNoSafety))
{

View File

@ -57,6 +57,11 @@ namespace Aurora::IO::FS
return {};
}
AuOptional<bool> PlatformFS::HookNamedMap(NamedMapRequest &parameters)
{
return {};
}
AUKN_SYM AuSPtr<IReadDir> ReadDir(const AuROString &path)
{
return GetCurrentPlatform()->ReadDir(path);

View File

@ -27,6 +27,8 @@ namespace Aurora::IO::FS
int flags,
AuUInt64 uFlags) override;
AuOptional<bool> HookNamedMap(NamedMapRequest &parameters) override;
IFileStream *OpenExNew(const AuROString &path,
EFileOpenMode openMode,
EFileAdvisoryLockLevel lock,

View File

@ -12,6 +12,7 @@
#include "AuProcessSectionFileMapView.NT.hpp"
#include <Source/IO/IPC/AuIPCHandle.hpp>
#include <Windows.h>
#include <Aurora/IO/FS/Hook/FSPlatform.hpp>
namespace Aurora::Process
{
@ -40,14 +41,61 @@ namespace Aurora::Process
AuFS::EFileOpenMode mode,
AuFS::EFileAdvisoryLockLevel sectionLock)
{
AuROString path2 { str };
bool bHooked {};
auto pHandle = AuIO::IOHandleShared();
if (!pHandle)
{
SysPushErrorMemory();
return nullptr;
return {};
}
AuIO::IIOHandle::HandleCreate createhandle(str);
{
AuFS::NamedMapRequest req;
AuOptional<AuUInt64> optOffset = uOffset;
AuOptional<AuUInt64> optLength = uLength;
AuOptional<AuFS::EFileOpenMode> opteMode = mode;
AuOptional<AuFS::EFileAdvisoryLockLevel> opteLock = sectionLock;
req.pPath = &path2;
req.pOpteMode = &opteMode;
req.pOptuFileMapOffset = &optOffset;
req.pOptuFileMapLength = &optLength;
req.pOptiAdjustStreamOffset = nullptr;
req.pOpteAdvisoryLevel = &opteLock;
req.pOptbLockEntireFile = nullptr;
req.pHandle = pHandle.get();
if (auto optResult = AuFS::GetCurrentPlatform()->HookNamedMap(req))
{
if (optResult.Value())
{
bHooked = true;
uOffset = optOffset.ValueOr(uOffset);
uLength = AuUInt { optLength.ValueOr(uLength) };
mode = opteMode.ValueOr(mode);
sectionLock = opteLock.ValueOr(sectionLock);
}
else
{
return {};
}
}
else
{
// nothing
}
}
if (bHooked && pHandle->IsValid())
{
// do nothing
}
else
{
AuIO::IIOHandle::HandleCreate createhandle(path2);
createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety;
createhandle.eMode = mode;
createhandle.bFailIfNonEmptyFile = false;
@ -56,7 +104,8 @@ namespace Aurora::Process
if (!pHandle->InitFromPath(createhandle))
{
return nullptr;
return {};
}
}
return this->MapFileByObject(pHandle, uOffset, uLength, mode, sectionLock);

View File

@ -141,17 +141,63 @@ namespace Aurora::Process
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
Aurora::IO::FS::EFileAdvisoryLockLevel sectionLock)
{
AuROString path2 { str };
bool bHooked {};
auto pHandle = AuIO::IOHandleShared();
if (!pHandle)
{
SysPushErrorMemory();
return nullptr;
return {};
}
AuIO::IIOHandle::HandleCreate createhandle(str);
{
AuFS::NamedMapRequest req;
AuOptional<AuUInt64> optOffset = uOffset;
AuOptional<AuUInt64> optLength = uLength;
AuOptional<AuFS::EFileOpenMode> opteMode = mode;
AuOptional<AuFS::EFileAdvisoryLockLevel> opteLock = sectionLock;
req.pPath = &path2;
req.pOpteMode = &opteMode;
req.pOptuFileMapOffset = &optOffset;
req.pOptuFileMapLength = &optLength;
req.pOptiAdjustStreamOffset = nullptr;
req.pOpteAdvisoryLevel = &opteLock;
req.pOptbLockEntireFile = nullptr;
req.pHandle = pHandle.get();
if (auto optResult = AuFS::GetCurrentPlatform()->HookNamedMap(req))
{
if (optResult.Value())
{
bHooked = true;
uOffset = optOffset.ValueOr(uOffset);
uLength = AuUInt { optLength.ValueOr(uLength) };
mode = opteMode.ValueOr(mode);
sectionLock = opteLock.ValueOr(sectionLock);
}
else
{
return {};
}
}
else
{
// nothing
}
}
if (bHooked && pHandle->IsValid())
{
// do nothing
}
else
{
AuIO::IIOHandle::HandleCreate createhandle(path2);
createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety;
createhandle.eMode = mode;
createhandle.bFailIfNonEmptyFile = false;
@ -160,10 +206,11 @@ namespace Aurora::Process
if (!pHandle->InitFromPath(createhandle))
{
return nullptr;
return {};
}
}
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, processLockLevel);
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, sectionLock);
}
AuSPtr<IProcessSectionMapView> ProcessSectionView::MapFileByObjectEx(AuUInt viewOffset,
@ -191,6 +238,11 @@ namespace Aurora::Process
return {};
}
if (processLockLevel != AuFS::EFileAdvisoryLockLevel::eNoSafety)
{
AuLogWarn("Section locking isn't implemented for POSIX yet!");
}
// TODO (Reece): lock garbage
int prot {};

View File

@ -13,6 +13,7 @@
#include "AuProcessSectionView.NT.hpp"
#include <Source/IO/IPC/AuIPCHandle.hpp>
#include <Windows.h>
#include <Aurora/IO/FS/Hook/FSPlatform.hpp>
namespace Aurora::Process
{
@ -310,14 +311,61 @@ namespace Aurora::Process
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel sectionLock)
{
AuROString path2 { str };
bool bHooked {};
auto pHandle = AuIO::IOHandleShared();
if (!pHandle)
{
SysPushErrorMemory();
return nullptr;
return {};
}
AuIO::IIOHandle::HandleCreate createhandle(str);
{
AuFS::NamedMapRequest req;
AuOptional<AuUInt64> optOffset = uOffset ;
AuOptional<AuUInt64> optLength = uLength ;
AuOptional<AuFS::EFileOpenMode> opteMode = mode ;
AuOptional<AuFS::EFileAdvisoryLockLevel> opteLock = sectionLock;
req.pPath = &path2;
req.pOpteMode = &opteMode;
req.pOptuFileMapOffset = &optOffset;
req.pOptuFileMapLength = &optLength;
req.pOptiAdjustStreamOffset = nullptr;
req.pOpteAdvisoryLevel = &opteLock;
req.pOptbLockEntireFile = nullptr;
req.pHandle = pHandle.get();
if (auto optResult = AuFS::GetCurrentPlatform()->HookNamedMap(req))
{
if (optResult.Value())
{
bHooked = true;
uOffset = optOffset.ValueOr(uOffset);
uLength = AuUInt { optLength.ValueOr(uLength) };
mode = opteMode.ValueOr(mode);
sectionLock = opteLock.ValueOr(sectionLock);
}
else
{
return {};
}
}
else
{
// nothing
}
}
if (bHooked && pHandle->IsValid())
{
// do nothing
}
else
{
AuIO::IIOHandle::HandleCreate createhandle(path2);
createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety;
createhandle.eMode = mode;
createhandle.bFailIfNonEmptyFile = false;
@ -326,7 +374,8 @@ namespace Aurora::Process
if (!pHandle->InitFromPath(createhandle))
{
return nullptr;
return {};
}
}
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, sectionLock);

View File

@ -173,16 +173,63 @@ namespace Aurora::Process
AuUInt64 uOffset,
AuUInt uLength,
Aurora::IO::FS::EFileOpenMode mode,
Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel)
Aurora::IO::FS::EFileAdvisoryLockLevel sectionLock)
{
AuROString path2 { str };
bool bHooked {};
auto pHandle = AuIO::IOHandleShared();
if (!pHandle)
{
SysPushErrorMemory();
return nullptr;
return {};
}
AuIO::IIOHandle::HandleCreate createhandle(str);
{
AuFS::NamedMapRequest req;
AuOptional<AuUInt64> optOffset = uOffset;
AuOptional<AuUInt64> optLength = uLength;
AuOptional<AuFS::EFileOpenMode> opteMode = mode;
AuOptional<AuFS::EFileAdvisoryLockLevel> opteLock = sectionLock;
req.pPath = &path2;
req.pOpteMode = &opteMode;
req.pOptuFileMapOffset = &optOffset;
req.pOptuFileMapLength = &optLength;
req.pOptiAdjustStreamOffset = nullptr;
req.pOpteAdvisoryLevel = &opteLock;
req.pOptbLockEntireFile = nullptr;
req.pHandle = pHandle.get();
if (auto optResult = AuFS::GetCurrentPlatform()->HookNamedMap(req))
{
if (optResult.Value())
{
bHooked = true;
uOffset = optOffset.ValueOr(uOffset);
uLength = AuUInt { optLength.ValueOr(uLength) };
mode = opteMode.ValueOr(mode);
sectionLock = opteLock.ValueOr(sectionLock);
}
else
{
return {};
}
}
else
{
// nothing
}
}
if (bHooked && pHandle->IsValid())
{
// do nothing
}
else
{
AuIO::IIOHandle::HandleCreate createhandle(path2);
createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety;
createhandle.eMode = mode;
createhandle.bFailIfNonEmptyFile = false;
@ -191,10 +238,11 @@ namespace Aurora::Process
if (!pHandle->InitFromPath(createhandle))
{
return nullptr;
return {};
}
}
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, processLockLevel);
return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, sectionLock);
}
AuSPtr<IProcessSectionMapView> ProcessSectionViewReserved::MapFileByObjectEx(AuUInt viewOffset,