In C, I am creating a program that uses WinAPI. For this program, I am writing a function that will enable the specified privileges. Here is what I have:
void EnablePrivileges(LPCWSTR awszPrivileges[], DWORD dwCount){
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
printf("Failed to open process token. Error: %lu\n", GetLastError());
return;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = dwCount;
for (DWORD i = 0; i < dwCount; ++i) {
wprintf(TEXT("Privilege constant: %ls | Iterator value: %i\n"), awszPrivileges[i], i);
if(!LookupPrivilegeValueW(NULL, awszPrivileges[i], &tp.Privileges[i].Luid)) {
printf("Failed to lookup privilege value. Error: %lu\n", GetLastError());
CloseHandle(hToken);
return;
}
tp.Privileges[i].Attributes = SE_PRIVILEGE_ENABLED;
}
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
printf("Failed to adjust token privileges. Error: %lu\n", GetLastError());
} else {
printf("Token privileges adjusted successfully.\n");
}
CloseHandle(hToken);
}
int main() {
LPCWSTR awszPrivileges[] = {SE_TAKE_OWNERSHIP_NAME, SE_AUDIT_NAME, SE_RESTORE_NAME};
EnablePrivileges(awszPrivileges, 3);
system("pause");
return 0;
}
It compiles with zero errors.
However, when I then run it with administrative privileges, it gives the following:
Privilege constant: SeTakeOwnershipPrivilege | Iterator value: 0
Privilege constant: SeAuditPrivilege | Iterator value: 1
Privilege constant: SeAuditPrivilege | Iterator value: 1
Privilege constant: SeAuditPrivilege | Iterator value: 1
Privilege constant: SeAuditPrivilege | Iterator value: 1
Privilege constant: SeAuditPrivilege | Iterator value: 1
… and so on.
It also did this when it was only two privileges attempting to be enabled. However, it works successfully with only one.
What is causing the for-loop to behave like this? What is the fix for this error?
>Solution :
You’re addressing off the end of tp.Privileges. That array has a size of 1. As stated in the documentation:
Important The constant
ANYSIZE_ARRAYis defined as 1 in the public header Winnt.h. To create this array with more than one element, you must allocate sufficient memory for the structure to take into account additional elements.
You must allocate a (properly aligned) block of memory that is at least sizeof(TOKEN_PRIVILEGES) + (dwCount - 1) * sizeof(LUID_AND_ATTRIBUTES), and initialize your TOKEN_PRIVILEGES object there.