Exemplo n.º 1
0
        //internal unsafe static bool Strcmp(byte* strA, byte* strB)
        //{
        //    byte a, b;
        //    bool different = false;
        //    do
        //    {
        //        a = *strA;
        //        b = *strB;
        //        strA++;
        //        strB++;
        //        if (a != b)
        //        {
        //            different = true;
        //            break;
        //        }
        //    } while (a != 0 && b != 0);
        //    return different;
        //}

        //internal static unsafe int Strlen(byte* str)
        //{
        //    int i = 0;
        //    checked // checked causes OverflowException to be raised if i overflows at int.MaxValue.
        //    {
        //        while (str[i] != 0)
        //            i++;
        //    }

        //    return i;
        //}

        internal static unsafe byte *Memmove(byte *dest, byte *src, int byteCount)
        {
            using (HeapPtr ptr = new HeapPtr(byteCount, AllocMethod.HGlobal))
            {
                ptr.ReadData(src, byteCount);
                Memcpy((void *)dest, ptr.ToPointer(), byteCount);
                return(dest);
            }
        }
Exemplo n.º 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);
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        //internal unsafe static bool Strcmp(byte* strA, byte* strB)
        //{
        //    byte a, b;
        //    bool different = false;
        //    do
        //    {
        //        a = *strA;
        //        b = *strB;
        //        strA++;
        //        strB++;
        //        if (a != b)
        //        {
        //            different = true;
        //            break;
        //        }
        //    } while (a != 0 && b != 0);
        //    return different;
        //}

        //internal static unsafe int Strlen(byte* str)
        //{
        //    int i = 0;
        //    checked // checked causes OverflowException to be raised if i overflows at int.MaxValue.
        //    {
        //        while (str[i] != 0)
        //            i++;
        //    }

        //    return i;
        //}

        internal static unsafe byte* Memmove(byte* dest, byte* src, int byteCount)
        {
            using (HeapPtr ptr = new HeapPtr(byteCount, AllocMethod.HGlobal))
            {
                ptr.ReadData(src, byteCount);
                Memcpy((void*)dest, ptr.ToPointer(), byteCount);
                return dest;
            }
        }
Exemplo n.º 5
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;
        }