Пример #1
0
        public InjectPE(PELoader peLoader, string parameters)
        {
            ////////////////////////////////////////////////////////////////////////////////
            IntPtr lpAddress     = IntPtr.Zero;
            UInt32 dwSize        = peLoader.sizeOfImage;
            IntPtr lpBaseAddress = Unmanaged.VirtualAlloc(lpAddress, dwSize, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_EXECUTE_READWRITE);

            WriteOutputGood("Allocated Space For " + peLoader.sizeOfImage.ToString("X4") + " at " + lpBaseAddress.ToString("X4"));

            ////////////////////////////////////////////////////////////////////////////////
            for (Int32 i = 0; i < peLoader.imageFileHeader.NumberOfSections; i++)
            {
                IntPtr lpBaseAddressSection = new IntPtr(lpBaseAddress.ToInt32() + peLoader.imageSectionHeaders[i].VirtualAddress);
                UInt32 dwSizeSection        = peLoader.imageSectionHeaders[i].SizeOfRawData;
                IntPtr lpAllocatedAddress   = Unmanaged.VirtualAlloc(lpBaseAddressSection, dwSizeSection, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_EXECUTE_READWRITE);
                Marshal.Copy(peLoader.imageBytes, (Int32)peLoader.imageSectionHeaders[i].PointerToRawData, lpAllocatedAddress, (Int32)peLoader.imageSectionHeaders[i].SizeOfRawData);
                Console.WriteLine("Copied " + peLoader.imageSectionHeaders[i].Name + " to " + lpAllocatedAddress.ToString("X4"));
            }

            ////////////////////////////////////////////////////////////////////////////////
            IntPtr relocationTable = new IntPtr(lpBaseAddress.ToInt32() + peLoader.baseRelocationTableAddress);

            Structs.IMAGE_BASE_RELOCATION relocationEntry = (Structs.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(Structs.IMAGE_BASE_RELOCATION));

            Int32  sizeOfRelocationStruct = Marshal.SizeOf(typeof(Structs.IMAGE_BASE_RELOCATION));
            Int32  sizeofNextBlock        = (Int32)relocationEntry.SizeOfBlock;
            IntPtr offset = relocationTable;

            ////////////////////////////////////////////////////////////////////////////////
            while (true)
            {
                Structs.IMAGE_BASE_RELOCATION relocationNextEntry = new Structs.IMAGE_BASE_RELOCATION();
                IntPtr lpNextRelocationEntry = new IntPtr(relocationTable.ToInt32() + (Int32)sizeofNextBlock);
                relocationNextEntry = (Structs.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(lpNextRelocationEntry, typeof(Structs.IMAGE_BASE_RELOCATION));
                IntPtr destinationAddress = new IntPtr(lpBaseAddress.ToInt32() + (Int32)relocationEntry.VirtualAdress);

                ////////////////////////////////////////////////////////////////////////////////
                for (Int32 i = 0; i < (Int32)((relocationEntry.SizeOfBlock - sizeOfRelocationStruct) / 2); i++)
                {
                    UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i));

                    UInt16 type  = (UInt16)(value >> 12);
                    UInt16 fixup = (UInt16)(value & 0xfff);

                    switch (type)
                    {
                    case 0x0:
                        break;

                    case 0xA:
                        if (peLoader.is64Bit)
                        {
                            IntPtr patchAddress    = new IntPtr(destinationAddress.ToInt64() + (Int32)fixup);
                            Int64  originalAddress = Marshal.ReadInt64(patchAddress);
                            Int64  delta64         = (Int64)(lpBaseAddress.ToInt64() - (Int64)peLoader.imageOptionalHeader64.ImageBase);
                            Marshal.WriteInt64(patchAddress, originalAddress + delta64);
                        }
                        else
                        {
                            IntPtr patchAddress    = new IntPtr(destinationAddress.ToInt32() + (Int32)fixup);
                            Int32  originalAddress = Marshal.ReadInt32(patchAddress);
                            Int32  delta32         = (Int32)(lpBaseAddress.ToInt32() - (Int32)peLoader.imageOptionalHeader32.ImageBase);
                            Marshal.WriteInt32(patchAddress, originalAddress + delta32);
                        }
                        break;
                    }
                }
                offset           = new IntPtr(relocationTable.ToInt32() + (int)sizeofNextBlock);
                sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock;
                relocationEntry  = relocationNextEntry;
                //"The last entry is set to zero (NULL) to indicate the end of the table." - cool
                if (0 == relocationNextEntry.SizeOfBlock)
                {
                    break;
                }
            }

            ////////////////////////////////////////////////////////////////////////////////
            //http://sandsprite.com/CodeStuff/Understanding_imports.html
            ////////////////////////////////////////////////////////////////////////////////
            Int32 sizeOfStruct = Marshal.SizeOf(typeof(Structs._IMAGE_IMPORT_DIRECTORY));
            Int32 multiplier   = 0;

            while (true)
            {
                Int32  dwImportTableAddressOffset = ((sizeOfStruct * multiplier++) + peLoader.importTableAddress);
                IntPtr lpImportAddressTable       = new IntPtr(lpBaseAddress.ToInt32() + dwImportTableAddressOffset);
                Structs._IMAGE_IMPORT_DIRECTORY imageImportDirectory = (Structs._IMAGE_IMPORT_DIRECTORY)Marshal.PtrToStructure(lpImportAddressTable, typeof(Structs._IMAGE_IMPORT_DIRECTORY));
                if (0 == imageImportDirectory.RvaImportAddressTable)
                {
                    break;
                }

                ////////////////////////////////////////////////////////////////////////////////
                IntPtr dllNamePTR = new IntPtr(lpBaseAddress.ToInt32() + imageImportDirectory.RvaModuleName);
                string dllName    = Marshal.PtrToStringAnsi(dllNamePTR);
                IntPtr hModule    = Unmanaged.LoadLibrary(dllName);
                WriteOutputGood("Loaded " + dllName + " at " + hModule.ToString("X4"));
                ////////////////////////////////////////////////////////////////////////////////
                IntPtr lpRvaImportAddressTable = new IntPtr(lpBaseAddress.ToInt32() + imageImportDirectory.RvaImportAddressTable);
                while (true)
                {
                    Int32 dwRvaImportAddressTable = Marshal.ReadInt32(lpRvaImportAddressTable);
                    if (0 == dwRvaImportAddressTable)
                    {
                        break;
                    }
                    else
                    {
                        IntPtr lpDllFunctionName = (new IntPtr(lpBaseAddress.ToInt32() + dwRvaImportAddressTable + 2));
                        string dllFunctionName   = Marshal.PtrToStringAnsi(lpDllFunctionName);
                        IntPtr functionAddress   = Unmanaged.GetProcAddress(hModule, dllFunctionName);
                        Marshal.WriteInt64(lpRvaImportAddressTable, (Int64)functionAddress);
                        lpRvaImportAddressTable = new IntPtr(lpRvaImportAddressTable.ToInt32() + 8);
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////////////////
            string parameter          = "";
            IntPtr lpThreadAttributes = IntPtr.Zero;
            UInt32 dwStackSize        = 0;
            Int32  dwStartAddress     = lpBaseAddress.ToInt32() + peLoader.addressOfEntryPoint;
            IntPtr lpStartAddress     = new IntPtr(dwStartAddress);
            IntPtr lpParameter        = new IntPtr(Convert.ToInt32(parameter));
            UInt32 dwCreationFlags    = 0;
            UInt32 lpThreadId         = 0;
            IntPtr hThread            = Unmanaged.CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, ref lpThreadId);

            WriteOutputGood("Created thread " + hThread);
            ////////////////////////////////////////////////////////////////////////////////
            Unmanaged.WaitForSingleObject(hThread, 0xFFFFFFFF);
        }
Пример #2
0
        public void execute()
        {
            ////////////////////////////////////////////////////////////////////////////////
            IntPtr lpBaseAddress = VirtualAllocExChecked(new IntPtr(0), peLoader.sizeOfImage);

            WriteOutputNeutral("Iterating through " + peLoader.imageFileHeader.NumberOfSections + " Headers");
            ////////////////////////////////////////////////////////////////////////////////
            for (Int32 i = 0; i < peLoader.imageFileHeader.NumberOfSections; i++)
            {
                IntPtr   lpBaseAddressSection = new IntPtr(lpBaseAddress.ToInt64() + peLoader.imageSectionHeaders[i].VirtualAddress);
                GCHandle pinnedArray          = GCHandle.Alloc(peLoader.imageBytes, GCHandleType.Pinned);
                IntPtr   imageBytesPtr        = new IntPtr((Int64)pinnedArray.AddrOfPinnedObject() + peLoader.imageSectionHeaders[i].PointerToRawData);
                UInt32   dwSizeSection        = peLoader.imageSectionHeaders[i].SizeOfRawData;
                string   sectionName          = new string(peLoader.imageSectionHeaders[i].Name);
                WriteProcessMemoryChecked(lpBaseAddressSection, imageBytesPtr, dwSizeSection, sectionName);
            }

            ////////////////////////////////////////////////////////////////////////////////
            IntPtr lpRelocationTable = new IntPtr(lpBaseAddress.ToInt64() + peLoader.baseRelocationTableAddress);

            Structs.IMAGE_BASE_RELOCATION relocationEntry = PtrToStructureRemote <Structs.IMAGE_BASE_RELOCATION>(lpRelocationTable);
            UInt32 imageSizeOfBaseRelocation = (UInt32)Marshal.SizeOf(typeof(Structs.IMAGE_BASE_RELOCATION));
            Int32  sizeofNextBlock           = (Int32)relocationEntry.SizeOfBlock;
            IntPtr offset = lpRelocationTable;

            ////////////////////////////////////////////////////////////////////////////////
            while (true)
            {
                IntPtr lpNextRelocationEntry = new IntPtr(lpRelocationTable.ToInt64() + (Int64)sizeofNextBlock);
                Structs.IMAGE_BASE_RELOCATION relocationNextEntry = PtrToStructureRemote <Structs.IMAGE_BASE_RELOCATION>(lpNextRelocationEntry);
                IntPtr destinationAddress = new IntPtr(lpBaseAddress.ToInt64() + (Int32)relocationEntry.VirtualAdress);
                Int32  entries            = (Int32)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2);

                ////////////////////////////////////////////////////////////////////////////////
                // Some magic from subtee
                ////////////////////////////////////////////////////////////////////////////////
                for (Int32 i = 0; i < entries; i++)
                {
                    UInt16 value = (UInt16)ReadInt16Remote(offset, 8 + (2 * i));
                    UInt16 type  = (UInt16)(value >> 12);
                    UInt16 fixup = (UInt16)(value & 0xfff);
                    switch (type)
                    {
                    case 0x0:
                        break;

                    case 0xA:
                        IntPtr lpPatchAddress    = new IntPtr(destinationAddress.ToInt64() + (Int32)fixup);
                        Int64  originalAddress   = ReadInt64Remote(lpPatchAddress);
                        Int64  delta64           = (Int64)(lpBaseAddress.ToInt64() - (Int64)peLoader.imageOptionalHeader64.ImageBase);
                        IntPtr lpOriginalAddress = new IntPtr(originalAddress + delta64);
                        WriteInt64Remote(lpPatchAddress, originalAddress + delta64);
                        break;
                    }
                }
                offset           = new IntPtr(lpRelocationTable.ToInt64() + (Int64)sizeofNextBlock);
                sizeofNextBlock += (Int32)relocationNextEntry.SizeOfBlock;
                relocationEntry  = relocationNextEntry;
                //"The last entry is set to zero (NULL) to indicate the end of the table." - cool
                if (0 == relocationNextEntry.SizeOfBlock)
                {
                    break;
                }
            }

            ////////////////////////////////////////////////////////////////////////////////
            //http://sandsprite.com/CodeStuff/Understanding_imports.html
            ////////////////////////////////////////////////////////////////////////////////
            Int32   sizeOfStruct        = Marshal.SizeOf(typeof(Structs._IMAGE_IMPORT_DIRECTORY));
            Int32   multiplier          = 0;
            Process localProcess        = Process.GetCurrentProcess();
            IntPtr  lpLocalBaseAddress  = localProcess.MainModule.BaseAddress;
            Process remoteProcess       = Process.GetProcessById((Int32)localProcess.Id);
            IntPtr  lpRemoteBaseAddress = remoteProcess.MainModule.BaseAddress;

            while (true)
            {
                Int32  dwImportTableAddressOffset = ((sizeOfStruct * multiplier++) + peLoader.importTableAddress);
                IntPtr lpImportAddressTable       = new IntPtr(lpBaseAddress.ToInt64() + dwImportTableAddressOffset);
                Structs._IMAGE_IMPORT_DIRECTORY imageImportDirectory = PtrToStructureRemote <Structs._IMAGE_IMPORT_DIRECTORY>(lpImportAddressTable);
                if (0 == imageImportDirectory.RvaImportAddressTable)
                {
                    break;
                }

                ////////////////////////////////////////////////////////////////////////////////
                IntPtr dllNamePTR           = new IntPtr(lpBaseAddress.ToInt64() + imageImportDirectory.RvaModuleName);
                string dllName              = PtrToStringAnsiRemote(dllNamePTR).Replace("\0", "");
                IntPtr lpLocalModuleAddress = Unmanaged.LoadLibrary(dllName);
                IntPtr lpModuleBaseAddress  = LoadLibraryRemote(dllName);
                WaitForSingleObjectExRemote(lpModuleBaseAddress);
                WriteOutputGood("Loaded " + dllName);

                ////////////////////////////////////////////////////////////////////////////////
                IntPtr lpRvaImportAddressTable = new IntPtr(lpBaseAddress.ToInt64() + imageImportDirectory.RvaImportAddressTable);

                while (true)
                {
                    Int32 dwRvaImportAddressTable = PtrToInt32Remote(lpRvaImportAddressTable);
                    if (0 == dwRvaImportAddressTable)
                    {
                        break;
                    }
                    else
                    {
                        IntPtr lpDllFunctionName         = (new IntPtr(lpBaseAddress.ToInt64() + dwRvaImportAddressTable + 2));
                        string dllFunctionName           = PtrToStringAnsiRemote(lpDllFunctionName).Replace("\0", "");
                        IntPtr hModule                   = Unmanaged.GetModuleHandle(dllName);
                        IntPtr lpLocalFunctionAddress    = Unmanaged.GetProcAddress(hModule, dllFunctionName);
                        IntPtr lpRelativeFunctionAddress = new IntPtr(lpLocalFunctionAddress.ToInt64() - lpLocalBaseAddress.ToInt64());
                        IntPtr lpFunctionAddress         = new IntPtr(lpRemoteBaseAddress.ToInt64() + lpRelativeFunctionAddress.ToInt64());
                        WriteOutputGood("\tLoaded Function " + dllFunctionName);
                        //baseRemote.WriteProcessMemoryUnChecked(lpRvaImportAddressTable, lpFunctionAddress, sizeof(Int64),"");

                        WriteInt64Remote(lpRvaImportAddressTable, (Int64)lpFunctionAddress);
                        lpRvaImportAddressTable = new IntPtr(lpRvaImportAddressTable.ToInt64() + sizeof(Int64));
                    }
                }
            }

            ////////////////////////////////////////////////////////////////////////////////
            Int64  dwStartAddress = lpBaseAddress.ToInt64() + peLoader.addressOfEntryPoint;
            IntPtr lpStartAddress = new IntPtr(dwStartAddress);
            IntPtr lpParameter    = IntPtr.Zero;

            CreateRemoteThreadChecked(lpStartAddress, lpParameter);
        }