Остался последний этап. Помогите уже добить эту прогу. Итак , я перехватываю CreateProcess из своей длл. Теперь я дожен внедрится в новое приложение.. Вот как я это делаю
А вот собствено вклинивание, т.е. функция OpenProcessin(DWORD dwProcessId, CString Dll_name), которой я передаю id перехваченого процесса для вклинивания
BOOL CExInjectDlg::OpenProcessin(DWORD dwProcessId, CString Dll_name)
{
BOOL fOk = FALSE; // Assume that the function fails
HANDLE hProcess = NULL, hThread = NULL;
PWSTR pszLibFileRemote = NULL;
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId);
if (hProcess == NULL)
{
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
return FALSE;
}
// Calculate the number of bytes needed for the DLL's pathnameint cch = 1 + lstrlenW(Dll_name.GetBuffer());
int cb = cch * sizeof(WCHAR);
// Allocate space in the remote process for the pathname
pszLibFileRemote = (PWSTR)
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL)
{
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
return FALSE;
}
// Copy the DLL's pathname to the remote process's address spaceif (!WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) Dll_name.GetBuffer(), cb, NULL))
{
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
return FALSE;
}
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL)
{
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
return FALSE;
}
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (hThread == NULL)
{
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
return FALSE;
}
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
fOk = TRUE; // Everything executed successfully
// Free the remote memory that contained the DLL's pathnameif (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
return fOk;
}
Так вот некоторые программы запускаются НЕ ДО ОКНЦА, а в ХР вообще ни опера и IExplorer не запускаются.. Хотя с блокнотом, офисными приложениями и многими другими-все ок..
Стоит убрать dwCreationFlags=CREATE_SUSPENDED;ResumeThread(lpProcessInformation->hThread)- все работает ,как по маслу..
Если закоментировать код, где передаю проге id — тоже все работает.Не пойму-что ж делать? Кто мешает? И почему не все приложения глючат? Почему 2000 и ХР по разному работают. И как все это побороть. Я уверен, что все же кто-то делал подобное, ведь я не первый.
[]
А>Стоит убрать dwCreationFlags=CREATE_SUSPENDED;ResumeThread(lpProcessInformation->hThread)- все работает ,как по маслу..
А зачем надо CREATE_SUSPENDED, что бы инициализация не была произведена?
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Вклинивание dll в новый процесс
От:
Аноним
Дата:
29.03.07 11:56
Оценка:
GN>А зачем надо CREATE_SUSPENDED, что бы инициализация не была произведена?
Да. Мне нужно вклинится до тех пор, пока программа не станет вызывать оригинальне функции, что б их перехватывать.. Секрета здесь никакого нет.. Правда не вижу ответа, почему-то только одни вопросы.. Если так нужно, значит так и делаю.. Может хотите предложить другой вариант?
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: Вклинивание dll в новый процесс
От:
Аноним
Дата:
30.03.07 09:04
Оценка:
Честно говоря, лень разбирать, но если еще надо то могу дать код
который запускает замороженный процесс внедряет туда длл и продолжает
загрузку основного процесса, Проверено на IE7 и прочем софте, все работает.
П.С. Внедрять в замороженный процесс можно dllки которые зависят только
от kernel32.dll и ntdll.dll, если надо какие-то еще dllки используй LoadLibrary.
В особо сложных случаях даже от kernel32.dll надо отказаться.
вот код:
int cmd_load(int argc, char * argv[])
{
if (argc < 3)
{
printf("Syntax: TACLoader.exe load [-d] <DLLImage> <Programm> [param1, [param2 ...]]\n");
return 1;
}
bool memdump = false;
if (!strcmpi(argv[1], "-d"))
{
memdump = true;
argc--; argv++;
if (argc < 3)
{
printf("Invalid params count\n");
return 1;
}
}
char *dll = argv[1];
argc--; argv++;
std::string application = argv[1];
std::string args = "\""+application+"\"";
argc--;
argv++;
for (int i = 1; i < argc; ++i)
{
if (!args.empty()) args += " ";
args+= argv[i];
}
char fullpath[_MAX_PATH];
char *filename;
if (!GetFullPathName(dll, sizeof(fullpath), fullpath, &filename))
{
printf("Get full path to %s failed with error %d\n", dll, GetLastError());
return 1;
}
if (GetFileAttributes(dll) == INVALID_FILE_ATTRIBUTES)
{
printf("Checking '%s' failed with error %d\n", fullpath, GetLastError());
return 1;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if(!CreateProcess(application.c_str(),
(LPSTR)args.c_str(), NULL, NULL, FALSE,
CREATE_SUSPENDED,
NULL, NULL, &si, &pi))
{
printf("Rum application '%s' failed with error %d\n",
application.c_str(), GetLastError());
return 1;
}
printf("suspended PID=%d\n", pi.dwProcessId);
if (memdump) {
printf("=== MEMORY DUMP BEGIN (BEFORE INJECT)===\n");
std::vector<VMQUERYEX> dump;
VQMemDump(pi.hProcess, dump);
std::string output = MemDumpStr(pi.hProcess, dump);
printf("%s\n", output.c_str());
printf("=== MEMORY DUMP END ===\n");
}
if (!InjectLib(pi.dwProcessId, fullpath))
printf("DLL injection failed of '%s' to %d failed\n", fullpath, pi.dwProcessId);
if (memdump) {
printf("=== MEMORY DUMP BEGIN (AFTER INJECT)===\n");
std::vector<VMQUERYEX> dump;
VQMemDump(pi.hProcess, dump);
std::string output = MemDumpStr(pi.hProcess, dump);
printf("%s\n", output.c_str());
printf("=== MEMORY DUMP END ===\n");
}
ResumeThread(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
InjectLib (c) Рихтер
#include <windows.h>
#ifdef UNICODE
#define InjectLib InjectLibW
#else
#define InjectLib InjectLibA
#endif// !UNICODE
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile);
BOOL WINAPI InjectLibA(DWORD dwProcessId, PCSTR pszLibFile);
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
BOOL fOk = FALSE; // Assume that the function fails
HANDLE hProcess = NULL, hThread = NULL;
PWSTR pszLibFileRemote = NULL;
__try {
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Calculate the number of bytes needed for the DLL's pathnameint cch = 1 + lstrlenW(pszLibFile);
int cb = cch * sizeof(WCHAR);
// Allocate space in the remote process for the pathname
pszLibFileRemote = (PWSTR)
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL) __leave;
// Copy the DLL's pathname to the remote process's address spaceif (!WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) pszLibFile, cb, NULL)) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
fOk = TRUE; // Everything executed successfully
}
__finally { // Now, we can clean everthing up
// Free the remote memory that contained the DLL's pathnameif (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(fOk);
}
BOOL WINAPI InjectLibA(DWORD dwProcessId, PCSTR pszLibFile) {
// Allocate a (stack) buffer for the Unicode version of the pathname
PWSTR pszLibFileW = (PWSTR)
_alloca((lstrlenA(pszLibFile) + 1) * sizeof(WCHAR));
// Convert the ANSI pathname to its Unicode equivalent
wsprintfW(pszLibFileW, L"%S", pszLibFile);
// Call the Unicode version of the function to actually do the work.return(InjectLibW(dwProcessId, pszLibFileW));
}
Re[2]: Вклинивание dll в новый процесс
От:
Аноним
Дата:
30.03.07 09:25
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Честно говоря, лень разбирать, но если еще надо то могу дать код А>который запускает замороженный процесс внедряет туда длл и продолжает А>загрузку основного процесса, Проверено на IE7 и прочем софте, все работает.
Спасибо.. Посмотрел. Все в точности, как у меня. Единственая разница, что ты запускаешь приложение из своей софтины, а я перехватываю у експлорера создание процесса, внедряюсь в своем приложении (из него),и продолжаю запуск замороженого процесса снова из эксплорера.Может тут и вся фича. Нашел еще одну статью про данный метод и данный баг. Люди решили его ,путем перехвата
не CraeteProcessW , а NtCreateThread и NtResumeThread. А так у них так же были глюки, как у меня. Вообщем буду рыть дальше . Спасибо.
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, <Аноним>, Вы писали:
А>>Правда не вижу ответа, почему-то только одни вопросы.. Если так нужно, значит так и делаю..
GN>Это был ответ, почему не работает.
А>>Может хотите предложить другой вариант?
GN>PsSetCreateProcessNotifyRoutine
Спасибо. Я просто наверное не так вас понял.. Сорри. Посмотрю
GN>>А зачем надо CREATE_SUSPENDED, что бы инициализация не была произведена? А>Да. Мне нужно вклинится до тех пор, пока программа не станет вызывать оригинальне функции, что б их перехватывать.. Секрета здесь никакого нет.. Правда не вижу ответа, почему-то только одни вопросы.. Если так нужно, значит так и делаю.. Может хотите предложить другой вариант?
Наступал на теже грабли, победил при помощи GetThreadContext/SetThreadContext.