View Single Post
  #6  
Old 02-19-2017, 01:45
n00b n00b is offline
Friend
 
Join Date: Mar 2009
Posts: 43
Rept. Given: 18
Rept. Rcvd 25 Times in 14 Posts
Thanks Given: 11
Thanks Rcvd at 59 Times in 20 Posts
n00b Reputation: 26
Some code that may aid you in creating an actual unpacker or unwrapper:

Yes, this is actual working sources (only partial!!) - and I've chosen to release this publically since EADRM/OriginDRM is more or less dead nowadays anyways...

(The code is crude, and not optimized at all!)

Code:
    /// 
    /// Struct for OEP & IAT + Version of OriginStub + Par file...
    /// 
    public struct OriginParameters
    {
        public OriginVersion VersionDetected;
        public OepIatSet OEPnIAT;
        public string ParamFileString;
    }

    /// 
    /// Struct for .par file...
    /// 
    public struct Parameters
    {
        public string ContentId;

        public string InstalledDistro;

        public string SupportedDistros;
    }

    /// 
    /// Struct for Version of OriginStub...
    /// 
    public enum OriginVersion
    {
        Error = -1,
        V1 = 0, //IREW
        V2 = 1  //AE64
    }

    /// 
    /// Struct for OEP & IAT...
    /// 
    public struct OepIatSet
    {
        public string OEP;
        public string IAT;
    }

    /// 
    /// Struct for OEP & IAT + Version of OriginStub + Par file...
    /// 
    public struct OriginParameters
    {
        public OriginVersion VersionDetected;
        public OepIatSet OEPnIAT;
        public string ParamFileString;
    }

        internal static OriginVersion DetectOriginVersion()
        {
            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsDetections::DetectOriginVersion]");
            var sOldBytes = Encoding.ASCII.GetBytes("IREW");
            var sNewBytes = Encoding.ASCII.GetBytes("AE64");
            sFileBytes = File.ReadAllBytes(szFileName);

            var fSearch1 = SearchBytes(sFileBytes, sOldBytes, 0L);
            if (fSearch1 == -1)
            {
                fSearch1 = SearchBytes(sFileBytes, sNewBytes, 0L);
                if (fSearch1 == -1)
                {
                    Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsDetections::DetectOriginVersion] Returned: " + OriginVersion.Error);
                    return OriginVersion.Error;
                }
                else
                {
                    sAddr = fSearch1;
                    Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsDetections::DetectOriginVersion] Returned: " + OriginVersion.V2);
                    return OriginVersion.V2;
                }
            }
            sAddr = fSearch1;
            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsDetections::DetectOriginVersion] Returned: " + OriginVersion.V1);
            return OriginVersion.V1;
        }

        internal static OriginParameters LoadExePar()
        {
            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsAnalyse::LoadExePar]");
            var myParams = new OriginParameters();
            var myOepIat = new OepIatSet();

            myParams.VersionDetected = clsDetections.DetectOriginVersion();
            var outOEP = "";
            var outIAT = "";
            clsDetections.GrabOEPnIAT(out outOEP, out outIAT);
            myOepIat.IAT = outIAT;
            myOepIat.OEP = outOEP;
            myParams.OEPnIAT = myOepIat;
            myParams.ParamFileString = clsDetections.GetParFile();

            myParameters = clsDetections.ReadParameters(myParams.ParamFileString);
            myPrvt = myParams;

            return myParams;
        }

        public static bool PatchChecks()
        {
            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsAnalyse::PatchChecks]");
            //var parCrcCheckBytes = "56 57 E8 ?? ?? ?? ?? 83 C4 08 39 ?? ??"; //Generic to both EXE & DLL
            //var requiredToPlayV1Bytes = "83 C4 08 85 C0 0F 94 C3"; //Generic to both EXE & DLL
            //var actExe = DetectEACoreExe();
            //var actDll = DetectEACoreDll();
            //var mFileBytesExe = new byte[1];
            //var mFileBytesDll = new byte[1];
            clsXor.xorList = clsXor.CreateNewCheckSumTable();

            var xorKey = Encoding.ASCII.GetBytes("q@pO3o#5jNA6$sjP3qwe1");
            var szParFileName = clsDetections.DetectParFile();

            if (szParFileName != String.Empty)
            {
                var parFileBytes = File.ReadAllBytes(szParFileName);
                var bytes4 = new byte[4];
                Array.Copy(parFileBytes, 0, bytes4, 0, 4);
                if (clsDetections.FirstBytes(bytes4, xorKey))
                {
                    //OLD NO CRC
                    bwWorker.ReportProgress(0, "[PatchChecks] Returned: PATCHED_PAR_FILE_COMPLETED");
                    File.WriteAllBytes(szParFileName, AddNoOrigin(Encoding.ASCII.GetString(clsXor.Xor(parFileBytes, xorKey)), false));
                    return true;
                }
                else
                {
                    Array.Copy(parFileBytes, 4, bytes4, 0, 4);
                    if (clsDetections.FirstBytes(bytes4, xorKey))
                    {
                        //CRC
                        var parFileBytes2 = new byte[parFileBytes.Length - 4];
                        Array.Copy(parFileBytes, 4, parFileBytes2, 0, parFileBytes2.Length);

                        bwWorker.ReportProgress(0, "[PatchChecks] Returned: PATCHED_PAR_FILE_COMPLETED_CRC_VER");
                        File.WriteAllBytes(szParFileName, AddNoOrigin(Encoding.ASCII.GetString(clsXor.Xor(parFileBytes, xorKey)), true));
                        return true;
                    }
                    else
                    {
                        bwWorker.ReportProgress(0, "[PatchChecks] Returned: FAILED_TO_FIND_XOR_CRC");
                        return false;
                    }
                }
            }
            else
            {
                bwWorker.ReportProgress(0, "[PatchChecks] Returned: FAILED_TO_FIND_PARAMETER_FILE");
                return false;
            }


            //var patchOffsets = new EACorePatch
            //{
            //    crcOffset = -1,
            //    reqToPlayOffset = -1,
            //    szActivationFName = String.Empty
            //};

            //if (actExe != String.Empty) mFileBytesExe = File.ReadAllBytes(actExe);
            //else
            //{
            //    bwWorker.ReportProgress(0, "[PatchChecks] Returned: FAILED_TO_READ_EXE_FILE");
            //    return false;
            //}
            //if (actDll != String.Empty) mFileBytesDll = File.ReadAllBytes(actDll);
            //else
            //{
            //    bwWorker.ReportProgress(0, "[PatchChecks] Returned: FAILED_TO_READ_DLL_FILE");
            //    return false;
            //}

            //long fOffset = 0;

            //if (Pattern.Find(mFileBytesExe, Pattern.Transform(parCrcCheckBytes), out fOffset))
            //{
            //    for (int i = 0; i < 20; i++)
            //    {
            //        if (mFileBytesExe[fOffset + Pattern.Transform(parCrcCheckBytes).Length + i] == 0x74)
            //        {
            //            bwWorker.ReportProgress(0, "[PatchChecks] Returned: CRC_JE_FOUND_EXE");
            //            patchOffsets.crcOffset = fOffset + Pattern.Transform(parCrcCheckBytes).Length + i;
            //        }
            //    }

            //    if (Pattern.Find(mFileBytesExe, Pattern.Transform(requiredToPlayV1Bytes), out fOffset))
            //    {
            //        for (int i = 0; i < 20; i++)
            //        {
            //            if (mFileBytesExe[fOffset + Pattern.Transform(requiredToPlayV1Bytes).Length + i] == 0x72)
            //            {
            //                bwWorker.ReportProgress(0, "[PatchChecks] Returned: REQUIRETOPLAYV1_JB_FOUND_EXE");
            //                patchOffsets.reqToPlayOffset = fOffset + Pattern.Transform(requiredToPlayV1Bytes).Length + i;
            //                patchOffsets.szActivationFName = actExe;
            //                return PatchActivation(patchOffsets, bwWorker);
            //            }
            //        }
            //    }
            //}
            //else if (Pattern.Find(mFileBytesDll, Pattern.Transform(parCrcCheckBytes), out fOffset))
            //{
            //    for (int i = 0; i < 20; i++)
            //    {
            //        if (mFileBytesDll[fOffset + Pattern.Transform(parCrcCheckBytes).Length + i] == 0x74)
            //        {
            //            bwWorker.ReportProgress(0, "[PatchChecks] Returned: CRC_JE_FOUND_DLL");
            //            patchOffsets.crcOffset = fOffset + Pattern.Transform(parCrcCheckBytes).Length + i;
            //        }
            //    }

            //    if (Pattern.Find(mFileBytesDll, Pattern.Transform(requiredToPlayV1Bytes), out fOffset))
            //    {
            //        for (int i = 0; i < 20; i++)
            //        {
            //            if (mFileBytesDll[fOffset + Pattern.Transform(requiredToPlayV1Bytes).Length + i] == 0x72)
            //            {
            //                bwWorker.ReportProgress(0, "[PatchChecks] Returned: REQUIRETOPLAYV1_JB_FOUND_DLL");
            //                patchOffsets.reqToPlayOffset = fOffset + Pattern.Transform(requiredToPlayV1Bytes).Length + i;
            //                patchOffsets.szActivationFName = actDll;
            //                return PatchActivation(patchOffsets, bwWorker);
            //            }
            //        }
            //    }
            //}

            //bwWorker.ReportProgress(0, "[PatchChecks] Returned: FAILED_TO_FIND_PATCH_PATTERNS");
            //return false;
        }

        internal static string GetLicense()
        {
            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsAnalyse::GetLicense]");
            var licPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
                          + "\\Electronic Arts\\EA Services\\License";

            if (myParameters.ContentId.Trim().Contains(","))
            {
                var a = myParameters.ContentId.Trim().Split(new char[] { ',' });
                foreach (var VARIABLE in a)
                {
                    if (File.Exists(licPath + "\\" + VARIABLE.Trim() + ".dlf"))
                    {
                        var tmpBytes = File.ReadAllBytes(licPath + "\\" + VARIABLE.Trim() + ".dlf");
                        var bMore = new BoyerMoore(new byte[] { 0xC0, 0x1E, 0x0F, 0x86, 0xDA, 0xF1, 0xF8, 0x5F }, tmpBytes);
                        if (bMore.Match() > -1)
                        {
                            bwWorker.ReportProgress(0, "[GetLicense] BOYERMOORE_MATCH_FOUND_SIG");
                            var myArray = new byte[tmpBytes.Length - bMore.Match()];
                            Array.Copy(tmpBytes, bMore.Match(), myArray, 0, tmpBytes.Length - bMore.Match());
                            var tmpXml = clsHelpers.ParseXml(clsAes.AesDecrypt(myArray));

                            bwWorker.ReportProgress(0, "[GetLicense] XML_CIPHERKEY_FOUND");
                            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsAnalyse::GetLicense] Returned: " + tmpXml.CipherKey);
                            return tmpXml.CipherKey;
                        }
                    }
                }
            }
            else if (File.Exists(licPath + "\\" + myParameters.ContentId.Trim() + ".dlf"))
            {
                    var tmpBytes = File.ReadAllBytes(licPath + "\\" + myParameters.ContentId.Trim() + ".dlf");
                    var bMore = new BoyerMoore(new byte[] { 0xC0, 0x1E, 0x0F, 0x86, 0xDA, 0xF1, 0xF8, 0x5F }, tmpBytes);
                    if (bMore.Match() > -1)
                    {
                        bwWorker.ReportProgress(0, "[GetLicense] BOYERMOORE_MATCH_FOUND_SIG");
                        var myArray = new byte[tmpBytes.Length - bMore.Match()];
                        Array.Copy(tmpBytes, bMore.Match(), myArray, 0, tmpBytes.Length - bMore.Match());
                        var tmpXml = clsHelpers.ParseXml(clsAes.AesDecrypt(myArray));

                        bwWorker.ReportProgress(0, "[GetLicense] XML_CIPHERKEY_FOUND");
                        Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsAnalyse::GetLicense] Returned: " + tmpXml.CipherKey);
                        return tmpXml.CipherKey;
                    }
            }
            else
            {
                bwWorker.ReportProgress(0, "[GetLicense] GAME_NOT_RUN_FIRST");
                Debug.WriteLine(DateTime.Now.ToShortTimeString() + " GetLicense] Returned: Game Never Ran before!");
                return "ERROR: Run game once first!";
            }
            bwWorker.ReportProgress(0, "[GetLicense] XML_CIPHERKEY_NOT_FOUND");
            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsAnalyse::GetLicense] Returned: NULL");
            return string.Empty;
        }


        internal static byte[] AddNoOrigin(string toFix, bool useChecksum)
        {
            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsAnalyse::AddNoOrigin]");
            if (!toFix.Contains("RequiredToPlayV1"))
            {
                var a =
                    clsXor.Xor(
                        Encoding.ASCII.GetBytes(
                            toFix.Replace("InstalledDistro = ", "InstalledDistro = RequiredToPlayV1,")),
                        Encoding.ASCII.GetBytes("q@pO3o#5jNA6$sjP3qwe1"));
                var b = clsXor.Xor2(clsHelpers.CreateCorrectTable(a));
                var bitBugA = new byte[1];
                if (useChecksum)
                {
                    bitBugA = new byte[a.Length + b.Length];
                    Array.Copy(b, 0, bitBugA, 0, b.Length);
                    Array.Copy(a, 0, bitBugA, b.Length, a.Length);
                    return bitBugA;
                }
                else
                {
                    return a;
                }
            }
            else
            {
                var a = clsXor.Xor(Encoding.ASCII.GetBytes(toFix), Encoding.ASCII.GetBytes("q@pO3o#5jNA6$sjP3qwe1"));
                var b = clsXor.Xor2(clsHelpers.CreateCorrectTable(a));
                var bitBugA = new byte[1];

                if (useChecksum)
                {
                    bitBugA = new byte[a.Length + b.Length];
                    Array.Copy(b, 0, bitBugA, 0, b.Length);
                    Array.Copy(a, 0, bitBugA, b.Length, a.Length);
                    return bitBugA;
                }
                else
                {
                    return a;
                }
            }
        }

        internal static bool PatchActivation(EACorePatch patchDetails)
        {
            Debug.WriteLine(DateTime.Now.ToShortTimeString() + " clsAnalyse::PatchActivation]");
            if (patchDetails.crcOffset != -1 && patchDetails.reqToPlayOffset != -1
                && patchDetails.szActivationFName != String.Empty)
            {
                var mBytes = File.ReadAllBytes(patchDetails.szActivationFName);
                File.Copy(patchDetails.szActivationFName, patchDetails.szActivationFName + ".bak", true);
                mBytes[patchDetails.crcOffset] = 0xEB;
                mBytes[patchDetails.reqToPlayOffset] = 0xEB;
                try
                {
                    File.WriteAllBytes(patchDetails.szActivationFName, mBytes);
                    bwWorker.ReportProgress(0, "[PatchActivation] Returned: FILE_PATCHED_AND_SAVED");
                    return true;
                }
                catch (Exception ex)
                {
                    bwWorker.ReportProgress(0, "[PatchActivation] Returned: FILE_PATCH_FAILED (" + ex.Message + ")");
                    return false;
                }
            }
            bwWorker.ReportProgress(0, "[PatchActivation] Returned: FILE_PATCH_FAILED_MISSING_DETAILS");
            return false;
        }
As I said earlier in this reply; this code is far from complete, its just something that may or may not help an experienced coder create something they want with - and yes, the code is entirely mine and mine alone

Anywho; use this code as you wish, but credit me if you do
Reply With Quote
The Following 3 Users Say Thank You to n00b For This Useful Post:
chants (02-19-2017), e0qs (12-29-2017), tonyweb (02-19-2017)