سؤال

لقد قمت بإنشاء موضوع إضافي في بعض تطبيقات الاختبار الصغيرة وأريد تعليق الخيط الرئيسي من هذا الموضوع الإضافي. يتم إنشاء الخيط الإضافي عبر CreateRemoteThread من عملية خارجية.

حيث SuspendThread يحتاج HANDLE إلى الموضوع الذي يجب تعليقه ، أريد أن أعرف كيفية الحصول على هذا HANDLE من رمز يعمل في موضوع إضافي.

هل كانت مفيدة؟

المحلول 2

DWORD GetMainThreadId () {
    const std::tr1::shared_ptr<void> hThreadSnapshot(
        CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0), CloseHandle);
    if (hThreadSnapshot.get() == INVALID_HANDLE_VALUE) {
        throw std::runtime_error("GetMainThreadId failed");
    }
    THREADENTRY32 tEntry;
    tEntry.dwSize = sizeof(THREADENTRY32);
    DWORD result = 0;
    DWORD currentPID = GetCurrentProcessId();
    for (BOOL success = Thread32First(hThreadSnapshot.get(), &tEntry);
        !result && success && GetLastError() != ERROR_NO_MORE_FILES;
        success = Thread32Next(hThreadSnapshot.get(), &tEntry))
    {
        if (tEntry.th32OwnerProcessID == currentPID) {
            result = tEntry.th32ThreadID;
        }
    }
    return result;
}

نصائح أخرى

لا أعتقد أن هناك أي شيء يميز الخيط الرئيسي عن المواضيع الأخرى بمجرد بدء العملية. ومع ذلك ، يمكنك تعداد جميع المواضيع في العملية, والاستخدام getThReadTimes للعثور على الخيط مع أقرب وقت لإنشاء. يتصل Openthread للحصول على HANDLE من معرف الموضوع.

احصل على معرف الموضوع مع هذه الوظيفة:

/* CAUTION: ONLY x86 TESTED
 * get the thread id of the main thread of a target process
 *
 * params:
 *     DWORD dwPid  process id of the target process
 *
 * return:
 *     Success      thread id
 *     Error        NULL
 */
DWORD GetMainThreadId(DWORD dwPid)
{
    LPVOID lpTid;

    _asm
    {
        mov eax, fs:[18h]
        add eax, 36
        mov [lpTid], eax
    }

    HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, dwPid);
    if(hProcess == NULL)
        return NULL;

    DWORD dwTid;
    if(ReadProcessMemory(hProcess, lpTid, &dwTid, sizeof(dwTid), NULL) == FALSE)
    {
        CloseHandle(hProcess);
        return NULL;
    }

    CloseHandle(hProcess);

    return dwTid;
}

افتح الخيط بسيط للحصول على المقبض:

/*
 * get a handle to the main thread of a target process
 * if successfull, the returned handle must be closed with CloseHandle()
 *
 * params:
 *     DWORD dwPid              process id of the target process
 *     DWORD dwDesiredAccess    desired access rights to the thread
 *
 * return:
 *     Success      thread handle with desired access rights
 *     Error        NULL
 */
HANDLE GetMainThreadHandle(DWORD dwPid, DWORD dwDesiredAccess)
{
    DWORD dwTid = GetMainThreadId(dwPid);
    if(dwTid == FALSE)
        return NULL;

    return OpenThread(dwDesiredAccess, FALSE, dwTid);
}

لماذا لا تقوم فقط بإنشاء عالمي على مستوى البرنامج (استخدام خارجي إذا كان لديك ل)

HANDLE mainThread ;
DWORD mainThreadId ;

في السطر الأول من الرئيسي ، (قبل إنشاء أي مؤشرات ترابط)

mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;

يمكنك استخدام أي شكل من أشكال IPC لمشاركة المعرف أو المقبض مع العملية عن بُعد (لم يتم التحقق من مشاركة المقبض ولكن يجب أن يعمل!)

هناك عدد من وظائف API المفيدة من هذا النوع تحت (بالطبع!) مساعدة الأداة جناح. ال CreateToolhelp32Snapshot() سوف يأخذ API لقطة من مؤشرات الترابط الجري لعملية محددة.

// Take a snapshot of all running threads  
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); 
if( hThreadSnap == INVALID_HANDLE_VALUE ) 
  return( FALSE );

رمز المثال الكامل هنا.

الهيكل الذي تم إرجاعه لا يفرق الخيط الأساسي عن الآخرين. لا أعرف آلية للقيام بذلك ؛ على الرغم من أن بعض إصدارات وقت التشغيل C ستحصل على ExitProcess () في نهاية الخيط الأساسي ، في جميع الإصدارات الحديثة ، تستمر العملية في العمل حتى يخرج الخيط الأخير.

قد تكون توصية Interjay لاستخدام GetThReadTimes أفضل رهان. إذا استطعت CreateProcess() العملية المستهدفة ، عضو HTREAD في PROCESS_INFORMATION يحتوي الكتلة على TID للخيط الأساسي. نرحب بأي أفكار من الآخرين.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top