Example #1
0
        private static unsafe void PerformBaseReloc(byte* baseaddr, PeFileReader.NtHeaders* ntheader, int relocOffset)
        {
            int i;
            PeFileReader.NtHeaders.ImageDataDirectory* directory;
            directory = (PeFileReader.NtHeaders.ImageDataDirectory*)&ntheader->OptionalHeader.IDD5;

            if (directory->Size > 0)
            {
                PeFileReader.ImageBaseRelocation* relocation = (PeFileReader.ImageBaseRelocation*)(baseaddr + directory->VirtualAddress);
                for (; relocation->VirtualAddress > 0; )
                {
                    byte* dest = (byte*)(baseaddr + relocation->VirtualAddress);
                    ushort* relocInfo = (ushort*)((byte*)relocation + IMAGE_SIZEOF_BASE_RELOCATION);
                    for (i = 0; i < ((relocation->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relocInfo++)
                    {
                        uint* patch_addr;
                        int type, offset;
                        type = *relocInfo >> 12;
                        offset = *relocInfo & 0xfff;
                        if (type == IMAGE_REL_BASED_HIGHLOW)
                        {
                            patch_addr = (uint*)(dest + offset);
                            *patch_addr += unchecked((uint)relocOffset);
                        }
                    }

                    relocation = (PeFileReader.ImageBaseRelocation*)(((ulong)relocation) + (ulong)relocation->SizeOfBlock);
                }
            }
        }
Example #2
0
        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;
        }
Example #3
0
 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;
         }
     }
 }
Example #4
0
        private static unsafe bool ProcessRelocDir(LockdownHeap heap, byte* baseaddr, PeFileReader.NtHeaders.ImageDataDirectory* relocDir)
        {
            int i, edx;
            int[] data = new int[4];

            PeFileReader.ImageBaseRelocation* relocation = (PeFileReader.ImageBaseRelocation*)(baseaddr + relocDir->VirtualAddress);
            for (; relocation->VirtualAddress > 0; )
            {
                short* relocInfo = (short*)((byte*)relocation + IMAGE_SIZEOF_BASE_RELOCATION);
                for (i = 0; i < ((relocation->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relocInfo++)
                {
                    int type, offset;
                    type = *relocInfo >> 12;
                    offset = *relocInfo & 0xfff;
                    if (type != 0)
                    {
                        switch (type)
                        {
                            case IMAGE_REL_BASED_LOW:
                                edx = 2;
                                break;
                            case IMAGE_REL_BASED_HIGHLOW:
                                edx = 4;
                                break;
                            case IMAGE_REL_BASED_DIR64:
                                edx = 8;
                                break;
                            default:
                                return false;
                        }

                        data[0] = relocation->VirtualAddress + offset;
                        data[1] = edx;
                        data[2] = 2;
                        data[3] = type;

                        heap.Add(data);
                    }
                }

                relocation = (PeFileReader.ImageBaseRelocation*)(((byte*)relocation) + relocation->SizeOfBlock);
            }

            return true;
        }