Функция GetThreadContext всегда возвращает 0(код ошибки 6) в программе подключения API, написанной на C

#hacklang #reversing #api-hook #antimalware

Вопрос:

 """
#include <stdio.h>
#include <Windows.h>

DWORD dwPid;
BYTE INT3_BYTE = 0xCC;
BYTE Original_Byte = 0;
LPVOID p_WriteFile;
DWORD addOfString, lengthOfString;
CREATE_PROCESS_DEBUG_INFO cpdi;
char* lpBuffer;
CONTEXT ctx;

"""


int main(int argc, char* argv[])
{

    if (argc != 2)
    {
        printf("Usage : %s <PID>n", argv[0]);
        exit(1);
    }

    dwPid = atoi(argv[1]);

    //Start Debugging target process.
    if (!DebugActiveProcess(dwPid))
    {
        printf("Debug Process Failed!n");
        exit(1);
    }

    //if DebugActiveProcess() function succeed, call *DebugLoop()* function
    DebugLoop(dwPid);

    return 0;
}
 

Вышеуказанная область является основной функцией, и целью программы является отладка другого процесса, идентификатор которого задан параметром основные функции.

 '''
void DebugLoop (DWORD dwpid)
{
    DEBUG_EVENT de;
    while (WaitForDebugEvent(amp;de, INFINITE))
    {
        //If target process's attached to debugger..Call OnCreateProcessDebugEvent()
        if (de.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT)
            OnCreateProcessDebugEvent(amp;de);

        //If target process exit, debugger also exit the program.
        else if (de.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
            break;

        //If Debug Event arises in debuggee, call OnExceptionDebugEvent() function
        else if (de.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
        {
            if (OnExceptionDebugEvent(amp;de))
                continue;
        }

        ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
    }
}
'''

'''
BOOL OnCreateProcessDebugEvent(LPDEBUG_EVENT pde)
{
    //Get address of "WriteFile Function". because i want to hook "WriteFile"
    p_WriteFile = GetProcAddress(GetModuleHandleA("kernel32.dll"), "WriteFile");

    //Back-up process's information of Debuggee.
    memcpy(amp;cpdi, amp;pde->u.CreateProcessInfo, sizeof(CREATE_PROCESS_DEBUG_INFO));

    //Back-up 1st byte of "WriteFile" function's address
    ReadProcessMemory(cpdi.hProcess, p_WriteFile,
        amp;Original_Byte, sizeof(BYTE), NULL);

    //set "0xCC"byte the first byte of "WriteFile" function's address
    WriteProcessMemory(cpdi.hProcess, p_WriteFile,
        amp;INT3_BYTE, sizeof(BYTE), NULL);

    return TRUE;
}

'''
 

если отладочный процесс подключен к отладчику, вызовите указанную выше функцию.

 '''
BOOL OnExceptionDebugEvent(LPDEBUG_EVENT pde)
{
    // Is the reason of DEBUG_EVENT is BREAKPOINT?
    if (pde->u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
    {
        //Is it from the address "WriteFile" Function??
        if (pde->u.Exception.ExceptionRecord.ExceptionAddress == p_WriteFile)
        {
            //if Yes, write the original byte at the fisrt BYTE of function's address
            WriteProcessMemory(cpdi.hProcess, p_WriteFile,
                amp;Original_Byte, sizeof(BYTE), NULL);

            //Get current thread's register status.
            //This makes me frustrated. "GetThreadContext function returns always 
            0(Failed)"
            ctx.ContextFlags = CONTEXT_CONTROL;
            if (!GetThreadContext(cpdi.hThread, amp;ctx))
                printf("Context Get Failed!nError Code : %d n",GetLastError());

            //Get Address of the WriteFile function's second parameter(String to write)
            ReadProcessMemory(cpdi.hProcess, (LPCVOID)(ctx.Esp   0x8),
                amp;addOfString, sizeof(DWORD), NULL);

            //Get Address of the WriteFile function's third parameter(Length of String)
            ReadProcessMemory(cpdi.hProcess, (LPCVOID)(ctx.Esp   0xC),
                amp;lengthOfString, sizeof(DWORD), NULL);

            //Allocate memory for the string that will be read from debuggee.
            lpBuffer = (char*)malloc(lengthOfString   1);
            memset(lpBuffer, 0, lengthOfString 1);

            //Get third parameter(String Data) from debuggee.
            ReadProcessMemory(pde->u.CreateProcessInfo.hProcess, (LPVOID)addOfString,
                (LPVOID)lpBuffer,lengthOfString, NULL);

            
            printf("###Original String ###n%sn", lpBuffer);

            //Change all lowercase into uppercase
            for (DWORD i = 0;i < lengthOfString;i  )
            {
                if ('a' <= lpBuffer[i] amp;amp; lpBuffer[i] <= 'z')
                    lpBuffer -= ('a' - 'A');
            }

            //print changed string
            printf("###Changed String ###n%sn", lpBuffer);

            //write corrected string data to debuggee.
            WriteProcessMemory(pde->u.CreateProcessInfo.hProcess, (LPVOID)addOfString,
                (LPVOID)lpBuffer, sizeof(lpBuffer), NULL);

            //free allocated memory for string data
            free(lpBuffer);

            
            ctx.Eip = (DWORD)p_WriteFile;
            SetThreadContext(pde->u.CreateThread.hThread, amp;ctx);

            //Continue debuggee's process until next debug_event
            ContinueDebugEvent(pde->dwProcessId, pde->dwThreadId, DBG_CONTINUE);

            Sleep(0);

            //for next hooking, write "0xCC" at the first byte of the "WriteFile" func.
            WriteProcessMemory(pde->u.CreateProcessInfo.hProcess, (LPVOID)p_WriteFile,
                (LPVOID)amp;INT3_BYTE, sizeof(BYTE), NULL);

            return TRUE;
        }
    }
    return FALSE;
}

''' 
 

Каждый раз, когда я пытаюсь получить статус регистра текущего потока с помощью «GetThreadContext», он всегда не возвращает 0 (код ошибки 6 : Недопустимый дескриптор потока)
Я думал, что все правильные ручки(процесс и поток) переданы всем функциям. Я хочу знать, в чем проблема