Beispiel #1
0
        internal unsafe static bool HashFile(LockdownSha1.Context context, string filename, int seed)
        {
            int          i, headersSize, sectionAlignment;
            byte *       imageBase;
            PeFileLoader module;
            byte *       firstSection;
            byte *       baseaddr;

            //PeFileReader.NtHeaders.ImageDataDirectory* importDir;
            PeFileReader.NtHeaders.ImageDataDirectory *relocDir;
            PeFileReader.DosImageHeader *dosheader;
            PeFileReader.NtHeaders *     ntheader;

            LockdownHeap heap = new LockdownHeap();

            module = new PeFileLoader(filename);

            baseaddr         = module.BaseAddress;
            dosheader        = (PeFileReader.DosImageHeader *)baseaddr;
            ntheader         = (PeFileReader.NtHeaders *)(baseaddr + dosheader->e_lfanew);
            sectionAlignment = ntheader->OptionalHeader.SectionAlignment;
            imageBase        = (byte *)ntheader->OptionalHeader.ImageBase;

            //importDir = (PeFileReader.NtHeaders.ImageDataDirectory*)&ntheader->OptionalHeader.IDD1;
            relocDir = (PeFileReader.NtHeaders.ImageDataDirectory *) & ntheader->OptionalHeader.IDD5;

            // roughly, IMAGE_FIRST_SECTION macro.  0x18 is the offset of the optional header, plus size of optional header.
            firstSection = (byte *)(((byte *)ntheader) + 0x18 + ntheader->SizeOfOptionalHeader);

            headersSize = ntheader->OptionalHeader.SizeOfHeaders;

            LockdownSha1.Update(context, baseaddr, headersSize);

            if (relocDir->VirtualAddress != 0 && relocDir->Size != 0)
            {
                if (!ProcessRelocDir(heap, baseaddr, relocDir))
                {
                    module.Dispose();
                    heap = null;
                    return(false);
                }
            }

            for (i = 0; i < (ntheader->NumberOfSections); i++)
            {
                if (!ProcessSection(context, heap, baseaddr, imageBase, (PeFileReader.ImageSectionHeader *)(firstSection + (i * 0x28)), sectionAlignment, seed))
                {
                    module.Dispose();
                    heap = null;
                    return(false);
                }
            }

            heap = null;
            module.Dispose();

            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// Calculates the lockdown checkrevision.
        /// </summary>
        /// <param name="file1">The first game file</param>
        /// <param name="file2">The second game file</param>
        /// <param name="file3">The third game file</param>
        /// <param name="valueString">The value calculation string from the server</param>
        /// <param name="version">The version</param>
        /// <param name="checksum">The checksum</param>
        /// <param name="digest">The result</param>
        /// <param name="lockdownFile">The name of the lockdown file</param>
        /// <param name="imageDump">The path to the screen dump</param>
        /// <returns></returns>
        public static unsafe bool CheckRevision(string file1, string file2, string file3, byte[] valueString, ref int version, ref int checksum, out byte[] digest,
                                                string lockdownFile, string imageDump)
        {
            int returnIsValid = 1;
            int moduleOffset = 0;
            int seed, i;

            digest = null;

            int digit = GetDigit(lockdownFile);

            seed    = seeds[digit];
            version = PeFileLoader.GetVersion(file1);

            // note that the HeapPtr can be implicitly cast to byte* and so therefore
            // can be used in method calls that would normally accept a byte* parameter.
            using (HeapPtr pSha1Buf = new HeapPtr(20, AllocMethod.HGlobal))
                using (HeapPtr pSha1Buf2 = new HeapPtr(20, AllocMethod.HGlobal))
                    using (HeapPtr pValStr = new HeapPtr(valueString.Length, AllocMethod.HGlobal))
                        using (HeapPtr pValStrEnc = new HeapPtr(valueString.Length, AllocMethod.HGlobal))
                            using (HeapPtr pValStrBuffer1 = new HeapPtr(0x40, AllocMethod.HGlobal))
                                using (HeapPtr pValStrBuffer2 = new HeapPtr(0x40, AllocMethod.HGlobal))
                                    using (HeapPtr pTempMem = new HeapPtr(16, AllocMethod.HGlobal))
                                        using (HeapPtr pDigest = new HeapPtr(17, AllocMethod.HGlobal))
                                        {
                                            pValStr.MarshalData(valueString);

                                            if (!ShuffleValueString(pValStr, valueString.Length, pValStrEnc))
                                            {
                                                return(false);
                                            }

                                            Native.Memset(pValStrBuffer1.ToPointer(), 0x36, 0x40);
                                            Native.Memset(pValStrBuffer2.ToPointer(), 0x5c, 0x40);

                                            byte *valuestrBuffer1 = pValStrBuffer1;
                                            byte *valuestrBuffer2 = pValStrBuffer2;
                                            byte *valueStrEncoded = pValStrEnc;

                                            for (i = 0; i < 0x10; i++)
                                            {
                                                valuestrBuffer1[i] ^= valueStrEncoded[i];
                                                valuestrBuffer2[i] ^= valueStrEncoded[i];
                                            }

                                            LockdownSha1.Context context = LockdownSha1.Init();
                                            LockdownSha1.Update(context, valuestrBuffer1, 0x40);

                                            if (!HashFile(context, lockdownFile, seed))
                                            {
                                                return(false);
                                            }

                                            if (!HashFile(context, file1, seed))
                                            {
                                                return(false);
                                            }

                                            if (!HashFile(context, file2, seed))
                                            {
                                                return(false);
                                            }

                                            if (!HashFile(context, file3, seed))
                                            {
                                                return(false);
                                            }

                                            LockdownSha1.HashFile(context, imageDump);

                                            LockdownSha1.Update(context, (byte *)&returnIsValid, 4);
                                            LockdownSha1.Update(context, (byte *)&moduleOffset, 4);

                                            LockdownSha1.Final(context, pSha1Buf);

                                            context = LockdownSha1.Init();
                                            LockdownSha1.Update(context, pValStrBuffer2, 0x40);
                                            LockdownSha1.Update(context, pSha1Buf, 0x14);
                                            LockdownSha1.Final(context, pSha1Buf2);

                                            checksum = *(int *)((byte *)pSha1Buf2);
                                            Native.Memmove(pTempMem, ((byte *)pSha1Buf2) + 4, 0x10);

                                            int valstrLen = 0xff;
                                            if (!CalculateDigest(pDigest, ref valstrLen, pTempMem))
                                            {
                                                return(false);
                                            }

                                            ((byte *)pDigest)[valstrLen] = 0x00;

                                            digest = new byte[valstrLen];
                                            Marshal.Copy(new IntPtr(pDigest.ToPointer()), digest, 0, valstrLen);
                                        }

            return(true);
        }