Ladies and gentlemen, Good day! I strongly need to learn how to change the integrity level for different files . Alas, but my searches in Google were unsuccessful. Only code that does this in C ++ was found, and failed to translate it into C # - pinvoke.net does not know the design of a number of functions that are used in C ++.

Do you have any idea where to start? If anyone is interested, attach the code.

  • one
    And why not just run icacls.exe ? - VladD
  • @VladD can also be through icacls.exe, but in this case it is necessary to do this programmatically. - E. Zubkov
  • Well, if you really need, you can also start icacls.exe programmatically. This is if there is no direct path. - VladD

3 answers 3

In general, the next thing came out. There are a lot of examples on the Internet about how to change the integrity level of a file in C ++. Therefore, it was decided to write a DLL with C ++ functional for use in C #.

Here are the three files needed for the build.

IntegrityLevel.h

 #include <stdexcept> #include <iostream> #include <windows.h> #include <Aclapi.h> #include <WinError.h> #include <Sddl.h> #include <tchar.h> #include <winnt.h> using namespace std; namespace IntegrityLevel { extern "C" { __declspec(dllexport) int GetFileIntegrityLevel(LPCWSTR FileName); } extern "C" { __declspec(dllexport) bool SetFileIntegrityLevel(int level, LPCWSTR FileName); } } 

IntegrityLevel.cpp

 #include "IntegrityLevel.h" namespace IntegrityLevel { int GetFileIntegrityLevel(LPCWSTR FileName) { DWORD integrityLevel = SECURITY_MANDATORY_UNTRUSTED_RID; PSECURITY_DESCRIPTOR pSD = NULL; PACL acl = 0; if (ERROR_SUCCESS == ::GetNamedSecurityInfo(FileName, SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION, 0, 0, 0, &acl, &pSD)) { if (0 != acl && 0 < acl->AceCount) { SYSTEM_MANDATORY_LABEL_ACE* ace = 0; if (::GetAce(acl, 0, reinterpret_cast<void**>(&ace))) { SID* sid = reinterpret_cast<SID*>(&ace->SidStart); integrityLevel = sid->SubAuthority[0]; } } PWSTR stringSD; ULONG stringSDLen = 0; ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1, LABEL_SECURITY_INFORMATION, &stringSD, &stringSDLen); if (pSD) { LocalFree(pSD); } } if (integrityLevel == 0x0000) return 0; else if (integrityLevel == 0x1000) return 1; else if (integrityLevel == 0x2000) return 2; else if (integrityLevel == 0x3000) return 3; else if (integrityLevel == 0x4000) return 4; else return -1; } bool SetFileIntegrityLevel(int level, LPCWSTR FileName) { LPCWSTR INTEGRITY_SDDL_SACL_W; if (level == 0) INTEGRITY_SDDL_SACL_W = L"S:(ML;;NR;;;LW)"; else if (level == 1) INTEGRITY_SDDL_SACL_W = L"S:(ML;;NR;;;ME)"; else if (level == 2) INTEGRITY_SDDL_SACL_W = L"S:(ML;;NR;;;HI)"; DWORD dwErr = ERROR_SUCCESS; PSECURITY_DESCRIPTOR pSD = NULL; PACL pSacl = NULL; BOOL fSaclPresent = FALSE; BOOL fSaclDefaulted = FALSE; if (ConvertStringSecurityDescriptorToSecurityDescriptorW( INTEGRITY_SDDL_SACL_W, SDDL_REVISION_1, &pSD, NULL)) { if (GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl, &fSaclDefaulted)) { dwErr = SetNamedSecurityInfoW((LPWSTR)FileName, SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl); if (dwErr == ERROR_SUCCESS) { return true; } } LocalFree(pSD); return false; } return false; } } 

IntegrityLevel.def - for some reason, hitched, but without it the project did not work

 LIBRARY INTEGRITYLEVEL 

Now how the collected library to use.

 [DllImport("<директория>\\IntegrityLevel.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern int GetFileIntegrityLevel(string FileName); [DllImport("<директория>\\IntegrityLevel.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern bool SetFileIntegrityLevel(int level, string FileName); 
  • Cool. A small native library is the right way. - VladD
  • @VladD did not manage to solve the problem differently. - E. Zubkov
  • But this is a good way. Complex native code that works with WinAPI is best kept in its native form. At the same time, the probability of errors is less. - VladD

I collected a dll, but when I use it, I get an error. Additional Information: I cannot find the entry point "GetFileIntegrityLevel" in the DLL I tried to view the dll in PE Explorer, and it says that no function is exported. Copied your files, collected dll in Visual studio (if this is important)

  • Is this an answer or a question? - Visman
  • Probably, the encoding or bitness of the library and the application used is not observed. It is also necessary to run the application from the administrator . - E. Zubkov
  • all this is complied with - Ameko

Thank you, yes, figured out, launched. Now new problems: 1. In SetFileIntegrityLevel INTEGRITY_SDDL_SACL_W is not defined at the very beginning, and the compiler curses. What better to feed there, so as not to affect the work? 2. By SetFileIntegrityLevel it is clear that 0 is Low, 1 is Medium, 2 is High. What corresponds to Untrusted and System. In GetFileIntegrityLevel 4 options - what? 3. At the moment, all files return 0 to me when received and false when I try to change.

  • 1 - It is defined in this function by the string LPCWSTR INTEGRITY_SDDL_SACL_W; 2 - In this program, it is not possible to set these integrity levels for a file. In my opinion, they can not be put in principle. 3 - See in code, in GetFileIntegrityLevel, the following options <! - language: lang-cpp -> if (integrityLevel == 0x0000) // Untrusted else if (integrityLevel == 0x1000) // Low else if (integrityLevel == 0x2000 ) // Medium else if (integrityLevel == 0x3000) // High else if (integrityLevel == 0x4000) // System <! - language: lang-cpp -> - E. Zubkov
  • and what then does the SetFileIntegrityLevel function do? - Ameko
  • it sets a new level of integrity for the file. - E. Zubkov
  • > 2 - In this program, it is not possible to set these integrity levels for a file. In my opinion, they can not be put in principle. - Ameko
  • Sorry, send jamb) The idea is that you said above that you cannot change the integrity level. And at the same time SetFileIntegrityLevel changes it? - Ameko