├── .gitattributes ├── utility ├── saveerror.h ├── registry.h ├── config.h ├── cnvpath.h └── funcinfo.h ├── compile.bat ├── README.md ├── mod ├── kernel32 │ ├── lz.h │ ├── mutex.h │ ├── drive.h │ ├── ini.h │ ├── path.h │ ├── process.h │ ├── system.h │ └── file.h ├── imagehlp.h ├── shlwapi.h ├── msi.h ├── msvcrt.h ├── shell32 │ ├── icon.h │ ├── directory.h │ ├── exec.h │ └── folder.h ├── advapi32 │ ├── security.h │ └── reg.h ├── winmm.h ├── shlwapi │ ├── path.h │ └── reg.h ├── user32.h ├── psapi.h ├── shell32.h ├── version.h ├── advapi32.h ├── kernel32.h └── ole32.h ├── sandbox.cfg ├── include ├── path.h ├── directory.h └── string.h ├── LICENSE └── sandbox.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /utility/saveerror.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct SaveError 4 | { 5 | DWORD e; 6 | SaveError() 7 | { 8 | e = GetLastError(); 9 | } 10 | ~SaveError() 11 | { 12 | SetLastError(e); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /compile.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | if "%Platform%" == "x64" ( 3 | cl /Fesandbox64 /MTd /EHsc sandbox.cpp 4 | cl /Fesandbox64 /LDd /EHsc sandbox.cpp 5 | ) else if "%1" == "release" ( 6 | cl /Ox /EHsc /MT sandbox.cpp 7 | cl /Ox /EHsc /LD sandbox.cpp 8 | ) else ( 9 | cl /MTd /EHsc sandbox.cpp 10 | cl /LDd /EHsc sandbox.cpp 11 | ) 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sandbox 2 | Application virtualization tool for Windows 3 | 4 | registry and C:drive access redirect to virtual 5 | 6 | ## compile 7 | see compile.bat 8 | 9 | ## use 10 | in commandline 11 | `sandbox target` 12 | 13 | ## LICENSE 14 | 15 | ### sandbox.cpp and under mod directory 16 | LGPL v3 17 | 18 | ### others 19 | NO LICENSE 20 | -------------------------------------------------------------------------------- /mod/kernel32/lz.h: -------------------------------------------------------------------------------- 1 | static INT WINAPI LZOpenFile( 2 | const C *lpFileName, 3 | LPOFSTRUCT lpReOpenBuf, 4 | WORD wStyle 5 | ) 6 | { 7 | auto x = info(add_suffix("LZOpenFile"), lpFileName, lpReOpenBuf, wStyle); 8 | string f; 9 | if (wStyle == OF_READ) 10 | f = cnv::getExists(lpFileName).c_str(); 11 | else 12 | f = cnv::sp(lpFileName).c_str(); 13 | x.l(6, lpFileName, " > ", f); 14 | return x.result = orig(LZOpenFile)(f.c_str(), lpReOpenBuf, wStyle); 15 | } 16 | -------------------------------------------------------------------------------- /mod/imagehlp.h: -------------------------------------------------------------------------------- 1 | struct Imagehlp 2 | { 3 | static BOOL WINAPI MakeSureDirectoryPathExists(const char *DirPath) 4 | { 5 | auto x = info("MakeSureDirectoryPathExists", DirPath); 6 | auto sp = cnv::sp(DirPath); 7 | x.l(3, DirPath, " > ", sp); 8 | return x.result = orig(MakeSureDirectoryPathExists)(sp.c_str()); 9 | } 10 | 11 | static void Attach() 12 | { 13 | HMODULE imagehlp = LoadLibraryA("imagehlp"); 14 | reg(imagehlp, "MakeSureDirectoryPathExists", MakeSureDirectoryPathExists); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /sandbox.cfg: -------------------------------------------------------------------------------- 1 | #logfile = 1 2 | #console = 1 3 | #loglevel = 9 4 | #GetLogicalDrives = 0x00000004 5 | api-ms-win-core-file = l1-1-0 6 | api-ms-win-core-localregistry = l1-1-0 7 | api-ms-win-core-processenvironment = l1-1-0 8 | api-ms-win-core-sysinfo = l1-1-0 9 | api-ms-win-core-processthreads = l1-1-0 10 | api-ms-win-core-synch = l1-1-0 11 | api-ms-win-core-debug = l1-1-0 12 | api-ms-win-core-misc = l1-1-0 13 | api-ms-win-core-libraryloader = l1-1-0 14 | api-ms-win-security-base = l1-1-0 15 | #api-ms-win-core-localregistry = l1-1-0 16 | -------------------------------------------------------------------------------- /mod/shlwapi.h: -------------------------------------------------------------------------------- 1 | template struct Shlwapi 2 | { 3 | typedef std::basic_string string; 4 | 5 | #include "shlwapi/path.h" 6 | #include "shlwapi/reg.h" 7 | 8 | static void Attach() 9 | { 10 | HMODULE shlwapi = LoadLibraryA("shlwapi"); 11 | reg(shlwapi, add_suffix("PathFileExists"), PathFileExists); 12 | reg(shlwapi, add_suffix("PathIsDirectory"), PathIsDirectory); 13 | 14 | reg(shlwapi, add_suffix("SHSetValue"), SHSetValue); 15 | reg(shlwapi, add_suffix("SHDeleteKey"), SHDeleteKey); 16 | reg(shlwapi, add_suffix("SHDeleteValue"), SHDeleteValue); 17 | } 18 | }; 19 | //SHCreateStreamOnFile 20 | -------------------------------------------------------------------------------- /mod/msi.h: -------------------------------------------------------------------------------- 1 | template struct Msi 2 | { 3 | typedef std::basic_string string; 4 | 5 | static UINT WINAPI MsiInstallProduct( 6 | const C *szPackagePath, 7 | const C *szCommandLine 8 | ) 9 | { 10 | auto x = info(add_suffix("MsiInstallProduct"), szPackagePath, szCommandLine); 11 | x.l(-1, "unimplemented"); 12 | x.l(-1, szPackagePath, " szCommandLine=", szCommandLine); 13 | return x.result = orig(MsiInstallProduct)(szPackagePath, szCommandLine); 14 | } 15 | 16 | static void Attach() 17 | { 18 | HMODULE msi = LoadLibraryA("msi"); 19 | reg(msi, add_suffix("MsiInstallProduct"), MsiInstallProduct); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /mod/msvcrt.h: -------------------------------------------------------------------------------- 1 | struct MSVCRT 2 | { 3 | static FILE *fopen( 4 | const char *filename, 5 | const char *mode 6 | ) 7 | { 8 | auto x = info("fopen", filename, mode); 9 | std::string m = mode; 10 | if (m.find("w") == std::string::npos) 11 | { 12 | auto f = cnv::getExists(filename); 13 | x.l(6, filename, " > ", f); 14 | x.result = orig(fopen)(f.c_str(), mode); 15 | } 16 | else 17 | { 18 | auto sp = cnv::sp(filename); 19 | x.l(3, filename, " > ", sp); 20 | x.result = orig(fopen)(sp.c_str(), mode); 21 | } 22 | return x.result; 23 | } 24 | 25 | static void Attach() 26 | { 27 | HMODULE msvcrt = LoadLibraryA("MSVCRT"); 28 | reg(msvcrt, "fopen", fopen); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /mod/shell32/icon.h: -------------------------------------------------------------------------------- 1 | static HICON WINAPI ExtractIcon( 2 | HINSTANCE hInst, 3 | const C *lpszExeFileName, 4 | UINT nIconIndex 5 | ) 6 | { 7 | auto x = info(add_suffix("ExtractIcon"), hInst, lpszExeFileName, nIconIndex); 8 | auto ep = cnv::getExists(lpszExeFileName); 9 | x.l(7, lpszExeFileName, " > ", ep); 10 | return x.result = orig(ExtractIcon)(hInst, ep.c_str(), nIconIndex); 11 | } 12 | 13 | static UINT WINAPI ExtractIconEx( 14 | const C *lpszFile, 15 | int nIconIndex, 16 | HICON *phiconLarge, 17 | HICON *phiconSmall, 18 | UINT nIcons 19 | ) 20 | { 21 | auto x = info(add_suffix("ExtractIconEx"), lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons); 22 | auto ep = cnv::getExists(lpszFile); 23 | x.l(7, lpszFile, " > ", ep); 24 | return x.result = orig(ExtractIconEx)(ep.c_str(), nIconIndex, phiconLarge, phiconSmall, nIcons); 25 | } 26 | -------------------------------------------------------------------------------- /utility/registry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct RegistryValue 4 | { 5 | DWORD type; 6 | DWORD size; 7 | union 8 | { 9 | DWORD dword; 10 | __int64 qword; 11 | BYTE data[8]; 12 | char str[8]; 13 | }; 14 | }; 15 | struct RegistryEntry 16 | { 17 | std::wstring name; 18 | std::vector data; 19 | RegistryValue *value; 20 | RegistryEntry(const std::wstring &f) 21 | { 22 | name = Path::GetFileName(f); 23 | 24 | auto h = CreateFileW(f.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 25 | if (h == INVALID_HANDLE_VALUE) 26 | return; 27 | 28 | DWORD size = GetFileSize(h, NULL); 29 | data.resize(size); 30 | 31 | DWORD dw; 32 | ReadFile(h, &data[0], size, &dw, NULL); 33 | value = (RegistryValue*)&data[0]; 34 | 35 | CloseHandle(h); 36 | } 37 | }; 38 | struct RegistryKey 39 | { 40 | std::wstring path; 41 | RegistryKey(const std::wstring &p) 42 | { 43 | path = p; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /mod/advapi32/security.h: -------------------------------------------------------------------------------- 1 | static BOOL WINAPI GetFileSecurity( 2 | const C *lpFileName, 3 | SECURITY_INFORMATION RequestedInformation, 4 | PSECURITY_DESCRIPTOR pSecurityDescriptor, 5 | DWORD nLength, 6 | LPDWORD lpnLengthNeeded 7 | ) 8 | { 9 | auto x = info(add_suffix("GetFileSecurity"), lpFileName, RequestedInformation, pSecurityDescriptor, nLength, lpnLengthNeeded); 10 | auto f = cnv::getExists(lpFileName); 11 | x.l(9, lpFileName, " > ", f); 12 | return x.result = orig(GetFileSecurity)(f.c_str(), RequestedInformation, pSecurityDescriptor, nLength, lpnLengthNeeded); 13 | } 14 | 15 | static BOOL WINAPI SetFileSecurity( 16 | const C *lpFileName, 17 | SECURITY_INFORMATION SecurityInformation, 18 | PSECURITY_DESCRIPTOR pSecurityDescriptor 19 | ) 20 | { 21 | auto x = info(add_suffix("SetFileSecurity"), lpFileName, SecurityInformation, pSecurityDescriptor); 22 | auto f = cnv::sp(lpFileName); 23 | x.l(9, lpFileName, " > ", f); 24 | return x.result = orig(SetFileSecurity)(f.c_str(), SecurityInformation, pSecurityDescriptor); 25 | } 26 | -------------------------------------------------------------------------------- /mod/winmm.h: -------------------------------------------------------------------------------- 1 | template struct Winmm 2 | { 3 | typedef std::basic_string string; 4 | 5 | static HMMIO WINAPI mmioOpen( 6 | C *szFilename, 7 | LPMMIOINFO lpmmioinfo, 8 | DWORD dwOpenFlags 9 | ) 10 | { 11 | auto x = info(add_suffix("mmioOpen"), szFilename, lpmmioinfo, dwOpenFlags); 12 | x.l(9, "log only"); 13 | return x.result = orig(mmioOpen)(szFilename, lpmmioinfo, dwOpenFlags); 14 | } 15 | 16 | static BOOL WINAPI sndPlaySound( 17 | const C *lpszSound, 18 | UINT fuSound 19 | ) 20 | { 21 | auto x = info(add_suffix("sndPlaySound"), lpszSound, fuSound); 22 | string f; 23 | if (lpszSound) 24 | { 25 | f = cnv::getExists(lpszSound); 26 | lpszSound = f.c_str(); 27 | } 28 | return x.result = orig(sndPlaySound)(lpszSound, fuSound); 29 | } 30 | 31 | static void Attach() 32 | { 33 | HMODULE winmm = LoadLibraryA("winmm"); 34 | reg(winmm, add_suffix("mmioOpen"), mmioOpen); 35 | reg(winmm, add_suffix("sndPlaySound"), sndPlaySound); 36 | } 37 | 38 | static void Detach() 39 | { 40 | IAT(mmioOpen, orig(mmioOpen)); 41 | IAT(sndPlaySound, orig(sndPlaySound)); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /mod/shlwapi/path.h: -------------------------------------------------------------------------------- 1 | static BOOL WINAPI PathFileExists(const C *pszPath) 2 | { 3 | auto x = info(add_suffix("PathFileExists"), pszPath); 4 | auto sp = cnv::sp(pszPath); 5 | x.result = orig(PathFileExists)(sp.c_str()); 6 | if (x.result) 7 | { 8 | SaveError s; 9 | x.l(7, pszPath, " > ", sp); 10 | return x.result; 11 | } 12 | auto cp = cnv::cp(pszPath); 13 | x.result = orig(PathFileExists)(cp.c_str()); 14 | if (x.result) 15 | { 16 | SaveError s; 17 | x.l(7, pszPath, " > ", cp); 18 | return x.result; 19 | } 20 | SaveError s; 21 | x.l(7, pszPath, " > false"); 22 | return x.result; 23 | } 24 | 25 | static BOOL WINAPI PathIsDirectory(const C *pszPath) 26 | { 27 | auto x = info(add_suffix("PathIsDirectory"), pszPath); 28 | auto sp = cnv::sp(pszPath); 29 | x.result = orig(PathIsDirectory)(sp.c_str()); 30 | if (x.result) 31 | { 32 | SaveError s; 33 | x.l(7, pszPath, " > ", sp); 34 | return x.result; 35 | } 36 | auto cp = cnv::cp(pszPath); 37 | x.result = orig(PathIsDirectory)(cp.c_str()); 38 | SaveError s; 39 | if (x.result) 40 | { 41 | x.l(7, pszPath, " > ", cp); 42 | } 43 | else 44 | { 45 | x.l(7, pszPath, " > false"); 46 | } 47 | return x.result; 48 | } 49 | -------------------------------------------------------------------------------- /mod/shlwapi/reg.h: -------------------------------------------------------------------------------- 1 | static LSTATUS WINAPI SHSetValue( 2 | HKEY hkey, 3 | const C *pszSubKey, 4 | const C *pszValue, 5 | DWORD dwType, 6 | LPCVOID pvData, 7 | DWORD cbData 8 | ) 9 | { 10 | auto x = info(add_suffix("SHSetValue"), hkey, pszSubKey, pszValue, dwType, pvData, cbData); 11 | HKEY key; 12 | x.result = Advapi32::RegCreateKeyEx(hkey, pszSubKey, 0, NULL, 0, KEY_WRITE, NULL, &key, NULL); 13 | if (x.result == ERROR_SUCCESS) 14 | { 15 | Advapi32::RegSetValueEx(key, pszValue, 0, dwType, (BYTE*)pvData, cbData); 16 | Advapi32::RegCloseKey(key); 17 | } 18 | return x.result; 19 | } 20 | 21 | static LSTATUS WINAPI SHDeleteKey( 22 | HKEY hkey, 23 | const C *pszSubKey 24 | ) 25 | { 26 | auto x = info(add_suffix("SHDeleteKey"), hkey, pszSubKey); 27 | return x.result = Advapi32::RegDeleteKeyEx(hkey, pszSubKey, 0, 0); 28 | } 29 | 30 | static LSTATUS WINAPI SHDeleteValue( 31 | HKEY hkey, 32 | const C *pszSubKey, 33 | const C *pszValue 34 | ) 35 | { 36 | auto x = info(add_suffix("SHDeleteValue"), hkey, pszSubKey, pszValue); 37 | HKEY key; 38 | x.result = Advapi32::RegOpenKeyEx(hkey, pszSubKey, 0, KEY_WRITE, &key); 39 | if (x.result == ERROR_SUCCESS) 40 | { 41 | Advapi32::RegDeleteValue(key, pszValue); 42 | Advapi32::RegCloseKey(key); 43 | } 44 | return x.result; 45 | } 46 | 47 | /* 48 | SHCopyKey 49 | SHGetValue 50 | SHRegOpenUSKey 51 | SHRegWriteUSValue 52 | SHRegSetUSValue 53 | SHRegSetPath 54 | */ 55 | -------------------------------------------------------------------------------- /mod/user32.h: -------------------------------------------------------------------------------- 1 | template struct User32 2 | { 3 | typedef std::basic_string string; 4 | 5 | static HANDLE WINAPI LoadImage( 6 | HINSTANCE hinst, 7 | const C *lpszName, 8 | UINT uType, 9 | int cxDesired, 10 | int cyDesired, 11 | UINT fuLoad 12 | ) 13 | { 14 | auto x = info(add_suffix("LoadImage"), hinst, lpszName, uType, cxDesired, cyDesired, fuLoad); 15 | if ((pointer_size_uint)lpszName >> 16) 16 | { 17 | auto f = cnv::getExists(lpszName); 18 | x.result = orig(LoadImage)(hinst, f.c_str(), uType, cxDesired, cyDesired, fuLoad); 19 | } 20 | else 21 | { 22 | x.result = orig(LoadImage)(hinst, lpszName, uType, cxDesired, cyDesired, fuLoad); 23 | } 24 | return x.result; 25 | } 26 | 27 | static HCURSOR WINAPI LoadCursorFromFile( 28 | const C *lpFileName 29 | ) 30 | { 31 | auto x = info(add_suffix("LoadCursorFromFile"), lpFileName); 32 | if ((pointer_size_uint)lpFileName >> 16) 33 | { 34 | auto f = cnv::getExists(lpFileName); 35 | x.result = orig(LoadCursorFromFile)(f.c_str()); 36 | } 37 | else 38 | { 39 | x.result = orig(LoadCursorFromFile)(lpFileName); 40 | } 41 | return x.result; 42 | } 43 | 44 | static BOOL WINAPI SystemParametersInfo( 45 | UINT uiAction, 46 | UINT uiParam, 47 | PVOID pvParam, 48 | UINT fWinIni 49 | ) 50 | { 51 | auto x = info(add_suffix("SystemParametersInfo"), uiAction, uiParam, pvParam, fWinIni); 52 | return x.result = orig(SystemParametersInfo)(uiAction, uiParam, pvParam, fWinIni); 53 | } 54 | 55 | static void Attach() 56 | { 57 | HMODULE user32 = LoadLibraryA("user32"); 58 | reg(user32, add_suffix("LoadImage"), LoadImage); 59 | reg(user32, add_suffix("LoadCursorFromFile"), LoadCursorFromFile); 60 | //reg(user32, add_suffix("SystemParametersInfo"), SystemParametersInfo); 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /mod/kernel32/mutex.h: -------------------------------------------------------------------------------- 1 | static HANDLE WINAPI CreateMutex( 2 | LPSECURITY_ATTRIBUTES lpMutexAttributes, 3 | BOOL bInitialOwner, 4 | const C *lpName 5 | ) 6 | { 7 | auto x = info(add_suffix("CreateMutex"), lpMutexAttributes, bInitialOwner, lpName); 8 | if (lpName) 9 | { 10 | std::string s = String::tstr(lpName); 11 | if (!String::starts_with(s, "Local")) 12 | { 13 | auto n = lpName + cnv::mutex; 14 | return x.result = orig(CreateMutex)(lpMutexAttributes, bInitialOwner, n.c_str()); 15 | } 16 | } 17 | return x.result = orig(CreateMutex)(lpMutexAttributes, bInitialOwner, lpName); 18 | } 19 | static HANDLE WINAPI CreateMutexEx( 20 | LPSECURITY_ATTRIBUTES lpMutexAttributes, 21 | const C *lpName, 22 | DWORD dwFlags, 23 | DWORD dwDesiredAccess 24 | ) 25 | { 26 | auto x = info(add_suffix("CreateMutexEx"), lpMutexAttributes, lpName, dwFlags, dwDesiredAccess); 27 | if (lpName) 28 | { 29 | std::string s = String::tstr(lpName); 30 | if (!String::starts_with(s, "Local")) 31 | { 32 | auto n = lpName + cnv::mutex; 33 | return x.result = orig(CreateMutexEx)(lpMutexAttributes, n.c_str(), dwFlags, dwDesiredAccess); 34 | } 35 | } 36 | return x.result = orig(CreateMutexEx)(lpMutexAttributes, lpName, dwFlags, dwDesiredAccess); 37 | } 38 | static HANDLE WINAPI OpenMutex( 39 | DWORD dwDesiredAccess, 40 | BOOL bInheritHandle, 41 | const C *lpName 42 | ) 43 | { 44 | auto x = info(add_suffix("OpenMutex"), dwDesiredAccess, bInheritHandle, lpName); 45 | if (lpName) 46 | { 47 | std::string s = String::tstr(lpName); 48 | if (!String::starts_with(s, "Local")) 49 | { 50 | auto n = lpName + cnv::mutex; 51 | return x.result = orig(OpenMutex)(dwDesiredAccess, bInheritHandle, n.c_str()); 52 | } 53 | } 54 | return x.result = orig(OpenMutex)(dwDesiredAccess, bInheritHandle, lpName); 55 | } 56 | -------------------------------------------------------------------------------- /mod/shell32/directory.h: -------------------------------------------------------------------------------- 1 | static int WINAPI SHCreateDirectoryEx( 2 | HWND hwnd, 3 | const C *pszPath, 4 | const SECURITY_ATTRIBUTES *psa 5 | ) 6 | { 7 | auto x = info(add_suffix("SHCreateDirectoryEx"), hwnd, pszPath, psa); 8 | auto sp = cnv::sp(pszPath); 9 | x.l(3, pszPath, " > ", sp); 10 | x.result = orig(SHCreateDirectoryEx)(hwnd, sp.c_str(), psa); 11 | return x.result; 12 | } 13 | 14 | static int WINAPI SHCreateDirectory( 15 | HWND hwnd, 16 | PCWSTR pszPath // only W 17 | ) 18 | { 19 | auto x = info("SHCreateDirectory", hwnd, pszPath); 20 | return x.result = Shell32::SHCreateDirectoryEx(hwnd, pszPath, NULL); 21 | } 22 | 23 | static HRESULT WINAPI SHPathPrepareForWrite( 24 | HWND hwnd, 25 | IUnknown *punkEnableModless, 26 | const C *pszPath, 27 | DWORD dwFlags 28 | ) 29 | { 30 | auto x = info(add_suffix("SHCreateDirectoryEx"), hwnd, punkEnableModless, pszPath, dwFlags); 31 | auto sp = cnv::sp(pszPath); 32 | return x.result = orig(SHPathPrepareForWrite)(hwnd, punkEnableModless, sp.c_str(), dwFlags); 33 | } 34 | 35 | static DWORD_PTR WINAPI SHGetFileInfo( 36 | const C *pszPath, 37 | DWORD dwFileAttributes, 38 | ShellFileInfo *psfi, 39 | UINT cbFileInfo, 40 | UINT uFlags 41 | ) 42 | { 43 | auto x = info(add_suffix("SHGetFileInfo"), pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags); 44 | auto f = cnv::getExists(pszPath); 45 | return x.result = orig(SHGetFileInfo)(f.c_str(), dwFileAttributes, psfi, cbFileInfo, uFlags); 46 | } 47 | 48 | static int WINAPI SHFileOperation(ShellFileOperation *lpFileOp) 49 | { 50 | auto x = info(add_suffix("SHFileOperation"), lpFileOp); 51 | ShellFileOperation sfo = *lpFileOp; 52 | string from = cnv::getExists(lpFileOp->pFrom); 53 | sfo.pFrom = from.c_str(); 54 | string to; 55 | if (lpFileOp->pTo) 56 | { 57 | to = cnv::sp(lpFileOp->pTo); 58 | sfo.pTo = to.c_str(); 59 | x.l(3, lpFileOp->wFunc, ":", lpFileOp->pFrom, " > ", from, " > ", lpFileOp->pTo, " > ", to); 60 | } 61 | else 62 | { 63 | x.l(3, lpFileOp->wFunc, ":", lpFileOp->pFrom, " > ", from); 64 | } 65 | x.result = orig(SHFileOperation)(&sfo); 66 | lpFileOp->fAnyOperationsAborted = sfo.fAnyOperationsAborted; 67 | lpFileOp->hNameMappings = sfo.hNameMappings; 68 | return x.result; 69 | } 70 | //SHGetDiskFreeSpaceEx 71 | //SHGetNewLinkInfo 72 | -------------------------------------------------------------------------------- /mod/psapi.h: -------------------------------------------------------------------------------- 1 | template struct Psapi 2 | { 3 | typedef std::basic_string string; 4 | 5 | static DWORD WINAPI GetModuleBaseName( 6 | HANDLE hProcess, 7 | HMODULE hModule, 8 | C *lpBaseName, 9 | DWORD nSize 10 | ) 11 | { 12 | auto x = info(add_suffix("GetModuleBaseName"), hProcess, hModule, lpBaseName, nSize); 13 | x.result = orig(GetModuleBaseName)(hProcess, hModule, lpBaseName, nSize); 14 | SaveError s; 15 | if (x.result) 16 | { 17 | auto vp = cnv::vp(lpBaseName); 18 | x.l(7, lpBaseName, " > ", vp); 19 | x.result = String::cpy(lpBaseName, vp, nSize); 20 | } 21 | return x.result; 22 | } 23 | 24 | static DWORD WINAPI GetModuleFileNameEx( 25 | HANDLE hProcess, 26 | HMODULE hModule, 27 | C *lpFilename, 28 | DWORD nSize 29 | ) 30 | { 31 | auto x = info(add_suffix("GetModuleFileNameEx"), hProcess, hModule, lpFilename, nSize); 32 | x.result = orig(GetModuleFileNameEx)(hProcess, hModule, lpFilename, nSize); 33 | SaveError s; 34 | if (x.result) 35 | { 36 | auto vp = cnv::vp(lpFilename); 37 | x.l(7, lpFilename, " > ", vp); 38 | x.result = String::cpy(lpFilename, vp, nSize); 39 | } 40 | return x.result; 41 | } 42 | 43 | static DWORD WINAPI GetMappedFileName( 44 | HANDLE hProcess, 45 | LPVOID lpv, 46 | C *lpFilename, 47 | DWORD nSize 48 | ) 49 | { 50 | auto x = info(add_suffix("GetMappedFileName"), hProcess, lpv, lpFilename, nSize); 51 | x.result = orig(GetMappedFileName)(hProcess, lpv, lpFilename, nSize); 52 | SaveError s; 53 | if (x.result) 54 | { 55 | auto vp = cnv::vp(lpFilename); 56 | x.l(7, lpFilename, " > ", vp); 57 | x.result = String::cpy(lpFilename, vp, nSize); 58 | } 59 | return x.result; 60 | } 61 | 62 | static void Attach() 63 | { 64 | if (config.dword("psapi")) 65 | { 66 | HMODULE psapi = LoadLibraryA("psapi"); 67 | reg(psapi, add_suffix("GetModuleBaseName"), GetModuleBaseName); 68 | reg(psapi, add_suffix("GetModuleFileNameEx"), GetModuleFileNameEx); 69 | reg(psapi, add_suffix("GetMappedFileName"), GetMappedFileName); 70 | } 71 | else 72 | { 73 | HMODULE kernel32 = GetModuleHandleA("kernel32"); 74 | reg(kernel32, add_suffix("K32GetModuleBaseName"), GetModuleBaseName); 75 | reg(kernel32, add_suffix("K32GetModuleFileNameEx"), GetModuleFileNameEx); 76 | reg(kernel32, add_suffix("K32GetMappedFileName"), GetMappedFileName); 77 | } 78 | } 79 | }; 80 | //GetProcessImageFileName 81 | -------------------------------------------------------------------------------- /mod/shell32.h: -------------------------------------------------------------------------------- 1 | template struct Shell32 2 | { 3 | typedef std::basic_string string; 4 | template 5 | struct subtypes 6 | { 7 | typedef SHELLEXECUTEINFOA ShellExecuteInfo; 8 | typedef SHFILEINFOA ShellFileInfo; 9 | typedef SHFILEOPSTRUCTA ShellFileOperation; 10 | }; 11 | template<> 12 | struct subtypes 13 | { 14 | typedef SHELLEXECUTEINFOW ShellExecuteInfo; 15 | typedef SHFILEINFOW ShellFileInfo; 16 | typedef SHFILEOPSTRUCTW ShellFileOperation; 17 | }; 18 | typedef typename subtypes::ShellExecuteInfo ShellExecuteInfo; 19 | typedef typename subtypes::ShellFileInfo ShellFileInfo; 20 | typedef typename subtypes::ShellFileOperation ShellFileOperation; 21 | 22 | #include "shell32/folder.h" 23 | #include "shell32/directory.h" 24 | #include "shell32/exec.h" 25 | #include "shell32/icon.h" 26 | 27 | static void Attach() 28 | { 29 | HMODULE shell32 = LoadLibraryA("shell32"); 30 | reg(shell32, add_suffix("SHGetFolderPath"), SHGetFolderPath); 31 | reg(shell32, add_suffix("SHGetFolderPathAndSubDir"), SHGetFolderPathAndSubDir); 32 | reg(shell32, add_suffix("SHGetSpecialFolderPath"), SHGetSpecialFolderPath); 33 | 34 | reg(shell32, "SHGetSpecialFolderLocation", SHGetSpecialFolderLocation); 35 | reg(shell32, "SHGetFolderLocation", SHGetFolderLocation); 36 | reg(shell32, "SHGetFolderPathEx", SHGetFolderPathEx); 37 | reg(shell32, "SHGetKnownFolderPath", SHGetKnownFolderPath); 38 | reg(shell32, "SHGetKnownFolderIDList", SHGetKnownFolderIDList); 39 | 40 | reg(shell32, add_suffix("SHGetPathFromIDList"), SHGetPathFromIDList); 41 | reg(shell32, "SHGetPathFromIDListEx", SHGetPathFromIDListEx); 42 | reg(shell32, "SHILCreateFromPath", SHILCreateFromPath); 43 | reg(shell32, add_suffix("ILCreateFromPath"), ILCreateFromPath); 44 | reg(shell32, "SHSimpleIDListFromPath", SHSimpleIDListFromPath); 45 | 46 | reg(shell32, "SHGetDesktopFolder", SHGetDesktopFolder); 47 | 48 | reg(shell32, add_suffix("SHCreateDirectoryEx"), SHCreateDirectoryEx); 49 | reg(shell32, "SHCreateDirectory", SHCreateDirectory); 50 | reg(shell32, add_suffix("SHPathPrepareForWrite"), SHPathPrepareForWrite); 51 | reg(shell32, add_suffix("SHGetFileInfo"), SHGetFileInfo); 52 | reg(shell32, add_suffix("SHFileOperation"), SHFileOperation); 53 | 54 | reg(shell32, add_suffix("ShellExecuteEx"), ShellExecuteEx); 55 | reg(shell32, add_suffix("ShellExecute"), ShellExecute); 56 | 57 | reg(shell32, add_suffix("ExtractIcon"), ExtractIcon); 58 | reg(shell32, add_suffix("ExtractIconEx"), ExtractIconEx); 59 | } 60 | }; 61 | //SHParseDisplayName 62 | //SHGetSettings 63 | -------------------------------------------------------------------------------- /utility/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "include/string.h" 7 | 8 | class Config 9 | { 10 | public: 11 | typedef std::string string; 12 | std::map config; 13 | Config() 14 | { 15 | config["default"] = "value"; 16 | 17 | #ifdef _DEBUG 18 | config["logfile"] = "1"; 19 | config["console"] = "1"; 20 | config["loglevel"] = "5"; 21 | #endif 22 | 23 | config["username"] = "SANDBOX"; 24 | config["computername"] = "SANDBOX"; 25 | config["reg"] = "registry"; 26 | 27 | config["drive"] = "C:"; 28 | config["virtual_user_directory"] = "C:\\Users\\SANDBOX"; 29 | 30 | config["verifyversioninfo"] = "1"; 31 | } 32 | static Config Read(const string &file) 33 | { 34 | Config cfg; 35 | auto h = CreateFile(file.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 36 | if (h == INVALID_HANDLE_VALUE) 37 | return cfg; 38 | DWORD filesize = GetFileSize(h, NULL); 39 | string buffer(filesize, 0); 40 | DWORD NumberOfBytesRead; 41 | ReadFile(h, &buffer[0], filesize, &NumberOfBytesRead, NULL); 42 | buffer.resize(NumberOfBytesRead); 43 | auto list = String::split(buffer); 44 | 45 | for (auto &line : list) 46 | { 47 | auto x = String::split(line, "="); 48 | if (x.size() < 2) 49 | continue; 50 | cfg.config[String::tolower(String::trim(x[0]))] = String::trim(x[1]); 51 | } 52 | 53 | return cfg; 54 | } 55 | static DWORD parseNum(const string &s) 56 | { 57 | if (String::starts_with(s, "0x")) 58 | { 59 | return std::stoi(s.substr(2), nullptr, 16); 60 | } 61 | else 62 | { 63 | return std::stoi(s); 64 | } 65 | } 66 | bool exists(const string &s) 67 | { 68 | return config.count(String::tolower(s)); 69 | } 70 | DWORD dword(const string &s, DWORD def = 0) 71 | { 72 | auto l = String::tolower(s); 73 | if (config.count(l)) 74 | { 75 | return parseNum(config[l]); 76 | } 77 | return def; 78 | } 79 | int Int(const string &s, int def = 0) 80 | { 81 | auto l = String::tolower(s); 82 | if (config.count(l)) 83 | { 84 | return parseNum(config[l]); 85 | } 86 | return def; 87 | } 88 | string str(const string &s, const string &def = "") 89 | { 90 | auto l = String::tolower(s); 91 | if (config.count(l)) 92 | { 93 | return config[l]; 94 | } 95 | return def; 96 | } 97 | std::wstring wstr(const string &s, const std::wstring &def = L"") 98 | { 99 | auto l = String::tolower(s); 100 | if (config.count(l)) 101 | { 102 | return String::tstr(config[l]); 103 | } 104 | return def; 105 | } 106 | }; 107 | -------------------------------------------------------------------------------- /mod/version.h: -------------------------------------------------------------------------------- 1 | template struct Version 2 | { 3 | typedef std::basic_string string; 4 | 5 | static BOOL WINAPI GetFileVersionInfo( 6 | const C *lptstrFilename, 7 | DWORD dwHandle, 8 | DWORD dwLen, 9 | LPVOID lpData 10 | ) 11 | { 12 | auto x = info(add_suffix("GetFileVersionInfo"), lptstrFilename, dwHandle, dwLen, lpData); 13 | auto ep = cnv::getExists(lptstrFilename); 14 | x.l(5, lptstrFilename, " > ", ep); 15 | x.result = orig(GetFileVersionInfo)(ep.c_str(), dwHandle, dwLen, lpData); 16 | return x.result; 17 | } 18 | static BOOL WINAPI GetFileVersionInfoEx( 19 | DWORD dwFlags, 20 | const C *lpwstrFilename, 21 | DWORD dwHandle, 22 | DWORD dwLen, 23 | LPVOID lpData 24 | ) 25 | { 26 | auto x = info(add_suffix("GetFileVersionInfoEx"), dwFlags, lpwstrFilename, dwHandle, dwLen, lpData); 27 | auto ep = cnv::getExists(lpwstrFilename); 28 | x.l(5, lpwstrFilename, " > ", ep); 29 | x.result = orig(GetFileVersionInfoEx)(dwFlags, ep.c_str(), dwHandle, dwLen, lpData); 30 | return x.result; 31 | } 32 | static DWORD WINAPI GetFileVersionInfoSize( 33 | const C *lptstrFilename, 34 | LPDWORD lpdwHandle 35 | ) 36 | { 37 | auto x = info(add_suffix("GetFileVersionInfoSize"), lptstrFilename, lpdwHandle); 38 | auto ep = cnv::getExists(lptstrFilename); 39 | x.l(5, lptstrFilename, " > ", ep); 40 | x.result = orig(GetFileVersionInfoSize)(ep.c_str(), lpdwHandle); 41 | return x.result; 42 | } 43 | static DWORD WINAPI GetFileVersionInfoSizeEx( 44 | DWORD dwFlags, 45 | const C *lpwstrFilename, 46 | LPDWORD lpdwHandle 47 | ) 48 | { 49 | auto x = info(add_suffix("GetFileVersionInfoSizeEx"), dwFlags, lpwstrFilename, lpdwHandle); 50 | auto ep = cnv::getExists(lpwstrFilename); 51 | x.l(5, lpwstrFilename, " > ", ep); 52 | x.result = orig(GetFileVersionInfoSizeEx)(dwFlags, ep.c_str(), lpdwHandle); 53 | return x.result; 54 | } 55 | 56 | static BOOL WINAPI VerQueryValue( 57 | const LPVOID pBlock, 58 | const C *lpSubBlock, 59 | LPVOID *lplpBuffer, 60 | PUINT puLen 61 | ) 62 | { 63 | auto x = info(add_suffix("VerQueryValue"), pBlock, lpSubBlock, lplpBuffer, puLen); 64 | x.l(9, "log only"); 65 | return x.result = orig(VerQueryValue)(pBlock, lpSubBlock, lplpBuffer, puLen); 66 | } 67 | 68 | static void Attach() 69 | { 70 | HMODULE version = LoadLibraryA("version"); 71 | //Api-ms-win-core-version-l1-1-0? 72 | reg(version, add_suffix("GetFileVersionInfo"), GetFileVersionInfo); 73 | reg(version, add_suffix("GetFileVersionInfoEx"), GetFileVersionInfoEx); 74 | reg(version, add_suffix("GetFileVersionInfoSize"), GetFileVersionInfoSize); 75 | reg(version, add_suffix("GetFileVersionInfoSizeEx"), GetFileVersionInfoSizeEx); 76 | reg(version, add_suffix("VerQueryValue"), VerQueryValue); 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /utility/cnvpath.h: -------------------------------------------------------------------------------- 1 | enum class PathType 2 | { 3 | Sandbox, 4 | Virtual, 5 | System, 6 | Others, 7 | }; 8 | template 9 | struct cnv 10 | { 11 | typedef std::basic_string string; 12 | static string sandbox; 13 | static string drive; 14 | static string vuser; 15 | static string suser; 16 | static string mutex; 17 | static string sp(const string &path) 18 | { 19 | #ifdef NO_REDIRECT_USERHOME 20 | return String::replace(path, drive, sandbox, true, false); 21 | #else 22 | auto str = String::replace(path, suser, vuser, true, false); 23 | return String::replace(str, drive, sandbox, true, false); 24 | #endif 25 | } 26 | static string vp(const string &path) 27 | { 28 | #ifdef NO_REDIRECT_USERHOME 29 | return String::replace(path, sandbox, drive, true, false); 30 | #else 31 | auto str = String::replace(path, suser, vuser, true, false); 32 | return String::replace(str, sandbox, drive, true, false); 33 | #endif 34 | } 35 | static string cp(const string &path) 36 | { 37 | #ifdef NO_REDIRECT_USERHOME 38 | return String::replace(path, sandbox, drive, true, false); 39 | #else 40 | auto str = String::replace(path, sandbox, drive, true, false); 41 | return String::replace(str, vuser, suser, true, false); 42 | #endif 43 | } 44 | static bool is(const string &path, PathType pt) 45 | { 46 | auto lp = String::tolower(path); 47 | switch (pt) 48 | { 49 | case PathType::Sandbox: 50 | return (lp.find(sandbox) != string::npos); 51 | case PathType::Virtual: 52 | if (lp.find(suser) != string::npos) 53 | return false; 54 | return (lp.find(drive) != string::npos) 55 | case PathType::System: 56 | if (lp.find(vuser) != string::npos) 57 | return false; 58 | return (lp.find(drive) != string::npos) 59 | case Others: 60 | if (lp.find(sandbox) != string::npos) 61 | return false; 62 | if (lp.find(drive) != string::npos) 63 | return false; 64 | return true; 65 | } 66 | return false; 67 | } 68 | static string to(const string &path, PathType pt) 69 | { 70 | switch (pt) 71 | { 72 | case PathType::Sandbox: 73 | return sp(path); 74 | case PathType::Virtual: 75 | return vp(path); 76 | case PathType::System: 77 | return cp(path); 78 | } 79 | return path; 80 | } 81 | static string getExists(const string &path) 82 | { 83 | auto sandbox_path = to(path, PathType::Sandbox); 84 | if (orig(Kernel32::GetFileAttributes)(sandbox_path.c_str()) != -1) 85 | { 86 | return sandbox_path; 87 | } 88 | auto sys_path = to(path, PathType::System); 89 | auto attr = orig(Kernel32::GetFileAttributes)(sys_path.c_str()); 90 | if (attr != -1) 91 | { 92 | if (attr & FILE_ATTRIBUTE_DIRECTORY) 93 | { 94 | log(1, "getExists:CreateSandboxDirectory:", sandbox_path); 95 | Shell32::SHCreateDirectoryEx(NULL, sandbox_path.c_str(), NULL); 96 | } 97 | else 98 | { 99 | auto d = Path::GetDirectoryName(sandbox_path); 100 | auto dattr = orig(Kernel32::GetFileAttributes)(d.c_str()); 101 | if (dattr == -1) 102 | { 103 | log(1, "getExists:CreateSandboxDirectory:", d); 104 | Shell32::SHCreateDirectoryEx(NULL, d.c_str(), NULL); 105 | } 106 | } 107 | return sys_path; 108 | } 109 | return path; 110 | } 111 | }; 112 | -------------------------------------------------------------------------------- /utility/funcinfo.h: -------------------------------------------------------------------------------- 1 | namespace FuncInfo 2 | { 3 | template 4 | struct Info 5 | { 6 | std::string name; 7 | R result; 8 | Info(const std::string &n, const std::string &args = "") 9 | { 10 | name = n; 11 | result = R(); 12 | log(9, name, "(", args, "){\n"); 13 | } 14 | void l(int loglevel, const std::string &str) 15 | { 16 | log(loglevel, name, ":", str); 17 | } 18 | template 19 | void l(int ll, Args... args) 20 | { 21 | l(ll, String::concat(args...)); 22 | } 23 | ~Info() 24 | { 25 | log(9, name, "} result=", hex(result, sizeof(R) * 2)); 26 | } 27 | }; 28 | 29 | std::string hex(pointer_size_uint h, int d = sizeof(pointer_size_uint) * 2) 30 | { 31 | std::string s; 32 | for (int i = 0; i < d; i++) 33 | { 34 | int n = (h >> (i*4)) & 0xF; 35 | if (n < 10) 36 | s = char('0' + n) + s; 37 | else 38 | s = char('A' + n - 10) + s; 39 | } 40 | return s; 41 | } 42 | std::string hex(const void *p, int d = sizeof(void*) * 2) 43 | { 44 | return hex((pointer_size_uint)p, d); 45 | } 46 | 47 | std::string guid(const GUID &g) 48 | { 49 | return 50 | hex(g.Data1, 8) + "-" + 51 | hex(g.Data2, 4) + "-" + 52 | hex(g.Data3, 4) + "-" + 53 | hex(g.Data4[0], 2) + 54 | hex(g.Data4[1], 2) + "-" + 55 | hex(g.Data4[2], 2) + 56 | hex(g.Data4[3], 2) + 57 | hex(g.Data4[4], 2) + 58 | hex(g.Data4[5], 2) + 59 | hex(g.Data4[6], 2) + 60 | hex(g.Data4[7], 2) 61 | ; 62 | } 63 | 64 | std::string Arg(int i) 65 | { 66 | return std::to_string(i); 67 | } 68 | 69 | std::string Arg(UINT u) 70 | { 71 | return hex(u); 72 | } 73 | 74 | std::string Arg(DWORD d) 75 | { 76 | return hex(d); 77 | } 78 | 79 | std::string Arg(DWORDLONG d) 80 | { 81 | return hex(d); 82 | } 83 | 84 | std::string Arg(const char *s) 85 | { 86 | if ((pointer_size_uint)s >> 16) 87 | { 88 | return String::concat(hex(s), "=", s); 89 | } 90 | else 91 | { 92 | return hex(s); 93 | } 94 | } 95 | 96 | std::string Arg(const wchar_t *s) 97 | { 98 | if ((pointer_size_uint)s >> 16) 99 | { 100 | return String::concat(hex(s), "=", s); 101 | } 102 | else 103 | { 104 | return hex(s); 105 | } 106 | } 107 | 108 | std::string Arg(char *s) 109 | { 110 | return hex(s); 111 | } 112 | 113 | std::string Arg(wchar_t *s) 114 | { 115 | return hex(s); 116 | } 117 | 118 | std::string Arg(const void *p) 119 | { 120 | return hex(p); 121 | } 122 | 123 | std::string Arg(const GUID &g) 124 | { 125 | return guid(g); 126 | } 127 | std::string Arg(const GUID *g) 128 | { 129 | if (g == NULL) 130 | return "(NULL)"; 131 | else 132 | return guid(*g); 133 | } 134 | 135 | template 136 | std::string Arguments(T t) 137 | { 138 | return Arg(t); 139 | } 140 | template 141 | std::string Arguments(T t, Args... args) 142 | { 143 | return Arg(t) + "," + Arguments(args...); 144 | } 145 | } 146 | 147 | template 148 | FuncInfo::Info info(const std::string &n, Args... args) 149 | { 150 | return FuncInfo::Info(n, FuncInfo::Arguments(args...)); 151 | } 152 | 153 | template 154 | FuncInfo::Info info(const std::string &n) 155 | { 156 | return FuncInfo::Info(n, ""); 157 | } 158 | -------------------------------------------------------------------------------- /mod/kernel32/drive.h: -------------------------------------------------------------------------------- 1 | static DWORD WINAPI GetLogicalDrives() 2 | { 3 | auto x = info("GetLogicalDrives"); 4 | if (config.exists("GetLogicalDrives")) 5 | x.result = config.dword("GetLogicalDrives"); 6 | else 7 | x.result = orig(GetLogicalDrives)(); 8 | return x.result; 9 | } 10 | 11 | static DWORD WINAPI GetLogicalDriveStrings( 12 | DWORD nBufferLength, 13 | C *lpBuffer 14 | ) 15 | { 16 | auto x = info(add_suffix("GetLogicalDriveStrings")); 17 | auto drives = GetLogicalDrives(); 18 | DWORD p = 0; 19 | for (int i = 0; i < 26; i++) 20 | { 21 | if (drives & (1 << i)) 22 | { 23 | if (p < (nBufferLength - 3)) 24 | { 25 | lpBuffer[p++] = C('a' + i); 26 | lpBuffer[p++] = C(':'); 27 | lpBuffer[p++] = C('\\'); 28 | lpBuffer[p++] = 0; 29 | } 30 | else 31 | { 32 | p += 4; 33 | } 34 | } 35 | } 36 | if (p <= nBufferLength) 37 | lpBuffer[p] = 0; 38 | return x.result = p; 39 | } 40 | 41 | static UINT WINAPI GetDriveType(const C *lpRootPathName) 42 | { 43 | auto x = info(add_suffix("GetDriveType"), lpRootPathName); 44 | x.result = orig(GetDriveType)(lpRootPathName); 45 | return x.result; 46 | //todo 47 | } 48 | 49 | static BOOL WINAPI GetDiskFreeSpace( 50 | const C *lpRootPathName, 51 | LPDWORD lpSectorsPerCluster, 52 | LPDWORD lpBytesPerSector, 53 | LPDWORD lpNumberOfFreeClusters, 54 | LPDWORD lpTotalNumberOfClusters 55 | ) 56 | { 57 | auto x = info(add_suffix("GetDiskFreeSpace"), lpRootPathName, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters); 58 | if (lpRootPathName) 59 | { 60 | auto sp = cnv::sp(lpRootPathName); 61 | x.result = orig(GetDiskFreeSpace)(sp.c_str(), lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters); 62 | } 63 | else 64 | { 65 | x.result = orig(GetDiskFreeSpace)(lpRootPathName, lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters); 66 | } 67 | return x.result; 68 | } 69 | 70 | static BOOL WINAPI GetDiskFreeSpaceEx( 71 | const C *lpDirectoryName, 72 | PULARGE_INTEGER lpFreeBytesAvailable, 73 | PULARGE_INTEGER lpTotalNumberOfBytes, 74 | PULARGE_INTEGER lpTotalNumberOfFreeBytes 75 | ) 76 | { 77 | auto x = info(add_suffix("GetDiskFreeSpaceEx"), lpDirectoryName, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes); 78 | if (lpDirectoryName) 79 | { 80 | auto sp = cnv::sp(lpDirectoryName); 81 | x.result = orig(GetDiskFreeSpaceEx)(sp.c_str(), lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes); 82 | } 83 | else 84 | { 85 | x.result = orig(GetDiskFreeSpaceEx)(lpDirectoryName, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes); 86 | } 87 | return x.result; 88 | } 89 | 90 | static BOOL WINAPI GetVolumeInformation( 91 | const C *lpRootPathName, 92 | C *lpVolumeNameBuffer, 93 | DWORD nVolumeNameSize, 94 | LPDWORD lpVolumeSerialNumber, 95 | LPDWORD lpMaximumComponentLength, 96 | LPDWORD lpFileSystemFlags, 97 | LPTSTR lpFileSystemNameBuffer, 98 | DWORD nFileSystemNameSize 99 | ) 100 | { 101 | auto x = info(add_suffix("GetVolumeInformation"), lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize); 102 | x.l(-1, "unimplemented"); 103 | x.result = orig(GetVolumeInformation)(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize); 104 | x.l(6, "lpVolumeNameBuffer=", lpVolumeNameBuffer); 105 | return x.result; 106 | } 107 | 108 | static BOOL WINAPI GetVolumePathName( 109 | C *lpszFileName, 110 | C *lpszVolumePathName, 111 | DWORD cchBufferLength 112 | ) 113 | { 114 | auto x = info(add_suffix("GetVolumePathName"), lpszFileName, lpszVolumePathName, cchBufferLength); 115 | x.result = orig(GetVolumePathName)(lpszFileName, lpszVolumePathName, cchBufferLength); 116 | x.l(6, "lpszVolumePathName=", lpszVolumePathName); 117 | return x.result; 118 | } 119 | //SetVolumeLabel 120 | -------------------------------------------------------------------------------- /include/path.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #pragma comment(lib, "shlwapi") 8 | 9 | struct Path 10 | { 11 | typedef std::string string; 12 | typedef std::wstring wstring; 13 | static string GetDirectoryName(const string &path) 14 | { 15 | string str = path; 16 | PathRemoveFileSpecA(&str[0]); 17 | return string(str.c_str()); 18 | } 19 | static wstring GetDirectoryName(const wstring &path) 20 | { 21 | wstring str = path; 22 | PathRemoveFileSpecW(&str[0]); 23 | return wstring(str.c_str()); 24 | } 25 | 26 | static string GetFileName(const string &path) 27 | { 28 | auto p = PathFindFileNameA(path.c_str()); 29 | return string(p); 30 | } 31 | static wstring GetFileName(const wstring &path) 32 | { 33 | auto p = PathFindFileNameW(path.c_str()); 34 | return wstring(p); 35 | } 36 | 37 | static string GetFileNameWithoutExtension(const string &path) 38 | { 39 | string p = PathFindFileNameA(path.c_str()); 40 | PathRemoveExtensionA(&p[0]); 41 | return string(p.c_str()); 42 | } 43 | static wstring GetFileNameWithoutExtension(const wstring &path) 44 | { 45 | wstring p = PathFindFileNameW(path.c_str()); 46 | PathRemoveExtensionW(&p[0]); 47 | return wstring(p.c_str()); 48 | } 49 | 50 | static string GetExtension(const string &path) 51 | { 52 | auto p = PathFindExtensionA(path.c_str()); 53 | return string(p ? p : ""); 54 | } 55 | static wstring GetExtension(const wstring &path) 56 | { 57 | auto p = PathFindExtensionW(path.c_str()); 58 | return wstring(p ? p : L""); 59 | } 60 | 61 | static string GetFullPath(const string &path) 62 | { 63 | string fullpath(MAX_PATH, 0); 64 | auto result = GetFullPathNameA(path.c_str(), MAX_PATH, &fullpath[0], NULL); 65 | if (result < MAX_PATH) 66 | { 67 | fullpath.resize(result); 68 | } 69 | else 70 | { 71 | fullpath.reserve(result); 72 | result = GetFullPathNameA(path.c_str(), result, &fullpath[0], NULL); 73 | fullpath.resize(result); 74 | } 75 | return fullpath; 76 | } 77 | static wstring GetFullPath(const wstring &path) 78 | { 79 | wstring fullpath(MAX_PATH, 0); 80 | auto result = GetFullPathNameW(path.c_str(), MAX_PATH, &fullpath[0], NULL); 81 | if (result < MAX_PATH) 82 | { 83 | fullpath.resize(result); 84 | } 85 | else 86 | { 87 | fullpath.reserve(result); 88 | result = GetFullPathNameW(path.c_str(), result, &fullpath[0], NULL); 89 | fullpath.resize(result); 90 | } 91 | return fullpath; 92 | } 93 | 94 | static string Combine(const string &path1, const string &path2) 95 | { 96 | string s(path1.size() + path2.size() + MAX_PATH, 0); 97 | PathCombineA(&s[0], path1.c_str(), path2.c_str()); 98 | s.resize(strlen(&s[0])); 99 | return s; 100 | } 101 | static wstring Combine(const wstring &path1, const wstring &path2) 102 | { 103 | wstring s(path1.size() + path2.size() + MAX_PATH, 0); 104 | PathCombineW(&s[0], path1.c_str(), path2.c_str()); 105 | s.resize(wcslen(&s[0])); 106 | return s; 107 | } 108 | template 109 | static string Combine(const string &path1, const string &path2, Args... args) 110 | { 111 | return Combine(Combine(path1, path2), args...); 112 | } 113 | template 114 | static wstring Combine(const wstring &path1, const wstring &path2, Args... args) 115 | { 116 | return Combine(Combine(path1, path2), args...); 117 | } 118 | 119 | static string RemoveBackslash(const string &path) 120 | { 121 | string s = path; 122 | PathRemoveBackslashA(&s[0]); 123 | s.resize(strlen(&s[0])); 124 | return s; 125 | } 126 | static wstring RemoveBackslash(const wstring &path) 127 | { 128 | wstring s = path; 129 | PathRemoveBackslashW(&s[0]); 130 | s.resize(wcslen(&s[0])); 131 | return s; 132 | } 133 | static string AddBackslash(const string &path) 134 | { 135 | string s = path; 136 | s.resize(s.size() + 1); 137 | PathAddBackslashA(&s[0]); 138 | s.resize(strlen(&s[0])); 139 | return s; 140 | } 141 | static wstring AddBackslash(const wstring &path) 142 | { 143 | wstring s = path; 144 | s.resize(s.size() + 1); 145 | PathAddBackslashW(&s[0]); 146 | s.resize(wcslen(&s[0])); 147 | return s; 148 | } 149 | }; 150 | -------------------------------------------------------------------------------- /mod/shell32/exec.h: -------------------------------------------------------------------------------- 1 | static bool isExecutableExt(const string &s) 2 | { 3 | auto ext = String::tolower(Path::GetExtension(s)); 4 | if (ext == String::tstr(".exe")) 5 | return true; 6 | return false; 7 | } 8 | 9 | static BOOL WINAPI ShellExecuteEx(ShellExecuteInfo *pExecInfo) 10 | { 11 | auto x = info(add_suffix("ShellExecuteEx"), pExecInfo); 12 | x.l(0, pExecInfo->lpFile); 13 | if (pExecInfo->lpVerb) 14 | x.l(2, "verb:", pExecInfo->lpVerb); 15 | if (pExecInfo->lpParameters) 16 | x.l(2, "param:", pExecInfo->lpParameters); 17 | if (pExecInfo->lpDirectory) 18 | x.l(2, "dir:", pExecInfo->lpDirectory); 19 | auto file = cnv::getExists(pExecInfo->lpFile); 20 | string directory; 21 | 22 | bool flag = false; 23 | if (!pExecInfo->lpVerb) 24 | { 25 | flag = true; 26 | } 27 | else 28 | { 29 | auto verb = String::tolower(String::tstr(pExecInfo->lpVerb)); 30 | if (verb == "open" || verb == "") 31 | { 32 | flag = true; 33 | } 34 | else if (verb == "runas") 35 | { 36 | DWORD bt; 37 | orig(Kernel32::GetBinaryType)(file.c_str(), &bt); 38 | auto newf = Path::Combine(cnv::sandbox, String::tstr(bt == SCS_64BIT_BINARY ? exename64 : exename32)); 39 | string param = pExecInfo->lpParameters; 40 | param = String::tstr("\"") + file + String::tstr("\" ") + directory + param; 41 | 42 | if (pExecInfo->lpDirectory) 43 | { 44 | directory = cnv::sp(pExecInfo->lpDirectory); 45 | directory = String::tstr("\"/D") + directory + String::tstr("\" "); 46 | } 47 | 48 | ShellExecuteInfo ei = *pExecInfo; 49 | ei.lpFile = newf.c_str(); 50 | ei.lpParameters = param.c_str(); 51 | x.l(1, ei.lpFile, " ", ei.lpParameters); 52 | x.result = orig(ShellExecuteEx)(&ei); 53 | SaveError s; 54 | x.l(7, "result=", x.result, " hInstApp = ", (int)ei.hInstApp, " hProcess = ", (int)ei.hProcess); 55 | if (x.result) 56 | { 57 | WaitForSingleObject(ei.hProcess, INFINITE); 58 | DWORD code; 59 | GetExitCodeProcess(ei.hProcess, &code); 60 | pExecInfo->hInstApp = ei.hInstApp; 61 | pExecInfo->hProcess = (HANDLE)code; 62 | } 63 | return x.result; 64 | } 65 | } 66 | 67 | if (flag) 68 | { 69 | C path[MAX_PATH]; 70 | auto ext_exe = String::tstr(".exe"); 71 | auto result = orig(Kernel32::SearchPath)(NULL, file.c_str(), ext_exe.c_str(), MAX_PATH, path, NULL); 72 | if (!result && pExecInfo->lpDirectory) 73 | { 74 | directory = cnv::sp(pExecInfo->lpDirectory); 75 | result = orig(Kernel32::SearchPath)(directory.c_str(), file.c_str(), ext_exe.c_str(), MAX_PATH, path, NULL); 76 | } 77 | SaveError s; 78 | if (result > 0 && isExecutableExt(path)) 79 | { 80 | if (pExecInfo->lpDirectory) 81 | { 82 | directory = cnv::sp(pExecInfo->lpDirectory); 83 | } 84 | else 85 | { 86 | directory = Path::GetDirectoryName(path); 87 | } 88 | 89 | Kernel32::StartupInfo si; 90 | ZeroMemory(&si, sizeof(si)); 91 | si.cb = sizeof(si); 92 | PROCESS_INFORMATION pi; 93 | ZeroMemory(&pi, sizeof(pi)); 94 | string command = String::tstr("\"") + path + String::tstr("\""); 95 | if (pExecInfo->lpParameters) 96 | { 97 | command += C(' '); 98 | command += pExecInfo->lpParameters; 99 | } 100 | x.result = Kernel32::CreateProcess(path, &command[0], NULL, NULL, false, 101 | NORMAL_PRIORITY_CLASS | CREATE_DEFAULT_ERROR_MODE, 102 | NULL, directory.c_str(), &si, &pi 103 | ); 104 | pExecInfo->hProcess = pi.hProcess; 105 | pExecInfo->hInstApp = x.result ? (HINSTANCE)100 : (HINSTANCE)(GetLastError() & 0x1F); 106 | return x.result; 107 | } 108 | } 109 | auto origf = pExecInfo->lpFile; 110 | auto origd = pExecInfo->lpDirectory; 111 | pExecInfo->lpFile = file.c_str(); 112 | if (pExecInfo->lpDirectory) 113 | { 114 | directory = cnv::sp(pExecInfo->lpDirectory); 115 | pExecInfo->lpDirectory = directory.c_str(); 116 | } 117 | x.result = orig(ShellExecuteEx)(pExecInfo); 118 | pExecInfo->lpFile = origf; 119 | pExecInfo->lpDirectory = origd; 120 | return x.result; 121 | } 122 | 123 | static HINSTANCE WINAPI ShellExecute( 124 | HWND hwnd, 125 | const C *lpVerb, 126 | const C *lpFile, 127 | const C *lpParameters, 128 | const C *lpDirectory, 129 | INT nShowCmd 130 | ) 131 | { 132 | auto x = info(add_suffix("ShellExecute"), hwnd, lpVerb, lpFile, lpParameters, lpDirectory, nShowCmd); 133 | ShellExecuteInfo si; 134 | ZeroMemory(&si, sizeof(si)); 135 | si.cbSize = sizeof(si); 136 | si.lpVerb = lpVerb; 137 | si.lpFile = lpFile; 138 | si.lpParameters = lpParameters; 139 | si.lpDirectory = lpDirectory; 140 | si.nShow = nShowCmd; 141 | ShellExecuteEx(&si); 142 | return x.result = si.hInstApp; 143 | } 144 | //FindExecutable 145 | -------------------------------------------------------------------------------- /include/directory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "path.h" 9 | 10 | struct Directory 11 | { 12 | typedef std::string string; 13 | typedef std::wstring wstring; 14 | typedef std::vector slist; 15 | typedef std::vector wslist; 16 | typedef std::vector infolist; 17 | typedef std::vector winfolist; 18 | 19 | static bool Exists(const string &d) 20 | { 21 | return PathIsDirectoryA(d.c_str()); 22 | } 23 | static bool Exists(const wstring &d) 24 | { 25 | return PathIsDirectoryW(d.c_str()); 26 | } 27 | 28 | template 29 | static R GetBase(const string &d, const T &f) 30 | { 31 | R result; 32 | WIN32_FIND_DATAA data; 33 | HANDLE h = FindFirstFileA(d.c_str(), &data); 34 | if (h == INVALID_HANDLE_VALUE) 35 | return result; 36 | 37 | do 38 | { 39 | f(data, result); 40 | } while (FindNextFile(h, &data)); 41 | FindClose(h); 42 | 43 | return result; 44 | } 45 | template 46 | static R GetBase(const wstring &d, const T &f) 47 | { 48 | R result; 49 | WIN32_FIND_DATAW data; 50 | HANDLE h = FindFirstFileW(d.c_str(), &data); 51 | if (h == INVALID_HANDLE_VALUE) 52 | return result; 53 | 54 | do 55 | { 56 | f(data, result); 57 | } while (FindNextFileW(h, &data)); 58 | FindClose(h); 59 | 60 | return result; 61 | } 62 | 63 | static slist GetFiles(const string &d, const string &s = "*") 64 | { 65 | return GetBase(Path::Combine(d, s), [](WIN32_FIND_DATAA &data, slist &list) 66 | { 67 | if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 68 | list.push_back(data.cFileName); 69 | }); 70 | } 71 | static slist GetDirectories(const string &d, const string &s = "*") 72 | { 73 | return GetBase(Path::Combine(d, s), [](WIN32_FIND_DATAA &data, slist &list) 74 | { 75 | if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (data.cFileName[0] != '.')) 76 | list.push_back(data.cFileName); 77 | }); 78 | } 79 | static wslist GetFiles(const wstring &d, const wstring &s = L"*") 80 | { 81 | return GetBase(Path::Combine(d, s), [](WIN32_FIND_DATAW &data, wslist &list) 82 | { 83 | if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 84 | list.push_back(data.cFileName); 85 | }); 86 | } 87 | static wslist GetDirectories(const wstring &d, const wstring &s = L"*") 88 | { 89 | return GetBase(Path::Combine(d, s), [](WIN32_FIND_DATAW &data, wslist &list) 90 | { 91 | if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (data.cFileName[0] != '.')) 92 | list.push_back(data.cFileName); 93 | }); 94 | } 95 | 96 | static infolist GetFileInfos(const string &d, const string&s = "*") 97 | { 98 | return GetBase(Path::Combine(d, s), [](WIN32_FIND_DATAA &data, infolist &list) 99 | { 100 | if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (data.cFileName[0] != '.')) 101 | list.push_back(data); 102 | }); 103 | } 104 | static infolist GetDirectoryInfos(const string &d, const string&s = "*") 105 | { 106 | return GetBase(Path::Combine(d, s), [](WIN32_FIND_DATAA &data, infolist &list) 107 | { 108 | if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 109 | list.push_back(data); 110 | }); 111 | } 112 | static winfolist GetFileInfos(const wstring &d, const wstring&s = L"*") 113 | { 114 | return GetBase(Path::Combine(d, s), [](WIN32_FIND_DATAW &data, winfolist &list) 115 | { 116 | if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (data.cFileName[0] != '.')) 117 | list.push_back(data); 118 | }); 119 | } 120 | static winfolist GetDirectoryInfos(const wstring &d, const wstring&s = L"*") 121 | { 122 | return GetBase(Path::Combine(d, s), [](WIN32_FIND_DATAW &data, winfolist &list) 123 | { 124 | if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 125 | list.push_back(data); 126 | }); 127 | } 128 | 129 | static BOOL Delete(const string &d, bool recursive = false) 130 | { 131 | if (recursive) 132 | { 133 | auto files = GetFiles(d); 134 | for (auto &f : files) 135 | { 136 | DeleteFileA(Path::Combine(d, f).c_str()); 137 | } 138 | auto dirs = GetDirectories(d); 139 | for (auto &n : dirs) 140 | { 141 | Delete(Path::Combine(d, n).c_str(), true); 142 | } 143 | } 144 | return RemoveDirectoryA(d.c_str()); 145 | } 146 | static BOOL Delete(const wstring &d, bool recursive = false) 147 | { 148 | if (recursive) 149 | { 150 | auto files = GetFiles(d); 151 | for (auto &f : files) 152 | { 153 | DeleteFileW(Path::Combine(d, f).c_str()); 154 | } 155 | auto dirs = GetDirectories(d); 156 | for (auto &n : dirs) 157 | { 158 | Delete(Path::Combine(d, n).c_str(), true); 159 | } 160 | } 161 | return RemoveDirectoryW(d.c_str()); 162 | } 163 | }; 164 | -------------------------------------------------------------------------------- /include/string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | struct String 9 | { 10 | typedef std::string string; 11 | typedef std::wstring wstring; 12 | static DWORD cpy(char *dest, const string &src, size_t size) 13 | { 14 | #ifdef _DEBUG 15 | if (dest == NULL) 16 | printf("copy to null:%s\n", src.c_str()); 17 | #endif 18 | strncpy(dest, src.c_str(), size); 19 | return src.size() < size ? src.size() : size; 20 | } 21 | static DWORD cpy(wchar_t *dest, const wstring &src, size_t size) 22 | { 23 | #ifdef _DEBUG 24 | if (dest == NULL) 25 | printf("copy to null:%S\n", src.c_str()); 26 | #endif 27 | wcsncpy(dest, src.c_str(), size); 28 | return src.size() < size ? src.size() : size; 29 | } 30 | 31 | template 32 | static std::basic_string tstr(const string &s) 33 | { 34 | return s; 35 | } 36 | template<> 37 | static std::basic_string tstr(const string &s) 38 | { 39 | auto size = s.size() + 1; 40 | wstring ws(size, 0); 41 | size = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), &ws[0], size); 42 | ws.resize(size); 43 | return ws; 44 | } 45 | template 46 | static std::basic_string tstr(const wstring &s) 47 | { 48 | return s; 49 | } 50 | template<> 51 | static std::basic_string tstr(const wstring &s) 52 | { 53 | auto size = s.size() * sizeof(wchar_t) + 1; 54 | string str(size, 0); 55 | size = WideCharToMultiByte(CP_ACP, 0, s.c_str(), s.size(), &str[0], size, 0, 0); 56 | str.resize(size); 57 | return str; 58 | } 59 | template 60 | static std::basic_string tstr(const char *s) 61 | { 62 | return tstr(string(s)); 63 | } 64 | template 65 | static std::basic_string tstr(const wchar_t *s) 66 | { 67 | return tstr(wstring(s)); 68 | } 69 | template 70 | static std::basic_string tstr(char *s) 71 | { 72 | return tstr(string(s)); 73 | } 74 | template 75 | static std::basic_string tstr(wchar_t *s) 76 | { 77 | return tstr(wstring(s)); 78 | } 79 | template 80 | static std::basic_string tstr(T t) 81 | { 82 | return std::to_string(t); 83 | } 84 | 85 | template 86 | static S trim_tmp(const S &s, const S &c) 87 | { 88 | auto begin = s.find_first_not_of(c); 89 | if (begin == S::npos) 90 | return S(); 91 | auto end = s.find_last_not_of(c); 92 | return s.substr(begin, end - begin + 1); 93 | } 94 | static string trim(const string &s, const string &c = " \t\r\n") 95 | { 96 | return trim_tmp(s, c); 97 | } 98 | static wstring trim(const wstring &s, const wstring &c = L" \t\r\n") 99 | { 100 | return trim_tmp(s, c); 101 | } 102 | 103 | template 104 | static S tolower_tmp(const S &s) 105 | { 106 | S d = s; 107 | std::transform(s.begin(), s.end(), d.begin(), ::tolower); 108 | return d; 109 | } 110 | static string tolower(const string &s) 111 | { 112 | return tolower_tmp(s); 113 | } 114 | static wstring tolower(const wstring &s) 115 | { 116 | return tolower_tmp(s); 117 | } 118 | 119 | template 120 | static S replace_tmp(const S &s, const S &o, const S &n, bool i = false, bool g = true) 121 | { 122 | auto sm = s; 123 | auto sl = i ? tolower(s) : s; 124 | auto ol = i ? tolower(o) : o; 125 | 126 | S::size_type p = 0; 127 | while ((p = sl.find(ol, p)) != S::npos) 128 | { 129 | sm.replace(p, o.size(), n); 130 | sl.replace(p, ol.size(), n); 131 | if (!g) 132 | break; 133 | p += n.size(); 134 | } 135 | 136 | return sm; 137 | } 138 | static string replace(const string &s, const string &oldstr, const string &newstr, bool ignorecase = false, bool repeat = true) 139 | { 140 | return replace_tmp(s, oldstr, newstr, ignorecase, repeat); 141 | } 142 | static wstring replace(const wstring &s, const wstring &oldstr, const wstring &newstr, bool ignorecase = false, bool repeat = true) 143 | { 144 | return replace_tmp(s, oldstr, newstr, ignorecase, repeat); 145 | } 146 | 147 | static bool starts_with(const string &s1, const string &s2) 148 | { 149 | if (s1.size() < s2.size()) 150 | return false; 151 | return s1.substr(0, s2.size()) == s2; 152 | } 153 | 154 | static std::vector split(const string &str, const string &sep = "\n") 155 | { 156 | std::vector list; 157 | 158 | auto slen = sep.size(); 159 | string::size_type start = 0; 160 | auto pos = str.find(sep); 161 | while (pos != string::npos) 162 | { 163 | list.push_back(str.substr(start, pos - start)); 164 | start = pos + slen; 165 | pos = str.find(sep, start); 166 | } 167 | list.push_back(str.substr(start)); 168 | return list; 169 | } 170 | 171 | template 172 | static string concat(T s) 173 | { 174 | return tstr(s); 175 | } 176 | template 177 | static string concat(T s, Args... args) 178 | { 179 | return tstr(s) + concat(args...); 180 | } 181 | }; 182 | -------------------------------------------------------------------------------- /mod/kernel32/ini.h: -------------------------------------------------------------------------------- 1 | static DWORD WINAPI GetPrivateProfileString( 2 | const C *lpAppName, 3 | const C *lpKeyName, 4 | const C *lpDefault, 5 | C *lpReturnedString, 6 | DWORD nSize, 7 | const C *lpFileName 8 | ) 9 | { 10 | auto x = info(add_suffix("GetPrivateProfileString"), lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, lpFileName); 11 | auto f = cnv::getExists(lpFileName); 12 | return x.result = orig(GetPrivateProfileString)(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, f.c_str()); 13 | } 14 | 15 | static UINT WINAPI GetPrivateProfileInt( 16 | const C *lpAppName, 17 | const C *lpKeyName, 18 | INT nDefault, 19 | const C *lpFileName 20 | ) 21 | { 22 | auto x = info(add_suffix("GetPrivateProfileInt"), lpAppName, lpKeyName, nDefault, lpFileName); 23 | auto f = cnv::getExists(lpFileName); 24 | return x.result = orig(GetPrivateProfileInt)(lpAppName, lpKeyName, nDefault, f.c_str()); 25 | } 26 | static BOOL WINAPI GetPrivateProfileStruct( 27 | const C *lpszSection, 28 | const C *lpszKey, 29 | LPVOID lpStruct, 30 | UINT uSizeStruct, 31 | const C *szFile 32 | ) 33 | { 34 | auto x = info(add_suffix("GetPrivateProfileStruct"), lpszSection, lpszKey, lpStruct, uSizeStruct, szFile); 35 | auto f = cnv::getExists(szFile); 36 | return x.result = orig(GetPrivateProfileStruct)(lpszSection, lpszKey, lpStruct, uSizeStruct, f.c_str()); 37 | } 38 | static DWORD WINAPI GetPrivateProfileSection( 39 | const C *lpAppName, 40 | C *lpReturnedString, 41 | DWORD nSize, 42 | const C *lpFileName 43 | ) 44 | { 45 | auto x = info(add_suffix("GetPrivateProfileSection"), lpAppName, lpReturnedString, nSize, lpFileName); 46 | auto f = cnv::getExists(lpFileName); 47 | return x.result = orig(GetPrivateProfileSection)(lpAppName, lpReturnedString, nSize, f.c_str()); 48 | } 49 | static DWORD WINAPI GetPrivateProfileSectionNames( 50 | C *lpszReturnBuffer, 51 | DWORD nSize, 52 | const C *lpFileName 53 | ) 54 | { 55 | auto x = info(add_suffix("GetPrivateProfileSectionNames"), lpszReturnBuffer, nSize, lpFileName); 56 | auto f = cnv::getExists(lpFileName); 57 | return x.result = orig(GetPrivateProfileSectionNames)(lpszReturnBuffer, nSize, f.c_str()); 58 | } 59 | 60 | static BOOL WINAPI WritePrivateProfileString( 61 | const C *lpAppName, 62 | const C *lpKeyName, 63 | const C *lpString, 64 | const C *lpFileName 65 | ) 66 | { 67 | auto x = info(add_suffix("WritePrivateProfileString"), lpAppName, lpKeyName, lpString, lpFileName); 68 | auto f = cnv::sp(lpFileName); 69 | return x.result = orig(WritePrivateProfileString)(lpAppName, lpKeyName, lpString, f.c_str()); 70 | } 71 | 72 | static BOOL WINAPI WritePrivateProfileStruct( 73 | const C *lpszSection, 74 | const C *lpszKey, 75 | LPVOID lpStruct, 76 | UINT uSizeStruct, 77 | const C *szFile 78 | ) 79 | { 80 | auto x = info(add_suffix("WritePrivateProfileStruct"), lpszSection, lpszKey, lpStruct, uSizeStruct, szFile); 81 | auto f = cnv::sp(szFile); 82 | return x.result = orig(WritePrivateProfileStruct)(lpszSection, lpszKey, lpStruct, uSizeStruct, f.c_str()); 83 | } 84 | 85 | static BOOL WINAPI WritePrivateProfileSection( 86 | const C *lpAppName, 87 | const C *lpString, 88 | const C *lpFileName 89 | ) 90 | { 91 | auto x = info(add_suffix("WritePrivateProfileSection"), lpAppName, lpString, lpFileName); 92 | auto f = cnv::sp(lpFileName); 93 | return x.result = orig(WritePrivateProfileSection)(lpAppName, lpString, f.c_str()); 94 | } 95 | 96 | static DWORD WINAPI GetProfileString( 97 | const C *lpAppName, 98 | const C *lpKeyName, 99 | const C *lpDefault, 100 | C *lpReturnedString, 101 | DWORD nSize 102 | ) 103 | { 104 | auto x = info(add_suffix("GetProfileString"), lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize); 105 | C buf[MAX_PATH]; 106 | orig(GetWindowsDirectory)(buf, MAX_PATH); 107 | auto f = cnv::getExists(Path::Combine(buf, String::tstr("Win.ini"))); 108 | return x.result = orig(GetPrivateProfileString)(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, f.c_str()); 109 | } 110 | 111 | static UINT WINAPI GetProfileInt( 112 | const C *lpAppName, 113 | const C *lpKeyName, 114 | INT nDefault 115 | ) 116 | { 117 | auto x = info(add_suffix("GetProfileString"), lpAppName, lpKeyName, nDefault); 118 | C buf[MAX_PATH]; 119 | orig(GetWindowsDirectory)(buf, MAX_PATH); 120 | auto f = cnv::getExists(Path::Combine(buf, String::tstr("Win.ini"))); 121 | return x.result = orig(GetPrivateProfileInt)(lpAppName, lpKeyName, nDefault, f.c_str()); 122 | } 123 | 124 | static DWORD WINAPI GetProfileSection( 125 | const C *lpAppName, 126 | C *lpReturnedString, 127 | DWORD nSize 128 | ) 129 | { 130 | auto x = info(add_suffix("GetProfileString"), lpAppName, lpReturnedString, nSize); 131 | C buf[MAX_PATH]; 132 | orig(GetWindowsDirectory)(buf, MAX_PATH); 133 | auto f = cnv::getExists(Path::Combine(buf, String::tstr("Win.ini"))); 134 | return x.result = orig(GetPrivateProfileSection)(lpAppName, lpReturnedString, nSize, f.c_str()); 135 | } 136 | 137 | static BOOL WINAPI WriteProfileString( 138 | const C *lpAppName, 139 | const C *lpKeyName, 140 | const C *lpString 141 | ) 142 | { 143 | auto x = info(add_suffix("WriteProfileString"), lpAppName, lpKeyName, lpString); 144 | C buf[MAX_PATH]; 145 | orig(GetWindowsDirectory)(buf, MAX_PATH); 146 | auto f = cnv::sp(Path::Combine(buf, String::tstr("Win.ini"))); 147 | return x.result = orig(WritePrivateProfileString)(lpAppName, lpKeyName, lpString, f.c_str()); 148 | } 149 | 150 | static BOOL WINAPI WriteProfileSection( 151 | const C *lpAppName, 152 | const C *lpString 153 | ) 154 | { 155 | auto x = info(add_suffix("WriteProfileSection"), lpAppName, lpString); 156 | C buf[MAX_PATH]; 157 | orig(GetWindowsDirectory)(buf, MAX_PATH); 158 | auto f = cnv::sp(Path::Combine(buf, String::tstr("Win.ini"))); 159 | return x.result = orig(WritePrivateProfileSection)(lpAppName, lpString, f.c_str()); 160 | } 161 | -------------------------------------------------------------------------------- /mod/advapi32.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "utility/registry.h" 3 | 4 | template struct Advapi32 5 | { 6 | typedef std::basic_string string; 7 | struct NativeRegistry 8 | { 9 | HKEY key; 10 | LONG result; 11 | NativeRegistry(const std::wstring &s) 12 | { 13 | key = NULL; 14 | std::wstring sub; 15 | HKEY hk; 16 | std::wstring::size_type pos; 17 | if ((pos = s.find(L"HKEY_LOCAL_MACHINE")) != std::wstring::npos) 18 | { 19 | hk = HKEY_LOCAL_MACHINE; 20 | sub = s.substr(pos + 19); 21 | } 22 | else if ((pos = s.find(L"HKEY_CLASSES_ROOT")) != std::wstring::npos) 23 | { 24 | hk = HKEY_CLASSES_ROOT; 25 | sub = s.substr(pos + 18); 26 | } 27 | else if ((pos = s.find(L"HKEY_CURRENT_CONFIG")) != std::wstring::npos) 28 | { 29 | hk = HKEY_CURRENT_CONFIG; 30 | sub = s.substr(pos + 20); 31 | } 32 | else 33 | { 34 | result = ERROR_FILE_NOT_FOUND; 35 | return; 36 | } 37 | 38 | result = orig(Advapi32::RegOpenKeyEx)(hk, sub.c_str(), 0, KEY_READ, &key); 39 | } 40 | ~NativeRegistry() 41 | { 42 | orig(Advapi32::RegCloseKey)(key); 43 | } 44 | }; 45 | 46 | static bool isNativeHKey(HKEY hKey) 47 | { 48 | return (hKey >= HKEY_CLASSES_ROOT) || !((pointer_size_uint)hKey >> 16); 49 | } 50 | 51 | static std::wstring GetDirectoryName(HKEY hKey) 52 | { 53 | std::wstring rpath; 54 | if (hKey >= HKEY_CLASSES_ROOT) 55 | { 56 | switch ((DWORD)hKey) 57 | { 58 | case HKEY_CLASSES_ROOT: 59 | rpath = Path::Combine(cnv::sandbox, config.wstr("reg"), L"HKEY_CLASSES_ROOT"); 60 | break; 61 | case HKEY_CURRENT_CONFIG: 62 | rpath = Path::Combine(cnv::sandbox, config.wstr("reg"), L"HKEY_CURRENT_CONFIG"); 63 | break; 64 | case HKEY_CURRENT_USER: 65 | rpath = Path::Combine(cnv::sandbox, config.wstr("reg"), L"HKEY_CURRENT_USER"); 66 | break; 67 | case HKEY_LOCAL_MACHINE: 68 | rpath = Path::Combine(cnv::sandbox, config.wstr("reg"), L"HKEY_LOCAL_MACHINE"); 69 | break; 70 | case HKEY_USERS: 71 | rpath = Path::Combine(cnv::sandbox, config.wstr("reg"), L"HKEY_USERS"); 72 | break; 73 | default: 74 | rpath = Path::Combine(cnv::sandbox, config.wstr("reg"), L"_"); 75 | break; 76 | } 77 | } 78 | else if ((pointer_size_uint)hKey >> 16) 79 | { 80 | rpath = ((RegistryKey*)hKey)->path; 81 | } 82 | else 83 | { 84 | log(1, "native HKEY?:", FuncInfo::hex(hKey)); 85 | rpath = Path::Combine(cnv::sandbox, config.wstr("reg"), L"_"); 86 | } 87 | return rpath; 88 | } 89 | 90 | static std::wstring replace_invalid(const std::wstring &path) 91 | { 92 | std::wstring str = path; 93 | const std::wstring invalid = L":/*?\"<>|"; 94 | auto pos = str.find_first_of(invalid, 2); 95 | while (pos != std::wstring::npos) 96 | { 97 | str[pos] = L'$'; 98 | pos = str.find_first_of(invalid, pos + 1); 99 | } 100 | return str; 101 | } 102 | 103 | static bool DirectoryExists(const std::wstring &s) 104 | { 105 | auto attr = orig(Kernel32::GetFileAttributes)(s.c_str()); 106 | return (attr != -1 && (attr & FILE_ATTRIBUTE_DIRECTORY)); 107 | } 108 | 109 | #include "advapi32/reg.h" 110 | #include "advapi32/security.h" 111 | 112 | static void Attach() 113 | { 114 | HMODULE advapi32 = LoadLibraryA("advapi32"); 115 | { 116 | auto lib = std::string("api-ms-win-core-localregistry-") + config.str("api-ms-win-core-localregistry", ""); 117 | HMODULE registry = ::LoadLibraryA(lib.c_str()); 118 | log(7, "try to load ", lib); 119 | if (!registry) 120 | { 121 | registry = advapi32; 122 | } 123 | else 124 | { 125 | log(7, "use ", lib); 126 | } 127 | reg(registry, add_suffix("RegOpenKeyEx"), RegOpenKeyEx); 128 | reg(registry, add_suffix("RegOpenKey"), RegOpenKey); 129 | reg(registry, "RegOpenCurrentUser", RegOpenCurrentUser); 130 | reg(registry, "RegOpenUserClassesRoot", RegOpenUserClassesRoot); 131 | reg(registry, "RegCloseKey", RegCloseKey); 132 | reg(registry, "RegFlushKey", RegFlushKey); 133 | 134 | reg(registry, add_suffix("RegCreateKeyEx"), RegCreateKeyEx); 135 | reg(registry, add_suffix("RegCreateKey"), RegCreateKey); 136 | reg(registry, add_suffix("RegDeleteKeyEx"), RegDeleteKeyEx); 137 | reg(registry, add_suffix("RegDeleteKey"), RegDeleteKey); 138 | reg(registry, add_suffix("RegDeleteValue"), RegDeleteValue); 139 | 140 | reg(registry, add_suffix("RegEnumKeyEx"), RegEnumKeyEx); 141 | reg(registry, add_suffix("RegEnumKey"), RegEnumKey); 142 | reg(registry, add_suffix("RegEnumValue"), RegEnumValue); 143 | reg(registry, add_suffix("RegQueryValueEx"), RegQueryValueEx); 144 | reg(registry, add_suffix("RegQueryValue"), RegQueryValue); 145 | reg(registry, add_suffix("RegSetValueEx"), RegSetValueEx); 146 | reg(registry, add_suffix("RegSetValue"), RegSetValue); 147 | reg(registry, add_suffix("RegQueryInfoKey"), RegQueryInfoKey); 148 | 149 | reg(registry, add_suffix("RegQueryMultipleValues"), RegQueryMultipleValues); 150 | reg(registry, add_suffix("RegSaveKey"), RegSaveKey); 151 | reg(registry, add_suffix("RegRestoreKey"), RegRestoreKey); 152 | reg(registry, add_suffix("RegLoadKey"), RegLoadKey); 153 | reg(registry, add_suffix("RegReplaceKey"), RegReplaceKey); 154 | reg(registry, add_suffix("RegUnLoadKey"), RegUnLoadKey); 155 | reg(registry, "RegNotifyChangeKeyValue", RegNotifyChangeKeyValue); 156 | reg(registry, "RegOverridePredefKey", RegOverridePredefKey); 157 | reg(registry, add_suffix("RegConnectRegistry"), RegConnectRegistry); 158 | } 159 | 160 | { 161 | auto lib = std::string("api-ms-win-security-base-") + config.str("api-ms-win-security-base", "L1-1-0"); 162 | HMODULE security = ::LoadLibraryA(lib.c_str()); 163 | log(7, "try to load ", lib); 164 | if (!security) 165 | { 166 | security = advapi32; 167 | } 168 | else 169 | { 170 | log(7, "use ", lib); 171 | } 172 | reg(security, add_suffix("GetFileSecurity"), GetFileSecurity); 173 | reg(security, add_suffix("SetFileSecurity"), SetFileSecurity); 174 | } 175 | } 176 | }; 177 | //GetUserName 178 | //CreateProcessAsUser 179 | //CreateProcessWithLogonW 180 | //CreateProcessWithTokenW 181 | //CreateService 182 | -------------------------------------------------------------------------------- /mod/kernel32/path.h: -------------------------------------------------------------------------------- 1 | static BOOL WINAPI SetCurrentDirectory(const C *lpPathName) 2 | { 3 | auto x = info(add_suffix("SetCurrentDirectory"), lpPathName); 4 | auto sp = cnv::sp(lpPathName); 5 | x.l(2, lpPathName, " > ", sp); 6 | return x.result = orig(SetCurrentDirectory)(sp.c_str()); 7 | } 8 | 9 | static DWORD WINAPI GetCurrentDirectory(DWORD nBufferLength, C *lpBuffer) 10 | { 11 | auto x = info(add_suffix("GetCurrentDirectory"), nBufferLength, lpBuffer); 12 | string buf(MAX_PATH, 0); 13 | auto size = orig(GetCurrentDirectory)(MAX_PATH, &buf[0]); 14 | buf.resize(size); 15 | if (size > MAX_PATH) 16 | buf.resize(orig(GetCurrentDirectory)(size, &buf[0])); 17 | SaveError s; 18 | auto vp = cnv::vp(buf); 19 | x.l(5, buf, " > ", vp); 20 | if (nBufferLength <= vp.size()) 21 | x.result = vp.size() + 1; 22 | else 23 | x.result = String::cpy(lpBuffer, vp, nBufferLength); 24 | return x.result; 25 | } 26 | 27 | static UINT WINAPI GetTempPath(DWORD nBufferLength, C *lpBuffer) 28 | { 29 | auto x = info(add_suffix("GetTempPath"), nBufferLength, lpBuffer); 30 | if (config.exists("TEMP")) 31 | { 32 | auto s = String::tstr(config.str("TEMP")); 33 | if (nBufferLength <= s.size()) 34 | x.result = s.size() + 1; 35 | else 36 | x.result = String::cpy(lpBuffer, s, nBufferLength); 37 | } 38 | else 39 | x.result = orig(GetTempPath)(nBufferLength, lpBuffer); 40 | return x.result; 41 | } 42 | 43 | static UINT WINAPI GetWindowsDirectory(C *lpBuffer, UINT uSize) 44 | { 45 | auto x = info(add_suffix("GetWindowsDirectory"), lpBuffer, uSize); 46 | return x.result = orig(GetWindowsDirectory)(lpBuffer, uSize); 47 | } 48 | 49 | static UINT WINAPI GetSystemWindowsDirectory(C *lpBuffer, UINT uSize) 50 | { 51 | auto x = info(add_suffix("GetSystemWindowsDirectory"), lpBuffer, uSize); 52 | return x.result = orig(GetSystemWindowsDirectory)(lpBuffer, uSize); 53 | } 54 | 55 | static UINT WINAPI GetSystemDirectory(C *lpBuffer, UINT uSize) 56 | { 57 | auto x = info(add_suffix("GetSystemDirectory"), lpBuffer, uSize); 58 | return x.result = orig(GetSystemDirectory)(lpBuffer, uSize); 59 | } 60 | 61 | static UINT WINAPI GetSystemWow64Directory(C *lpBuffer, UINT uSize) 62 | { 63 | auto x = info(add_suffix("GetSystemWow64Directory"), lpBuffer, uSize); 64 | return x.result = orig(GetSystemWow64Directory)(lpBuffer, uSize); 65 | } 66 | 67 | static DWORD WINAPI GetModuleFileName( 68 | HMODULE hModule, 69 | C *lpFilename, 70 | DWORD nSize 71 | ) 72 | { 73 | auto x = info(add_suffix("GetModuleFileName"), hModule, lpFilename, nSize); 74 | string buf(MAX_PATH, 0); 75 | x.result = orig(GetModuleFileName)(hModule, &buf[0], MAX_PATH); 76 | SaveError s; 77 | if (x.result == 0) 78 | { 79 | x.l(5, "failed!"); 80 | return x.result; 81 | } 82 | buf.resize(x.result); 83 | auto vp = cnv::vp(buf); 84 | x.l(5, buf, " > ", vp); 85 | x.result = String::cpy(lpFilename, vp, nSize); 86 | if (x.result == nSize) 87 | lpFilename[nSize - 1] = 0; 88 | return x.result; 89 | } 90 | 91 | static DWORD WINAPI GetFullPathName( 92 | const C *lpFileName, 93 | DWORD nBufferLength, 94 | C *lpBuffer, 95 | C **lpFilePart 96 | ) 97 | { 98 | auto x = info(add_suffix("GetFullPathName"), lpFileName, nBufferLength, lpBuffer, lpFilePart); 99 | C *filepart; 100 | string buf(MAX_PATH, 0); 101 | x.result = orig(GetFullPathName)(lpFileName, MAX_PATH, &buf[0], &filepart); 102 | if (x.result == 0) 103 | { 104 | SaveError s; 105 | x.l(6, "failed!"); 106 | return x.result; 107 | } 108 | buf.resize(x.result); 109 | if (x.result > MAX_PATH) 110 | buf.resize(orig(GetFullPathName)(lpFileName, MAX_PATH, &buf[0], &filepart)); 111 | SaveError s; 112 | auto vp = cnv::vp(buf); 113 | x.l(6, lpFileName, " > ", buf, " > ", vp); 114 | 115 | if (!lpBuffer || nBufferLength <= vp.size()) 116 | return x.result = vp.size() + 1; 117 | if (lpFilePart && filepart) 118 | { 119 | *lpFilePart = lpBuffer + (vp.size() - buf.size()) + (filepart - &buf[0]); 120 | } 121 | return x.result = String::cpy(lpBuffer, vp, nBufferLength); 122 | } 123 | 124 | static DWORD WINAPI GetFinalPathNameByHandle( 125 | HANDLE hFile, 126 | C *lpszFilePath, 127 | DWORD cchFilePath, 128 | DWORD dwFlags 129 | ) 130 | { 131 | auto x = info(add_suffix("GetFinalPathNameByHandle"), hFile, lpszFilePath, cchFilePath, dwFlags); 132 | string buf(MAX_PATH, 0); 133 | x.result = orig(GetFinalPathNameByHandle)(hFile, &buf[0], MAX_PATH, dwFlags); 134 | buf.resize(x.result); 135 | if (x.result > MAX_PATH) 136 | buf.resize(orig(GetFinalPathNameByHandle)(hFile, &buf[0], x.result + 1, dwFlags)); 137 | SaveError s; 138 | auto vp = cnv::vp(buf); 139 | x.l(6, buf, " > ", vp); 140 | String::cpy(lpszFilePath, vp, cchFilePath); 141 | return x.result = vp.size(); 142 | } 143 | 144 | static DWORD WINAPI SearchPath( 145 | const C *lpPath, 146 | const C *lpFileName, 147 | const C *lpExtension, 148 | DWORD nBufferLength, 149 | C *lpBuffer, 150 | C **lpFilePart 151 | ) 152 | { 153 | auto x = info(add_suffix("SearchPath"), lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart); 154 | auto file = cnv::sp(lpFileName); 155 | string buf(MAX_PATH, 0); 156 | C *filepart; 157 | if (lpPath) 158 | { 159 | auto sp = cnv::sp(lpPath); 160 | x.result = orig(SearchPath)(sp.c_str(), file.c_str(), lpExtension, nBufferLength, &buf[0], &filepart); 161 | if (!x.result) 162 | { 163 | auto cp = cnv::cp(lpPath); 164 | if (sp != cp) 165 | x.result = orig(SearchPath)(cp.c_str(), file.c_str(), lpExtension, nBufferLength, &buf[0], &filepart); 166 | } 167 | } 168 | else 169 | { 170 | x.result = orig(SearchPath)(lpPath, file.c_str(), lpExtension, nBufferLength, &buf[0], &filepart); 171 | } 172 | SaveError s; 173 | 174 | if (x.result) 175 | { 176 | buf.resize(x.result); 177 | string vp = cnv::vp(buf); 178 | if (!lpBuffer || nBufferLength <= vp.size()) 179 | return vp.size() + 1; 180 | if (lpBuffer) 181 | { 182 | x.result = String::cpy(lpBuffer, vp, nBufferLength); 183 | if (lpFilePart && filepart) 184 | { 185 | *lpFilePart = lpBuffer + (vp.size() - buf.size()) + (filepart - &buf[0]); 186 | } 187 | } 188 | x.l(6, lpFileName, " > ", buf, " > ", vp); 189 | } 190 | return x.result; 191 | } 192 | 193 | static DWORD WINAPI GetShortPathName( 194 | const C *lpszLongPath, 195 | C *lpszShortPath, 196 | DWORD cchBuffer 197 | ) 198 | { 199 | auto x = info(add_suffix("GetShortPathName"), lpszLongPath, lpszShortPath, cchBuffer); 200 | x.result = orig(GetShortPathName)(lpszLongPath, lpszShortPath, cchBuffer); 201 | x.l(-1, "unimplemented:", lpszLongPath, " > ", lpszShortPath); 202 | return x.result; 203 | } 204 | 205 | static DWORD WINAPI GetLongPathName( 206 | const C *lpszShortPath, 207 | C *lpszLongPath, 208 | DWORD cchBuffer 209 | ) 210 | { 211 | auto x = info(add_suffix("GetLongPathName"), lpszShortPath, lpszLongPath, cchBuffer); 212 | x.result = orig(GetLongPathName)(lpszShortPath, lpszLongPath, cchBuffer); 213 | SaveError s; 214 | x.l(-1, "unimplemented:", lpszShortPath, " > ", lpszLongPath); 215 | return x.result; 216 | } 217 | -------------------------------------------------------------------------------- /mod/shell32/folder.h: -------------------------------------------------------------------------------- 1 | static HRESULT STDAPICALLTYPE SHGetFolderPath( 2 | HWND hwnd, 3 | int csidl, 4 | HANDLE hToken, 5 | DWORD dwFlags, 6 | C *pszPath 7 | ) 8 | { 9 | auto x = info(add_suffix("SHGetFolderPath"), hwnd, csidl, hToken, dwFlags, pszPath); 10 | x.result = orig(SHGetFolderPath)(hwnd, csidl & ~CSIDL_FLAG_MASK, hToken, dwFlags, pszPath); 11 | SaveError s; 12 | if (x.result != S_OK) 13 | { 14 | x.l(7, csidl & ~CSIDL_FLAG_MASK, " = error!"); 15 | return x.result; 16 | } 17 | auto vp = cnv::vp(pszPath); 18 | x.l(7, csidl & ~CSIDL_FLAG_MASK, " = ", pszPath, " > ", vp); 19 | if (csidl & CSIDL_FLAG_CREATE) 20 | { 21 | auto sp = cnv::sp(pszPath); 22 | x.l(3, "create:", sp); 23 | orig(SHCreateDirectoryEx)(hwnd, sp.c_str(), NULL); 24 | } 25 | String::cpy(pszPath, vp, vp.size() + 1); 26 | return x.result; 27 | } 28 | 29 | static HRESULT WINAPI SHGetFolderPathAndSubDir( 30 | HWND hwnd, 31 | int csidl, 32 | HANDLE hToken, 33 | DWORD dwFlags, 34 | const C *pszSubDir, 35 | C *pszPath 36 | ) 37 | { 38 | auto x = info(add_suffix("SHGetFolderPathAndSubDir"), hwnd, csidl, hToken, dwFlags, pszSubDir, pszPath); 39 | C spath[MAX_PATH]; 40 | x.result = SHGetFolderPath(hwnd, csidl, hToken, dwFlags, spath); 41 | auto path = Path::Combine(spath, pszSubDir); 42 | x.l(8, pszSubDir, " > ", path); 43 | String::cpy(pszPath, path, MAX_PATH); 44 | return x.result; 45 | } 46 | 47 | static BOOL WINAPI SHGetSpecialFolderPath( 48 | HWND hwnd, 49 | C *pszPath, 50 | int csidl, 51 | BOOL fCreate 52 | ) 53 | { 54 | auto x = info(add_suffix("SHGetSpecialFolderPath"), hwnd, pszPath, csidl, fCreate); 55 | return x.result = SHGetFolderPath(hwnd, csidl | (fCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0, pszPath); 56 | } 57 | 58 | static HRESULT WINAPI SHGetSpecialFolderLocation( 59 | HWND hwnd, 60 | int csidl, 61 | PIDLIST_ABSOLUTE *ppidl 62 | ) 63 | { 64 | auto x = info(add_suffix("SHGetSpecialFolderLocation"), hwnd, csidl, ppidl); 65 | x.result = orig(SHGetSpecialFolderLocation)(hwnd, csidl, ppidl); 66 | SaveError s; 67 | return x.result; 68 | } 69 | 70 | static HRESULT WINAPI SHGetFolderLocation( 71 | HWND hwnd, 72 | int csidl, 73 | HANDLE hToken, 74 | DWORD dwFlags, 75 | PIDLIST_ABSOLUTE *ppidl 76 | ) 77 | { 78 | auto x = info(add_suffix("SHGetFolderLocation"), hwnd, csidl, hToken, dwFlags, ppidl); 79 | x.result = orig(SHGetFolderLocation)(hwnd, csidl, hToken, dwFlags, ppidl); 80 | SaveError s; 81 | return x.result; 82 | } 83 | 84 | static HRESULT WINAPI SHGetFolderPathEx( 85 | REFKNOWNFOLDERID rfid, 86 | DWORD dwFlags, 87 | HANDLE hToken, 88 | LPWSTR pszPath, // only W 89 | UINT cchPath 90 | ) 91 | { 92 | auto x = info(add_suffix("SHGetFolderPathEx"), rfid, dwFlags, hToken, pszPath, cchPath); 93 | x.result = orig(SHGetFolderPathEx)(rfid, dwFlags, hToken, pszPath, cchPath); 94 | SaveError s; 95 | if (x.result == S_OK) 96 | { 97 | auto vp = cnv::vp(pszPath); 98 | x.l(7, FuncInfo::guid(rfid), " = ", pszPath, " > ", vp); 99 | String::cpy(pszPath, vp, cchPath); 100 | } 101 | else 102 | { 103 | x.l(2, FuncInfo::guid(rfid), " = error!"); 104 | } 105 | return x.result; 106 | } 107 | 108 | static HRESULT WINAPI SHGetKnownFolderPath( 109 | REFKNOWNFOLDERID rfid, 110 | DWORD dwFlags, 111 | HANDLE hToken, 112 | PWSTR *ppszPath // only W 113 | ) 114 | { 115 | auto x = info(add_suffix("SHGetKnownFolderPath"), rfid, dwFlags, hToken, ppszPath); 116 | x.result = orig(SHGetKnownFolderPath)(rfid, dwFlags, hToken, ppszPath); 117 | SaveError s; 118 | if (x.result == S_OK) 119 | { 120 | auto vp = cnv::vp(*ppszPath); 121 | x.l(7, FuncInfo::guid(rfid), " = ", *ppszPath, " > ", vp); 122 | auto l = wcslen(*ppszPath); 123 | if (l < vp.size()) 124 | { 125 | auto p = CoTaskMemRealloc(*ppszPath, (vp.size() + 1) * sizeof(wchar_t)); 126 | if (p) 127 | { 128 | x.l(7, "CoTaskMemRealloc:", FuncInfo::hex(*ppszPath), " to ", FuncInfo::hex(p)); 129 | *ppszPath = (PWSTR)p; 130 | } 131 | else 132 | { 133 | p = CoTaskMemAlloc((vp.size() + 1) * sizeof(wchar_t)); 134 | if (p) 135 | { 136 | CoTaskMemFree(*ppszPath); 137 | *ppszPath = (PWSTR)p; 138 | } 139 | else 140 | { 141 | vp.resize(l); 142 | } 143 | } 144 | } 145 | String::cpy(*ppszPath, vp, vp.size() + 1); 146 | } 147 | else 148 | { 149 | x.l(2, FuncInfo::guid(rfid), " = error!"); 150 | } 151 | return x.result; 152 | } 153 | 154 | static HRESULT WINAPI SHGetKnownFolderIDList( 155 | REFKNOWNFOLDERID rfid, 156 | DWORD dwFlags, 157 | HANDLE hToken, 158 | PIDLIST_ABSOLUTE *ppidl 159 | ) 160 | { 161 | auto x = info(add_suffix("SHGetKnownFolderIDList"), rfid, dwFlags, hToken, ppidl); 162 | return x.result = orig(SHGetKnownFolderIDList)(rfid, dwFlags, hToken, ppidl); 163 | } 164 | 165 | static BOOL WINAPI SHGetPathFromIDList( 166 | PCIDLIST_ABSOLUTE pidl, 167 | C *pszPath 168 | ) 169 | { 170 | auto x = info(add_suffix("SHGetPathFromIDList"), pidl, pszPath); 171 | x.result = orig(SHGetPathFromIDList)(pidl, pszPath); 172 | SaveError s; 173 | if (x.result) 174 | { 175 | auto vp = cnv::vp(pszPath); 176 | x.l(7, pszPath, " > ", vp); 177 | String::cpy(pszPath, vp, vp.size() + 1); 178 | } 179 | else 180 | { 181 | x.l(2, "error!"); 182 | } 183 | return x.result; 184 | } 185 | 186 | static BOOL WINAPI SHGetPathFromIDListEx( 187 | PCIDLIST_ABSOLUTE pidl, 188 | PWSTR pszPath, // only W 189 | DWORD cchPath, 190 | GPFIDL_FLAGS uOpts 191 | ) 192 | { 193 | auto x = info(add_suffix("SHGetPathFromIDListEx"), pidl, pszPath, cchPath, uOpts); 194 | x.result = orig(SHGetPathFromIDListEx)(pidl, pszPath, cchPath, uOpts); 195 | SaveError s; 196 | if (x.result) 197 | { 198 | auto vp = cnv::vp(pszPath); 199 | x.l(7, pszPath, " > ", vp); 200 | String::cpy(pszPath, vp, cchPath); 201 | } 202 | else 203 | { 204 | x.l(2, "error!"); 205 | } 206 | return x.result; 207 | } 208 | 209 | static HRESULT WINAPI SHILCreateFromPath( 210 | PCWSTR pszPath, // only W 211 | PIDLIST_ABSOLUTE *ppidl, 212 | DWORD *rgfInOut 213 | ) 214 | { 215 | auto x = info(add_suffix("SHILCreateFromPath"), pszPath, ppidl, rgfInOut); 216 | auto f = cnv::getExists(pszPath); 217 | return x.result = orig(SHILCreateFromPath)(f.c_str(), ppidl, rgfInOut); 218 | } 219 | 220 | static PIDLIST_ABSOLUTE WINAPI ILCreateFromPath( 221 | const C *pszPath 222 | ) 223 | { 224 | auto x = info(add_suffix("ILCreateFromPath"), pszPath); 225 | auto f = cnv::getExists(pszPath); 226 | return x.result = orig(ILCreateFromPath)(f.c_str()); 227 | } 228 | 229 | static PIDLIST_ABSOLUTE WINAPI SHSimpleIDListFromPath( 230 | PCWSTR pszPath 231 | ) 232 | { 233 | auto x = info(add_suffix("SHSimpleIDListFromPath"), pszPath); 234 | auto f = cnv::getExists(pszPath); 235 | return x.result = orig(SHSimpleIDListFromPath)(f.c_str()); 236 | } 237 | 238 | static HRESULT WINAPI SHGetDesktopFolder( 239 | IShellFolder **ppshf 240 | ) 241 | { 242 | auto x = info("SHGetDesktopFolder", ppshf); 243 | x.l(-1, "unimplemented"); 244 | return x.result = orig(SHGetDesktopFolder)(ppshf); 245 | } 246 | //SHBrowseForFolder 247 | -------------------------------------------------------------------------------- /mod/kernel32/process.h: -------------------------------------------------------------------------------- 1 | static BOOL WINAPI CreateProcess( 2 | const C *lpApplicationName, 3 | C *lpCommandLine, 4 | LPSECURITY_ATTRIBUTES lpProcessAttributes, 5 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 6 | BOOL bInheritHandles, 7 | DWORD dwCreationFlags, 8 | LPVOID lpEnvironment, 9 | const C *lpCurrentDirectory, 10 | StartupInfo *lpStartupInfo, 11 | LPPROCESS_INFORMATION lpProcessInformation 12 | ) 13 | { 14 | auto x = info(add_suffix("CreateProcess"), lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); 15 | string sname; 16 | const C *name = lpApplicationName; 17 | string scommand; 18 | C *command = lpCommandLine; 19 | string scd; 20 | const C *cd = lpCurrentDirectory; 21 | if (lpApplicationName) 22 | { 23 | sname = cnv::getExists(lpApplicationName); 24 | name = sname.c_str(); 25 | x.l(0, "App:", lpApplicationName, " > ", sname); 26 | } 27 | if (lpCommandLine) 28 | { 29 | scommand = cnv::sp(lpCommandLine); 30 | command = &scommand[0]; 31 | x.l(0, "cmd:", lpCommandLine, " > ", scommand); 32 | } 33 | if (lpCurrentDirectory) 34 | { 35 | scd = cnv::getExists(lpCurrentDirectory); 36 | cd = scd.c_str(); 37 | x.l(4, "dir:", lpCurrentDirectory, " > ", scd); 38 | } 39 | bool suspend = dwCreationFlags & CREATE_SUSPENDED; 40 | dwCreationFlags |= CREATE_SUSPENDED; 41 | /*#ifdef _DEBUG 42 | dwCreationFlags |= CREATE_NEW_CONSOLE; 43 | #endif*/ 44 | PROCESS_INFORMATION pi; 45 | ZeroMemory(&pi, sizeof(pi)); 46 | x.result = orig(CreateProcess)(name, command, NULL, NULL, bInheritHandles, dwCreationFlags, lpEnvironment, cd, lpStartupInfo, lpProcessInformation ? lpProcessInformation : &pi); 47 | if (!x.result) 48 | { 49 | SaveError s; 50 | x.l(0, "failed!"); 51 | x.l(0, GetLastErrorString()); 52 | return x.result; 53 | } 54 | 55 | HANDLE p = lpProcessInformation ? lpProcessInformation->hProcess : pi.hProcess; 56 | BOOL wow64 = true; 57 | orig(IsWow64Process)(p, &wow64); 58 | BOOL cwow64 = true; 59 | orig(IsWow64Process)(GetCurrentProcess(), &cwow64); 60 | 61 | if (wow64 == cwow64) 62 | { 63 | if (!inject(p, Path::Combine(cnv::sandbox, wow64 ? dllname32 : dllname64))) 64 | { 65 | if (!suspend) 66 | ResumeThread(lpProcessInformation ? lpProcessInformation->hThread : pi.hThread); 67 | } 68 | else 69 | { 70 | TerminateProcess(p, 0xFF); 71 | return 0; 72 | } 73 | } 74 | else 75 | { 76 | auto pid = GetProcessId(p); 77 | auto exe = Path::Combine(cnv::sandbox, wow64 ? exename32 : exename64); 78 | auto command = String::tstr(String::concat(exe, " /P", pid)); 79 | x.l(0, "cross command:", command); 80 | STARTUPINFOW si; 81 | ZeroMemory(&si, sizeof(si)); 82 | si.cb = sizeof(si); 83 | PROCESS_INFORMATION spi; 84 | ZeroMemory(&spi, sizeof(spi)); 85 | if (orig(Kernel32::CreateProcess)(NULL, &command[0], NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &spi)) 86 | { 87 | WaitForSingleObject(spi.hProcess, INFINITE); 88 | if (!suspend) 89 | ResumeThread(lpProcessInformation ? lpProcessInformation->hThread : pi.hThread); 90 | } 91 | else 92 | { 93 | x.l(0, "cross command:", GetLastErrorString()); 94 | TerminateProcess(p, 0xFF); 95 | return 0; 96 | } 97 | } 98 | 99 | return x.result; 100 | } 101 | 102 | static VOID WINAPI GetStartupInfo(StartupInfo *lpStartupInfo) 103 | { 104 | auto x = info(add_suffix("GetStartupInfo"), lpStartupInfo); 105 | return orig(GetStartupInfo)(lpStartupInfo); 106 | } 107 | 108 | static UINT WINAPI WinExec( 109 | LPCSTR lpCmdLine, 110 | UINT uCmdShow 111 | ) 112 | { 113 | auto x = info("WinExec", lpCmdLine, uCmdShow); 114 | auto path = std::string("\"") + Path::Combine(cnv::sandbox, exename32) + "\" " + cnv::getExists(lpCmdLine); 115 | x.l(0, path); 116 | return x.result = orig(WinExec)(path.c_str(), uCmdShow); 117 | } 118 | 119 | static HINSTANCE WINAPI LoadLibraryEx( 120 | const C *lpLibFileName, 121 | HANDLE hFile, 122 | DWORD dwFlags 123 | ) 124 | { 125 | auto x = info(add_suffix("LoadLibraryEx"), lpLibFileName, hFile, dwFlags); 126 | 127 | auto p = cnv::getExists(lpLibFileName); 128 | bool loaded = orig(GetModuleHandle)(p.c_str()); 129 | x.result = orig(LoadLibraryEx)(p.c_str(), hFile, dwFlags); 130 | if (x.result) 131 | { 132 | SaveError s; 133 | x.l(7, p, " = success"); 134 | } 135 | else 136 | { 137 | x.l(8, p, " = ", GetLastErrorString()); 138 | auto lib = Path::GetFileName(lpLibFileName); 139 | if (p != lib) 140 | { 141 | loaded = orig(GetModuleHandle)(lib.c_str()); 142 | x.result = orig(LoadLibraryEx)(lib.c_str(), hFile, dwFlags); 143 | SaveError s; 144 | if (x.result) 145 | { 146 | x.l(7, lib, " = success"); 147 | } 148 | else 149 | { 150 | x.l(8, lib, " = ", GetLastErrorString()); 151 | } 152 | } 153 | } 154 | SaveError s; 155 | if (x.result && !loaded) 156 | { 157 | for (auto &y : orig_to_mod) 158 | { 159 | if (config.dword("LoadLibrary")) 160 | { 161 | // Loaded module imports other module 162 | IAT(y.second, y.first); 163 | } 164 | else 165 | { 166 | // but, many dll loaded, too heavy 167 | moduleIAT(x.result, y.second, y.first); 168 | } 169 | } 170 | } 171 | return x.result; 172 | } 173 | 174 | static HMODULE WINAPI LoadLibrary(const C *lpFileName) 175 | { 176 | auto x = info(add_suffix("LoadLibrary"), lpFileName); 177 | return LoadLibraryEx(lpFileName, 0, 0); 178 | } 179 | 180 | static HMODULE WINAPI GetModuleHandle(const C *lpModuleName) 181 | { 182 | auto x = info(add_suffix("GetModuleHandle"), lpModuleName); 183 | if (!lpModuleName) 184 | { 185 | return x.result = orig(GetModuleHandle)(lpModuleName); 186 | } 187 | auto rp = cnv::getExists(lpModuleName); 188 | x.result = orig(GetModuleHandle)(rp.c_str()); 189 | if (!x.result) 190 | { 191 | auto lib = Path::GetFileName(lpModuleName); 192 | x.result = orig(GetModuleHandle)(lib.c_str()); 193 | } 194 | return x.result; 195 | } 196 | 197 | static FARPROC WINAPI GetProcAddress( 198 | HMODULE hModule, 199 | LPCSTR lpProcName 200 | ) 201 | { 202 | auto x = info("GetProcAddress", hModule, lpProcName); 203 | C modulepath[MAX_PATH]; 204 | orig(GetModuleFileName)(hModule, modulepath, MAX_PATH); 205 | if ((pointer_size_uint)lpProcName >> 16) 206 | { 207 | x.l(4, modulepath, ".", lpProcName); 208 | } 209 | else 210 | { 211 | x.l(4, modulepath, ".", (pointer_size_uint)lpProcName & 0xFFFF); 212 | } 213 | void *o = orig(GetProcAddress)(hModule, lpProcName); 214 | if (o && orig_to_mod.count(o)) 215 | x.result = (FARPROC)orig_to_mod[o]; 216 | else 217 | x.result = (FARPROC)o; 218 | return x.result; 219 | } 220 | 221 | static BOOL WINAPI IsWow64Process( 222 | HANDLE hProcess, 223 | PBOOL Wow64Process 224 | ) 225 | { 226 | auto x = info("IsWow64Process", hProcess, Wow64Process); 227 | if (config.exists("IsWow64Process") && hProcess && GetCurrentProcess() == hProcess && Wow64Process) 228 | { 229 | *Wow64Process = config.dword("IsWow64Process", 0); 230 | x.result = true; 231 | } 232 | else 233 | { 234 | x.result = orig(IsWow64Process)(hProcess, Wow64Process); 235 | } 236 | return x.result; 237 | } 238 | 239 | static BOOL WINAPI IsDebuggerPresent() 240 | { 241 | auto x = info("IsDebuggerPresent"); 242 | return x.result = false; 243 | } 244 | 245 | static BOOL WINAPI GetBinaryType( 246 | const C *lpApplicationName, 247 | LPDWORD lpBinaryType 248 | ) 249 | { 250 | auto x = info(add_suffix("GetBinaryType"), lpApplicationName, lpBinaryType); 251 | auto f = cnv::getExists(lpApplicationName); 252 | x.result = orig(GetBinaryType)(f.c_str(), lpBinaryType); 253 | x.l(7, lpApplicationName, " > ", f, " lpBinaryType=", *lpBinaryType); 254 | return x.result; 255 | } 256 | //LoadModule 257 | //CreateProcessAsUserW 258 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /mod/kernel32.h: -------------------------------------------------------------------------------- 1 | template struct Kernel32 2 | { 3 | typedef std::basic_string string; 4 | template 5 | struct subtypes 6 | { 7 | typedef OSVERSIONINFOEXA OSVersionInfo; 8 | typedef STARTUPINFOA StartupInfo; 9 | }; 10 | template<> 11 | struct subtypes 12 | { 13 | typedef OSVERSIONINFOEXW OSVersionInfo; 14 | typedef STARTUPINFOW StartupInfo; 15 | }; 16 | typedef typename subtypes::OSVersionInfo OSVersionInfo; 17 | typedef typename subtypes::StartupInfo StartupInfo; 18 | 19 | #include "kernel32/file.h" 20 | #include "kernel32/drive.h" 21 | #include "kernel32/path.h" 22 | #include "kernel32/system.h" 23 | #include "kernel32/ini.h" 24 | #include "kernel32/process.h" 25 | #include "kernel32/lz.h" 26 | #include "kernel32/mutex.h" 27 | 28 | static void Attach() 29 | { 30 | HMODULE kernel32 = ::GetModuleHandleA("kernel32"); 31 | { 32 | auto lib = std::string("api-ms-win-core-file-") + config.str("api-ms-win-core-file", "L1-1-0"); 33 | HMODULE file = ::LoadLibraryA(lib.c_str()); 34 | log(7, "try to load ", lib); 35 | if (!file) 36 | { 37 | file = kernel32; 38 | } 39 | else 40 | { 41 | log(7, "use ", lib); 42 | } 43 | reg(file, add_suffix("CreateFile"), CreateFile); 44 | reg(kernel32, add_suffix("MoveFile"), MoveFile); 45 | reg(file, add_suffix("MoveFileEx"), MoveFileEx); 46 | reg(file, add_suffix("CopyFile"), CopyFile); 47 | reg(file, add_suffix("CopyFileEx"), CopyFileEx); 48 | reg(file, add_suffix("DeleteFile"), DeleteFile); 49 | reg(file, add_suffix("ReplaceFile"), ReplaceFile); 50 | reg(file, add_suffix("CreateDirectory"), CreateDirectory); 51 | reg(file, add_suffix("CreateDirectoryEx"), CreateDirectoryEx); 52 | reg(file, add_suffix("RemoveDirectory"), RemoveDirectory); 53 | reg(file, add_suffix("FindFirstFile"), FindFirstFile); 54 | reg(file, add_suffix("FindFirstFileEx"), FindFirstFileEx); 55 | reg(file, add_suffix("SetFileAttributes"), SetFileAttributes); 56 | reg(file, add_suffix("GetFileAttributes"), GetFileAttributes); 57 | reg(file, add_suffix("GetFileAttributesEx"), GetFileAttributesEx); 58 | reg(file, add_suffix("GetTempFileName"), GetTempFileName); 59 | 60 | reg(file, "GetLogicalDrives", GetLogicalDrives); 61 | reg(file, add_suffix("GetLogicalDriveStrings"), GetLogicalDriveStrings); 62 | reg(file, add_suffix("GetDriveType"), GetDriveType); 63 | reg(file, add_suffix("GetDiskFreeSpace"), GetDiskFreeSpace); 64 | reg(file, add_suffix("GetDiskFreeSpaceEx"), GetDiskFreeSpaceEx); 65 | reg(file, add_suffix("GetVolumePathName"), GetVolumePathName); 66 | } 67 | reg(kernel32, "_lopen", _lopen); 68 | reg(kernel32, "OpenFile", OpenFile); 69 | 70 | reg(kernel32, add_suffix("GetPrivateProfileString"), GetPrivateProfileString); 71 | reg(kernel32, add_suffix("GetPrivateProfileInt"), GetPrivateProfileInt); 72 | reg(kernel32, add_suffix("GetPrivateProfileStruct"), GetPrivateProfileStruct); 73 | reg(kernel32, add_suffix("GetPrivateProfileSection"), GetPrivateProfileSection); 74 | reg(kernel32, add_suffix("GetPrivateProfileSectionNames"), GetPrivateProfileSectionNames); 75 | reg(kernel32, add_suffix("WritePrivateProfileString"), WritePrivateProfileString); 76 | reg(kernel32, add_suffix("WritePrivateProfileStruct"), WritePrivateProfileStruct); 77 | reg(kernel32, add_suffix("WritePrivateProfileSection"), WritePrivateProfileSection); 78 | reg(kernel32, add_suffix("GetProfileString"), GetProfileString); 79 | reg(kernel32, add_suffix("GetProfileInt"), GetProfileInt); 80 | reg(kernel32, add_suffix("GetProfileSection"), GetProfileSection); 81 | reg(kernel32, add_suffix("WriteProfileString"), WriteProfileString); 82 | reg(kernel32, add_suffix("WriteProfileSection"), WriteProfileSection); 83 | 84 | { 85 | auto lib = std::string("api-ms-win-core-processenvironment-") + config.str("api-ms-win-core-processenvironment", "L1-1-0"); 86 | HMODULE processenvironment = ::LoadLibraryA(lib.c_str()); 87 | log(7, "try to load ", lib); 88 | if (!processenvironment) 89 | { 90 | processenvironment = kernel32; 91 | } 92 | else 93 | { 94 | log(7, "use ", lib); 95 | } 96 | reg(processenvironment, add_suffix("SetCurrentDirectory"), SetCurrentDirectory); 97 | reg(processenvironment, add_suffix("GetCurrentDirectory"), GetCurrentDirectory); 98 | if (!reg(processenvironment, add_suffix("GetTempPath"), GetTempPath)) 99 | reg(kernel32, add_suffix("GetTempPath"), GetTempPath); 100 | reg(processenvironment, add_suffix("GetWindowsDirectory"), GetWindowsDirectory); 101 | reg(processenvironment, add_suffix("GetSystemWindowsDirectory"), GetSystemWindowsDirectory); 102 | reg(processenvironment, add_suffix("GetSystemDirectory"), GetSystemDirectory); 103 | if (!reg(processenvironment, add_suffix("GetSystemWow64Directory"), GetSystemWow64Directory)) 104 | reg(kernel32, add_suffix("GetSystemWow64Directory"), GetSystemWow64Directory); 105 | } 106 | 107 | reg(kernel32, add_suffix("GetModuleFileName"), GetModuleFileName); 108 | reg(kernel32, add_suffix("GetFullPathName"), GetFullPathName); 109 | reg(kernel32, add_suffix("GetFinalPathNameByHandle"), GetFinalPathNameByHandle); 110 | 111 | reg(kernel32, add_suffix("SearchPath"), SearchPath); 112 | 113 | reg(kernel32, add_suffix("GetShortPathName"), GetShortPathName); 114 | reg(kernel32, add_suffix("GetLongPathName"), GetLongPathName); 115 | 116 | { 117 | auto lib = std::string("api-ms-win-core-sysinfo-") + config.str("api-ms-win-core-sysinfo", "L1-1-0"); 118 | HMODULE sysinfo = ::LoadLibraryA(lib.c_str()); 119 | log(7, "try to load ", lib); 120 | if (!sysinfo) 121 | { 122 | sysinfo = kernel32; 123 | } 124 | else 125 | { 126 | log(7, "use ", lib); 127 | } 128 | reg(sysinfo, "GetSystemInfo", GetSystemInfo); 129 | if (!reg(sysinfo, "GetNativeSystemInfo", GetNativeSystemInfo)) 130 | reg(kernel32, "GetNativeSystemInfo", GetNativeSystemInfo); 131 | reg(sysinfo, "GetSystemTime", GetSystemTime); 132 | reg(sysinfo, "GetLocalTime", GetLocalTime); 133 | reg(sysinfo, "GetSystemTimeAsFileTime", GetSystemTimeAsFileTime); 134 | reg(sysinfo, add_suffix("GetVersionEx"), GetVersionEx); 135 | reg(sysinfo, "GetVersion", GetVersion); 136 | reg(kernel32, add_suffix("VerifyVersionInfo"), VerifyVersionInfo); 137 | if (!reg(sysinfo, "GetProductInfo", GetProductInfo)) 138 | reg(kernel32, "GetProductInfo", GetProductInfo); 139 | reg(sysinfo, "GetLogicalProcessorInformation", GetLogicalProcessorInformation); 140 | reg(sysinfo, "GetLogicalProcessorInformationEx", GetLogicalProcessorInformationEx); 141 | if (!reg(sysinfo, "IsProcessorFeaturePresent", IsProcessorFeaturePresent)) 142 | reg(kernel32, "IsProcessorFeaturePresent", IsProcessorFeaturePresent); 143 | reg(sysinfo, add_suffix("GetEnvironmentVariable"), GetEnvironmentVariable); 144 | reg(sysinfo, add_suffix("ExpandEnvironmentStrings"), ExpandEnvironmentStrings); 145 | reg(sysinfo, add_suffix("GetComputerName"), GetComputerName); 146 | reg(sysinfo, add_suffix("GetComputerNameEx"), GetComputerNameEx); 147 | } 148 | 149 | reg(kernel32, add_suffix("LZOpenFile"), LZOpenFile); 150 | 151 | { 152 | auto lib = std::string("api-ms-win-core-processthreads-") + config.str("api-ms-win-core-processthreads", "L1-1-0"); 153 | HMODULE processthreads = ::LoadLibraryA(lib.c_str()); 154 | log(7, "try to load ", lib); 155 | if (!processthreads) 156 | { 157 | processthreads = kernel32; 158 | } 159 | else 160 | { 161 | log(7, "use ", lib); 162 | } 163 | reg(processthreads, add_suffix("CreateProcess"), CreateProcess); 164 | } 165 | 166 | reg(kernel32, add_suffix("GetStartupInfo"), GetStartupInfo); 167 | reg(kernel32, "WinExec", WinExec); 168 | reg(kernel32, add_suffix("GetBinaryType"), GetBinaryType); 169 | 170 | //debug 171 | reg(kernel32, "IsDebuggerPresent", IsDebuggerPresent); 172 | 173 | //misc 174 | reg(kernel32, "IsWow64Process", IsWow64Process); 175 | 176 | //api-ms-win-core-synch 177 | reg(kernel32, add_suffix("CreateMutex"), CreateMutex); 178 | reg(kernel32, add_suffix("CreateMutexEx"), CreateMutexEx); 179 | reg(kernel32, add_suffix("OpenMutex"), OpenMutex); 180 | } 181 | }; 182 | -------------------------------------------------------------------------------- /mod/kernel32/system.h: -------------------------------------------------------------------------------- 1 | static VOID WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo) 2 | { 3 | auto x = info("GetSystemInfo", lpSystemInfo); 4 | orig(GetSystemInfo)(lpSystemInfo); 5 | lpSystemInfo->dwOemId; 6 | lpSystemInfo->wProcessorArchitecture; 7 | lpSystemInfo->wReserved; 8 | lpSystemInfo->dwPageSize; 9 | lpSystemInfo->lpMinimumApplicationAddress; 10 | lpSystemInfo->lpMaximumApplicationAddress; 11 | lpSystemInfo->dwActiveProcessorMask; 12 | lpSystemInfo->dwNumberOfProcessors; 13 | lpSystemInfo->dwProcessorType; 14 | lpSystemInfo->dwAllocationGranularity; 15 | lpSystemInfo->wProcessorLevel; 16 | lpSystemInfo->wProcessorRevision; 17 | } 18 | 19 | static void WINAPI GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) 20 | { 21 | auto x = info("GetNativeSystemInfo", lpSystemInfo); 22 | orig(GetNativeSystemInfo)(lpSystemInfo); 23 | } 24 | 25 | static VOID WINAPI GetSystemTime(LPSYSTEMTIME lpSystemTime) 26 | { 27 | auto x = info("GetSystemTime", lpSystemTime); 28 | orig(GetSystemTime)(lpSystemTime); 29 | SaveError s; 30 | lpSystemTime->wYear = config.dword("Time_wYear", lpSystemTime->wYear); 31 | lpSystemTime->wMonth = config.dword("Time_wMonth", lpSystemTime->wMonth); 32 | lpSystemTime->wDayOfWeek = config.dword("Time_wDayOfWeek", lpSystemTime->wDayOfWeek); 33 | lpSystemTime->wDay = config.dword("Time_wDay", lpSystemTime->wDay); 34 | lpSystemTime->wHour = config.dword("Time_wHour", lpSystemTime->wHour); 35 | lpSystemTime->wMinute = config.dword("Time_wMinute", lpSystemTime->wMinute); 36 | lpSystemTime->wSecond = config.dword("Time_wSecond", lpSystemTime->wSecond); 37 | lpSystemTime->wMilliseconds = config.dword("Time_wMilliseconds", lpSystemTime->wMilliseconds); 38 | } 39 | 40 | static VOID WINAPI GetLocalTime(LPSYSTEMTIME lpSystemTime) 41 | { 42 | auto x = info("GetLocalTime", lpSystemTime); 43 | orig(GetLocalTime)(lpSystemTime); 44 | SaveError s; 45 | lpSystemTime->wYear = config.dword("Time_wYear", lpSystemTime->wYear); 46 | lpSystemTime->wMonth = config.dword("Time_wMonth", lpSystemTime->wMonth); 47 | lpSystemTime->wDayOfWeek = config.dword("Time_wDayOfWeek", lpSystemTime->wDayOfWeek); 48 | lpSystemTime->wDay = config.dword("Time_wDay", lpSystemTime->wDay); 49 | lpSystemTime->wHour = config.dword("Time_wHour", lpSystemTime->wHour); 50 | lpSystemTime->wMinute = config.dword("Time_wMinute", lpSystemTime->wMinute); 51 | lpSystemTime->wSecond = config.dword("Time_wSecond", lpSystemTime->wSecond); 52 | lpSystemTime->wMilliseconds = config.dword("Time_wMilliseconds", lpSystemTime->wMilliseconds); 53 | } 54 | 55 | static VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) 56 | { 57 | auto x = info("GetSystemTimeAsFileTime", lpSystemTimeAsFileTime); 58 | orig(GetSystemTimeAsFileTime)(lpSystemTimeAsFileTime); 59 | SaveError s; 60 | lpSystemTimeAsFileTime->dwLowDateTime = config.dword("dwLowDateTime", lpSystemTimeAsFileTime->dwLowDateTime); 61 | lpSystemTimeAsFileTime->dwHighDateTime = config.dword("dwHighDateTime", lpSystemTimeAsFileTime->dwHighDateTime); 62 | } 63 | 64 | static BOOL WINAPI GetVersionEx(OSVersionInfo *lpVersionInfo) 65 | { 66 | auto x = info(add_suffix("GetVersionEx"), lpVersionInfo); 67 | x.result = orig(GetVersionEx)(lpVersionInfo); 68 | SaveError s; 69 | lpVersionInfo->dwMajorVersion = config.dword("dwMajorVersion", lpVersionInfo->dwMajorVersion); 70 | lpVersionInfo->dwMinorVersion = config.dword("dwMinorVersion", lpVersionInfo->dwMinorVersion); 71 | if (lpVersionInfo->dwOSVersionInfoSize == sizeof(OSVERSIONINFO)) 72 | return x.result; 73 | lpVersionInfo->wProductType = config.dword("wProductType", lpVersionInfo->wProductType); 74 | return x.result; 75 | } 76 | 77 | static DWORD WINAPI GetVersion() 78 | { 79 | auto x = info("GetVersion"); 80 | if (config.exists("GetVersion")) 81 | x.result = config.dword("GetVersion"); 82 | else 83 | x.result = orig(GetVersion)(); 84 | return x.result; 85 | } 86 | 87 | static BOOL WINAPI VerifyVersionInfo( 88 | OSVersionInfo *lpVersionInformation, 89 | DWORD dwTypeMask, 90 | DWORDLONG dwlConditionMask 91 | ) 92 | { 93 | auto x = info(add_suffix("VerifyVersionInfo"), lpVersionInformation, dwTypeMask, dwlConditionMask); 94 | if (config.exists("VerifyVersionInfo")) 95 | x.result = config.dword("VerifyVersionInfo"); 96 | else 97 | x.result = orig(VerifyVersionInfo)(lpVersionInformation, dwTypeMask, dwlConditionMask); 98 | return x.result; 99 | } 100 | 101 | static BOOL WINAPI GetProductInfo( 102 | DWORD dwOSMajorVersion, 103 | DWORD dwOSMinorVersion, 104 | DWORD dwSpMajorVersion, 105 | DWORD dwSpMinorVersion, 106 | PDWORD pdwReturnedProductType 107 | ) 108 | { 109 | auto x = info("GetProductInfo", dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion, pdwReturnedProductType); 110 | if (config.exists("GetProductInfo")) 111 | { 112 | *pdwReturnedProductType = config.dword("GetProductInfo"); 113 | x.result = true; 114 | } 115 | else 116 | { 117 | x.result = orig(GetProductInfo)(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion, pdwReturnedProductType); 118 | } 119 | return x.result; 120 | } 121 | 122 | static BOOL WINAPI GetLogicalProcessorInformation( 123 | PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, 124 | PDWORD ReturnLength 125 | ) 126 | { 127 | auto x = info("GetLogicalProcessorInformation", Buffer, ReturnLength); 128 | x.result = orig(GetLogicalProcessorInformation)(Buffer, ReturnLength); 129 | SaveError s; 130 | x.l(-1, "unimplemented"); 131 | return x.result; 132 | } 133 | static BOOL WINAPI GetLogicalProcessorInformationEx( 134 | LOGICAL_PROCESSOR_RELATIONSHIP RelationshipType, 135 | PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX Buffer, 136 | PDWORD ReturnedLength 137 | ) 138 | { 139 | auto x = info("GetLogicalProcessorInformation", RelationshipType, Buffer, ReturnedLength); 140 | x.result = orig(GetLogicalProcessorInformationEx)(RelationshipType, Buffer, ReturnedLength); 141 | SaveError s; 142 | x.l(-1, "unimplemented"); 143 | return x.result; 144 | } 145 | 146 | static BOOL WINAPI IsProcessorFeaturePresent( 147 | DWORD ProcessorFeature 148 | ) 149 | { 150 | auto x = info("IsProcessorFeaturePresent", ProcessorFeature); 151 | return x.result = orig(IsProcessorFeaturePresent)(ProcessorFeature); 152 | } 153 | 154 | static DWORD WINAPI GetEnvironmentVariable( 155 | const C *lpName, 156 | C *lpBuffer, 157 | DWORD nSize 158 | ) 159 | { 160 | auto x = info(add_suffix("GetEnvironmentVariable"), lpName, lpBuffer, nSize); 161 | string buf(nSize + MAX_PATH, 0); 162 | x.result = orig(GetEnvironmentVariable)(lpName, &buf[0], nSize + MAX_PATH); 163 | SaveError s; 164 | buf.resize(x.result); 165 | if (x.result) 166 | { 167 | auto vp = cnv::vp(buf); 168 | x.l(5, lpName, " = ", buf, " > ", vp); 169 | x.result = String::cpy(lpBuffer, vp, nSize); 170 | if (nSize <= vp.size()) 171 | x.result = vp.size() + 1; 172 | } 173 | else 174 | { 175 | x.l(6, lpName, " is not exists"); 176 | } 177 | return x.result; 178 | } 179 | 180 | static DWORD WINAPI ExpandEnvironmentStrings( 181 | const C *lpSrc, 182 | C *lpDst, 183 | DWORD nSize 184 | ) 185 | { 186 | auto x = info(add_suffix("ExpandEnvironmentStrings"), lpSrc, lpDst, nSize); 187 | string buf(nSize + MAX_PATH, 0); 188 | x.result = orig(ExpandEnvironmentStrings)(lpSrc, &buf[0], nSize); 189 | SaveError s; 190 | buf.resize(x.result); 191 | if (x.result) 192 | { 193 | auto vp = cnv::vp(buf); 194 | x.l(5, lpSrc, " > ", buf, " > ", vp); 195 | x.result = String::cpy(lpDst, vp, nSize); 196 | if (nSize <= vp.size()) 197 | x.result = vp.size() + 1; 198 | } 199 | else 200 | { 201 | x.l(6, "failed!"); 202 | } 203 | return x.result; 204 | } 205 | 206 | static BOOL WINAPI GetComputerName( 207 | C *lpBuffer, 208 | LPDWORD lpnSize 209 | ) 210 | { 211 | auto x = info(add_suffix("GetComputerName"), lpBuffer, lpnSize); 212 | return x.result = orig(GetComputerName)(lpBuffer, lpnSize); 213 | } 214 | 215 | static BOOL WINAPI GetComputerNameEx( 216 | COMPUTER_NAME_FORMAT NameType, 217 | C *lpBuffer, 218 | LPDWORD nSize 219 | ) 220 | { 221 | auto x = info(add_suffix("GetComputerNameEx"), NameType, lpBuffer, nSize); 222 | return x.result = orig(GetComputerNameEx)(NameType, lpBuffer, nSize); 223 | } 224 | 225 | //GetCurrentPackage**? 226 | //GetUserName -> advapi32 227 | //GetUserNameEx -> secur32 228 | //GetComputerObjectName -> secur32 229 | //GetCurrentHwProfile -> advapi32 230 | //https://msdn.microsoft.com/ja-jp/library/cc429371.aspx 231 | -------------------------------------------------------------------------------- /mod/ole32.h: -------------------------------------------------------------------------------- 1 | #pragma comment(lib, "ole32") 2 | struct Ole32 3 | { 4 | struct PreLoad 5 | { 6 | HMODULE m = NULL; 7 | PreLoad(REFCLSID rclsid) 8 | { 9 | wchar_t *buf; 10 | StringFromCLSID(rclsid, &buf); 11 | auto subkey = String::concat("CLSID\\", buf, "\\InProcServer32"); 12 | CoTaskMemFree(buf); 13 | HKEY key; 14 | if (!Advapi32::RegOpenKeyEx(HKEY_CLASSES_ROOT, subkey.c_str(), 0, KEY_READ, &key)) 15 | { 16 | wchar_t data[MAX_PATH]; 17 | DWORD size = MAX_PATH; 18 | if (!Advapi32::RegQueryValueEx(key, NULL, NULL, NULL, (BYTE*)&data, &size)) 19 | { 20 | wchar_t dest[MAX_PATH]; 21 | Kernel32::ExpandEnvironmentStrings(data, dest, MAX_PATH); 22 | m = Kernel32::GetModuleHandle(dest); 23 | if (m) 24 | { 25 | m = NULL; 26 | } 27 | else 28 | { 29 | log(1, "CoCreateInstance:PreLoad:", dest); 30 | m = Kernel32::LoadLibraryEx(dest, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); 31 | } 32 | } 33 | Advapi32::RegCloseKey(key); 34 | } 35 | } 36 | ~PreLoad() 37 | { 38 | if (m) 39 | FreeLibrary(m); 40 | } 41 | }; 42 | 43 | static HRESULT WINAPI CoCreateInstance( 44 | REFCLSID rclsid, 45 | LPUNKNOWN pUnkOuter, 46 | DWORD dwClsContext, 47 | REFIID riid, 48 | LPVOID *ppv 49 | ) 50 | { 51 | auto x = info("CoCreateInstance", rclsid, pUnkOuter, dwClsContext, riid, ppv); 52 | if (config.dword("NO_CLSID_ShellLink") && rclsid == CLSID_ShellLink) 53 | { 54 | x.l(1, "CLSID_ShellLink"); 55 | return x.result = 632L; 56 | } 57 | x.l(1, FuncInfo::guid(rclsid)); 58 | PreLoad p(rclsid); 59 | x.result = orig(CoCreateInstance)(rclsid, pUnkOuter, dwClsContext, riid, ppv); 60 | return x.result; 61 | } 62 | static HRESULT WINAPI combaseCoCreateInstance( 63 | REFCLSID rclsid, 64 | LPUNKNOWN pUnkOuter, 65 | DWORD dwClsContext, 66 | REFIID riid, 67 | LPVOID *ppv 68 | ) 69 | { 70 | auto x = info("combase.CoCreateInstance", rclsid, pUnkOuter, dwClsContext, riid, ppv); 71 | if (config.dword("NO_CLSID_ShellLink") && rclsid == CLSID_ShellLink) 72 | { 73 | x.l(1, "CLSID_ShellLink"); 74 | return x.result = 632L; 75 | } 76 | x.l(1, FuncInfo::guid(rclsid)); 77 | PreLoad p(rclsid); 78 | x.result = orig(combaseCoCreateInstance)(rclsid, pUnkOuter, dwClsContext, riid, ppv); 79 | return x.result; 80 | } 81 | 82 | static HRESULT WINAPI CoCreateInstanceEx( 83 | REFCLSID Clsid, 84 | IUnknown *punkOuter, 85 | DWORD dwClsCtx, 86 | COSERVERINFO *pServerInfo, 87 | DWORD dwCount, 88 | MULTI_QI *pResults 89 | ) 90 | { 91 | auto x = info("CoCreateInstanceEx", Clsid, punkOuter, dwClsCtx, pServerInfo, dwCount, pResults); 92 | if (config.dword("NO_CLSID_ShellLink") && Clsid == CLSID_ShellLink) 93 | { 94 | x.l(1, "CLSID_ShellLink"); 95 | return x.result = 632L; 96 | } 97 | x.l(1, FuncInfo::guid(Clsid)); 98 | PreLoad p(Clsid); 99 | x.result = orig(CoCreateInstanceEx)(Clsid, punkOuter, dwClsCtx, pServerInfo, dwCount, pResults); 100 | return x.result; 101 | } 102 | 103 | static HRESULT WINAPI CoGetInterfaceAndReleaseStream( 104 | LPSTREAM pStm, 105 | REFIID iid, 106 | LPVOID *ppv 107 | ) 108 | { 109 | auto x = info("CoGetInterfaceAndReleaseStream", pStm, iid, ppv); 110 | x.l(9, "log only"); 111 | x.result = orig(CoGetInterfaceAndReleaseStream)(pStm, iid, ppv); 112 | return x.result; 113 | } 114 | 115 | static HRESULT WINAPI CoMarshalInterThreadInterfaceInStream( 116 | REFIID riid, 117 | LPUNKNOWN pUnk, 118 | LPSTREAM *ppStm 119 | ) 120 | { 121 | auto x = info("CoMarshalInterThreadInterfaceInStream", riid, pUnk, ppStm); 122 | x.l(9, "log only"); 123 | x.result = orig(CoMarshalInterThreadInterfaceInStream)(riid, pUnk, ppStm); 124 | return x.result; 125 | } 126 | 127 | static HRESULT WINAPI CoRegisterClassObject( 128 | REFCLSID rclsid, 129 | LPUNKNOWN pUnk, 130 | DWORD dwClsContext, 131 | DWORD flags, 132 | LPDWORD lpdwRegister 133 | ) 134 | { 135 | auto x = info("CoRegisterClassObject", rclsid, pUnk, dwClsContext, flags, lpdwRegister); 136 | x.l(9, "log only"); 137 | x.result = orig(CoRegisterClassObject)(rclsid, pUnk, dwClsContext, flags, lpdwRegister); 138 | return x.result; 139 | } 140 | 141 | static HRESULT WINAPI CreateFileMoniker( 142 | LPCOLESTR lpszPathName, 143 | LPMONIKER *ppmk 144 | ) 145 | { 146 | auto x = info("CreateFileMoniker", lpszPathName, ppmk); 147 | x.l(9, "log only"); 148 | return x.result = orig(CreateFileMoniker)(lpszPathName, ppmk); 149 | } 150 | 151 | static HRESULT WINAPI StgCreateDocfile( 152 | const WCHAR *pwcsName, 153 | DWORD grfMode, 154 | DWORD reserved, 155 | IStorage **ppstgOpen 156 | ) 157 | { 158 | auto x = info("StgCreateDocfile", pwcsName, grfMode, reserved, ppstgOpen); 159 | x.l(9, "log only"); 160 | x.result = orig(StgCreateDocfile)(pwcsName, grfMode, reserved, ppstgOpen); 161 | return x.result; 162 | } 163 | 164 | static HRESULT WINAPI StgOpenStorage( 165 | const WCHAR *pwcsName, 166 | IStorage *pstgPriority, 167 | DWORD grfMode, 168 | SNB snbExclude, 169 | DWORD reserved, 170 | IStorage **ppstgOpen 171 | ) 172 | { 173 | auto x = info("StgOpenStorage", pwcsName, pstgPriority, grfMode, snbExclude, reserved, ppstgOpen); 174 | x.l(9, "log only"); 175 | return x.result = orig(StgOpenStorage)(pwcsName, pstgPriority, grfMode, snbExclude, reserved, ppstgOpen); 176 | } 177 | 178 | static HRESULT WINAPI StgOpenStorageEx( 179 | const WCHAR *pwcsName, 180 | DWORD grfMode, 181 | DWORD stgfmt, 182 | DWORD grfAttrs, 183 | STGOPTIONS *pStgOptions, 184 | PSECURITY_DESCRIPTOR pSecurityDescriptor, 185 | REFIID riid, 186 | void **ppObjectOpen 187 | ) 188 | { 189 | auto x = info("StgOpenStorage", pwcsName, grfMode, stgfmt, grfAttrs, pStgOptions, pSecurityDescriptor, riid, ppObjectOpen); 190 | x.l(9, "log only"); 191 | return x.result = orig(StgOpenStorageEx)(pwcsName, grfMode, stgfmt, grfAttrs, pStgOptions, pSecurityDescriptor, riid, ppObjectOpen); 192 | } 193 | 194 | static HRESULT WINAPI OleLoadPicturePath( 195 | LPOLESTR szURLorPath, 196 | LPUNKNOWN punkCaller, 197 | DWORD dwReserved, 198 | OLE_COLOR clrReserved, 199 | REFIID riid, 200 | LPVOID *ppvRet 201 | ) 202 | { 203 | auto x = info("OleLoadPicturePath", szURLorPath, punkCaller, dwReserved, clrReserved, riid, ppvRet); 204 | auto f = cnv::getExists(szURLorPath); 205 | return x.result = orig(OleLoadPicturePath)(szURLorPath, punkCaller, dwReserved, clrReserved, riid, ppvRet); 206 | } 207 | 208 | static HRESULT WINAPI LoadTypeLib( 209 | LPCOLESTR szFile, 210 | ITypeLib **pptlib 211 | ) 212 | { 213 | auto x = info("LoadTypeLib", szFile, pptlib); 214 | auto f = cnv::getExists(szFile); 215 | x.l(7, szFile, " > ", f); 216 | x.result = orig(LoadTypeLib)(f.c_str(), pptlib); 217 | return x.result; 218 | } 219 | static HRESULT WINAPI LoadTypeLibEx( 220 | LPCOLESTR szFile, 221 | REGKIND regkind, 222 | ITypeLib **pptlib 223 | ) 224 | { 225 | auto x = info("LoadTypeLib", szFile, regkind, pptlib); 226 | auto f = cnv::getExists(szFile); 227 | x.l(7, szFile, " > ", f); 228 | x.result = orig(LoadTypeLibEx)(f.c_str(), regkind, pptlib); 229 | return x.result; 230 | } 231 | 232 | static HRESULT WINAPI RegisterTypeLib( 233 | ITypeLib *ptlib, 234 | LPCOLESTR szFullPath, 235 | LPCOLESTR szHelpDir 236 | ) 237 | { 238 | auto x = info("RegisterTypeLib", ptlib, szFullPath, szHelpDir); 239 | auto f = cnv::getExists(szFullPath); 240 | x.l(7, szFullPath, " > ", f); 241 | x.result = orig(RegisterTypeLib)(ptlib, f.c_str(), szHelpDir); 242 | return x.result; 243 | } 244 | 245 | static void Attach() 246 | { 247 | HMODULE ole32 = LoadLibraryA("ole32"); 248 | reg(ole32, "CoCreateInstance", CoCreateInstance); 249 | reg(ole32, "CoCreateInstanceEx", CoCreateInstanceEx); 250 | //CoGetObject 251 | /*reg(ole32, "CoGetInterfaceAndReleaseStream", CoGetInterfaceAndReleaseStream); 252 | reg(ole32, "CoMarshalInterThreadInterfaceInStream", CoMarshalInterThreadInterfaceInStream); 253 | reg(ole32, "CoRegisterClassObject", CoRegisterClassObject); 254 | reg(ole32, "CreateFileMoniker", CreateFileMoniker); 255 | reg(ole32, "StgCreateDocfile", StgCreateDocfile); 256 | reg(ole32, "StgOpenStorage", StgOpenStorage); 257 | reg(ole32, "StgOpenStorageEx", StgOpenStorageEx);*/ 258 | 259 | HMODULE oleaut32 = LoadLibraryA("oleaut32"); 260 | reg(oleaut32, "OleLoadPicturePath", OleLoadPicturePath); 261 | reg(oleaut32, "LoadTypeLib", LoadTypeLib); 262 | reg(oleaut32, "LoadTypeLibEx", LoadTypeLibEx); 263 | reg(oleaut32, "RegisterTypeLib", RegisterTypeLib); 264 | 265 | if (config.dword("combase")) 266 | { 267 | HMODULE combase = LoadLibraryA("combase"); 268 | if (combase) 269 | { 270 | log(9, "combase load"); 271 | reg(combase, "CoCreateInstance", combaseCoCreateInstance); 272 | } 273 | } 274 | } 275 | }; 276 | //IShellLink 277 | //IPersistFile 278 | -------------------------------------------------------------------------------- /mod/kernel32/file.h: -------------------------------------------------------------------------------- 1 | static HANDLE WINAPI CreateFile( 2 | const C *lpFileName, 3 | DWORD dwDesiredAccess, 4 | DWORD dwShareMode, 5 | LPSECURITY_ATTRIBUTES lpSecurityAttributes, 6 | DWORD dwCreationDisposition, 7 | DWORD dwFlagsAndAttributes, 8 | HANDLE hTemplateFile 9 | ) 10 | { 11 | auto x = info(add_suffix("CreateFile"), lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); 12 | 13 | if (!(dwDesiredAccess & GENERIC_WRITE) 14 | && (dwCreationDisposition != CREATE_NEW && dwCreationDisposition != CREATE_ALWAYS && dwCreationDisposition != TRUNCATE_EXISTING) 15 | ) 16 | { 17 | auto ep = cnv::getExists(lpFileName); 18 | x.l(6, lpFileName, " > ", ep); 19 | x.result = orig(CreateFile)(ep.c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); 20 | return x.result; 21 | } 22 | else 23 | { 24 | auto sp = cnv::sp(lpFileName); 25 | x.l(3, lpFileName, " > ", sp); 26 | x.result = orig(CreateFile)(sp.c_str(), dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); 27 | return x.result; 28 | } 29 | } 30 | 31 | static BOOL WINAPI MoveFile( 32 | const C *lpExistingFileName, 33 | const C *lpNewFileName 34 | ) 35 | { 36 | auto x = info(add_suffix("MoveFile"), lpExistingFileName, lpNewFileName); 37 | auto ep = cnv::sp(lpExistingFileName); 38 | auto np = cnv::sp(lpNewFileName); 39 | x.l(3, lpExistingFileName, " > ", ep, " > ", np); 40 | x.result = orig(MoveFile)(ep.c_str(), np.c_str()); 41 | return x.result; 42 | } 43 | 44 | static BOOL WINAPI MoveFileEx( 45 | const C *lpExistingFileName, 46 | const C *lpNewFileName, 47 | DWORD dwFlags 48 | ) 49 | { 50 | auto x = info(add_suffix("MoveFileEx"), lpExistingFileName, lpNewFileName, dwFlags); 51 | string exf; 52 | string newf; 53 | if (lpExistingFileName) 54 | { 55 | exf = cnv::sp(lpExistingFileName); 56 | lpExistingFileName = exf.c_str(); 57 | } 58 | if (lpNewFileName) 59 | { 60 | newf = cnv::sp(lpNewFileName); 61 | lpNewFileName = newf.c_str(); 62 | } 63 | x.l(3, exf, " > ", newf); 64 | x.result = orig(MoveFileEx)(lpExistingFileName, lpNewFileName, dwFlags); 65 | return x.result; 66 | } 67 | 68 | static BOOL WINAPI CopyFile( 69 | const C *lpExistingFileName, 70 | const C *lpNewFileName, 71 | BOOL bFailIfExists 72 | ) 73 | { 74 | auto x = info(add_suffix("CopyFile"), lpExistingFileName, lpNewFileName, bFailIfExists); 75 | auto ef = cnv::getExists(lpExistingFileName); 76 | auto nf = cnv::sp(lpNewFileName); 77 | x.l(3, lpExistingFileName, " > ", ef, " > ", nf); 78 | x.result = orig(CopyFile)(ef.c_str(), nf.c_str(), bFailIfExists); 79 | return x.result; 80 | } 81 | 82 | static BOOL WINAPI CopyFileEx( 83 | const C *lpExistingFileName, 84 | const C *lpNewFileName, 85 | LPPROGRESS_ROUTINE lpProgressRoutine, 86 | LPVOID lpData, 87 | LPBOOL pbCancel, 88 | DWORD dwCopyFlags 89 | ) 90 | { 91 | auto x = info(add_suffix("CopyFileEx"), lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, pbCancel, dwCopyFlags); 92 | auto ef = cnv::getExists(lpExistingFileName); 93 | auto nf = cnv::sp(lpNewFileName); 94 | x.l(3, lpExistingFileName, " > ", ef, " > ", nf); 95 | x.result = orig(CopyFileEx)(ef.c_str(), nf.c_str(), lpProgressRoutine, lpData, pbCancel, dwCopyFlags); 96 | return x.result; 97 | } 98 | 99 | static BOOL WINAPI DeleteFile( 100 | const C *lpFileName 101 | ) 102 | { 103 | auto x = info(add_suffix("DeleteFile"), lpFileName); 104 | auto sp = cnv::sp(lpFileName); 105 | x.l(3, lpFileName, " > ", sp); 106 | x.result = orig(DeleteFile)(sp.c_str()); 107 | return x.result; 108 | } 109 | 110 | static BOOL WINAPI ReplaceFile( 111 | const C *lpReplacedFileName, 112 | const C *lpReplacementFileName, 113 | const C *lpBackupFileName, 114 | DWORD dwReplaceFlags, 115 | LPVOID lpExclude, 116 | LPVOID lpReserved 117 | ) 118 | { 119 | auto x = info(add_suffix("ReplaceFile"), lpReplacedFileName, lpReplacementFileName, lpBackupFileName, dwReplaceFlags, lpExclude, lpReserved); 120 | x.l(-1, "unimplemented"); 121 | //The backup file, replaced file, and replacement file must all reside on the same volume. 122 | auto from = cnv::sp(lpReplacedFileName); 123 | auto to = cnv::sp(lpReplacementFileName); 124 | string backup; 125 | if (lpBackupFileName) 126 | { 127 | backup = cnv::sp(lpBackupFileName); 128 | lpBackupFileName = backup.c_str(); 129 | } 130 | x.l(3, from, " > ", to, " : ", backup); 131 | x.result = orig(ReplaceFile)(from.c_str(), to.c_str(), lpBackupFileName, dwReplaceFlags, lpExclude, lpReserved); 132 | return x.result; 133 | } 134 | 135 | static BOOL WINAPI CreateDirectory( 136 | const C *lpPathName, 137 | LPSECURITY_ATTRIBUTES lpSecurityAttributes 138 | ) 139 | { 140 | auto x = info(add_suffix("CreateDirectory"), lpPathName, lpSecurityAttributes); 141 | if (lpPathName) 142 | { 143 | auto sp = cnv::sp(lpPathName); 144 | x.l(3, lpPathName, " > ", sp); 145 | x.result = orig(CreateDirectory)(sp.c_str(), lpSecurityAttributes); 146 | } 147 | else 148 | { 149 | x.l(3, "NULL"); 150 | x.result = orig(CreateDirectory)(lpPathName, lpSecurityAttributes); 151 | } 152 | return x.result; 153 | } 154 | 155 | static BOOL WINAPI CreateDirectoryEx( 156 | const C *lpTemplateDirectory, 157 | const C *lpNewDirectory, 158 | LPSECURITY_ATTRIBUTES lpSecurityAttributes 159 | ) 160 | { 161 | auto x = info(add_suffix("CreateDirectoryEx"), lpTemplateDirectory, lpNewDirectory, lpSecurityAttributes); 162 | auto td = cnv::getExists(lpTemplateDirectory); 163 | auto nd = cnv::sp(lpNewDirectory); 164 | x.l(3, lpNewDirectory, " > ", nd); 165 | x.result = orig(CreateDirectoryEx)(td.c_str(), nd.c_str(), lpSecurityAttributes); 166 | return x.result; 167 | } 168 | 169 | static BOOL WINAPI RemoveDirectory( 170 | const C *lpPathName 171 | ) 172 | { 173 | auto x = info(add_suffix("RemoveDirectory"), lpPathName); 174 | auto sp = cnv::sp(lpPathName); 175 | x.l(3, lpPathName, " > ", sp); 176 | x.result = orig(RemoveDirectory)(sp.c_str()); 177 | return x.result; 178 | } 179 | 180 | static HANDLE WINAPI FindFirstFile( 181 | const C *lpFileName, 182 | LPWIN32_FIND_DATA lpFindFileData 183 | ) 184 | { 185 | auto x = info(add_suffix("FindFirstFile"), lpFileName, lpFindFileData); 186 | auto sp = cnv::sp(lpFileName); 187 | x.result = orig(FindFirstFile)(sp.c_str(), lpFindFileData); 188 | if (x.result != INVALID_HANDLE_VALUE) 189 | { 190 | x.l(6, lpFileName, " > ", sp); 191 | } 192 | else 193 | { 194 | auto cp = cnv::cp(lpFileName); 195 | x.result = orig(FindFirstFile)(cp.c_str(), lpFindFileData); 196 | if (x.result != INVALID_HANDLE_VALUE) 197 | x.l(6, lpFileName, " > ", cp); 198 | else 199 | x.l(6, lpFileName, " failed!"); 200 | } 201 | return x.result; 202 | } 203 | 204 | static HANDLE WINAPI FindFirstFileEx( 205 | const C *lpFileName, 206 | FINDEX_INFO_LEVELS fInfoLevelId, 207 | LPVOID lpFindFileData, 208 | FINDEX_SEARCH_OPS fSearchOp, 209 | LPVOID lpSearchFilter, 210 | DWORD dwAdditionalFlags 211 | ) 212 | { 213 | auto x = info(add_suffix("FindFirstFileEx"), lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); 214 | auto sp = cnv::sp(lpFileName); 215 | x.result = orig(FindFirstFileEx)(sp.c_str(), fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); 216 | if (x.result != INVALID_HANDLE_VALUE) 217 | { 218 | x.l(6, lpFileName, " > ", sp); 219 | } 220 | else 221 | { 222 | auto cp = cnv::cp(lpFileName); 223 | x.result = orig(FindFirstFileEx)(cp.c_str(), fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); 224 | if (x.result != INVALID_HANDLE_VALUE) 225 | x.l(6, lpFileName, " > ", cp); 226 | else 227 | x.l(6, lpFileName, " failed!"); 228 | } 229 | return x.result; 230 | } 231 | 232 | static BOOL WINAPI SetFileAttributes(const C *lpFileName, DWORD dwFileAttributes) 233 | { 234 | auto x = info(add_suffix("SetFileAttributes"), lpFileName, dwFileAttributes); 235 | auto sp = cnv::sp(lpFileName); 236 | x.l(3, lpFileName, " > ", sp); 237 | x.result = orig(SetFileAttributes)(sp.c_str(), dwFileAttributes); 238 | return x.result; 239 | } 240 | 241 | static DWORD WINAPI GetFileAttributes(const C *lpFileName) 242 | { 243 | auto x = info(add_suffix("GetFileAttributes"), lpFileName); 244 | auto f = cnv::getExists(lpFileName); 245 | x.l(7, lpFileName, " > ", f); 246 | x.result = orig(GetFileAttributes)(f.c_str()); 247 | return x.result; 248 | } 249 | 250 | static DWORD WINAPI GetFileAttributesEx( 251 | const C *lpFileName, 252 | GET_FILEEX_INFO_LEVELS fInfoLevelId, 253 | LPVOID lpFileInformation 254 | ) 255 | { 256 | auto x = info(add_suffix("GetFileAttributesEx"), lpFileName, fInfoLevelId, lpFileInformation); 257 | if (lpFileName) 258 | { 259 | auto f = cnv::getExists(lpFileName); 260 | x.l(7, lpFileName, " > ", f); 261 | x.result = orig(GetFileAttributesEx)(f.c_str(), fInfoLevelId, lpFileInformation); 262 | } 263 | else 264 | { 265 | x.result = orig(GetFileAttributesEx)(lpFileName, fInfoLevelId, lpFileInformation); 266 | } 267 | return x.result; 268 | } 269 | 270 | static HFILE WINAPI _lopen( 271 | LPCSTR lpPathName, 272 | int iReadWrite 273 | ) 274 | { 275 | auto x = info("_lopen", lpPathName, iReadWrite); 276 | auto ep = cnv::getExists(lpPathName); 277 | x.result = orig(_lopen)(ep.c_str(), iReadWrite); 278 | return x.result; 279 | } 280 | static HFILE WINAPI OpenFile( 281 | LPCSTR lpFileName, 282 | LPOFSTRUCT lpReOpenBuff, 283 | UINT uStyle 284 | ) 285 | { 286 | auto x = info("OpenFile", lpFileName, lpReOpenBuff, uStyle); 287 | auto ep = cnv::getExists(lpFileName); 288 | x.result = orig(OpenFile)(ep.c_str(), lpReOpenBuff, uStyle); 289 | return x.result; 290 | } 291 | 292 | static UINT WINAPI GetTempFileName( 293 | const C *lpPathName, 294 | const C *lpPrefixString, 295 | UINT uUnique, 296 | C *lpTempFileName 297 | ) 298 | { 299 | auto x = info(add_suffix("GetTempFileName"), lpPathName, lpPrefixString, uUnique, lpTempFileName); 300 | auto sp = cnv::sp(lpPathName); 301 | x.result = orig(GetTempFileName)(sp.c_str(), lpPrefixString, uUnique, lpTempFileName); 302 | x.l(7, lpPathName, " > ", sp, " > ", lpTempFileName); 303 | return x.result; 304 | } 305 | 306 | /* 307 | CopyFileTransactedA 308 | CopyFileTransactedW 309 | CreateDirectoryTransactedA 310 | CreateDirectoryTransactedW 311 | CreateFileTransactedA 312 | CreateFileTransactedW 313 | DeleteFileTransactedA 314 | DeleteFileTransactedW 315 | FindFirstFileNameTransactedW 316 | FindFirstFileNameW 317 | FindFirstFileTransactedA 318 | FindFirstFileTransactedW 319 | MoveFileTransactedA 320 | MoveFileTransactedW 321 | RemoveDirectoryTransactedA 322 | RemoveDirectoryTransactedW 323 | 324 | FindFirstStreamTransactedW 325 | 326 | GetCompressedFileSizeA 327 | GetCompressedFileSizeTransactedA 328 | GetCompressedFileSizeTransactedW 329 | GetCompressedFileSizeW 330 | 331 | GetFileAttributesTransactedA 332 | GetFileAttributesTransactedW 333 | SetFileAttributesTransactedA 334 | SetFileAttributesTransactedW 335 | 336 | GetLongPathNameTransactedA 337 | GetLongPathNameTransactedW 338 | 339 | MoveFileWithProgress 340 | 341 | FindFirstChangeNotification 342 | 343 | FindFirstStreamW? 344 | */ 345 | -------------------------------------------------------------------------------- /mod/advapi32/reg.h: -------------------------------------------------------------------------------- 1 | static LONG WINAPI RegOpenKeyEx( 2 | HKEY hKey, 3 | const C *lpSubKey, 4 | DWORD ulOptions, 5 | REGSAM samDesired, 6 | PHKEY phkResult 7 | ) 8 | { 9 | auto x = info(add_suffix("RegOpenKeyEx"), hKey, lpSubKey, ulOptions, samDesired, phkResult); 10 | 11 | auto rpath = lpSubKey ? Path::Combine(GetDirectoryName(hKey), String::tstr(lpSubKey)) : GetDirectoryName(hKey); 12 | auto p = replace_invalid(rpath); 13 | if (!DirectoryExists(p)) 14 | { 15 | NativeRegistry n(rpath); 16 | if (n.result) 17 | { 18 | x.l(6, rpath, " error native key result=", n.result); 19 | return x.result = n.result; 20 | } 21 | } 22 | if (phkResult) 23 | { 24 | *phkResult = (HKEY)new RegistryKey(rpath); 25 | x.l(6, rpath, " HKEY=", FuncInfo::hex(*phkResult)); 26 | } 27 | else 28 | { 29 | x.l(6, rpath, " phkResult=NULL"); 30 | } 31 | 32 | return x.result = ERROR_SUCCESS; 33 | } 34 | static LONG WINAPI RegOpenKey( 35 | HKEY hKey, 36 | const C *lpSubKey, 37 | PHKEY phkResult 38 | ) 39 | { 40 | auto x = info(add_suffix("RegOpenKey"), hKey, lpSubKey, phkResult); 41 | return x.result = RegOpenKeyEx(hKey, lpSubKey, 0, 0, phkResult); 42 | } 43 | 44 | static LONG WINAPI RegOpenCurrentUser( 45 | REGSAM samDesired, 46 | PHKEY phkResult 47 | ) 48 | { 49 | auto x = info("RegOpenCurrentUser", samDesired, phkResult); 50 | return x.result = RegOpenKeyEx(HKEY_CURRENT_USER, NULL, 0, samDesired, phkResult); 51 | } 52 | 53 | static LONG WINAPI RegOpenUserClassesRoot( 54 | HANDLE hToken, 55 | DWORD dwOptions, 56 | REGSAM samDesired, 57 | PHKEY phkResult 58 | ) 59 | { 60 | auto x = info("RegOpenUserClassesRoot", hToken, dwOptions, samDesired, phkResult); 61 | return x.result = RegOpenKeyEx(HKEY_CLASSES_ROOT, NULL, 0, samDesired, phkResult); 62 | } 63 | 64 | static LONG WINAPI RegCloseKey(HKEY hKey) 65 | { 66 | auto x = info("RegCloseKey", hKey); 67 | if (hKey >= HKEY_CLASSES_ROOT) 68 | { 69 | return x.result = ERROR_SUCCESS; 70 | } 71 | if (isNativeHKey(hKey)) 72 | { 73 | x.l(5, "native HKEY?:", FuncInfo::hex(hKey)); 74 | return x.result = orig(RegCloseKey)(hKey); 75 | } 76 | RegistryKey *rk = (RegistryKey*)hKey; 77 | delete rk; 78 | return x.result = ERROR_SUCCESS; 79 | } 80 | 81 | static LONG WINAPI RegFlushKey(HKEY hKey) 82 | { 83 | auto x = info("RegFlushKey", hKey); 84 | return x.result = ERROR_SUCCESS; 85 | } 86 | 87 | static LONG WINAPI RegCreateKeyEx( 88 | HKEY hKey, 89 | const C *lpSubKey, 90 | DWORD Reserved, 91 | const C *lpClass, 92 | DWORD dwOptions, 93 | REGSAM samDesired, 94 | LPSECURITY_ATTRIBUTES lpSecurityAttributes, 95 | PHKEY phkResult, 96 | LPDWORD lpdwDisposition 97 | ) 98 | { 99 | auto x = info(add_suffix("RegCreateKeyEx"), hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); 100 | auto rpath = Path::Combine(GetDirectoryName(hKey), String::tstr(lpSubKey)); 101 | x.l(3, rpath); 102 | *phkResult = (HKEY)new RegistryKey(rpath); 103 | auto p = replace_invalid(rpath); 104 | if (DirectoryExists(p)) 105 | { 106 | if (lpdwDisposition) 107 | { 108 | *lpdwDisposition = REG_OPENED_EXISTING_KEY; 109 | } 110 | x.result = ERROR_SUCCESS; 111 | } 112 | else 113 | { 114 | if (lpdwDisposition) 115 | { 116 | *lpdwDisposition = REG_CREATED_NEW_KEY; 117 | } 118 | x.result = SHCreateDirectory(NULL, p.c_str()); 119 | } 120 | return x.result; 121 | } 122 | static LONG WINAPI RegCreateKey( 123 | HKEY hKey, 124 | const C *lpSubKey, 125 | PHKEY phkResult 126 | ) 127 | { 128 | auto x = info(add_suffix("RegCreateKey"), hKey, lpSubKey, phkResult); 129 | return x.result = RegCreateKeyEx(hKey, lpSubKey, NULL, NULL, 0, 0, NULL, phkResult, NULL); 130 | } 131 | 132 | static LONG WINAPI RegDeleteKeyEx( 133 | HKEY hKey, 134 | const C *lpSubKey, 135 | REGSAM samDesired, 136 | DWORD Reserved 137 | ) 138 | { 139 | auto x = info(add_suffix("RegDeleteKeyEx"), hKey, lpSubKey, samDesired, Reserved); 140 | auto rpath = Path::Combine(GetDirectoryName(hKey), String::tstr(lpSubKey)); 141 | auto p = replace_invalid(rpath); 142 | return x.result = !Directory::Delete(p, true); 143 | } 144 | static LONG WINAPI RegDeleteKey( 145 | HKEY hKey, 146 | const C *lpSubKey 147 | ) 148 | { 149 | auto x = info(add_suffix("RegDeleteKey"), hKey, lpSubKey); 150 | auto rpath = Path::Combine(GetDirectoryName(hKey), String::tstr(lpSubKey)); 151 | auto p = replace_invalid(rpath); 152 | return x.result = !Directory::Delete(p, true); 153 | } 154 | 155 | static LONG WINAPI RegDeleteValue( 156 | HKEY hKey, 157 | const C *lpValueName 158 | ) 159 | { 160 | auto x = info(add_suffix("RegDeleteValue"), hKey, lpValueName); 161 | auto rpath = Path::Combine(GetDirectoryName(hKey), String::tstr(lpValueName)); 162 | auto p = replace_invalid(rpath); 163 | return x.result = !orig(Kernel32::DeleteFile)(p.c_str()); 164 | } 165 | 166 | static LONG WINAPI RegEnumKeyEx( 167 | HKEY hKey, 168 | DWORD dwIndex, 169 | C *lpName, 170 | LPDWORD lpcName, 171 | LPDWORD lpReserved, 172 | C *lpClass, 173 | LPDWORD lpcClass, 174 | PFILETIME lpftLastWriteTime 175 | ) 176 | { 177 | auto x = info(add_suffix("RegEnumKeyEx"), hKey, dwIndex, lpName, lpcName, lpReserved, lpClass, lpcClass, lpftLastWriteTime); 178 | auto rpath = GetDirectoryName(hKey); 179 | x.l(6, rpath); 180 | auto p = replace_invalid(rpath); 181 | if (!DirectoryExists(p)) 182 | { 183 | NativeRegistry n(rpath); 184 | if (n.result == ERROR_SUCCESS) 185 | { 186 | x.result = orig(RegEnumKeyEx)(n.key, dwIndex, lpName, lpcName, lpReserved, lpClass, lpcClass, lpftLastWriteTime); 187 | x.l(5, "open native registry:", rpath); 188 | return x.result; 189 | } 190 | return x.result = n.result; 191 | } 192 | 193 | auto dirs = Directory::GetDirectoryInfos(p); 194 | if (dwIndex >= dirs.size()) 195 | return x.result = ERROR_NO_MORE_ITEMS; 196 | 197 | if (lpftLastWriteTime) 198 | { 199 | *lpftLastWriteTime = dirs[dwIndex].ftLastWriteTime; 200 | } 201 | 202 | *lpcName = String::cpy(lpName, String::tstr(dirs[dwIndex].cFileName), *lpcName); 203 | 204 | return x.result = ERROR_SUCCESS; 205 | } 206 | static LONG WINAPI RegEnumKey( 207 | HKEY hKey, 208 | DWORD dwIndex, 209 | C *lpName, 210 | DWORD cchName 211 | ) 212 | { 213 | auto x = info(add_suffix("RegEnumKey"), hKey, dwIndex, lpName, cchName); 214 | return x.result = RegEnumKeyEx(hKey, dwIndex, lpName, &cchName, NULL, NULL, NULL, NULL); 215 | } 216 | 217 | static LONG WINAPI RegEnumValue( 218 | HKEY hKey, 219 | DWORD dwIndex, 220 | C *lpValueName, 221 | LPDWORD lpcValueName, 222 | LPDWORD lpReserved, 223 | LPDWORD lpType, 224 | LPBYTE lpData, 225 | LPDWORD lpcbData 226 | ) 227 | { 228 | auto x = info(add_suffix("RegEnumValue"), hKey, dwIndex, lpValueName, lpcValueName, lpReserved, lpType, lpData, lpcbData); 229 | auto rpath = GetDirectoryName(hKey); 230 | x.l(6, rpath); 231 | auto p = replace_invalid(rpath); 232 | if (!DirectoryExists(p)) 233 | { 234 | NativeRegistry n(rpath); 235 | if (n.result == ERROR_SUCCESS) 236 | { 237 | x.result = orig(RegEnumValue)(n.key, dwIndex, lpValueName, lpcValueName, lpReserved, lpType, lpData, lpcbData); 238 | x.l(5, "open native registry:", rpath); 239 | return x.result; 240 | } 241 | return x.result = n.result; 242 | } 243 | 244 | auto files = Directory::GetFiles(p); 245 | if (dwIndex >= files.size()) 246 | return x.result = ERROR_NO_MORE_ITEMS; 247 | 248 | *lpcValueName = String::cpy(lpValueName, String::tstr(files[dwIndex]), *lpcValueName); 249 | 250 | auto s = String::tstr(files[dwIndex]); 251 | return x.result = RegQueryValueEx(hKey, s.c_str(), NULL, lpType, lpData, lpcbData); 252 | } 253 | static LONG WINAPI RegQueryValueEx( 254 | HKEY hKey, 255 | const C *lpValueName, 256 | LPDWORD lpReserved, 257 | LPDWORD lpType, 258 | LPBYTE lpData, 259 | LPDWORD lpcbData 260 | ) 261 | { 262 | auto x = info(add_suffix("RegQueryValueEx"), hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); 263 | const C *valuename = lpValueName; 264 | string defaultname = String::tstr("@"); 265 | if (!lpValueName || lpValueName[0] == 0) 266 | { 267 | valuename = defaultname.c_str(); 268 | } 269 | auto rpath = GetDirectoryName(hKey); 270 | if (isNativeHKey(hKey)) 271 | { 272 | x.result = orig(RegQueryValueEx)(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); 273 | x.l(5, "native HKEY?:", FuncInfo::hex(hKey)); 274 | return x.result; 275 | } 276 | auto f = replace_invalid(Path::Combine(rpath, String::tstr(valuename))); 277 | x.l(6, f); 278 | 279 | auto h = orig(Kernel32::CreateFile)(f.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 280 | if (h == INVALID_HANDLE_VALUE) 281 | { 282 | NativeRegistry n(rpath); 283 | if (n.result == ERROR_SUCCESS) 284 | { 285 | x.result = orig(RegQueryValueEx)(n.key, lpValueName, lpReserved, lpType, lpData, lpcbData); 286 | x.l(5, "open native registry:", rpath); 287 | return x.result; 288 | } 289 | return x.result = n.result; 290 | } 291 | 292 | DWORD dw; 293 | DWORD dwType; 294 | ReadFile(h, &dwType, sizeof(DWORD), &dw, NULL); 295 | if (lpType) 296 | { 297 | *lpType = dwType; 298 | } 299 | if (lpData || lpcbData) 300 | { 301 | DWORD size; 302 | ReadFile(h, &size, sizeof(DWORD), &dw, NULL); 303 | if ((sizeof(C) == sizeof(char)) && (dwType == REG_SZ || dwType == REG_MULTI_SZ || dwType == REG_EXPAND_SZ)) 304 | { 305 | std::wstring ws(size, 0); 306 | ReadFile(h, &ws[0], size, &size, NULL); 307 | ws.resize(size); 308 | auto s = String::tstr(ws); 309 | size = s.size() + 1; 310 | if (lpData) 311 | { 312 | if (*lpcbData < size) 313 | { 314 | size = *lpcbData; 315 | } 316 | String::cpy((char*)lpData, s, size); 317 | } 318 | *lpcbData = size; 319 | } 320 | else if (lpData) 321 | { 322 | if (*lpcbData < size) 323 | size = *lpcbData; 324 | ReadFile(h, lpData, size, &size, NULL); 325 | *lpcbData = size; 326 | } 327 | else if (lpcbData) 328 | { 329 | *lpcbData = size; 330 | } 331 | } 332 | CloseHandle(h); 333 | 334 | return x.result = ERROR_SUCCESS; 335 | } 336 | static LONG WINAPI RegQueryValue( 337 | HKEY hKey, 338 | const C *lpSubKey, 339 | C *lpData, 340 | PLONG lpcbData 341 | ) 342 | { 343 | auto x = info(add_suffix("RegQueryValue"), hKey, lpSubKey, lpData, lpcbData); 344 | return x.result = RegQueryValueEx(hKey, lpSubKey, NULL, NULL, (LPBYTE)lpData, (LPDWORD)lpcbData); 345 | } 346 | 347 | static LONG WINAPI RegSetValueEx( 348 | HKEY hKey, 349 | const C *lpValueName, 350 | DWORD Reserved, 351 | DWORD dwType, 352 | CONST BYTE *lpData, 353 | DWORD cbData 354 | ) 355 | { 356 | auto x = info(add_suffix("RegSetValueEx"), hKey, lpValueName, Reserved, dwType, lpData, cbData); 357 | const C *valuename = lpValueName; 358 | string defaultname = String::tstr("@"); 359 | if (!lpValueName || lpValueName[0] == 0) 360 | { 361 | valuename = defaultname.c_str(); 362 | } 363 | auto rpath = GetDirectoryName(hKey); 364 | auto f = replace_invalid(Path::Combine(rpath, String::tstr(valuename))); 365 | x.l(3, f); 366 | 367 | auto p = replace_invalid(rpath); 368 | if (!DirectoryExists(p)) 369 | SHCreateDirectory(NULL, p.c_str()); 370 | auto h = orig(Kernel32::CreateFile)(f.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 371 | if (h == INVALID_HANDLE_VALUE) 372 | return x.result = ERROR_ACCESS_DENIED; 373 | 374 | DWORD dw; 375 | auto r = WriteFile(h, &dwType, sizeof(DWORD), &dw, NULL); 376 | 377 | if ((sizeof(C) == sizeof(char)) && (dwType == REG_SZ || dwType == REG_MULTI_SZ || dwType == REG_EXPAND_SZ)) 378 | { 379 | //cut with cbData? 380 | auto ws = String::tstr((C*)lpData); 381 | DWORD size = (ws.size() + 1) * sizeof(wchar_t); 382 | r &= WriteFile(h, &size, sizeof(DWORD), &dw, NULL); 383 | r &= WriteFile(h, ws.c_str(), size, &dw, NULL); 384 | } 385 | else 386 | { 387 | r &= WriteFile(h, &cbData, sizeof(DWORD), &dw, NULL); 388 | r &= WriteFile(h, lpData, cbData, &dw, NULL); 389 | } 390 | 391 | if (!r) 392 | x.result = GetLastError(); 393 | else 394 | x.result = ERROR_SUCCESS; 395 | 396 | CloseHandle(h); 397 | 398 | return x.result; 399 | } 400 | static LONG WINAPI RegSetValue( 401 | HKEY hKey, 402 | const C *lpSubKey, 403 | DWORD dwType, 404 | const C *lpData, 405 | DWORD cbData 406 | ) 407 | { 408 | auto x = info(add_suffix("RegSetValue"), hKey, lpSubKey, dwType, lpData, cbData); 409 | return x.result = RegSetValueEx(hKey, lpSubKey, 0, dwType, (const BYTE*)lpData, cbData); 410 | } 411 | 412 | static LONG WINAPI RegQueryInfoKey( 413 | HKEY hKey, 414 | C *lpClass, 415 | LPDWORD lpcClass, 416 | LPDWORD lpReserved, 417 | LPDWORD lpcSubKeys, 418 | LPDWORD lpcMaxSubKeyLen, 419 | LPDWORD lpcMaxClassLen, 420 | LPDWORD lpcValues, 421 | LPDWORD lpcMaxValueNameLen, 422 | LPDWORD lpcMaxValueLen, 423 | LPDWORD lpcbSecurityDescriptor, 424 | PFILETIME lpftLastWriteTime 425 | ) 426 | { 427 | auto x = info(add_suffix("RegQueryInfoKey"), hKey, lpClass, lpcClass, lpReserved, lpcSubKeys, lpcMaxSubKeyLen, lpcMaxClassLen, lpcValues, lpcMaxValueNameLen, lpcMaxValueLen, lpcbSecurityDescriptor, lpftLastWriteTime); 428 | auto rpath = GetDirectoryName(hKey); 429 | x.l(6, rpath); 430 | auto p = replace_invalid(rpath); 431 | if (!DirectoryExists(p)) 432 | { 433 | NativeRegistry n(rpath); 434 | if (n.result == ERROR_SUCCESS) 435 | { 436 | auto result = orig(RegQueryInfoKey)(n.key, lpClass, lpcClass, lpReserved, lpcSubKeys, lpcMaxSubKeyLen, lpcMaxClassLen, lpcValues, lpcMaxValueNameLen, lpcMaxValueLen, lpcbSecurityDescriptor, lpftLastWriteTime); 437 | x.l(5, "open native registry result=", result); 438 | return result; 439 | } 440 | return n.result; 441 | } 442 | 443 | auto dirs = Directory::GetDirectoryInfos(p); 444 | if (lpcSubKeys) 445 | *lpcSubKeys = dirs.size(); 446 | if (lpcMaxSubKeyLen) 447 | { 448 | *lpcMaxSubKeyLen = 0; 449 | for (auto &d : dirs) 450 | { 451 | auto len = std::wstring(d.cFileName).size() + 1; 452 | if (*lpcMaxSubKeyLen < len) 453 | *lpcMaxSubKeyLen = len; 454 | } 455 | } 456 | auto files = Directory::GetFileInfos(p); 457 | if (lpcValues) 458 | *lpcValues = files.size(); 459 | if (lpcMaxValueNameLen) 460 | *lpcMaxValueNameLen = 0; 461 | if (lpcMaxValueLen) 462 | *lpcMaxValueLen = 0; 463 | if (lpftLastWriteTime) 464 | { 465 | lpftLastWriteTime->dwHighDateTime = 0; 466 | lpftLastWriteTime->dwLowDateTime = 0; 467 | } 468 | for (auto &f : files) 469 | { 470 | if (lpcMaxValueNameLen) 471 | { 472 | auto l = std::wstring(f.cFileName).size() + 1; 473 | if (*lpcMaxValueNameLen < l) 474 | *lpcMaxValueNameLen = l; 475 | } 476 | if (lpcMaxValueLen) 477 | { 478 | if (*lpcMaxValueLen < f.nFileSizeLow) 479 | *lpcMaxValueLen = f.nFileSizeLow; 480 | } 481 | if (lpftLastWriteTime) 482 | { 483 | if (lpftLastWriteTime->dwHighDateTime < f.ftLastWriteTime.dwHighDateTime) 484 | { 485 | lpftLastWriteTime->dwHighDateTime = f.ftLastWriteTime.dwHighDateTime; 486 | lpftLastWriteTime->dwLowDateTime = f.ftLastWriteTime.dwLowDateTime; 487 | } 488 | else if (lpftLastWriteTime->dwHighDateTime == f.ftLastWriteTime.dwHighDateTime && lpftLastWriteTime->dwLowDateTime < f.ftLastWriteTime.dwLowDateTime) 489 | { 490 | lpftLastWriteTime->dwLowDateTime = f.ftLastWriteTime.dwLowDateTime; 491 | } 492 | } 493 | } 494 | 495 | if (dirs.empty() && files.empty()) 496 | return x.result = ERROR_FILE_NOT_FOUND; 497 | 498 | return x.result = ERROR_SUCCESS; 499 | } 500 | 501 | static LONG WINAPI RegQueryMultipleValues( 502 | HKEY hKey, 503 | PVALENT val_list, 504 | DWORD num_vals, 505 | C *lpValueBuf, 506 | LPDWORD ldwTotsize 507 | ) 508 | { 509 | log(9, add_suffix("RegQueryMultipleValues")); 510 | return ERROR_CANTREAD; 511 | } 512 | 513 | static LONG WINAPI RegSaveKey( 514 | HKEY hKey, 515 | const C *lpFile, 516 | LPSECURITY_ATTRIBUTES lpSecurityAttributes 517 | ) 518 | { 519 | log(9, add_suffix("RegSaveKey")); 520 | return ERROR_FILE_NOT_FOUND; 521 | } 522 | 523 | static LONG WINAPI RegRestoreKey( 524 | HKEY hKey, 525 | const C *lpFile, 526 | DWORD dwFlags 527 | ) 528 | { 529 | log(9, add_suffix("RegRestoreKey")); 530 | return ERROR_FILE_NOT_FOUND; 531 | } 532 | 533 | static LONG WINAPI RegLoadKey( 534 | HKEY hKey, 535 | const C *lpSubKey, 536 | const C *lpFile 537 | ) 538 | { 539 | log(9, add_suffix("RegLoadKey")); 540 | return ERROR_FILE_NOT_FOUND; 541 | } 542 | 543 | static LONG WINAPI RegReplaceKey( 544 | HKEY hKey, 545 | const C *lpSubKey, 546 | const C *lpNewFile, 547 | const C *lpOldFile 548 | ) 549 | { 550 | log(9, add_suffix("RegReplaceKey")); 551 | return ERROR_FILE_NOT_FOUND; 552 | } 553 | 554 | static LONG WINAPI RegUnLoadKey( 555 | HKEY hKey, 556 | const C *lpSubKey 557 | ) 558 | { 559 | log(9, add_suffix("RegUnLoadKey")); 560 | return ERROR_FILE_NOT_FOUND; 561 | } 562 | 563 | static LONG WINAPI RegNotifyChangeKeyValue( 564 | HKEY hKey, 565 | BOOL bWatchSubtree, 566 | DWORD dwNotifyFilter, 567 | HANDLE hEvent, 568 | BOOL fAsynchronous 569 | ) 570 | { 571 | log(9, "RegNotifyChangeKeyValue"); 572 | return ERROR_FILE_NOT_FOUND; 573 | } 574 | 575 | static LONG WINAPI RegOverridePredefKey( 576 | HKEY hKey, 577 | HKEY hNewHKey 578 | ) 579 | { 580 | log(9, "RegOverridePredefKey"); 581 | return ERROR_FILE_NOT_FOUND; 582 | } 583 | 584 | static LONG WINAPI RegConnectRegistry( 585 | const C *lpMachineName, 586 | HKEY hKey, 587 | PHKEY phkResult 588 | ) 589 | { 590 | log(9, add_suffix("RegConnectRegistry")); 591 | return ERROR_FILE_NOT_FOUND; 592 | } 593 | -------------------------------------------------------------------------------- /sandbox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #pragma comment(lib, "DbgHelp") 11 | #pragma comment(lib, "shell32") 12 | #pragma comment(lib, "advapi32") 13 | 14 | #include "include/string.h" 15 | #include "include/path.h" 16 | #include "include/directory.h" 17 | 18 | #ifdef _WIN64 19 | typedef unsigned long long pointer_size_uint; 20 | #else 21 | typedef unsigned long pointer_size_uint; 22 | #endif 23 | 24 | template T *orig(T *m) 25 | { 26 | #ifdef _DEBUG 27 | if (!mod_to_orig.count(m)) 28 | { 29 | log(-1, "orig error:", FuncInfo::hex(m)); 30 | return m; 31 | } 32 | #endif 33 | return (T*)mod_to_orig[m]; 34 | } 35 | 36 | #include "utility/config.h" 37 | #include "utility/cnvpath.h" 38 | #include "utility/saveerror.h" 39 | #include "utility/funcinfo.h" 40 | 41 | Config config; 42 | HANDLE hlog = NULL; 43 | std::string cnv::sandbox; 44 | std::string cnv::drive; 45 | std::string cnv::vuser; 46 | std::string cnv::suser; 47 | std::string cnv::mutex; 48 | std::wstring cnv::sandbox; 49 | std::wstring cnv::drive; 50 | std::wstring cnv::vuser; 51 | std::wstring cnv::suser; 52 | std::wstring cnv::mutex; 53 | int loglevel = 0; 54 | 55 | std::string exename32; 56 | std::string dllname32; 57 | std::string exename64; 58 | std::string dllname64; 59 | 60 | void initname(const std::wstring &name) 61 | { 62 | auto basename = String::replace(String::tstr(name), "64", ""); 63 | exename32 = basename + ".exe"; 64 | dllname32 = basename + ".dll"; 65 | exename64 = basename + "64.exe"; 66 | dllname64 = basename + "64.dll"; 67 | } 68 | 69 | void log(int level, const std::string &str) 70 | { 71 | SaveError e; 72 | 73 | if (loglevel < level) 74 | return; 75 | 76 | auto s = String::trim(str); 77 | auto th = GetCurrentThreadId(); 78 | 79 | printf("log:%X:%s\n", th, s.c_str()); 80 | 81 | if (hlog && hlog != INVALID_HANDLE_VALUE) 82 | { 83 | s = FuncInfo::hex(th) + ":" + s + "\r\n"; 84 | DWORD size = s.size(); 85 | WriteFile(hlog, s.c_str(), s.size(), &size, 0); 86 | } 87 | } 88 | template 89 | static void log(int loglevel, Args... args) 90 | { 91 | log(loglevel, String::concat(args...)); 92 | } 93 | 94 | std::string GetLastErrorString() 95 | { 96 | std::string msg(MAX_PATH, 0); 97 | auto size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, &msg[0], MAX_PATH, NULL); 98 | msg.resize(size); 99 | return msg; 100 | } 101 | 102 | void moduleIAT(HMODULE m, void *dest, void *src) 103 | { 104 | ULONG size; 105 | PIMAGE_IMPORT_DESCRIPTOR imp = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(m, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size); 106 | if (imp) 107 | { 108 | while (imp->FirstThunk) 109 | { 110 | PIMAGE_THUNK_DATA td = (PIMAGE_THUNK_DATA)((BYTE*)m + imp->FirstThunk); 111 | while (td->u1.Function) 112 | { 113 | PROC *p = (PROC*)&td->u1.Function; 114 | if (*p == src) 115 | { 116 | DWORD d; 117 | VirtualProtect(p, sizeof(p), PAGE_EXECUTE_READWRITE, &d); 118 | *p = (PROC)dest; 119 | VirtualProtect(p, sizeof(p), d, &d); 120 | } 121 | td++; 122 | } 123 | imp++; 124 | } 125 | } 126 | /*PImgDelayDescr dd = (PImgDelayDescr)ImageDirectoryEntryToData(m, TRUE, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT, &size); 127 | if (dd) 128 | { 129 | while (dd->rvaIAT) 130 | { 131 | PIMAGE_THUNK_DATA td = (PIMAGE_THUNK_DATA)((BYTE*)m + dd->rvaIAT); 132 | while (td->u1.Function) 133 | { 134 | PROC *p = (PROC*)&td->u1.Function; 135 | if (*p == src) 136 | { 137 | DWORD d; 138 | VirtualProtect(p, sizeof(p), PAGE_EXECUTE_READWRITE, &d); 139 | *p = (PROC)dest; 140 | VirtualProtect(p, sizeof(p), d, &d); 141 | } 142 | td++; 143 | } 144 | dd++; 145 | } 146 | }*/ 147 | } 148 | 149 | void IAT(void *dest, void *src) 150 | { 151 | HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); 152 | if (h < 0) 153 | { 154 | log(0, "error:CreateToolhelp32Snapshot:", GetLastErrorString()); 155 | return; 156 | } 157 | 158 | MODULEENTRY32 me; 159 | me.dwSize = sizeof(me); 160 | 161 | BOOL b = Module32First(h, &me); 162 | while (b) 163 | { 164 | moduleIAT(me.hModule, dest, src); 165 | b = Module32Next(h, &me); 166 | } 167 | 168 | CloseHandle(h); 169 | } 170 | 171 | std::map orig_to_mod; 172 | std::map mod_to_orig; 173 | 174 | bool reg(HMODULE h, const std::string name, void *m) 175 | { 176 | void *o = GetProcAddress(h, name.c_str()); 177 | if (o) 178 | { 179 | #ifdef _DEBUG 180 | if (o == m) 181 | { 182 | log(1, "reg original function?:", name); 183 | } 184 | #endif 185 | orig_to_mod[o] = m; 186 | mod_to_orig[m] = o; 187 | IAT(m, o); 188 | log(9, "reg:", name, " mod=", FuncInfo::hex(m), " orig=", FuncInfo::hex(o)); 189 | } 190 | else 191 | { 192 | log(1, "reg error:", name); 193 | } 194 | return o; 195 | } 196 | 197 | template std::string add_suffix(const char *name) 198 | { 199 | std::string str = name; 200 | str += "A"; 201 | return str; 202 | } 203 | template<> std::string add_suffix(const char *name) 204 | { 205 | std::string str = name; 206 | str += "W"; 207 | return str; 208 | } 209 | 210 | struct vae 211 | { 212 | HANDLE p; 213 | void *m; 214 | DWORD s; 215 | vae(HANDLE h, DWORD size) 216 | { 217 | p = h; 218 | s = size; 219 | m = VirtualAllocEx(h, NULL, size, MEM_COMMIT, PAGE_READWRITE); 220 | } 221 | ~vae() 222 | { 223 | if (m) 224 | VirtualFreeEx(p, m, s, MEM_DECOMMIT); 225 | } 226 | }; 227 | 228 | int inject(HANDLE ph, const std::string &dllpath) 229 | { 230 | vae v(ph, dllpath.size() + 1); 231 | if (!v.m) 232 | { 233 | log(0, "error:VirtualAllocEx:", GetLastErrorString()); 234 | return 1; 235 | } 236 | if (!WriteProcessMemory(ph, v.m, dllpath.c_str(), dllpath.size() + 1, NULL)) 237 | { 238 | log(0, "error:WriteProcessMemory:", GetLastErrorString()); 239 | return 2; 240 | } 241 | 242 | HMODULE kernel32 = GetModuleHandleA("kernel32"); 243 | FARPROC loadlibrary = orig(GetProcAddress)(kernel32, "LoadLibraryA"); 244 | 245 | HANDLE h = CreateRemoteThread(ph, NULL, 0, (LPTHREAD_START_ROUTINE)loadlibrary, v.m, 0, NULL); 246 | if (!h) 247 | { 248 | auto e = GetLastError(); 249 | log(0, "error:CreateRemoteThread:", GetLastErrorString()); 250 | if (e == 5) 251 | { 252 | return 64; 253 | } 254 | else 255 | { 256 | return 3; 257 | } 258 | } 259 | WaitForSingleObject(h, INFINITE); 260 | log(0, "hook success"); 261 | CloseHandle(h); 262 | 263 | return 0; 264 | } 265 | 266 | void initval(const std::wstring &modulepath) 267 | { 268 | cnv::sandbox = Path::GetDirectoryName(modulepath); 269 | cnv::sandbox = Path::RemoveBackslash(cnv::sandbox); 270 | cnv::sandbox = String::tstr(cnv::sandbox); 271 | 272 | config = Config::Read(Path::Combine(cnv::sandbox, "sandbox.cfg")); 273 | 274 | loglevel = config.Int("loglevel"); 275 | 276 | cnv::drive = config.str("drive", "C:"); 277 | cnv::drive = config.wstr("drive", L"C:"); 278 | cnv::vuser = Path::RemoveBackslash(config.str("virtual_user_directory", "C:\\Users\\SANDBOX")); 279 | cnv::vuser = config.wstr("virtual_user_directory", L"C:\\Users\\SANDBOX"); 280 | char path[MAX_PATH]; 281 | SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, path); 282 | cnv::suser = Path::RemoveBackslash(path); 283 | cnv::suser = String::tstr(cnv::suser); 284 | cnv::mutex = String::replace(config.str("mutex", cnv::sandbox), "\\", "_"); 285 | cnv::mutex = String::tstr(cnv::mutex); 286 | 287 | SetEnvironmentVariable("SANDBOX", cnv::sandbox.c_str()); 288 | //SetEnvironmentVariable("USERNAME", config.str("USERNAME").c_str()); 289 | //SetEnvironmentVariable("COMPUTERNAME", config.str("COMPUTERNAME").c_str()); 290 | log(0, "sandbox:", cnv::sandbox); 291 | } 292 | 293 | void Init(HMODULE module) 294 | { 295 | wchar_t modulepath[MAX_PATH]; 296 | GetModuleFileNameW(module, modulepath, MAX_PATH); 297 | 298 | initname(Path::GetFileNameWithoutExtension(modulepath)); 299 | initval(modulepath); 300 | 301 | if (config.exists("TEMP")) 302 | { 303 | SetEnvironmentVariable("TEMP", config.str("TEMP").c_str()); 304 | SetEnvironmentVariable("TMP", config.str("TEMP").c_str()); 305 | config.config["temp"] = Path::AddBackslash(config.str("TEMP")); 306 | } 307 | 308 | if (config.dword("logfile")) 309 | { 310 | char exepath[MAX_PATH]; 311 | GetModuleFileNameA(NULL, exepath, sizeof(exepath)); 312 | char logfile[MAX_PATH]; 313 | SYSTEMTIME st; 314 | GetLocalTime(&st); 315 | auto f = Path::GetFileName(exepath); 316 | sprintf(logfile, "%s_%.2d-%.2d-%.2d_%.2d%.2d%.2d.log", f.c_str(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); 317 | auto p = Path::Combine(cnv::sandbox, logfile); 318 | hlog = CreateFileA(p.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 319 | } 320 | 321 | if (config.dword("console")) 322 | { 323 | AllocConsole(); 324 | freopen("CONOUT$", "w", stdout); 325 | } 326 | } 327 | 328 | void Final() 329 | { 330 | log(0, "detach sandbox"); 331 | if (hlog && hlog != INVALID_HANDLE_VALUE) 332 | CloseHandle(hlog); 333 | } 334 | 335 | #include "mod/kernel32.h" 336 | #include "mod/advapi32.h" 337 | #include "mod/shell32.h" 338 | #include "mod/ole32.h" 339 | #include "mod/user32.h" 340 | #include "mod/shlwapi.h" 341 | #include "mod/imagehlp.h" 342 | #include "mod/version.h" 343 | #include "mod/psapi.h" 344 | #include "mod/winmm.h" 345 | #include "mod/msi.h" 346 | #include "mod/msvcrt.h" 347 | 348 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 349 | { 350 | switch (fdwReason) 351 | { 352 | case DLL_PROCESS_ATTACH: 353 | Init(hinstDLL); 354 | Kernel32::Attach(); 355 | Kernel32::Attach(); 356 | Advapi32::Attach(); 357 | Advapi32::Attach(); 358 | Shell32::Attach(); 359 | Shell32::Attach(); 360 | Ole32::Attach(); 361 | User32::Attach(); 362 | User32::Attach(); 363 | Shlwapi::Attach(); 364 | Shlwapi::Attach(); 365 | Imagehlp::Attach(); 366 | Version::Attach(); 367 | Version::Attach(); 368 | Psapi::Attach(); 369 | Psapi::Attach(); 370 | Winmm::Attach(); 371 | Winmm::Attach(); 372 | Msi::Attach(); 373 | Msi::Attach(); 374 | MSVCRT::Attach(); 375 | { 376 | auto kernel32 = GetModuleHandle("kernel32"); 377 | auto lib = std::string("api-ms-win-core-libraryloader-") + config.str("api-ms-win-core-libraryloader", "L1-1-0"); 378 | auto libraryloader = LoadLibrary(lib.c_str()); 379 | if (!libraryloader) 380 | libraryloader = kernel32; 381 | else 382 | log(7, "load ", lib); 383 | 384 | if (!reg(libraryloader, "LoadLibraryA", Kernel32::LoadLibrary)) 385 | reg(kernel32, "LoadLibraryA", Kernel32::LoadLibrary); 386 | if (!reg(libraryloader, "LoadLibraryW", Kernel32::LoadLibrary)) 387 | reg(kernel32, "LoadLibraryA", Kernel32::LoadLibrary); 388 | reg(libraryloader, "LoadLibraryExA", Kernel32::LoadLibraryEx); 389 | reg(libraryloader, "LoadLibraryExW", Kernel32::LoadLibraryEx); 390 | reg(libraryloader, "GetModuleHandleA", Kernel32::GetModuleHandle); 391 | reg(libraryloader, "GetModuleHandleW", Kernel32::GetModuleHandle); 392 | reg(libraryloader, "GetProcAddress", Kernel32::GetProcAddress); 393 | } 394 | break; 395 | case DLL_PROCESS_DETACH: 396 | Final(); 397 | for (auto &x : orig_to_mod) 398 | { 399 | IAT(x.first, x.second); 400 | } 401 | break; 402 | } 403 | 404 | return TRUE; 405 | } 406 | 407 | void InitEnv() 408 | { 409 | DllMain(NULL, DLL_PROCESS_ATTACH, NULL); 410 | 411 | char path[MAX_PATH]; 412 | GetTempPath(MAX_PATH, path); 413 | SHCreateDirectoryEx(NULL, path, NULL); 414 | 415 | SHGetFolderPath(NULL, CSIDL_ALTSTARTUP | CSIDL_FLAG_CREATE, NULL, 0, path); 416 | SHGetFolderPath(NULL, CSIDL_COMMON_ALTSTARTUP | CSIDL_FLAG_CREATE, NULL, 0, path); 417 | SHGetFolderPath(NULL, CSIDL_COMMON_FAVORITES | CSIDL_FLAG_CREATE, NULL, 0, path); 418 | SHGetFolderPath(NULL, CSIDL_WINDOWS | CSIDL_FLAG_CREATE, NULL, 0, path); 419 | SHGetFolderPath(NULL, CSIDL_SYSTEM | CSIDL_FLAG_CREATE, NULL, 0, path); 420 | SHGetFolderPath(NULL, CSIDL_SYSTEMX86 | CSIDL_FLAG_CREATE, NULL, 0, path); 421 | SHGetFolderPath(NULL, CSIDL_PROFILE | CSIDL_FLAG_CREATE, NULL, 0, path); 422 | 423 | HKEY key; 424 | RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, NULL, 0, 0, NULL, &key, NULL); 425 | RegCloseKey(key); 426 | RegCreateKeyEx(HKEY_CLASSES_ROOT, "CLSID", 0, NULL, 0, 0, NULL, &key, NULL); 427 | RegCloseKey(key); 428 | 429 | SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES | CSIDL_FLAG_CREATE, NULL, 0, path); 430 | SHGetFolderPath(NULL, CSIDL_PROGRAM_FILESX86 | CSIDL_FLAG_CREATE, NULL, 0, path); 431 | SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMON | CSIDL_FLAG_CREATE, NULL, 0, path); 432 | SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMONX86 | CSIDL_FLAG_CREATE, NULL, 0, path); 433 | 434 | SHGetFolderPath(NULL, CSIDL_ADMINTOOLS | CSIDL_FLAG_CREATE, NULL, 0, path); 435 | SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path); 436 | SHGetFolderPath(NULL, CSIDL_INTERNET_CACHE | CSIDL_FLAG_CREATE, NULL, 0, path); 437 | SHGetFolderPath(NULL, CSIDL_CDBURN_AREA | CSIDL_FLAG_CREATE, NULL, 0, path); 438 | SHGetFolderPath(NULL, CSIDL_COOKIES | CSIDL_FLAG_CREATE, NULL, 0, path); 439 | SHGetFolderPath(NULL, CSIDL_DESKTOP | CSIDL_FLAG_CREATE, NULL, 0, path); 440 | SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE, NULL, 0, path); 441 | SHGetFolderPath(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL, 0, path); 442 | SHGetFolderPath(NULL, CSIDL_FONTS | CSIDL_FLAG_CREATE, NULL, 0, path); 443 | SHGetFolderPath(NULL, CSIDL_HISTORY | CSIDL_FLAG_CREATE, NULL, 0, path); 444 | SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path); 445 | SHGetFolderPath(NULL, CSIDL_MYMUSIC | CSIDL_FLAG_CREATE, NULL, 0, path); 446 | SHGetFolderPath(NULL, CSIDL_MYPICTURES | CSIDL_FLAG_CREATE, NULL, 0, path); 447 | SHGetFolderPath(NULL, CSIDL_MYVIDEO | CSIDL_FLAG_CREATE, NULL, 0, path); 448 | SHGetFolderPath(NULL, CSIDL_NETHOOD | CSIDL_FLAG_CREATE, NULL, 0, path); 449 | SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path); 450 | SHGetFolderPath(NULL, CSIDL_PRINTHOOD | CSIDL_FLAG_CREATE, NULL, 0, path); 451 | SHGetFolderPath(NULL, CSIDL_PROGRAMS | CSIDL_FLAG_CREATE, NULL, 0, path); 452 | SHGetFolderPath(NULL, CSIDL_RECENT | CSIDL_FLAG_CREATE, NULL, 0, path); 453 | SHGetFolderPath(NULL, CSIDL_SENDTO | CSIDL_FLAG_CREATE, NULL, 0, path); 454 | SHGetFolderPath(NULL, CSIDL_STARTMENU | CSIDL_FLAG_CREATE, NULL, 0, path); 455 | SHGetFolderPath(NULL, CSIDL_STARTUP | CSIDL_FLAG_CREATE, NULL, 0, path); 456 | SHGetFolderPath(NULL, CSIDL_TEMPLATES | CSIDL_FLAG_CREATE, NULL, 0, path); 457 | 458 | SHGetFolderPath(NULL, CSIDL_COMMON_ADMINTOOLS | CSIDL_FLAG_CREATE, NULL, 0, path); 459 | SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path); 460 | SHGetFolderPath(NULL, CSIDL_COMMON_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE, NULL, 0, path); 461 | SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, path); 462 | SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS | CSIDL_FLAG_CREATE, NULL, 0, path); 463 | SHGetFolderPath(NULL, CSIDL_COMMON_STARTMENU | CSIDL_FLAG_CREATE, NULL, 0, path); 464 | SHGetFolderPath(NULL, CSIDL_COMMON_STARTUP | CSIDL_FLAG_CREATE, NULL, 0, path); 465 | SHGetFolderPath(NULL, CSIDL_COMMON_TEMPLATES | CSIDL_FLAG_CREATE, NULL, 0, path); 466 | SHGetFolderPath(NULL, CSIDL_COMMON_MUSIC | CSIDL_FLAG_CREATE, NULL, 0, path); 467 | SHGetFolderPath(NULL, CSIDL_COMMON_PICTURES | CSIDL_FLAG_CREATE, NULL, 0, path); 468 | SHGetFolderPath(NULL, CSIDL_COMMON_VIDEO | CSIDL_FLAG_CREATE, NULL, 0, path); 469 | SHGetFolderPath(NULL, CSIDL_COMMON_OEM_LINKS | CSIDL_FLAG_CREATE, NULL, 0, path); 470 | 471 | { 472 | STARTUPINFO si; 473 | ZeroMemory(&si, sizeof(si)); 474 | si.cb = sizeof(si); 475 | PROCESS_INFORMATION pi; 476 | ZeroMemory(&pi, sizeof(pi)); 477 | orig(Kernel32::CreateProcess)(NULL, "cmd /c mklink /j \"Users\\SANDBOX\\Application Data\" Users\\SANDBOX\\AppData\\Roaming", NULL, NULL, false, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi); 478 | } 479 | DllMain(NULL, DLL_PROCESS_DETACH, NULL); 480 | } 481 | 482 | std::wstring getcmdparam(int i, int argc, wchar_t **argv) 483 | { 484 | std::wstring cp = L""; 485 | for (; i < argc; i++) 486 | { 487 | cp += L"\""; 488 | cp += argv[i]; 489 | cp += L"\" "; 490 | } 491 | return cp; 492 | } 493 | 494 | int wmain(int argc, wchar_t **argv) 495 | { 496 | if (argc == 1) 497 | { 498 | InitEnv(); 499 | return 0; 500 | } 501 | 502 | wchar_t exepath[MAX_PATH]; 503 | ZeroMemory(exepath, MAX_PATH * sizeof(wchar_t)); 504 | GetModuleFileNameW(NULL, exepath, sizeof(exepath)); 505 | initname(Path::GetFileNameWithoutExtension(exepath)); 506 | initval(exepath); 507 | auto exedir = Path::GetDirectoryName(exepath); 508 | 509 | mod_to_orig[GetProcAddress] = GetProcAddress; 510 | 511 | bool suspend = false; 512 | int target_id = 0; 513 | std::wstring targetdir; 514 | 515 | for (int i = 1; i < argc; i++) 516 | { 517 | if (argv[i][0] == L'/') 518 | { 519 | switch (argv[i][1]) 520 | { 521 | case L'd': 522 | case L'D': 523 | targetdir = argv[i]; 524 | break; 525 | case L'p': 526 | case L'P': 527 | { 528 | int pid = std::stoi(argv[i] + 2); 529 | log(0, "pid=", pid); 530 | HANDLE p = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 531 | if (p) 532 | { 533 | BOOL wow64; 534 | IsWow64Process(p, &wow64); 535 | inject(p, Path::Combine(String::tstr(cnv::sandbox), wow64 ? dllname32 : dllname64)); 536 | CloseHandle(p); 537 | } 538 | return pid; 539 | } 540 | case L's': 541 | case L'S': 542 | log(0, "process continue suspended"); 543 | suspend = true; 544 | break; 545 | default: 546 | log(0, "unknown option"); 547 | } 548 | } 549 | else if (!target_id) 550 | { 551 | target_id = i; 552 | break; 553 | } 554 | } 555 | 556 | if (target_id == 0) 557 | { 558 | log(0, "no target exe"); 559 | return 0; 560 | } 561 | 562 | wchar_t targetpath[MAX_PATH]; 563 | auto spr = SearchPathW(NULL, argv[target_id], L".exe", MAX_PATH, targetpath, NULL); 564 | if (!spr) 565 | { 566 | log(0, GetLastErrorString()); 567 | return 0; 568 | } 569 | if (targetdir.empty()) 570 | targetdir = Path::GetDirectoryName(targetpath); 571 | log(0, "target:", targetpath); 572 | 573 | auto cp = getcmdparam(target_id, argc, argv); 574 | log(0, "command:", cp); 575 | 576 | STARTUPINFOW si; 577 | ZeroMemory(&si, sizeof(si)); 578 | si.cb = sizeof(si); 579 | PROCESS_INFORMATION pi; 580 | ZeroMemory(&pi, sizeof(pi)); 581 | 582 | mod_to_orig[Kernel32::CreateProcess] = CreateProcessW; 583 | mod_to_orig[Kernel32::GetFileAttributes] = GetFileAttributesW; 584 | mod_to_orig[Kernel32::IsWow64Process] = IsWow64Process; 585 | 586 | auto result = Kernel32::CreateProcess( 587 | targetpath, &cp[0], 588 | NULL, NULL, false, 589 | NORMAL_PRIORITY_CLASS | CREATE_DEFAULT_ERROR_MODE | (suspend ? CREATE_SUSPENDED : 0), 590 | NULL, targetdir.c_str(), &si, &pi 591 | ); 592 | if (!result) 593 | { 594 | auto e = GetLastError(); 595 | if (e == 740 || e == 5) 596 | { 597 | ShellExecuteW(NULL, L"runas", exepath, &cp[0], targetdir.c_str(), SW_SHOWNORMAL); 598 | } 599 | else 600 | { 601 | log(0, GetLastErrorString()); 602 | } 603 | return 0; 604 | } 605 | 606 | return GetProcessId(pi.hProcess); 607 | } 608 | --------------------------------------------------------------------------------