Я пытаюсь запустить 64-разрядную DLL исключительно в виртуальной памяти процессов без «вручную отображать» ее (то есть вручную разрешать перемещение/импорт).64-битная кодовая строка Возврат Неправильная точка входа
План заключается в том, чтобы вводить код в целевое приложение и загружать модуль с помощью обычных средств, таких как LoadLibrary.
Я был в предположении, что LoadLibrary будет исправлять перемещение/импорт модулей самостоятельно, так как это то, что он предназначен для выполнения.
После загрузки модуля введенный код получит информацию о модуле с GetModuleInformation, передаст его во временный буфер памяти, освободит модуль, распределит память по тому же адресу, на который он был первоначально загружен, запишет его и выполнить точку входа.
Этот последний шаг - это то место, где я считаю, что ошибка происходит.
Чтобы проверить эту теорию, у меня есть жестко кодирующие адреса точек входа, отладка удаленного приложения с помощью функции «Присоединить к процессу» Visual Studio, эмуляция аналогичной среды для исправления арифметики с плохими указателями, чтобы получить бит больше информации о том, что может быть ошибкой.
Вот некоторые общие сведения, которые могут или не могут быть полезны:
- Оба приложения (инжектор, и DLL), составляются для работы в 64-разрядных архитектур
- тестовое приложение, которое я использовал для тестирования метода инъекции, - это приложение для обновления Windows (wuauclt.exe - находится в/System32 /), оно, конечно, скомпилировано для запуска в виде 64-разрядного PE
- Хост-компьютер: Windows 7 Home до Mium (тип системы: 64-разрядная операционная система)
Насколько информация, относящаяся непосредственно к инжектору идет:
- Способ первичной инъекции код работает (насколько я могу сказать) , и я это доказал с помощью отладчика caveman с MessageBoxA
- Проект использует многобайтовый набор символов с отключенными оптимизациями кода. Код был составлен с использованием VS 2013 Ultimate (с обоих проектов, построенных для выпуска x64)
- СВД проверки выключены, поскольку используются небезопасные функции (STRCPY и друзей)
- Инжектор отлажена с повышенными привилегиями (так высоко, как SE_DEBUG_PRIVILEGES) каждый время его побежало.
Код Предисловие: Код экспонировались ниже не в любой, какой путь означало выглядеть довольно или экспонат хорошо практики программирования. Помните об этом при просмотре кода. Он был специально разработан для тестирования метода ввода кода для проверки его работоспособности. Если у вас есть проблемы с макетом программы, структурой и т. Д., Не стесняйтесь исправлять их и/или реструктурировать их самостоятельно. Это не причина, по которой я здесь.Если это не то, что в результате ошибки, то это полностью причина, почему я здесь :)
Код для инжектора:http://pastebin.com/FF5G9nnR
/*
Some of the code was truncated (functions not pertaining to the injection), but
I have verified the code compiles and works correctly with it's injeteme.dll counterpart
*/
#include <Windows.h>
#include <Psapi.h>
#define TARGET_PID 1124
typedef BOOL(WINAPI* pFreeLibrary)(HMODULE);
typedef HMODULE(WINAPI* pLoadLibraryA)(LPCSTR);
typedef HANDLE(WINAPI* pGetCurrentProcess)(void);
typedef BOOL(WINAPI* DLL_MAIN)(HMODULE, DWORD, LPVOID);
typedef HANDLE(WINAPI* pOpenProcess)(DWORD, BOOL, DWORD);
typedef BOOL(WINAPI* pVirtualFree)(LPVOID, SIZE_T, DWORD);
typedef int(__stdcall* pMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
typedef LPVOID(WINAPI* pVirtualAlloc)(LPVOID, SIZE_T, DWORD, DWORD);
typedef BOOL(WINAPI* pGetModuleInformation)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
typedef BOOL(WINAPI* pWriteProcessMemory)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*);
//////////////////////////////////////////////////////////////////
struct IINFO
{
LPVOID stubAddr;
LPVOID retStatusPtr;
char fullModulePath[MAX_PATH];
DWORD pId, sizeOfCurrStruct;
// DEBUG
pMessageBoxA messageBox;
pOpenProcess openProcess;
pVirtualFree virtualFree;
pFreeLibrary freeLibrary;
pLoadLibraryA loadLibrary;
pVirtualAlloc virtualAlloc;
pGetCurrentProcess getCurrProc;
pWriteProcessMemory writeMemory;
pGetModuleInformation getModInfo;
};
static DWORD WINAPI stub(IINFO *iInfo)
{
HMODULE hMod;
MODULEINFO mInfo;
DLL_MAIN dllMain;
LPVOID lpNewMod, lpTempModBuff;
PIMAGE_DOS_HEADER pIDH;
PIMAGE_NT_HEADERS pINH;
iInfo->messageBox(NULL, iInfo->fullModulePath, NULL, 0);
hMod = iInfo->loadLibrary(iInfo->fullModulePath);
if (!hMod)
return 0;
if (!iInfo->getModInfo(iInfo->getCurrProc(), hMod, &mInfo, sizeof(MODULEINFO)))
return 0;
lpTempModBuff = iInfo->virtualAlloc(NULL, mInfo.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!lpTempModBuff)
return 0;
if (!iInfo->writeMemory(iInfo->getCurrProc(), lpTempModBuff, mInfo.lpBaseOfDll, mInfo.SizeOfImage, NULL))
return 0;
if (!iInfo->freeLibrary(hMod))
return 0;
lpNewMod = iInfo->virtualAlloc(mInfo.lpBaseOfDll, mInfo.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!lpNewMod)
return 0;
// using wpm since we have already acquired the function
if (!iInfo->writeMemory(iInfo->getCurrProc(), lpNewMod, lpTempModBuff, mInfo.SizeOfImage, NULL))
return 0;
if (!iInfo->virtualFree(lpTempModBuff, 0, MEM_RELEASE))
return 0;
/*if (!iInfo->virtualFree(iInfo, 0, MEM_RELEASE))
return 0;
iInfo->messageBox(NULL, NULL, NULL, 0); */
pIDH = (PIMAGE_DOS_HEADER)lpNewMod;
if (!pIDH)
return 0;
pINH = (PIMAGE_NT_HEADERS)((LPBYTE)lpNewMod + pIDH->e_lfanew);
if (!pINH)
return 0;
dllMain = (DLL_MAIN)((LPBYTE)lpNewMod + pINH->OptionalHeader.AddressOfEntryPoint);
if (!dllMain)
return 0;
iInfo->messageBox(NULL, NULL, NULL, 0);
dllMain((HINSTANCE)lpNewMod, DLL_PROCESS_ATTACH, NULL);
return 1;
}
static DWORD WINAPI stubEnd(){ return 0; }
//////////////////////////////////////////////////////////////////
int main()
{
HANDLE hThread = 0;
DWORD dwStubSize = 0;
int sucResp = 0, count = 0;
HMODULE hUser32 = 0, hNtdll = 0;
char fullPathName[] = "C:\\injectme.dll";
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, TARGET_PID);
if (!hProc || hProc == INVALID_HANDLE_VALUE)
return 0;
__int64 SizeOfStub = (LPBYTE)stubEnd - (LPBYTE)stub;
LPVOID lpStub = VirtualAllocEx(hProc, NULL, SizeOfStub, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!lpStub)
return 0;
hUser32 = LoadLibraryA("user32.dll");
if (!hUser32)
return 0;
hNtdll = LoadLibraryA("kernel32.dll");
if (!hNtdll)
return 0;
IINFO iInfo = {};
iInfo.retStatusPtr = &sucResp;
strcpy(iInfo.fullModulePath, fullPathName);
iInfo.sizeOfCurrStruct = sizeof(IINFO);
iInfo.stubAddr = lpStub;
iInfo.pId = GetCurrentProcessId();
iInfo.messageBox = (pMessageBoxA)GetProcAddress(hUser32, "MessageBoxA");
iInfo.openProcess = (pOpenProcess)GetProcAddress(hNtdll, "OpenProcess");
iInfo.virtualFree = (pVirtualFree)GetProcAddress(hNtdll, "VirtualFree");
iInfo.freeLibrary = (pFreeLibrary)GetProcAddress(hNtdll, "FreeLibrary");
iInfo.loadLibrary = (pLoadLibraryA)GetProcAddress(hNtdll, "LoadLibraryA");
iInfo.virtualAlloc = (pVirtualAlloc)GetProcAddress(hNtdll, "VirtualAlloc");
iInfo.getCurrProc = (pGetCurrentProcess)GetProcAddress(hNtdll, "GetCurrentProcess");
iInfo.writeMemory = (pWriteProcessMemory)GetProcAddress(hNtdll, "WriteProcessMemory");
iInfo.getModInfo = (pGetModuleInformation)GetProcAddress(hNtdll, "K32GetModuleInformation");
LPVOID lpStubInfo = VirtualAllocEx(hProc, NULL, sizeof(IINFO), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!lpStubInfo)
return 0;
if (!WriteProcessMemory(hProc, lpStub, stub, SizeOfStub, NULL))
return 0;
if (!WriteProcessMemory(hProc, lpStubInfo, &iInfo, sizeof(iInfo), NULL))
return 0;
hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpStub, lpStubInfo, 0, NULL);
if (!hThread || hThread == INVALID_HANDLE_VALUE)
return 0;
WaitForSingleObject(hThread, INFINITE);
return 1;
}
Код для DLL, который будет введен :http://pastebin.com/8WXxcpu1
#include <Windows.h>
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpParam)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
MessageBoxA(NULL, "Hello from injectme.dll!", "", MB_OK | MB_ICONINFORMATION);
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Погрешность при запуске код выше дословное (если вы также применены вышеуказанные настройки и имеют сходную среду) в отладчике VS2013 заключается в следующем:
«Необработанное исключение в 0x000007FEEA5125D4 в wuauclt.exe: 0xC0000005: нарушение прав доступа выполнение местоположения 0x000007FEEA5125D4.»
При просмотре процесса «wuauclt.exe» в Process Hacker я отчетливо вижу, что модуль был первоначально изначально (после загрузки через LoadLibrary) на 0x7fef67c0000. Это показано в контекстном меню-> по разным-> разгруженным модулям.
После двойного щелчка «wuauclt.exe» вы можете просматривать виртуальную память приложения, чтобы все работало должным образом. Я могу подтвердить этот текущий сеанс, буфер памяти RWX был выделен на 0x7fef67c0000 с точным размером разгруженного модуля, содержащим модуль injectme.dll. При перекопании в injectme.dll с CFF Explorer, точка входа RVA кажется 0x132C, что не складывается, учитывая, что ошибка намного больше в памяти. Кроме того, я могу проверить еще два буфера памяти RWX, содержащих заглушку ввода кода, и структуру информации. Оглядываясь назад, структура информации, вероятно, не нуждается в RWX. Во всяком случае, я не могу за всю жизнь понять ошибку.
Я надеюсь, что вы сможете мне помочь. Я очень благодарен за ваше время.
введите код здесь – manetsus
@manetsus my bad, код был перемещен из pastebin. Извините за любые неудобства. – astra