#define MI_64K_ALIGN(x) (x + 0x0F) >> 4 #define MmHighsetUserAddress 0x7FFFFFEFFFF typedef PIMAGE_BASE ULONG_PTR; typedef enum _MI_MEMORY_HIGHLOW { MiMemoryHigh = 0, MiMemoryLow = 1, MiMemoryHighLow = 2 } MI_MEMORY_HIGHLOW, *PMI_MEMORY_HIGHLOW; MI_MEMORY_HIGHLOW MiSelectBitMapForImage(PSEGMENT pSeg) { if (!(pSeg->SegmentFlags & FLAG_BINARY32)) // WOW binary { if (!(pSeg->ImageInformation->ImageFlags & FLAG_BASE_BELOW_4GB)) { if (pSeg->BasedAddress > 0x100000000) { return MiMemoryHighLow; } else { return MiMemoryLow; } } } return MiMemoryHigh; } PIMAGE_BASE MiSelectImageBase(void* a1<rcx>, PSEGMENT pSeg) { MI_MEMORY_HIGHLOW ImageBitmapType; ULONG ImageBias; RTL_BITMAP *pImageBitMap; ULONG_PTR ImageTopAddress; ULONG RelocationSizein64k; MI_SECTION_IMAGE_INFORMATION *pImageInformation; ULONG_PTR RelocDelta; PIMAGE_BASE Result = NULL; // rsi = rcx // rcx = rdx // rdi = rdx pImageInformation = pSeg->ImageInformation; ImageBitmapType = MiSelectBitMapForImage(pSeg); a1->off_40h = ImageBitmapType; if (ImageBitmapType == MiMemoryLow) { // 64-bit executable with image base below 4 GB ImageBias = MiImageBias64Low; pImageBitMap = MiImageBitMap64Low; ImageTopAddress = 0x78000000; } else { if (ImageBitmapType == MiMemoryHighLow) { // 64-bit executable with image base above 4 GB ImageBias = MiImageBias64High; pImageBitMap = MiImageBitMap64High; ImageTopAddress = 0x7FFFFFE0000; } else { // MiMemoryHigh 32-bit executable image ImageBias = MiImageBias; pImageBitMap = MiImageBitMap; ImageTopAddress = 0x78000000; } } // pSeg->ControlArea->BitMap ^= (pSeg->ControlArea->BitMap ^ (ImageBitmapType << 29)) & 0x60000000; // or bitfield form pSeg->ControlArea.BitMap = ImageBitmapType; RelocationSizein64k = MI_64K_ALIGN(pSeg->TotalNumberOfPtes); if (pSeg->ImageInformation->ImageCharacteristics & IMAGE_FILE_DLL) { ULONG StartBit = 0; ULONG GlobalRelocStartBit = 0; StartBit = RtlFindClearBits(pImageBitMap, RelocationSizein64k, ImageBias); if (StartBit != 0xFFFFFFFF) { StartBit = MiObtainRelocationBits(pImageBitMap, RelocationSizein64k, StartBit, 0); if (StartBit != 0xFFFFFFFF) { Result = ImageTopAddress - (((RelocationSizein64k) + StartBit) << 0x10); if (Result == (pSeg->BasedAddress - a1->SelectedBase)) { GlobalRelocStartBit = MiObtainRelocationBits(pImageBitMap, RelocationSizein64k, StartBit, 1); StartBit = (GlobalRelocStartBit != 0xFFFFFFFF) ? GlobalRelocStartBit : StartBit; Result = ImageTopAddress - (RelocationSizein64k + StartBit) << 0x10; } a1->RelocStartBit = StartBit; a1->RelocationSizein64k = RelocationSizein64k; pSeg->ControlArea->ImageRelocationStartBit = StartBit; pSeg->ControlArea->ImageRelocationSizeIn64k = RelocationSizein64k; return Result; } } } else { // EXE image if (a1->SelectedBase != NULL) { return pSeg->BasedAddress; } if (ImageBitmapType == MiMemoryHighLow) { a1->RelocStartBit = 0xFFFFFFFF; a1->RelocationSizein64k = (WORD)RelocationSizein64k; pSeg->ControlArea->ImageRelocationStartBit = 0xFFFFFFFF; pSeg->ControlArea->ImageRelocationSizeIn64k = (WORD)RelocationSizein64k; return ((DWORD)(ExGenRandom(1) % (0x20001 - RelocationSizein64k)) + 0x7F60000) << 16; } } ULONG RandomVal = ExGenRandom(1); RandomVal = (RandomVal % 0xFE + 1) << 0x10; RelocDelta = pSeg->BasedAddress - a1->SelectedBase; if (RelocDelta > MmHighsetUserAddress) { return 0; } if ((RelocationSizein64k << 0x10) > MmHighsetUserAddress) { return 0; } if (RelocDelta + (RelocationSizein64k << 0x10) <= RelocDelta) { return 0; } if (RelocDelta + (RelocationSizein64k << 0x10) > MmHighsetUserAddress) { return 0; } if (a1->SelectedBase + RandomVal == 0) { Result = pSeg->BasedAddress; } else { if (RelocDelta > RandomVal) { Result = RelocDelta - RandomVal; } else { Result = RelocDelta + RandomVal; if (Result < RelocDelta) { return 0; } if (((RelocationSizein64k << 0x10) + RelocDelta + RandomVal) > 0x7FFFFFDFFFF) { return 0; } if (((RelocationSizein64k << 0x10) + RelocDelta + RandomVal) < (RelocDelta + (RelocationSizein64k << 0x10)))) { return 0; } } } //random_epilog a1->RelocStartBit = 0xFFFFFFFF; a1->RelocationSizein64k = RelocationSizein64k; pSeg->ControlArea->ImageRelocationStartBit = 0xFFFFFFFF; pSeg->ControlArea->ImageRelocationSizeIn64k = RelocationSizein64k; return Result; }
VOID MiInitializeRelocations() { MiImageBias = ExGenRandom(1) % 256; MiImageBias64Low = ExGenRandom(1) % MiImageBitMap64Low.SizeOfBitMap; MiImageBias64High = ExGenRandom(1) % MiImageBitMap64High.SizeOfBitMap; return; }
Source: https://habr.com/ru/post/162617/
All Articles