private static unsafe void CopySections(byte *data, PeFileReader.NtHeaders *header, byte *baseaddr) { int i, size; byte *dest; // roughly, IMAGE_FIRST_SECTION macro. 0x18 is the offset of the optional header, plus size of optional header. PeFileReader.ImageSectionHeader *section = (PeFileReader.ImageSectionHeader *)(((byte *)header) + 0x18 + header->SizeOfOptionalHeader); for (i = 0; i < header->NumberOfSections; i++, section++) { if (section->SizeOfRawData == 0) { size = header->OptionalHeader.SectionAlignment; if (size > 0) { dest = (byte *)(baseaddr + section->VirtualAddress); section->PhysicalAddress = (int)dest; Native.Memset(dest, 0, size); } } else { dest = (byte *)(baseaddr + section->VirtualAddress); Native.Memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData); section->PhysicalAddress = (int)dest; } } }
private static unsafe bool ProcessSection(LockdownSha1.Context context, LockdownHeap heap, byte *baseaddr, byte *preferredBaseAddr, PeFileReader.ImageSectionHeader *section, int sectionAlignment, int seed) { int eax, virtualAddr, virtualSize, value; int index, bytes; int i; using (HeapPtr hpLockdownMem = heap.ToPointer()) { int * lockdown_memory = (int *)hpLockdownMem.ToPointer(); byte *allocatedMemoryBase; int lowerOffset = (int)baseaddr - (int)preferredBaseAddr; virtualAddr = section->VirtualAddress; virtualSize = section->VirtualSize; bytes = ((virtualSize + sectionAlignment - 1) & ~(sectionAlignment - 1)) - virtualSize; if (section->Characteristics < 0) { LockdownSha1.Pad(context, bytes + virtualSize); } else { index = 0; if (heap.CurrentLength > 0) { for (i = 0; index < heap.CurrentLength && lockdown_memory[i] < virtualAddr; i += 4) { index++; } } if (virtualSize > 0) { byte *startingMemory = baseaddr + virtualAddr; byte *ptrMemory = startingMemory; int memoryOffset = index * 4; do { int sectionLength = (int)(startingMemory - ptrMemory + virtualSize); eax = 0; if (index < heap.CurrentLength) { eax = (int)(lockdown_memory[memoryOffset] + startingMemory - virtualAddr); } if (eax != 0) { eax -= (int)ptrMemory; if (eax < sectionLength) { sectionLength = eax; } } if (sectionLength != 0) { LockdownSha1.Update(context, ptrMemory, sectionLength); ptrMemory += sectionLength; } else { //int* heapBuffer = stackalloc int[0x10]; int *heapBuffer = (int *)Marshal.AllocHGlobal(0x10 * sizeof(int)); Native.Memcpy((void *)heapBuffer, lockdown_memory + memoryOffset, 0x10); value = (*(int *)ptrMemory - lowerOffset) ^ seed; LockdownSha1.Update(context, (byte *)&value, 4); ptrMemory += heapBuffer[1]; index++; memoryOffset += 4; Marshal.FreeHGlobal((IntPtr)heapBuffer); heapBuffer = null; } } while ((ptrMemory - startingMemory) < virtualSize); } if (bytes > 0) { int i2 = 0; IntPtr memoryAllocation = Marshal.AllocHGlobal(bytes); allocatedMemoryBase = (byte *)memoryAllocation.ToPointer(); Native.Memset(allocatedMemoryBase, 0, bytes); do { eax = 0; if (index < heap.CurrentLength) { value = *(int *)(((byte *)lockdown_memory) + (index * 16)); eax = (int)(value - virtualSize - virtualAddr + allocatedMemoryBase); } bytes += i2; if (eax != 0) { eax -= ((int *)allocatedMemoryBase)[i2 / 4]; if (eax < bytes) { bytes = eax; } } if (bytes != 0) { LockdownSha1.Update(context, &allocatedMemoryBase[i2], bytes); i2 += bytes; } } while (i2 < bytes); Marshal.FreeHGlobal(memoryAllocation); } } } return(true); }