从服务调用的VirtualProtectEx返回false,但GetLastError为0(成功)

时间:2019-01-20 05:11:39

标签: c++ winapi visual-studio-2013 windows-services

为什么从服务应用程序调用时VirtualProtectEx函数失败?已经从一个简单的应用程序执行,一切正常。

然后,是否有可能使该功能也可以通过服务使用?

这是我的代码:

void WriteProcMem(HANDLE hProcess, VOID *pAddr)
{
    DWORD oldProtection;
    DWORD bytesWritten = 0;
    BYTE data[] = { 0x90, 0x90, 0x90, 0x90, 0x90 }; // Only a example of assembly data

    if (!VirtualProtectEx(hProcess, (LPVOID)pAddr, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtection)) {
        printf("\n VirtualProtectEx() error - %d\n", GetLastError());

        //=============== To debug from service application ===================

        FILE * pFile;
        pFile = fopen("C:\\myfile.txt", "w");
        if (pFile != NULL)
        {

            char * str = new char[100];
            sprintf(str, "%d", GetLastError());

            fputs(str, pFile);
            fclose(pFile);
        }

        //======================================================================

        return;
    }

    if (WriteProcessMemory(hProcess, (LPVOID)pAddr, &data, sizeof(data), &bytesWritten)) {

        printf("\n Data written success! \n");

        if (!VirtualProtectEx(hProcess, (LPVOID)pAddr, sizeof(DWORD), oldProtection, &oldProtection))
            printf("\n VirtualProtectEx() [2] error - %d \n", GetLastError());
    }

}
  

该服务以调试模式执行子进程,并使用SYSTEM帐户将这些数据写入“ child.exe ”。


版本:

回答@ S.M。 GetLastError()返回的实际值是:

  

ERROR_INVALID_HANDLE :6(0x6)-句柄无效。

但是就像我已经说过的,当不作为服务执行时,一切正常。为什么会这样?

1 个答案:

答案 0 :(得分:1)

这是标题的答案。

pFile = fopen("C:\\myfile.txt", "w");行调用Windows API函数,并且可能会重置最后的错误代码。因此,正确处理最后一个错误代码是在有趣的API调用之后立即将其保存到变量中。试试下面的代码,在调用VirtualProtectEx之后,您应该会得到真正的错误代码。

if (!VirtualProtectEx(hProcess, (LPVOID)pAddr, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtection)) {
    int err_code = GetLastError();
    printf("\n VirtualProtectEx() error - %d\n", err_code):

    //=============== To debug from service application ===================

    FILE * pFile = fopen("C:\\myfile.txt", "w");
    if (pFile != NULL)
    {
        fprintf(pFile, "%d\n", err_code);
        fclose(pFile);
    }
    ...