0

I am getting the warning (treated as error):

Type Cast Pointer Truncation from HANDLE to ULONG

When I try to compile, I understand that the type has a different length as I am compiling ARM64 rather than ARM, therefore I need to change the type or static_cast it, however I receive errors such as "expected (" when changing the line to something like this:

return static_cast<ULONG>PsGetProcessId(current_process); //this gives me invalid conversion type as 
                                                          //there are no brackets around the static cast 
                                                          //because I am returning its value

I add brackets, however there is always a problem and it never seems to work, always "Expected (":

return (static_cast<ULONG>)PsGetProcessId(current_process); //this bracket error 

ORIGINAL CODE BELOW

ULONG memory::get_process_id_by_name(PEPROCESS start_process, const char* process_name)
{
    PLIST_ENTRY active_process_links;
    PEPROCESS current_process = start_process;

    do
    {
        PKPROCESS kproc = (PKPROCESS)current_process;
        PDISPATCHER_HEADER header = (PDISPATCHER_HEADER)kproc;
        LPSTR current_process_name = (LPSTR)((PUCHAR)current_process + IMAGE_FILE_NAME);

        if (header->SignalState == 0 && strcmp(current_process_name, process_name) == 0)
        {   
            return (ULONG)PsGetProcessId(current_process); //warning occurs here
        }

        active_process_links = (PLIST_ENTRY)((PUCHAR)current_process + ACTIVE_PROCESS_LINKS_FLINK);
        current_process = (PEPROCESS)(active_process_links->Flink);
        current_process = (PEPROCESS)((PUCHAR)current_process - ACTIVE_PROCESS_LINKS_FLINK);

    } while (start_process != current_process);

    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770

2 Answers2

1

Use ULONG_PTR instead of ULONG:

static_cast<ULONG_PTR>(hHandle)

If the value the handle holds is actually meant to be used as a ULONG then cast the ULONG_PTR to ULONG:

static_cast<ULONG>(static_cast<ULONG_PTR>(hHandle))
SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • Hello, thank you for the fast reply, however I run into another problem when using the solution. ``` return static_cast(static_cast(PsGetProcessId(current_process))); ``` I get the error: 'static_cast': cannot convert from 'HANDLE' to 'ULONG_PTR' Do you have any idea how to fix? This problem persists for both solutions you have offered – TheManTheGuy69 Dec 18 '20 at 03:25
1

The HANDLE type is used to point to an opaque structure.

It usually stores an index value, but in the winnt.h header file, it is defined as a pointer-length type.

typedef void *HANDLE;

So the correct approach is to treat the process id as a pointer-length type as well.

I know you don't like HANDLE, so you can use ULONG_PTR, it has the same length as the pointer type.

Here is the fixed code:

ULONG_PTR memory::get_process_id_by_name(PEPROCESS start_process, const char* process_name)
{
    PLIST_ENTRY active_process_links;
    PEPROCESS current_process = start_process;

    do
    {
        PKPROCESS kproc = (PKPROCESS)current_process;
        PDISPATCHER_HEADER header = (PDISPATCHER_HEADER)kproc;
        LPSTR current_process_name = (LPSTR)((PUCHAR)current_process + IMAGE_FILE_NAME);

        if (header->SignalState == 0 && strcmp(current_process_name, process_name) == 0)
        {
            return (ULONG_PTR)PsGetProcessId(current_process);
        }

        active_process_links = (PLIST_ENTRY)((PUCHAR)current_process + ACTIVE_PROCESS_LINKS_FLINK);
        current_process = (PEPROCESS)(active_process_links->Flink);
        current_process = (PEPROCESS)((PUCHAR)current_process - ACTIVE_PROCESS_LINKS_FLINK);

    } while (start_process != current_process);

    return 0;
}

If you have to use ULONG for other reasons, you can refer to @SoronelHaetir's solution.


Example for comment:

Before:

void test()
{
    ULONG value = (ULONG_PTR)0xFFFFFFFFFFFF;
    UNREFERENCED_PARAMETER(value);
}

EXTERN_C NTSTATUS DriverEntry(DRIVER_OBJECT *pDriverObject, UNICODE_STRING *pRegistryPath)
{
    UNREFERENCED_PARAMETER(pDriverObject);
    UNREFERENCED_PARAMETER(pRegistryPath);
    test();
    return STATUS_UNSUCCESSFUL;
}

Warnings:

error C2220: the following warning is treated as an error
warning C4305: 'initializing': truncation from 'ULONG_PTR' to 'ULONG'
warning C4309: 'initializing': truncation of constant value
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

After:

#pragma warning(push)
#pragma warning(disable: 4305)
#pragma warning(disable: 4309)
void test()
{
    ULONG value = (ULONG_PTR)0xFFFFFFFFFFFF;
    UNREFERENCED_PARAMETER(value);
}
#pragma warning(pop)

EXTERN_C NTSTATUS DriverEntry(DRIVER_OBJECT *pDriverObject, UNICODE_STRING *pRegistryPath)
{
    UNREFERENCED_PARAMETER(pDriverObject);
    UNREFERENCED_PARAMETER(pRegistryPath);
    test();
    return STATUS_UNSUCCESSFUL;
}

No warnings:

========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
Sprite
  • 3,222
  • 1
  • 12
  • 29
  • Hey, thanks for the reply! When following your solution, I get the error: '=': conversion from 'ULONG_PTR' to 'ULONG', possible loss of data In a different file of my driver. Please see the post below for code causing error. – TheManTheGuy69 Dec 18 '20 at 03:31
  • if (ioctl == NF_GET_PROCESS_ID) { PNF_PROCESS_ID_REQUEST process_id_request = (PNF_PROCESS_ID_REQUEST)irp->AssociatedIrp.SystemBuffer; process_id_request->process_id = memory::get_process_id_by_name(IoGetCurrentProcess(), process_id_request->process_name); if (process_id_request->process_id) { status = STATUS_SUCCESS; } bytes_io = sizeof(NF_PROCESS_ID_REQUEST); DbgPrintEx(0, 0, " NF_GET_PROCESS_ID\n"); } – TheManTheGuy69 Dec 18 '20 at 03:33
  • @TheManTheGuy69 You can just disable that warning [this way](https://stackoverflow.com/a/7159392/13433323). – Sprite Dec 18 '20 at 06:02
  • unfortunately I cannot disable the warning as I am working on a kernel driver. – TheManTheGuy69 Dec 18 '20 at 07:25
  • @TheManTheGuy69 I tested that it works fine (yes, kernel driver), and with `#pragma warning(push)` and `#pragma warning(pop)` you can disable specific warnings only for that function, not globally. – Sprite Dec 18 '20 at 07:59
  • @TheManTheGuy69 I would recommend that you just change the type of `process_id_request->process_id` to ULONG_PTR, if possible (this will break ABI compatibility). – Sprite Dec 18 '20 at 08:09
  • Thank you so much I forgot the push and pop. Everything working now, thank you! – TheManTheGuy69 Dec 18 '20 at 08:34