2012-02-26 9 views
6

मैं एक प्रोग्राम लिखने की कोशिश कर रहा हूं जो CreateRemoteThread का उपयोग एक डीएल इंजेक्ट करने के लिए करता है।CreateRemoteTrread वापसी ERROR_ACCESS_DENIED - विंडोज 7 डीएलएल इंजेक्शन

समस्या यह है कि CreateRemoteThread काम करने से इनकार कर रहा है। GetLastError() 5 लौटा रहा है जो ERROR_ACCESS_DENIED है। मैं समझ नहीं सकता क्यों!

मैं इस वीडियो http://www.youtube.com/watch?v=H3O3hmXkt1I से काम कर रहा हूं।

#include <iostream> 
#include <direct.h> 
#include <Windows.h> 
#include <TlHelp32.h> 

using namespace std; 


char* GetCurrentDir() 
{ 
    char* szRet = (char*)malloc(MAX_PATH); 
    _getcwd(szRet, MAX_PATH); 
    return szRet; 
} 

LPCTSTR SzToLPCTSTR(char* szString) 
{ 
    LPTSTR lpszRet; 
    size_t size = strlen(szString)+1; 

    lpszRet = (LPTSTR)malloc(MAX_PATH); 
    mbstowcs_s(NULL, lpszRet, size, szString, _TRUNCATE); 

    return lpszRet; 
} 

void WaitForProcessToAppear(LPCTSTR lpcszProc, DWORD dwDelay) 
{ 
    HANDLE   hSnap; 
    PROCESSENTRY32 peProc; 
    BOOL   bAppeared = FALSE; 

    while(!bAppeared) 
    { 
     if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE) 
     { 
      peProc.dwSize = sizeof(PROCESSENTRY32); 
      if(Process32First(hSnap, &peProc)) 
       while(Process32Next(hSnap, &peProc) && !bAppeared) 
        if(!lstrcmp(lpcszProc, peProc.szExeFile)) 
         bAppeared = TRUE; 
     } 
     CloseHandle(hSnap); 
     Sleep(dwDelay); 
    } 
} 

DWORD GetProcessIdByName(LPCTSTR lpcszProc) 
{ 
    HANDLE   hSnap; 
    PROCESSENTRY32 peProc; 
    DWORD   dwRet = -1; 

    if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE) 
    { 
     peProc.dwSize = sizeof(PROCESSENTRY32); 
     if(Process32First(hSnap, &peProc)) 
      while(Process32Next(hSnap, &peProc)) 
       if(!lstrcmp(lpcszProc, peProc.szExeFile)) 
        dwRet = peProc.th32ProcessID; 
    } 
    CloseHandle(hSnap); 

    return dwRet; 
} 

BOOL InjectDll(DWORD dwPid, char* szDllPath) 
{ 
    DWORD dwMemSize; 
    HANDLE hProc; 
    LPVOID lpRemoteMem, lpLoadLibrary; 
    BOOL bRet = FALSE; 

    if((hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) != NULL) 
    { 
     dwMemSize = strlen(szDllPath); 
     if((lpRemoteMem = VirtualAllocEx(hProc, NULL, dwMemSize, MEM_COMMIT, PAGE_READWRITE)) != NULL) 
      if(WriteProcessMemory(hProc, lpRemoteMem, szDllPath, dwMemSize, NULL)) 
      { 
       lpLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); 
       if(CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpRemoteMem, 0, NULL) != NULL) 
       { 
        bRet = TRUE; 
       } 
       cout << GetLastError(); 
      } 
    } 
    CloseHandle(hProc); 

    return bRet; 
} 

int main() 
{ 
    char szProc[MAX_PATH], szDll[MAX_PATH]; 
    char* szDllPath = (char*)malloc(MAX_PATH); 
    LPTSTR lpszProc = NULL; 

    for(;;) 
    { 
     cout << "Process: "; 
     cin >> szProc; 
     cout << "DLL: "; 
     cin >> szDll; 

     szDllPath = GetCurrentDir(); 
     strcat_s(szDllPath, MAX_PATH, "\\"); 
     strcat_s(szDllPath, MAX_PATH, szDll); 

     cout << "Waiting for process.. ." << szDllPath << " " << szDll << endl; 
     WaitForProcessToAppear(SzToLPCTSTR(szProc), 100); 
     if(InjectDll(GetProcessIdByName(SzToLPCTSTR(szProc)), szDllPath)) 
      cout << "Injection Succeeded!" << endl; 
     else 
      cout << "Injection Failed!" << endl; 
     cout << "\n"; 

    } 

    return 0; 

उचित मात्रा में गुगलिंग के बाद मुझे कोई कारण नहीं मिल रहा है कि यह क्यों काम नहीं कर रहा है।

क्या बनाएँRemoteThread विंडोज 7 के तहत काम नहीं करता है? यदि ऐसा होता है, तो क्या मैंने कोई स्पष्ट गलतियां की हैं?

+1

इस कोड में बहुत सारी बग हैं। सबसे प्रासंगिक एक GetLastError को कॉल कर रहा है भले ही आपको एपीआई फ़ंक्शन से FALSE रिटर्न न मिले। –

+0

मुझे लगता है कि आपको यह भी सुनिश्चित करना चाहिए कि आप अपनी सामग्री को व्यवस्थापक के रूप में चलाएं, न कि नियमित उपयोगकर्ता के रूप में, क्योंकि यूएसी शायद इंजेक्शन प्रक्रिया के साथ गड़बड़ कर लेता है। – foxx1337

+1

एक एक्सेस संबंधित समस्या यह है कि आपको 'PROCESS_ALL_ACCESS' के साथ 'ओपनप्रोसेस' नहीं बुलाया जाना चाहिए। आवश्यक पहुंच अधिकारों के न्यूनतम सेट के साथ इसे कॉल करें। इसके पीछे कारण यहां दस्तावेज है: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx –

उत्तर

2

तत्काल समस्याओं मैं देख रहा हूँ कि आप पहुँच टोकन के रूप में ऐसा किया जाना चाहिए नहीं मिल रहा है कर रहे हैं:

HANDLE hToken; 
TOKEN_PRIVILEGES tp; 
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); 

tp.PrivilegeCount = 1; 
LookupPrivilegeValue(NULL, _T("SeDebugPrivilege"), &tp.Privileges[0].Luid); 
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken); 

AdjustTokenPrivileges(hToken, FALSE, &tp, NULL, NULL, NULL); 
CloseHandle(hToken); 

मैं समय अपने सभी कोड के माध्यम से अभी देखने के लिए नहीं है, लेकिन यहाँ कुछ है मैं अपनी पिछली परियोजनाओं में से एक से बाहर निकल गया:

// returns open process handle 
HANDLE InjectDLL(DWORD dwPID, LPCWSTR szDLLPath, HMODULE* lphInjected) { 
    int  cszDLL; 
    LPVOID lpAddress; 
    HMODULE hMod; 
    HANDLE hThread; 
    HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | 
     PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | 
     PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwPID); 

    if(hProcess == NULL) { 
    return NULL; 
    } 

    cszDLL = (wcslen(szDLLPath) + 1) * sizeof(WCHAR); 

    // Injection 
    lpAddress = VirtualAllocEx(hProcess, NULL, cszDLL, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 
    if(lpAddress == NULL) { 
    return NULL; 
    } 

    WriteProcessMemory(hProcess, lpAddress, szDLLPath, cszDLL, NULL); 

    hMod = GetModuleHandle(L"kernel32.dll"); 
    if(hMod == NULL) { 
    return NULL; 
    } 

    hThread = CreateRemoteThread(hProcess, NULL, 0, 
     (LPTHREAD_START_ROUTINE)(GetProcAddress(hMod, 
     "LoadLibraryW")), lpAddress, 0, NULL); 

    // Locate address our payload was loaded 
    if(hThread != 0) { 
    WaitForSingleObject(hThread, INFINITE); 
    GetExitCodeThread(hThread, (LPDWORD)lphInjected); 
    VirtualFreeEx(hProcess, lpAddress, 0, MEM_RELEASE); 
    CloseHandle(hThread); 
    } 

    return hThread != 0 ? hProcess : NULL; 
} 

देखें कि यह मदद करता है या नहीं। बाद में फिर से देखेंगे।

0

मुझे लगता है कि CreateRemoteThread() dll इंजेक्शन विधि विंडोज़ 7

CreateRemoteThread (के चौथे पैरामीटर में काम नहीं कर सकते हैं) एक पते है। आपके मामले में यह LoadLibraryA पता है। हालांकि, विंडोज 7 में, कर्नेल 32.dll/LoadLibraryA आधार पता विभिन्न प्रक्रियाओं में अलग-अलग होगा; इसलिए, CreateRemoteThread() काम नहीं करेगा क्योंकि पता आपके द्वारा अपेक्षित नहीं है। यह मेरी राय है, उम्मीद है कि इससे मदद मिलेगी। :)

2

ठीक है, आपका कोड "संरक्षित प्रक्रियाओं" की वजह से विंडोज 7 और Vista में विफल होने की संभावना है, यानी, प्रक्रियाओं को केवल अन्य संरक्षित प्रक्रियाओं जैसे एक्सप्लोरर.एक्सई आदि द्वारा छेड़छाड़ की जा सकती है ... में विंडोज 7 एक्स 32 एक तरीका है: चूंकि आप बिना हस्ताक्षरित ड्राइवर लोड कर सकते हैं ... अच्छा, आप कर चुके हैं (Google में एलेक्स Ionescu के लिए खोजें)। विंडोज 7 64 में, हालांकि, आप कर सकते हैं नहीं (ओह!)

"CreateRemoteThread() के चौथे पैरामीटर एक पते, खिड़कियों में 7, Kernel32 है। आपके मामले में यह LoadLibraryA पता है। हालांकि .dll/LoadLibraryA आधार पता विभिन्न प्रक्रियाओं में विभिन्न होगा; "

ठीक है, यह दूरस्थ रूप से सत्य नहीं है, क्योंकि एएसएलआर के बावजूद डीएलएल को हर प्रक्रिया में एक ही पते पर साझा किया जाता है। डीएलएल को फिर से बदला जा सकता है, लेकिन आप CreateRemoteThread को कॉल करने से पहले GetProcAddress को कॉल कर सकते हैं, इसलिए यह बहुत ही असंभव है कि डीएलएल इस बीच रिबेस हो जाएगा।

14

कारण यह विफल रहता है क्योंकि आपका कोड 32-बिट है और आपकी लक्ष्य प्रक्रिया 64-बिट है।

इससे कोई फ़र्क नहीं पड़ता कि आपके पास कितने विशेषाधिकार हैं। विंडोज ऐसा नहीं होने देगा।

मुझे एक ही समस्या थी। या तो आप 32-बिट exe सिस्टम को उत्पन्न करते हैं और उसको इंजेक्ट करते हैं या 64-बिट पर अपना कोड पोर्ट करते हैं (जिसका अर्थ है कि यह 32-बिट सिस्टम पर काम नहीं करेगा)।

संपादित

एक लंबे समय पहले, मैं में और किसी भी प्रोसेसर मोड लक्ष्य से कोड इंजेक्शन लगाने का एक अच्छा तरीका मिल गया। इसमें गतिशील रूप से प्रोसेसर मोड को (किसी भी) लक्ष्य को स्विच करना शामिल है। "स्वर्ग का द्वार" डब किया गया। ऐसा करने के लिए आपको इनलाइन असेंबली का उपयोग करना होगा। तो मूल रूप से आपके पास 32-बिट एक्सई में 64-बिट और 32-बिट कोड दोनों हो सकते हैं, यह पता लगाएं कि मशीन 64-बिट है या नहीं, फिर 64-बिट मोड में कूदें और 64-बिट कोड चलाएं। फिर आप ntdll को खोजने और 64-बिट kernel.dll और अन्य पुस्तकालयों को लोड करने के लिए आयात चलेंगे। यहां रुचि रखने वाले किसी भी व्यक्ति के लिए उदाहरणों का एक लिंक दिया गया है: http://bit.ly/19P0Lh3

+0

इनलाइन असेंबली का उपयोग क्यों करें ?? आप 'Wow64DisableWow64FsRedirection' – ST3

+0

Wow64DisableWow64FsRedirection के साथ जा सकते हैं विशेष रूप से जब प्रक्रियाओं को उत्पन्न करते हैं तो अधिक समस्याएं उत्पन्न होती हैं। आखिरकार, यह केवल एक्सपी प्रो से उपलब्ध है। 64 बिट नीचे कुछ भी काम नहीं करेगा। यह विधि कुछ समय के लिए रही है। Wow64DisableWow64FsRedirection आपको 32 बिट के अंदर 64 बिट कोड को निष्पादित करने नहीं देगा। यह सिर्फ एक फाइल सिस्टम पुनर्निर्देशन है। यहां टिप्पणियां पढ़ें: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365743(v=vs.85).aspx – TheRealChx101

0

CreateRemote थ्रेड फ़ंक्शन Win Vista/7 में काम नहीं करता है। आपको NTCreateThread फ़ंक्शन का उपयोग करना होगा, जो इसके लिए अनियंत्रित है।

+0

[यह] (http://msdn.microsoft.com/en -us/लाइब्रेरी/विंडोज/डेस्कटॉप/ms682437% 28v = vs.85% 29.aspx) यह इंगित करता है कि यह WinXP और बाद में सब कुछ पर काम करता है। मैंने व्यक्तिगत रूप से इसे Win7 पर भी काम किया है। –

+1

CreateRemoteThread Win VISTA/7 के लिए काम कर सकता है लेकिन वास्तव में मेरा मतलब यूआईपीआई था, जिसे Vista और बाद में ओएस में कार्यान्वित किया गया है, उच्च अखंडता स्तर पर प्रक्रियाओं को उच्च अखंडता स्तर पर प्रक्रियाओं से रोकता है, हालांकि आईएल को निकालना संभव है। – user101847