//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); } }
public HeapPtr ToPointer() { int byteLength = m_obs.Count * 16; HeapPtr ptr = new HeapPtr(byteLength, AllocMethod.HGlobal); for (int i = 0; i < m_obs.Count; i++) { IntPtr memoryBase = (IntPtr)ptr; IntPtr memoryOffset = new IntPtr(memoryBase.ToInt64() + (i * 16)); Marshal.Copy(m_obs[i].data, 0, memoryOffset, 16); } return ptr; }
public HeapPtr ToPointer() { int byteLength = m_obs.Count * 16; HeapPtr ptr = new HeapPtr(byteLength, AllocMethod.HGlobal); for (int i = 0; i < m_obs.Count; i++) { IntPtr memoryBase = (IntPtr)ptr; IntPtr memoryOffset = new IntPtr(memoryBase.ToInt64() + (i * 16)); Marshal.Copy(m_obs[i].data, 0, memoryOffset, 16); } return(ptr); }
public static unsafe void Final(Context ctx, HeapPtr ptr) { byte[] hashResult; Final(ctx, out hashResult); ptr.MarshalData(hashResult); }
/// <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); }
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); }
//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; } }
public static unsafe void Final(Context ctx, HeapPtr ptr) { byte[] hashResult; Final(ctx, out hashResult); ptr.MarshalData(hashResult); }
/// <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; }