984259h Код (Text): PVOID pBuffer = NULL; NtStatus = NtAllocateVirtualMemory(hProcess,&pBuffer,0,&dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if (NT_SUCCESS(NtStatus)) { NtStatus = NtWriteVirtualMemory(hProcess,pBuffer,pBuffer,dwSize,0); не особо понял, а где вы релоки правите? попробуйте вот этот код http://wasm.ru/forum/viewtopic.php?id=37450 юзать так: Код (Text): DWORD dwAddr = InjectCode( hProcess, f_Main ); bool ret = false; if ( dwAddr != -1 ) { if ( pCreateRemoteThread( hProcess, 0, 0, (LPTHREAD_START_ROUTINE)dwAddr, NULL, 0, 0 ) != NULL ) { ..
Код (Text): HANDLE hModule = GetModuleHandleA(NULL); и базу лучше более универсально получать, иначе уже находят в адрессном пространстве другого процесса не выйдет инжект сделать. Код (Text): DWORD GetImageBase() { DWORD dwRet = 0; __asm { call GetBase GetBase: pop eax and eax, 0FFFF0000h Find: cmp word ptr [ eax ], 0x5A4D je end sub eax, 00010000h jmp Find End: mov [ dwRet ], eax } return dwRet; }
ilja_ Базу лучше искать через TEB. То есть получать LDR_MODULE.BaseAddress. Вот для 64 бит пример, для 32 бит поправить 1 строчку вроде нужно: Код (Text): ;fasm macro. macro GetBaseOfKernel32Into reg { mov reg , [gs:dword 30h] ;TEB mov reg , [reg + 60h] ;PEB mov reg , [reg + 24] ;PEB->Ldr mov reg , [reg + 32] ;first module(InMemoryOrder module list) mov reg , [reg] ;assume that ntdll will be second in module list. mov reg , [reg] ;assume that kernel32 will be third in module list. mov reg , [reg + 32] ;LDR_MODULE64.BaseAddress } macro GetBaseOfNtdllInto reg { mov reg , [gs:dword 30h] ;TEB mov reg , [reg + 60h] ;PEB mov reg , [reg + 24] ;PEB->Ldr mov reg , [reg + 32] ;first module(InMemoryOrder module list) mov reg , [reg] ;assume that ntdll will be second in module list. mov reg , [reg + 32] ;LDR_MODULE64.BaseAddress }
ziral2088 Плохой способ, более того не желательный для использования. Модуль следует искать по имени, в идеале по полному. Например у меня многие процессы запускаются с верификатором, это системный механизм, провайдеры грузятся до загрузки kernel32.dll, таким образом нет никакой гарантии что kernel32 тритий модуль в списке.
ziral2088 Сделали вы инжект в процесс, дальше из этого процесса вам нужно прыгнуть в следующий, тем способом который дали вы, вы получите базу процесса в котором вы находитесь, а не базу своего образа внутри этого процесса.
Что то не пойму, а зачем мне база моего образа? Мне нужна база нтдлл или кернела, но никак не своего. Clerk Можешь рассказать как настроить\что поставить в системе, что бы kernel32.dll в памяти оказалась не второй?(то есть в списке InLoadOrderModuleList она и так не вторая часто, к примеру в том же csrss.exe она третья, а в списке InMemoryOrderModuleList у меня всегда была вторая) Был бы очень признателен за совет.
ilja_ Перечитал топ еще раз, понял о чем вы говорите. Да мой код был немного не в тему, не видел что вы искали базу своей дллки в чужом процессе.
заработало таким образом : Код (Text): BOOL NativeInjectProcess(DWORD ( WINAPI *pFunction )( LPVOID ),char *szProcessName) { BOOL bRet = FALSE; CLIENT_ID C_ID; C_ID.UniqueProcess = (HANDLE)GetProcessID(szProcessName); C_ID.UniqueThread = NULL; OBJECT_ATTRIBUTES ObjectAttributes; InitializeObjectAttributes(&ObjectAttributes,NULL,0,NULL,NULL); BOOLEAN bPrivilegeEnable = TRUE; NTSTATUS NtStatus = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE,TRUE,FALSE,&bPrivilegeEnable); if (NT_SUCCESS(NtStatus)) { HANDLE hProcess = NULL; NtStatus = NtOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&ObjectAttributes,&C_ID); if (NT_SUCCESS(NtStatus)) { HANDLE hModule; // Get my hModule by PEB (Process Environment Block) __asm { push ebx xor ebx, ebx // clear ebx mov ebx, fs:[ 0x30 ] // get a pointer to the PEB mov ebx, [ebx + 0x08 ] // get PEB->ImageBaseAddress mov [hModule], ebx pop ebx } DWORD dwSize = ((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE*)(hModule)+ ((PIMAGE_DOS_HEADER)(hModule))->e_lfanew + sizeof(DWORD)+ sizeof(IMAGE_FILE_HEADER))))->SizeOfImage; PVOID pBuffer = NULL; NtStatus = NtAllocateVirtualMemory(NtCurrentProcess(),&pBuffer,0,&dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if (NT_SUCCESS(NtStatus)) { DWORD ReadBytes; NtStatus = NtReadVirtualMemory(NtCurrentProcess(),(PVOID)hModule,pBuffer,dwSize,&ReadBytes); if (NT_SUCCESS(NtStatus)) { // NtFreeVirtualMemory(hProcess,(PVOID*)hModule,&ReadBytes,MEM_RELEASE); PVOID pMemory = (PVOID)hModule; NtStatus = NtAllocateVirtualMemory(hProcess,&pMemory,0,&ReadBytes,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if (NT_SUCCESS(NtStatus)) { DWORD OldProction; NtStatus = NtProtectVirtualMemory(hProcess,&pMemory,&ReadBytes,PAGE_EXECUTE_READWRITE,&OldProction); if (NT_SUCCESS(NtStatus)) { DWORD WriteBytes; NtStatus = NtWriteVirtualMemory(hProcess,pMemory,pBuffer,ReadBytes,&WriteBytes); if (NT_SUCCESS(NtStatus)) { HANDLE hRemoteThread = NULL; NtStatus = RtlCreateUserThread(hProcess,NULL,FALSE,0,NULL,NULL,pFunction,pMemory,&hRemoteThread,0); if (NT_SUCCESS(NtStatus)) { if (hRemoteThread != NULL) { NtClose(hRemoteThread); bRet = TRUE; } } } } } } } } NtClose(hProcess); } return bRet; }
984259h Код (Text): __asm { push ebx xor ebx, ebx // clear ebx mov ebx, fs:[ 0x30 ] // get a pointer to the PEB mov ebx, [ebx + 0x08 ] // get PEB->ImageBaseAddress mov [hModule], ebx pop ebx } DWORD dwSize = ((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE*)(hModule)+ ((PIMAGE_DOS_HEADER)(hModule))->e_lfanew + sizeof(DWORD)+ sizeof(IMAGE_FILE_HEADER))))->SizeOfImage; Желательно найти описатель модуля в базе данных загрузчика, оттуда и брать базу и размер модуля. Он может быть иного размера, чем указанный в хидере. Все обращения к его базе данных должны исполняться с захваченной кс LdrpLoaderLock. Код (Text): NtStatus = NtAllocateVirtualMemory(NtCurrentProcess(),&pBuffer,0,&dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if (NT_SUCCESS(NtStatus)) { DWORD ReadBytes; NtStatus = NtReadVirtualMemory(NtCurrentProcess(),(PVOID)hModule,pBuffer,dwSize,&ReadBytes); if (NT_SUCCESS(NtStatus)) { Это не нужно. Незачем копировать образ в иное место в текущем процессе. Код (Text): DWORD OldProction; NtStatus = NtProtectVirtualMemory(hProcess,&pMemory,&ReadBytes,PAGE_EXECUTE_READWRITE,&OldProction); Это тоже не нужно. Атрибуты задаются при аллокации. Код (Text): NtClose(hRemoteThread); Следует возвратить описатель из функции. Некоторые параметры для RtlCreateUserThread() должны быть внешними. Код (Text): NULL,FALSE,0,NULL,NULL Слишком много нулей. Следует использовать push eax для загрузки нуля, в нём статус из предыдущего сервиса. - В общем отвратительный способ. Следует учитывать релокацию, импорт и прочее. Для обычного приложения такой копипаст образа закончится крахом.