CreateRemoteThread возвращает ERROR_ACCESS_DENIED - Windows 7 DLL инъекций - PullRequest
6 голосов
/ 26 февраля 2012

Я пытаюсь написать программу, которая использует CreateRemoteThread для ввода DLL.

Проблема в том, что 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;

После большого количества поиска в Google я не могу найти причину, по которой это не должно работать.

Не работает ли CreateRemoteThread под Windows 7?Если да, я допустил какие-либо очевидные ошибки?

Ответы [ 5 ]

15 голосов
/ 28 октября 2012

Причина сбоя в том, что ваш код 32-битный, а целевой процесс 64-битный.

Не имеет значения, сколько у вас привилегий.Windows не допустит этого.

У меня была такая же проблема.Либо вы запускаете системный 32-битный exe-файл и внедряете его, либо переносите свой код на 64-битный (что означает, что он не будет работать на 32-битных системах).

EDIT

Давным-давно, я нашел хороший способ вставлять код в любую цель режима процессора и из нее.Это включает в себя динамическое переключение режима процессора в режим (любой) цели.Называется "небесные врата".Для этого вам нужно использовать встроенную сборку.Таким образом, в основном вы можете иметь как 64-битный, так и 32-битный код в 32-битном exe-файле, определить, является ли машина 64-битной, затем перейти в 64-битный режим и запустить 64-битный код.Затем вы пройдете по импорту, чтобы найти ntdll и загрузить 64-битную версию kernel.dll и других библиотек.Вот ссылка на примеры для тех, кто заинтересован: http://bit.ly/19P0Lh3

2 голосов
/ 07 мая 2012

ОК, ваш код, скорее всего, выйдет из строя в Windows 7 и Vista из-за «Защищенных процессов», то есть процессов, которыми могут манипулировать только другие Защищенные процессы, такие как explorer.exe и т. Д. В Windows 7 x32есть способ: поскольку вы можете загружать неподписанные драйверы, ... что ж, все готово (ищите Алекса Ионеску в google).В Windows 7 x64, однако, вы не можете (ду!)

"Четвертый параметр CreateRemoteThread () - это адрес. В вашем случае это адрес LoadLibraryA. Однако в Windows7, Kernel32.dll / LoadLibraryA базовый адрес будет отличаться в разных процессах; "

Что ж, это не так, потому что DLL совместно используются по одним и тем же адресам в каждом процессе, несмотря на ASLR.DLL могут быть перебазированы, но вы можете вызвать GetProcAddress перед вызовом CreateRemoteThread, так что очень маловероятно, что DLL будет перебазирован тем временем.

2 голосов
/ 27 февраля 2012

Непосредственные проблемы, которые я вижу, состоят в том, что вы не получаете токен доступа, что должно быть сделано так:

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 голосов
/ 26 мая 2013

Функция CreateRemoteThread не работает в Win Vista / 7. Для этого вы должны использовать недокументированную функцию NTCreateThread.

0 голосов
/ 19 апреля 2012

Я думаю, что метод внедрения DLL CreateRemoteThread () не может работать в Windows 7.

Четвертый параметр CreateRemoteThread () - это адрес. В вашем случае это адрес LoadLibraryA. Однако в Windows 7 базовый адрес Kernel32.dll / LoadLibraryA будет различным в разных процессах; Следовательно, CreateRemoteThread () не будет работать, поскольку адрес не соответствует ожидаемому. Это моё собственное мнение, надеюсь, оно поможет. :)

...