-2

I have enabled the SeDubugPrivilege but the GetModuleBaseName not working, I have all the admin rights. I tried it on different pc it works fine. But in my pc i cannot get the desired output.

Here's my code:

void printError(){
    wchar_t buf[256];
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
           NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
           buf, sizeof(buf), NULL);
    wcout<<buf;
}
BOOL SetPrivilege(
    HANDLE hToken,          // access token handle
    LPCTSTR lpszPrivilege,  // name of privilege to enable/disable
    BOOL bEnablePrivilege   // to enable or disable privilege
)
{
    TOKEN_PRIVILEGES tp;
    LUID luid;

    if ( !LookupPrivilegeValue(
            NULL,            // lookup privilege on local system
            lpszPrivilege,   // privilege to lookup
            &luid ) )        // receives LUID of privilege
    {
    printf("LookupPrivilegeValue error: %u\n", (unsigned int)GetLastError() 
    );
    return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
    tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.

if ( !AdjustTokenPrivileges(
       hToken,
       FALSE,
       &tp,
       sizeof(TOKEN_PRIVILEGES),
       (PTOKEN_PRIVILEGES) NULL,
       (PDWORD) NULL) )
{
      printf("AdjustTokenPrivileges error: \n");
      printError();
      return FALSE;
}

if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)

{
        printError();
      printf("The token does not have the specified privilege. \n");
      return FALSE;
}
return TRUE;
}
int main(){
   Sleep(5000);
   HWND currWindow = GetForegroundWindow();
   int titleLength = GetWindowTextLengthW(currWindow)+1;
   wchar_t s[titleLength];
   GetWindowTextW(currWindow,s,titleLength);
   wcout<<s<<endl;
   unsigned long i = 0;
   long unsigned *p = &i;
   GetWindowThreadProcessId(currWindow,p);
   cout<<*p<<endl;
   HANDLE handleForCurrentProcess = OpenProcess(PROCESS_QUERY_INFORMATION | 
   PROCESS_VM_READ,FALSE,*p);

   HANDLE accessToken;
   OpenProcessToken(handleForCurrentProcess,TOKEN_ADJUST_PRIVILEGES | 
   TOKEN_QUERY ,&accessToken);
   SetPrivilege(accessToken,SE_DEBUG_NAME,TRUE);
   wchar_t moduleName[500];
   cout<<GetModuleBaseNameW(handleForCurrentProcess,NULL,moduleName,500);
   wcout<<moduleName<<endl;
   cout<<GetModuleFileNameExW(handleForCurrentProcess,NULL,moduleName,500);
   wcout<<moduleName;
   return 0;
}

This works fine in another pc. Also i have enabled the SeDebugPrivilege in security policies.

EDIT Here the updated code with error checking calls in main

int main(){
Sleep(3000);
HWND currWindow = GetForegroundWindow();
int titleLength = GetWindowTextLengthW(currWindow)+1;
wchar_t s[titleLength];
DWORD status = GetWindowTextW(currWindow,s,titleLength);
if(status == 0){
    cout<<"Error in GetWindowTextW";
    printLastError();
}
wcout<<"Title : "<<s<<endl;
unsigned long id = 0;
GetWindowThreadProcessId(currWindow,&id);
cout<<"Process Id : "<<id<<endl;
HANDLE handleForForegroundProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,id);
if(handleForForegroundProcess == NULL){
    cout<<"Error in OpenProcess";
    printLastError();
}
HANDLE accessToken;
BOOL processStatus = OpenProcessToken(handleForForegroundProcess,TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY ,&accessToken);
if(processStatus == 0){
    cout<<"Error in OpenProcessToken";
    printLastError();
}
SetPrivilege(accessToken,SE_DEBUG_NAME,TRUE);
wchar_t moduleName[500];
status = GetModuleBaseNameW(handleForForegroundProcess,NULL,moduleName,500);
if(status == 0){
    cout<<"Error in GetModuleBaseNameW";
    printLastError();
}
wcout<<"Module Name : "<<moduleName<<endl;

wchar_t modulePath[2000];
status = GetModuleFileNameExW(handleForForegroundProcess,NULL,modulePath,2000);
if(status == 0){
    cout<<"Error in GetModuleFileNameExW";
    printLastError();
}
wcout<<"Module path : "<<modulePath;
return 0;
}

Here's the output when the foreground window is Google Chrome

Title : Error Checking in C++ (Windows) - Google Chrome
Process Id : 14528
The token does not have the specified privilege.
Not all privileges or groups referenced are assigned to the caller.
Error in GetModuleBaseNameWOnly part of a ReadProcessMemory or WriteProcessMemory request was completed.
Module Name : -
Module path : C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

And here's the output when the foreground window is the process from which the code is runned i.e Code Blocks

Title : main.cpp - Code::Blocks 17.12
Process Id : 4008
The token does not have the specified privilege.
Not all privileges or groups referenced are assigned to the caller.
Module Name : codeblocks.exe
Module path : C:\Program Files (x86)\CodeBlocks\codeblocks.exe

I am not getting the modulename for chrome. Thanks.

  • Inconsistent formatting is the siamese twin of poor code. Please fix. And if you want to fix this, make sure your error reporting is correct. Yours isn't. – IInspectable Mar 02 '18 at 20:31
  • 1
    `OpenProcess` is probably failing, not that you'd know. Enabling the debug privilege after calling `OpenProcess` misunderstands how access is granted. A kernel handle is created with the level of access that is requested and granted at the time the object is opened. A kernel component or driver accesses an object referenced by handle via [`ObReferenceObjectByHandle`](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-obreferenceobjectbyhandle). This returns the object pointer only if the handle is valid, has the right type, and was granted sufficient access. – Eryk Sun Mar 02 '18 at 21:29
  • It's pointless anybody looking at this without you having first made an effort to debug it. What's the point in us doing it for you? If we do, you will still not know how to debug. Fix the error checking and take it from there. – David Heffernan Mar 02 '18 at 21:57
  • But the same code works fine on a different machine and gives the proper output. Why so? – Shailesh Jain Mar 03 '18 at 03:38
  • Add error checking for every call in `main`, and fix the obvious mistake that I mentioned previously, i.e. enable the debug privilege *before* calling `OpenProcess`. Then we'll have something to talk about. – Eryk Sun Mar 03 '18 at 09:56
  • I have made the changes and even checked each line of execution by printing the output. And also if i enable debug privilege before `OpenProcess` what handle should i pass to the `OpenProcessToken` function? If i pass the `HWND` handle of current window, it gives an error the handle is invalid. And as i mentioned it works fine on another machine. – Shailesh Jain Mar 03 '18 at 10:57
  • Why do you think you need to enable debug privilege? For whom do you think it needs to be enabled? To which process do you assume `handleForCurrentProcess` refers? Bear in mind, you're writing a console application. For argument's sake, let's assume the console is the foreground window at the time you call `GetForegroundWindow` (not necessarily), who do you think is the effective owner of that window, as returned by `GetWindowThreadProcessId`? Can it be another process? Is it *usually* another process? Who allocated the console? – Eryk Sun Mar 03 '18 at 12:37
  • When i execute the program, it gives me the correct output for the window `codeblocks` and its child i.e console. And for the rest only window title is received by outputted. The path, base name is not received. But it works for all the process (ex. Chrome, Explorer ) i.e gives the name, path of the process on different pc. But not on mine. And by `handleForCurrentWindow` i mean the active window. – Shailesh Jain Mar 03 '18 at 12:55
  • `handleForCurrentProcess` is not necessarily *the* current process. The name you chose is misleading. But then you get its token to enable debug privilege *as if* it's the current process, which makes no sense. If you want the current process, it's simply `GetCurrentProcess()`. You need that no matter what in order to enable the debug privilege to ensure you can open the process that owns the foreground window, which could be anything. That said, debug privilege won't let you open *protected* processes (e.g. smss.exe, csrss.exe, or services.exe) to read memory and query info. – Eryk Sun Mar 03 '18 at 19:01
  • Sorry for the misleading name i have given. Please help me getting the path, name for a foreground process. So to access the process( such as chrome, file explorer,etc) other than the process from which i am running the program i should enable the debug privileges. I am new to Windows programming. `handleForForegroundProcess` should be the correct name i think so. Please help me in getting other process information. Thanks alot. – Shailesh Jain Mar 03 '18 at 19:25
  • The process you need to enable debug privilege for is the current process, i.e. `GetCurrentProcess()`. FYI, a process or impersonating thread has a Token, which includes groups and privileges, any of which can be currently enabled or disabled. Privileges are checked by associated kernel components, typically when creating or opening an object. For example, when opening a process or thread, if the caller has debug privilege enabled, then any desired access is granted -- unless the target is a protected process. – Eryk Sun Mar 03 '18 at 22:30
  • Update your question to show the error checking for the calls in `main`, and show the error code for the call that fails. – Eryk Sun Mar 03 '18 at 22:30
  • Please see the edited part i have given the error checking code in main. And also provided the output. Please bare me as i am new at `Stack Overflow` for asking question. – Shailesh Jain Mar 04 '18 at 06:36
  • You're still incorrectly trying to enable the debug privilege in someone else's token. If it can be enabled (e.g. you're running as an elevated administrator), then it needs to be done for the current process before calling `OpenProcess`. That said, now that I see the error, you don't need debug privilege to open the process that's giving you a problem. That's working fine as is. `GetModuleBaseName` is probably failing because you built a 32-bit executable, and you're trying to read the memory of a 64-bit process. Change your build target to 64-bit. – Eryk Sun Mar 04 '18 at 23:44
  • The location "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" suggests it's 32-bit, but I wouldn't wager on it. – Eryk Sun Mar 04 '18 at 23:47
  • Thanks alot for helping me out. I got what you explained. Thanks. And also understood the `OpenProcess` and `SetPrivilege` part. And it worked when i build 64 bit build. – Shailesh Jain Mar 05 '18 at 19:31

1 Answers1

0

Here's a working version of the program. You don't need to enable SE_DEBUG_PRIVILEGE just to get a module's base name (or its full path, if you use QueryFullProcessImageName instead of GetModuleBaseName). That simplifies the code a bit:

#include <windows.h>
#include <TlHelp32.h>
#include <psapi.h>
#include <iostream>
#include <iomanip>

#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "user32.lib")

void show_task(DWORD processID) { 
    HANDLE process = OpenProcess(
        PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
        FALSE,
        processID);

    char name[MAX_PATH];
    DWORD length = sizeof(name);

    GetModuleBaseName(process, NULL, name, sizeof(name));
    //QueryFullProcessImageName(process, NULL, name, &length);
    std::cout << name << "\n";
}

int main() {
    Sleep(5000);

    HWND currWindow = GetForegroundWindow();
    DWORD proc_id;
    GetWindowThreadProcessId(currWindow, &proc_id);

    show_task(proc_id);
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • `GetModuleBaseName` has to read the loader data directly from the target process. This fails with `ERROR_PARTIAL_COPY` for a 32-bit program that tries to read the memory of a 64-bit program, which is the error the OP is getting. – Eryk Sun Mar 05 '18 at 14:52
  • 1
    The OP's `GetModuleFileNameEx` call with a `NULL` module handle is effectively the same as `QueryFullProcessImageName` nowadays with PSAPI version 2 (both call `NtQueryInformationProcess` to get the same info), which is why it worked for the OP. Of course only the former is formally specified to work like that. This query requires only the right to query limited information, so if it's used instead of `GetModuleBaseName`, the `OpenProcess` call should be changed as well. – Eryk Sun Mar 05 '18 at 14:54