Hack Age of Empires III لتغيير إعدادات جودة التظليل

بداية مايو 2020 - إذا كنت مثلي ، فإن الحجر الصحي جعلك تعيد الألعاب التي لم يتم إطلاقها لسنوات عديدة.

وإذا كنت مثلي أكثر فأكثر ، ففي مكان ما قد يكون لديك قرص من Age of Empires 3. مستلقيًا. ربما تلعب على جهاز Mac ، ربما لم تقم بالترقية إلى Catalina حتى الآن وتريد قيادة Morgan Black.

لذا ، تبدأ اللعبة ، وتدخل إلى القائمة الرئيسية ، وتلاحظ على الفور أن هناك خطأ ما ... القائمة تبدو مقرفة .


إذا كنت تتساءل ما هو بالضبط "مثير للاشمئزاز" ، ثم انتبه إلى الماء. كل شيء آخر رهيب أيضًا ، ولكنه أقل وضوحًا.


لذا ، انتقل إلى الخيارات ، ورفع جميع المعلمات إلى أقصى حد ... لكن اللعبة لا تزال قبيحة.

لاحظت أن خيارات " جودة Shader " مقفلة بشكل مثير للريبة إلى " منخفضة ".

المحاولة رقم 1 - معلمات الاختراق


في هذه المرحلة ، تبدأ في البحث عن مجلد اللعبة ، والذي من المفترض أنه تم إنشاؤه في مكان ما في مجلد المستندات ، لأن اللعبة كانت في عام 2005 ، ثم قام بها الجميع.

ما الذي تبحث عنه؟ بالطبع ، الملف الذي يتم تخزين المعلمات فيه. لا تسمح لنا واجهة القائمة بتغيير الإعدادات ، لكننا صعبون ، أليس كذلك؟

نجد XML الصحيح ، لأن اللعبة هي 2005 وهي بالطبع ، XML ، حيث نأتي عبر خيار " optiongrfxshaderquality " ، الذي تم تعيينه على 0. يبدو أننا كنا نبحث عنه ، لذلك قمنا بزيادة القيمة إلى 100 ، لأنه لا يوجد الكثير من الجودة. أنا هنا أتفق معك.


قد تلاحظ أيضًا أن هذا استخدام رهيب لـ XML. لحسن الحظ ، ليس لديه استخدامات جيدة.

نحن راضون عن أنفسنا ، نطلق اللعبة. للأسف ، لم يتغير شيء. بالنظر مرة أخرى إلى ملف XML ، نرى أنه تم تعيين المعلمة مرة أخرى على 0. Ensemble Studios (أتمنى أن ترقد بسلام) تبدو بازدراء في كل براعة.

بعد ذلك ، يمكن أن نستسلم . هذا هو جهاز Mac ، لذلك ، من غير المحتمل العثور على التصحيحات التي كتبها المستخدمون (في الواقع ، راجعت - هناك جميع أنواع الحلول المريبة التي قد تعمل). كل شيء عن الرسومات. يبدو أن حل المشكلة سيكون صعبا.

لكننا لن نستسلم. لأننا نتذكر كيف يجب أن يكون شكل العمر 3. نتذكر كيف أعجبنا بهذه المياه المتموجة الجميلة. هذه تأثيرات الجسيمات. هذه السفن الضخمة التي لا تتناسب مع الإطار. وكان فقط أن الكاميرا تم تكبيرها ، ما كنت أفكر فقط؟

المحاولة رقم 1 - قرصنة البيانات


في بداية المجلد في المستندات ، يوجد ملف سجل. وكتبت اللعبة بطاقة رسومات هناك وأفادت أنها اختارت إعداد "dx7 العام". تقول أنك قمت بتثبيت Intel GMA 950 ، التي كانت بالفعل على جهاز الكمبيوتر السابق.

ولكن في هذا لديك Intel Iris Graphics 6100. هناك خطأ ما. أنت تقوم بافتراض - تحدد اللعبة القدرات الرسومية للكمبيوتر ، وتقارنها بقاعدة بيانات من بطاقات الرسوم بدلاً من التحقق من قدرات البطاقة نفسها. لأن هذا بالضبط ما يفعله مطورو AAA ، وإذا كنت تعمل على RTS مفتوح المصدر ، فأنت تعرف كيف يحدث ذلك.


محتويات ملف السجل. إذا وجدت أنه من المضحك أن Intel مصنفة على أنها 0x8086 ، فقد اخترت المقالة المناسبة.

عن طريق الصدفة ، تجد ملاحظات التصحيح القديمة التي تؤكد مخاوفك. تنظر إلى مجلد GameData ، ولكن هناك ملفات .bar و xmb فقط غير قابلة للقراءة في الغالب. أنت تبحث عن grep " Intel " و " dx7 ". لا يحدث شيء. حذف عدة ملفات ... لا يحدث شيء. لكنك تعلم أن ألعاب AAA يمكنها تخزين بعض الموارد في أماكن غريبة ، وهذا هو منفذ ألعاب Windows على Mac ، لذلك يمكن أن يكون كل شيء غريبًا جدًا هنا.

في النهاية ، ستجد الملف "make.bar" ؛ إذا قمت بنقله ، فإن اللعبة تتعطل عندما تبدأ. ليس واضحًا جدًا ، لكن ليس سيئًا. نفتح الملف في Hex Fiend ، لأن هذا البرنامج يسمح لك عادةً بتعلم شيء عن الملفات الثنائية. وهكذا اتضح. جزء من هذه البيانات هو نص قابل للقراءة. بعضهم تظليل. لكن معظم البيانات مقسمة بغرابة عن طريق المساحة الفارغة ...


واجهة Hex Fiend إنه أضيق الحدود ، لكنه يعمل. البايت الأول هي الأحرف "ESPN" ، والتي غالبًا ما تكون رأس .bar.

أنت تصيح: "من الواضح أن هذا هو UTF-16!" تم إنشاء اللعبة لنظام التشغيل Windows ، لذلك فمن المنطقي أن تقوم بتخزين النص في UTF-16 ، مما يهدر ما يقرب من نصف ملف بيانات 30 ميجابايت. بعد كل شيء ، أحب Windows UTF-16 (على الرغم من أنه لا ينبغي أن يكون كذلك ) ، فلماذا لا تستخدم هذا التشفير وتظليل ASCII في ملف واحد. إنها فكرة منطقية!

(في الواقع ، استغرق الأمر مني يومًا تقريبًا لمعرفة ذلك)

Hex Fiend لديه خيار تحليل وحدات البايت مثل UTF-16 ، لذلك مرة أخرى نبحث عن سلسلة grep dx7. هناك العديد من الإدخالات. نستبدلهم بخط dx9 ، والذي يوجد أيضًا في البيانات ، ونحفظ الملف ونطلق اللعبة.

بلى السجلات مرة أخرى لا تعرض "dx9". ربما تم تعيين هذا في مكان آخر.

لنجرب شيئًا آخر. افترض أن اللعبة تتعرف على بطاقات الرسومات ، وأن معرّفاتها السداسية يتم تخزينها في السجلات (في حالتي ، 0x8086 هي Intel ، وكذلك 0x2773). نحن نبحث عن "8086" في Hex Fiend ، نجد شيئًا ، وجزء من النص يبدو واعدًا. سلسلة Intel 9 هي سلسلة GMA 950 ، وربما لا يعمل Age 3 بشكل جيد جدًا عليها.


بعض الأرقام مثل معرفات البطاقة (2582 ، 2592) ؛ ربما إذا قمت باستبدالها ، فسوف يتغير شيء ما. أنشأنا نسخة من الملف على أي حال ، حتى تتمكن من المحاولة.

للأسف ، هذا طريق مسدود أيضًا. في الواقع ، نحن ندرس الملف الخطأ. لحسن الحظ، أستطيع أن أقول لكم هذا لأنني قضيت الكثير من الوقت على ذلك، وحاول أيضا من ذلك بكثير. استغرق هذا الأمر لعنة حوالي 20 ساعة. وهذا لا يحسب الوقت لجميع لقطات الشاشة ...

يسمى الملف المطلوب "DataP.bar" ، وإذا استبدلنا المعرّف بحكمة ، فسوف نرى شيئًا جديدًا تمامًا في السجلات:


لا أفهم تمامًا سبب عدم تطابق "dx7 العام" كما في لقطة الشاشة أعلاه.

بالطبع ، في اللعبة ما زلنا مقيدين بإعدادات "منخفضة" ، أي أن السجلات لا تكذب. كنا نأمل في المتوسط ​​، ولكن للأسف .

يبدو أنه لا يمكن تحقيق المزيد من بيانات القرصنة. حان الوقت للحصول على الأدوات بجدية.

المحاولة رقم 2 - القرصنة


لذلك ، إذا لم ينجح أي شيء ، فلدينا شيء أخير متبقي: تغيير الملف القابل للتنفيذ نفسه (أي ، كما قالوا في عام 2005 ، "كسرها"). يبدو أنه اليوم يسمى ببساطة القرصنة ، ولكن تم الحفاظ على هذا المصطلح في مجال قرصنة اللعبة (بالطبع ، أنا شخصياً لم أفعل ذلك من قبل).

ننتقل إلى الجزء الأكثر إثارة للاهتمام من المقالة (نعم ، لقد قرأت بالفعل ألف كلمة ، ولكن ألم يكن ذلك غريبًا؟).

تفكيك هوبر


في هذه المرحلة ، ستكون أداتنا عبارة عن أداة تفكيك: تطبيق يتلقى الرمز الثنائي للملف القابل للتنفيذ ويحوله إلى رمز تجميع قابل للقراءة (ha ha). الأكثر شيوعًا هو IDA Pro ، ولكنه مكلف للغاية لدرجة أنني لست متأكدًا مما إذا كان يعمل على جهاز Mac ، لذلك سأستخدم Hopper . إنها ليست مجانية (تكلف 90 دولارًا) ، ولكن يمكن استخدامها مجانًا لمدة 30 دقيقة في كل مرة تقريبًا مع جميع الوظائف الضرورية.

لن أشرح الواجهة بالتفصيل ، لأن كل شيء تم وضعه بشكل جيد في البرنامج التعليمي لـ Hopper ، لكنني سأخبرك بما سأفعله وأحاول التقاط لقطات كافية حتى تتمكن من تعلم شيء ما.

عليك أولاً أن تقول: استغرق الأمر خمسة أيام لحلها ، وقد تم إجراء العديد من المحاولات غير الناجحة. في الأساس ، سأتحدث عن الخطوات الناجحة ، لذلك سيبدو الأمر سحريًا. لكنها كانت صعبة . لا تقلق إذا كان لديك أي مشاكل.

وملاحظة أخرى: "التكسير" غالبًا ما يكون غير قانوني و / أو يتم تنفيذه لأغراض غير قانونية. أعرض مثالًا نادرًا إلى حد ما على الاستخدام المشروع إلى حد ما ، والذي يعد في نفس الوقت "قبعة بيضاء" تمامًا ، لذلك كل شيء على ما يرام هنا. سأفترض ، بشكل دقيق ، أن هذا غير قانوني / يتعارض مع اتفاقية المستخدم النهائي ، ولكن ، من الواضح ، هو حالة قوة قاهرة . كن على هذا النحو ، ادفع مقابل ما تريد ، وفقط لذلك ، لأن معاداة الاستهلاك رائع.




اسحب تطبيق Age 3 لفتحه. ما عليك سوى اختيار "x86" بدلاً من powerPC ، لأن اللعبة هي شيء 2005.

المرحلة 1 - ابحث عن الجزء المطلوب


من المستغرب أن هذا قد يكون الأصعب. لدينا رمز مفكك ، لكن ليس لدينا أي فكرة إلى أين ننظر. نعم ، تحتوي بعض الألعاب على رموز تصحيح ، بحيث يمكنك قراءة أسماء الوظائف ، ولكن ليس في حالتنا. يعطينا هوبر أسماء مثل "sub_a8cbb6" ، والتي علينا التعامل معها بمفردنا.

لحسن الحظ ، لدينا السبق: ملف السجل الخاص بنا . من المحتمل جدًا أن يتم استخدام سلسلة حرفية عند الكتابة إلى السجل، أي ، يتم وميض ASCII في الملف القابل للتنفيذ. يمكننا البحث عنها باستخدام grep ، لأننا لن نتخلص منها بأي تجميع (ومع ذلك ، يمكن إخفاؤها عن طريق التعتيم البرمجي. لحسن الحظ ، لم يحدث هذا.). عادة ما يكون العثور على حرفية سلسلة grep هو أول ما يفعلونه عند تفكيك البرنامج. لذا ، دعنا ندخل "بائع تم العثور عليه" في مربع بحث Hopper وسيجد شيئًا:


أوه نعم ، سلسلة حرفية ، أعشقهم.

هذا في حد ذاته لم يقدم لنا الكثير. ولكن بما أن عنوان هذه "السلسلة الحرفية" مشفر ، يمكننا إيجاد روابط لها. أبرزهم هوبر باللون الأخضر على اليمين: "DATA XREF = sub_1d5908 + 1252." بالنقر المزدوج على الخط ، سننتقل إلى بطلنا - إجراء sub_1d5908 .


هنا نجد رمز المجمع. يعتقد أنه من الصعب قراءتها ، لكنها ليست كذلك. أصعب شيء هو فهمه.

بشكل افتراضي ، يستخدم Hopper "بناء جملة Intel" ، أي أن المعامل الأول هو جهاز الاستقبال ، والثاني هو المصدر. في السطر المميز نرى mov dword [esp+0x1DC8+var_1DC4], aXmlRenderConfi. دعونا نجعلها.

خطنا الأول في المجمع


movهو فريق MOV معروف بكونه على x86 Turing-Complete . ينقل (ينسخ في الواقع) البيانات من A إلى B ، مما يعني بشكل أساسي قراءة A وكتابتها إلى B. بناءً على ما سبق ، aXmlRenderConfiهذا هو A ، dword [esp+0x1DC8+var_1DC4]وهذا هو B ، المتلقي. دعونا نلقي نظرة فاحصة على هذا.

aXmlRenderConfi- هذه هي القيمة التي يساعدنا هوبر. هذا في الواقع اسم مستعار لعنوان ذاكرة السلسلة الحرفية التي نقرنا عليها قبل بضع ثوانٍ. إذا قسمت النافذة ونظرت إلى الرمز في وضع Hex (وهو الوضع المفضل للمتسللين) ، فسنرى هناك 88 18 83 00.


يبرز القادوس بشكل ملائم نفس الأجزاء المحددة في كلتا النوافذ.

إذا كانت قيمة "flip" صحيحة ، فسوف نحصل على 0x00831888 - عنوان ذاكرة السلسلة الحرفية (في إحدى لقطات الشاشة الموضحة أعلاه مظللة باللون الأصفر). لذلك ، يتم حل لغز واحد: ينفذ الرمز MOV ، أي أنه يكتب العنوان 0x00831888.

لماذا هو مكتوب 88 18 83 00، وليس كيف 00 83 18 88؟ حدث هذا بسبب ترتيب البايت - وهو موضوع مربك نوعًا ما يكون له تأثير ضئيل في العادة. هذه إحدى الأشياء التي تجعل الناس يقولون أن "أجهزة الكمبيوتر لا تعمل". بالنسبة لنا ، هذا يعني أن هذه المشكلة ستحدث في جميع الأرقام التي سنعمل معها اليوم.

قد تلاحظ أنني قلت "اكتب العنوان" ، وهذا صحيح: نحن لا نهتم حقًا بالمحتويات ، التي اتضح أنها سلسلة حرفية مع صفر بايت في النهاية. نكتب العنوان لأن الرمز سيشير لاحقًا إلى هذا العنوان. هذا مؤشر.

ماذا عن dword [esp+0x1DC8+var_1DC4]؟ كل شيء أكثر تعقيدًا هنا. dwordيعني أننا نعمل مع "كلمات مزدوجة (كلمات مزدوجة)" ، أي بت 16 * 2 بت. أي أننا ننسخ 32 بت. أذكر: عنواننا0x00831888، أي 8 أحرف سداسية عشرية ، ويمكن أن يحتوي كل حرف سداسي عشري على 16 قيمة ، أي 4 بتات بيانات. لذا نحصل على 8 * 4 = 32. بالمناسبة ، جاءت العلامة "32 بت" لأنظمة الكمبيوتر من هنا. إذا استخدمنا 64 بت ، فسيتم كتابة عنوان الذاكرة على النحو 0x001122334455667788 ، وسيكون ضعف الطول و 2 ^ 32 مرة أكبر ، وسيكون علينا نسخ 16 بايت. لذلك سيكون لدينا ذاكرة أكبر بكثير ، ولكن نسخ المؤشر يتطلب ضعف العمل ، وبالتالي فإن 64 بت ليست في الواقع ضعف سرعة 32 بت. بالمناسبة ، يمكن العثور على شرح أكثر تفصيلاً لمصطلح "كلمة" هنا . لأنه ، بالطبع ، أكثر تعقيدًا من تفسيري.

إذن ، ماذا عن الجزء الموجود بين قوسين معقوفين؟ تعني الأقواس أننا نحسب ما بداخله ونعتبره مؤشرًا. لذلك ، سوف يكتب الأمر MOV إلى عنوان الذاكرة التي تم الحصول عليها من الحسابات. دعنا نلقي نظرة عليها مرة أخرى بمزيد من التفصيل (ولا تقلق ، عندما تنتهي من ذلك ، ستعرف بشكل أساسي كيفية قراءة رمز المجمّع باستخدام بنية Intel).

espإنه سجل في المجمع هو أقرب ما يعادل متغير. هناك الكثير من السجلات في بنية x86 ، والسجلات المختلفة لها طرق مختلفة للتطبيق ، لكننا لن نهتم حقًا. تعلم المزيد عن هذا هنا.. فقط كن على دراية بأن هناك سجلات خاصة لأرقام الفاصلة العائمة ، بالإضافة إلى "الأعلام" المستخدمة في المقارنات والعمليات المماثلة. كل شيء آخر هو مجرد أرقام سداسية عشرية أعاد هوبر تعديلها قليلاً لمساعدتنا. var_1DC4- هذا -0x1DC4، يمكننا رؤيته في بداية الإجراء ، أو في اللوحة اليمنى. هذا يعني أن نتيجة الحساب [esp+0x1DC8+var_1DC4]ستكون [esp + 0x1DC8 — 0x1DC4]متساوية [esp + 4]. يعني هذا في جوهره "أخذ قيمة 32 بت من سجل ESP وإضافة 4 وتفسير النتيجة كعنوان للذاكرة."

لذا ، نكرر: نكتب عنوان السلسلة الحرفية في "esp + 4". هذه معلومات صحيحة ، لكنها غير مجدية تمامًا. ماذا يعني هذا؟

هذه هي الصعوبة في قراءة رمز التجميع: في تحليل ما يجب أن تفعله. هنا لدينا بداية: نعلم أنه على الأرجح يكتب شيئًا إلى السجل. لذلك ، يمكننا أن نتوقع استدعاء دالة تكتب إلى السجل. دعونا نبحث عنها.


في لقطة الشاشة أعلاه ، هناك العديد من المكالمات المماثلة ، بالإضافة إلى الأمر callالذي يستدعي الإجراء. يتحدث هوبر عادة عن هذا (لا أعرف لماذا لم يفعل ذلك هنا) ، ولكن في الجوهر ، نقدم حججًا لاستدعاء الوظيفة. إذا قمت بالنقر فوق مكالمات روتين فرعي مختلفة ، نجد شيئًا يسمى imp___jump_table___Z22StringVPrintfExWorkerAPcmmPS_PmmPKcS_. هذا هو الاسم الذي تم فك ترميزه للدالة ، والجزء "Printf" كافٍ لفهم أنه ينتج شيئًا حقًا. نحن لا نهتم كيف تفعل ذلك.

خذ خطوة للوراء


في هذه المرحلة ، ابتعدنا تمامًا عما فعلناه: حاولنا إقناع اللعبة بأن بطاقة الرسومات لعام 2015 كانت قوية بما يكفي لإطلاق لعبة 2005. دعونا نلخص. وجدنا المكان الذي يتم فيه تسجيل السجل. إذا كنا محظوظين ، فإليك الرمز الذي يتحقق من معلمات وإمكانيات بطاقات الرسوم. لحسن الحظ ، كنا محظوظين حقًا (هناك احتمال كبير بأن هذه المقالة لم تكن لتحدث).

للحصول على الصورة الكبيرة ، سنستخدم وظيفة الرسم البياني للتحكم في تدفق هوبر ، والتي تقسم الشفرة إلى كتل صغيرة وترسم الأسهم التي تشير إلى التحولات المختلفة. هذا أسهل بكثير في الفهم منه في المجمع العادي ، حيث يكون كل شيء في حالة فوضى.


يتم استدعاء إدخال السجل في منتصف وظيفة طويلة بشكل رهيب ، لأن هذا ، مرة أخرى ، يحدث عادة في ألعاب AAA. هنا يجب أن نبحث عن حرفية سلسلة هوبر و "تلميحات" أخرى ، على أمل العثور على شيء ما. في بداية الإجراء بقية التسجيل ، وتوجد أدناه أجزاء مثيرة للاهتمام حول "فرض dx7" وخيارات "عالية جدًا" ، بالإضافة إلى مشكلة في إصدار تظليل البكسل ... التي لدينا.

أفاد سجل بياناتنا "المخترقة" بوجود تظليل بكسل للإصدار 0.0 ، وهي غير متوافقة مع معلمات "عالية". يقع هذا الرمز في الزاوية اليسرى السفلية من وظيفتنا ، وإذا نظرت عن كثب ، يمكنك رؤية شيء غريب (تم تمييزه من قبل خادمك المتواضع): هذا هو الرمز نفسه مكررًا أربع مرات للمعلمات "مرتفع جدًا" و "مرتفع" و "متوسط" و "منخفض". ونعم ، استغرق الأمر عدة ساعات للعثور على هذا.


أبرزت باللون الأزرق الكتلة التي يتم فيها عرض "pixel shader version 0.0 High" في السجل. سلطت الضوء على أجزاء مماثلة بألوان جميلة أخرى.

الاختلافات الوحيدة هي أننا نكتب "0x0" و "0x1" و "0x2" و "0x3" في أماكن مختلفة. هذا مشابه بشكل مثير للريبة لملف المعلمات الذي فحصناه أعلاه ومعلمة optiongrfxshaderquality (قد لا تفهم ذلك بعد. ولكن ، صدقوني).

في هذه المرحلة ، يمكننا محاولة السير بطرق مختلفة ، وهو ما فعلته. لكن سأكون مختصراً - سنفعل أكثر ما هو ضروري: اكتشف سبب فشل التحقق من تظليل البكسل. دعونا نبحث عن فرع. كتلة الخرج إلى السجل خطي ، مما يعني أنه يجب أن يكون في مكان ما أعلاه.


مراوح SEMVER ، راجع تنسيق الإصدار الأكثر تقدمًا: أرقام الفاصلة العائمة.

وفي الواقع ، يوجد فوقها مباشرة jbأمر انتقالي (فكر في "goto"). هذه " قفزة مشروطة " ، والشرط هو " إذا كان أقل ". يعمل المُجمِّع "ifs" من خلال أعلام التسجيل ، التي تحدثت عنها بإيجاز أعلاه. يكفي فقط أن تعرف أننا بحاجة إلى إلقاء نظرة على الأمر أعلاه: على الأرجح ، فإنه يضع العلم. غالبًا ما يكون هذا أمرًا ، cmpأو testيستخدم هنا ucomiss. هذه بربرية. لكنها بسهولة جوجل: ucomiss . هذا أمر مقارنة الفاصلة العائمة ، وهذا يفسر سبب وجود التعليمات البرمجيةxmm0: هذا سجل بأرقام الفاصلة العائمة. هذا منطقي: تشير السجلات إلى أن نسختنا من تظليل البكسل هي "0.0" ، وهي قيمة فاصلة عائمة. فما الذي يقع في عنوان الذاكرة 0x89034c إذن؟ البيانات السداسية العشرية لها مظهر 00 00 00 40وقد تكون مربكة. لكننا نعلم أننا يجب أن نتوقع أرقام الفاصلة العائمة ، لذلك دعونا نفسر البيانات على هذا النحو: هذا يعني 2.0. وهي قيمة نقطة عائمة منطقية لإصدار تظليل البكسل الذي استخدمته Microsoft بالفعل في لغة التظليل عالية المستوىالتي تتم كتابة تظليل DirectX عليه. و Age 3 هي لعبة DirectX ، على الرغم من أن المنفذ على Mac يستخدم OpenGL. من المنطقي أيضًا أن تكون تظليل البكسل من الإصدار 2.0 مطلوبة في عام 2005 لتمكين المعلمة High ، لذلك نتحرك في الاتجاه الصحيح.

كيف يمكننا حل هذه المشكلة؟ هذه التعليمات مقارنة بأداء مقارنة مع القيمة في xmm0الذي يرد في السطر أعلاه: movss xmm0, dword [eax+0xA2A8]. MOVSS هو أمر "تحريك" خاص لتسجيلات الفاصلة العائمة ، ونكتب 32 بت من العنوان ، وهو نتيجة لتقييم eax + 0xA2A8.

من المفترض أن هذه القيمة ليست 2.0 ، بل 0.0. دعنا نصلحه.

القيام بالقرصنة الحقيقية


أخيرًا ، نحن جاهزون للوصول إلى معايير اللعبة العالية. نريد أن نسير في المسار "الأحمر" ونتخطى كل المنطق باستخدام "نسخة خاطئة من تظليل البكسل". يمكن القيام بذلك عن طريق تمرير المقارنة بنجاح ، أي عن طريق عكس حالة الانتقال ، ولكن لدينا خدعة أخرى: يتكون الرمز بطريقة عند حذف الانتقال سنذهب إلى الطريقة "الحمراء". دعنا فقط نستبدل عملية النقل nopبعملية لا تفعل شيئًا (من المستحيل ببساطة حذف أو إضافة بيانات إلى الملف القابل للتنفيذ لأن الإزاحة ستحدث وسيتكسر كل شيء).

أوصي بالخروج من CFG لهذا ، لأنه بخلاف ذلك يبدأ هوبر بالجنون. إذا تم كل شيء بشكل صحيح ، فعندئذٍ في نافذة Hex سنرى خطوطًا حمراء.



يظهر الأحمر التغييرات التي أجريناها. عند هذه النقطة ، إذا قمت بالدفع مقابل Hopper ، يمكنك ببساطة حفظ الملف. لكنني لم أدفع ، لذلك سأفتح الملف القابل للتنفيذ في Hex Fiend ، والعثور على المنطقة المطلوبة (عن طريق نسخ المنطقة من Hopper إلى علامة التبويب Find داخل Hex Fiend) وتغييرها يدويًا. كن حذرا هنا ، يمكنك كسر كل شيء ، لذلك أوصي بنسخ الملف القابل للتنفيذ المصدر في مكان ما.

بعد القيام بذلك ، ابدأ اللعبة ، وانتقل إلى الخيارات ... وهتافات - يمكننا تحديد "عالية". ولكن لا يمكننا اختيار "متوسط". ولا يمكننا استخدام إعدادات الظل العالي. ومع ذلك ، فإننا نحرز تقدماً!


ما عليك سوى إلقاء نظرة على هذه الانعكاسات الرائعة في الماء!

التحسينات


في الواقع ، يمكنك إصلاح ذلك بأفضل طريقة. نجح الحل الخاص بنا ، ولكن يمكننا أن نجعله يتم تحقيق الشرط بشكل صحيح: جعل اللعبة تعتقد أن بطاقة الرسومات الخاصة بنا تحتوي بالفعل على تظليل من الإصدار 2.0.

كما نتذكر ، تقوم اللعبة بتحميل القيمة على العنوان eax+0xA2A8. يمكنك استخدام هوبر لمعرفة ما تم تسجيله أصلاً هناك. نحتاج إلى العثور على أمر يتم فيه استخدام 0xA2A8 كمعامل المستلم (اخترت 0xA2A8 لأنها قيمة محددة إلى حد ما ، ولا يمكننا التأكد من أن نفس السجل لم يتم استخدامه في مكان آخر). هنا الإضاءة الخلفية لـ Hopper مفيدة جدًا لنا ، لأنه يمكننا فقط النقر على 0xA2A8 والبحث عن الأجزاء الصفراء في CFG.


فوزنا أعلى قليلاً: كما هو متوقع ، نكتب قيمة نوع من تسجيل الفاصلة العائمة. أعترف أنني لا أفهم حقًا ما يحدث قبل هذا (أفضل تخميني: اللعبة تتحقق من إمكانية ضغط النسيج) ، لكن هذا ليس مهمًا بشكل خاص. لنكتب "2.0" ونكمل العمل.

للقيام بذلك ، سنستخدم "تعليمات التجميع" لتطبيق Hopper ، ثم نقوم بنفس التلاعبات في Hex Fiend.




نستخدم MOV بدلاً من MOVSS لأننا نكتب القيمة المعتادة ، وليس القيمة الخاصة لتسجيل النقطة العائمة. بالإضافة إلى ذلك ، فإنه في ترتيب بايت مباشر ، أي مقلوب.

ستلاحظ أن شيئًا غريبًا يحدث: "أكلنا" الفريق jb. حدث ذلك لأن الأمر الجديد يأخذ وحدات بايت أكثر من السابقة ، وكما قلت ، لا يمكننا إضافة أو إزالة البيانات من الملف التنفيذي لحفظ الإزاحات. لذلك ، ليس أمام هوبر خيار سوى تدمير الفريق jb. يمكن أن يصبح هذا مشكلة ، ويمكننا إزالته عن طريق تحريك الأمر لأعلى (بعد كل شيء ، لم نعد بحاجة إلى كتابة قيمة xmm3). سيعمل هذا هنا ، لأنه على أي حال ، نحن نقوم بالتفرع على الطريق الصحيح. سعيد الحظ.

إذا بدأت اللعبة ... فلن يتغير شيء كثيرًا. اقترحت أن سلسلة Intel 9 ليست سريعة بما فيه الكفاية ، لذلك تشكو اللعبة. هذه ليست مشكلة ، لأننا في الواقع نسعى جاهدين من أجل "عالية جدًا".

ما هي أقوى بطاقة عام 2004؟ NVIDIA GeforceFX 6800. لنخدعنا في إقناع اللعبة التي قمنا بتثبيتها.

أسفل فتحة الارانب


نعم ، هذا قسم جديد تمامًا.

نحن نعلم أن اللعبة تستخدم رموز Hex للإشارة إلى بطاقات الرسوم ، وأنها تتلقى معلومات من ملفات البيانات. نحن نعلم أن هذا يجب أن يحدث في الوظيفة التي ندرسها (على الأقل سيكون الأمر غريبًا إذا لم يكن كذلك). حتى نتمكن من العثور على الرمز الذي يفعل ذلك. ولكن لا يزال الأمر صعبًا ، لأننا لا نعرف بالضبط ما الذي نبحث عنه.

لدينا فكرة واحدة: الخيارات تتصرف بغرابة ؛ هناك منخفض / مرتفع ، ولكن لا يوجد متوسط. لذلك ربما يكون هناك رمز آخر يعالج كل هذه "عالية جدًا" و "عالية" و "متوسطة" و "منخفضة". وهو في نفس الوظيفة. لقد كان كثيرًا في CFG ، ويبدو مثيرًا للاهتمام.


يمكننا أن نفترض أن البيانات الأولية يتم تخزينها في نوع ما من XML ، لأنه من المحتمل جدًا ، لأن هناك العديد من ملفات البيانات الأخرى هي XML. و XML هو في الأساس مجموعة من المؤشرات والسمات. لذلك ، فإن الشفرة هنا على الأرجح تتحقق من بعض سمات XML (وفي الواقع ، أدناه هو "المتوقع من المعرف ، مرتفع جدًا ..." ، والذي يشبه إلى حد كبير التحقق من صحة الملف). يمكننا تخيل بنية XML مماثلة تحدد فيها القيم المنطقية جودة التظليل:


تجدر الإشارة إلى أن هذا تخمين تعسفي للغاية. قد يبدو كل شيء مختلفًا قليلاً.

يظهر جزء مثير للاهتمام للغاية على الجانب الأيسر من CFG (بالنسبة لك يمكن أن يكون على اليمين ، ولكن يظهر على اليسار في لقطة الشاشة): نرى نفس الجزء var_CCالمستخدم في الرمز الذي يكتب معرف الجهاز في السجل. أي ebp+var_CC، ربما يشير إلى معرف جهازنا ، 0x2773. الشيء الغريب هو أنه لا توجد سلسلة حرفية في "الاختيار" الأول ، ولكن هذا خطأ هوبر: يحتوي العنوان 0x0089da8e على بيانات سداسية عشرية 69006400 ، والتي تعني في UTF-16 "معرف" (في الواقع ، ربما لم تتمكن هوبر من فهم ذلك لأن UTF16). ونحن نبحث فقط عن معرف.

أتعلم؟ دعونا تشغيل المصحح والتحقق من كل شيء في الواقع.

لعبة تصحيح الأخطاء


افتح نافذة طرفية وقم بتشغيل lldb (فقط اكتب lldb واضغط على Enter). نحتاج أولاً إلى إخبار LLDB باتباع العمر 3 ، وبعد ذلك يمكننا بدء اللعبة عن طريق الاتصال run. تبدأ اللعبة ، ولا نحصل على أي شيء مفيد.


نحتاج الآن إلى إضافة نقطة توقف: لتأكيد افتراضاتنا ، نريد إيقاف التنفيذ عندما نصل إلى الرمز الموضح أعلاه. ليس لدينا رمز مصدر ، ولكن لا يهم: يمكننا تحديد نقطة توقف على عنوان الذاكرة. ولدينا العنوان في الكود. دعنا نضيف إيقافًا إلى مكالمة MOV التي تتلقى "معرف" ، عنوانها هو 0x001d5e68. لإضافة نقطة توقف ، أدخل فقط br set -a 001D5E68. بعد بدء اللعبة ، يتوقف ويعرض LLDB الرمز المفكك (في بنية AT&T ، وليس Intel ، لذلك يتم عكس جميع المعاملات ، لكننا نرى أن هذا هو نفس الرمز). قد تلاحظ أن LLDB في هذه الحالة أكثر ذكاءً من Hopper ؛ يخبرنا أننا نجري عمليات تتعلق بـ XML وإخراج printf.



هل تشعر بأنك مخترق؟

للمضي قدما ، دعنا نأخذ "تعليمات خطوة". أمر قصيرة لهذا
هو ni. نكرر عدة مرات ، نلاحظ أننا عدنا إلى حيث بدأنا. هذه دورة! وهذا منطقي تمامًا: ربما نتكرر حول نوع من XML. في الواقع ، أظهر لنا هوبر هذا - إذا اتبعنا CFG ، فسوف نرى دورة (ممكنة).


هذا يعني:if (*(ebp+var_CC) == *(ebp+var_28)) { *(ebp+var_1D84)=edi }

شرط الخروج هو أن ebp+var_1D84تكون القيمة غير صفرية. ونرى معلمة كود مثيرة للاهتمام في تلك التي أبرزتها أنا var_CC.

دعونا نضيف نقطة توقف على هذه cmpالنقطة وسنكتشفها.



على اليسار: قم بتعيين نقطة توقف على CMP واستمر في التنفيذ. على اليمين ، نراقب السجلات والذاكرة.

نحن ننظر إلى السجلات مع reg rوقيمة الذاكرة مع mem read $ebp-0x28. eaxوفي الواقع يحتوي على 0x2773 ، والقيمة في الذاكرة هي الآن 0x00A0. إذا قمت بتنفيذها عدة مرات thread c، فسوف نرى أن التكرار يحدث عبر معرفات مختلفة بحثًا عن تطابقات. في مرحلة ما ، ستتزامن القيم ، وستخرج الحلقة ، وستبدأ اللعبة. الآن نحن نعرف كيفية إدارتها.

استدعي ملف السجل: حدد كل من الجهاز والشركة المصنعة. ربما في مكان ما هناك دورة مماثلة لأسماء الشركات المصنعة. وفي الواقع ، إنها متشابهة جدًا وتقع في CFG فوق دورتنا مباشرةً. هذه الحلقة أبسط قليلاً ، ونحن نبحث عن سلسلة "البائع".

هذه المرة تتم المقارنة معvar_D0. يتم استخدام هذا المتغير في الواقع كمعرف الشركة المصنعة. إذا وضعنا نقطة توقف هنا eaxوفحصنا كل شيء ، فسوف نرى 0x8086 المألوف عند ، وفي نفس الوقت ، تحدث مقارنة مع 0x10DE. دعونا نكتبها eaxونرى ما سيحدث.



رائع.

أي أن 0x10DE هو NVIDIA. في الواقع ، يمكن للمرء أن يفهم هذا عند دراسة ملف البيانات ، لكنه ليس مثيرًا للاهتمام. السؤال الآن: ما هو معرّف GeforceFX 6800؟ يمكننا استخدام LLDB وفحص كل معرف فقط ، ولكن الأمر سيستغرق بعض الوقت (هناك الكثير منهم ، حاولت العثور على الصحيح). لذلك دعونا نلقي نظرة على تقديم .bar هذه المرة.


لنفترض أن هذا هو "XMB" ، التمثيل الثنائي لـ XML المستخدم في العمر 3.

هذا الملف فوضوي جدًا. ولكن بعد علامات Geforce FX 6800 ، نرى العديد من المعرّفات. على الأرجح ، نحن بحاجة إلى واحد منهم. لنجرب 00F1.

أسهل طريقة لاختبار ذلك هي استخدام LLDB وتعيين نقاط التوقف المطلوبة. سوف أتخطى هذه الخطوة ، ولكن سأقول أن 00F1 جاء (لحسن الحظ).

في هذه المرحلة ، نحتاج إلى إجابة السؤال: "كيف نجعل هذا التغيير دائمًا؟" يبدو أنه سيكون من الأسهل تغيير القيم var_CCوعلى var_D00X00F1 و 0 X10DE. للقيام بذلك ، نحتاج فقط إلى الحصول على مساحة للرمز.

قد يكون الحل البسيط هو استبدال أحد مكالمات سجل السجل بـ NOP ، على سبيل المثال ، استدعاء نظام فرعي. هذا سيحررنا عدة عشرات من البايتات ، وهذا أكثر من اللازم. دعنا نختار كل هذا ونستبدلها بـ NOP. ثم نحتاج فقط إلى كتابة المعلومات باستخدام متغيرات MOV: المجمع mov dword [ebp+var_CC], 0xF1و mov dword [ebp+var_D0], 0x10DE.



قبل وبعد

تشغيل اللعبة. أخيرًا ، حققنا شيئًا: يمكنك الاختيار من بين منخفضة أو متوسطة أو عالية ، بالإضافة إلى تمكين المعلمات العالية للظلال.


لكننا ما زلنا لا نستطيع تمكين مرتفع للغاية ، وهذا أمر محزن. ماذا يحدث؟


آه ، فهمت.

كما اتضح ، يجب أن يدعم Geforce FX 6800 تظليل الإصدار 3.0 بكسل ، وقمنا بتعيين الإصدار 2.0 فقط. الآن أصبح من السهل علينا إصلاحها: فقط اكتب 3.0 الفاصلة العائمة ebp+0xA2A8. هذه القيمة هي 0x40400000.

أخيرًا ، لم تعد اللعبة متقلبة ، ويمكننا الاستمتاع بإعدادات عالية جدًا.


غريب ، لكنه يبدو مختلفًا تمامًا. الألوان أقل حيوية ، وقد ظهر الضباب المعتمد على النطاق. هناك أيضًا مشكلة صغيرة في تعارض الظل (وهي أيضًا في لقطات الشاشة أعلاه ، ويرجع ذلك إلى معلمات الظل العالية ، وليس جودة التظليل) ، والتي لم أتمكن من حلها بعد.

وهذه نهاية رحلتنا ، شكرا للقراءة.

بالإضافة إلى ذلك ، سأقدم أمثلة على كيف تبدو كل من المعلمات في اللعبة ، لأن جميع لقطات الشاشة الموجودة على الإنترنت رهيبة أو غير مكتملة.

الرسومات على Medium مقبولة تمامًا ، ولكنها تعاني من نقص في الظلال. بقدر ما أستطيع أن أقول ، يضيف High High في معظمه LUT مختلفًا تمامًا (يمكن العثور على تفسير جيد لهذا المصطلح في قسم درجات اللون في هذه المقالة.) ، الضباب في المسافة ، وربما حتى نموذج إضاءة مختلف تمامًا؟ الصورة مختلفة جدا وهي غريبة نوعا ما.





من الأعلى إلى الأسفل: عالي جدًا ، مرتفع (مع خيارات ظل عالية) ، متوسط ​​(فقط مع تمكين الظل) ، منخفض (مع تعطيل الظل).

روابط مفيدة أخرى


تحتوي المدونة التي قمت بربطها أعلاه بتحليل رائع لخطوط الأنابيب الحديثة: http://www.adriancourreges.com/blog/

Rate 0 AD هي لعبة RTS مفتوحة المصدر من نفس النوع: https://play0ad.com . إنها تحتاج إلى مطورين.

إذا كنت تريد معرفة المزيد عن تنسيق XMB ، يمكنك قراءة الكود الخاص به في 0 م . لم أتحقق من ذلك ، لكنني متأكد تقريبًا من أن هذا هو نفس التنسيق ، لأن الشخص الذي كتب وحدة فك ترميز XMB لـ Age 3 on Age of Empires heaven قام أيضًا بتنفيذ هذه الملفات في كود المصدر 0 AD في عام 2004. لذلك سيكون هذا درسًا ممتعًا في علم الحفريات البرمجية. شكرا لكم على كل عمل يكروش.

أتذكر بالضبط أنني قرأت برنامجًا تعليميًا ممتازًا حول استخدام Hopper ، ولكن الآن لا يمكنني العثور على الرابط. إذا كان أي شخص يعرف ما أتحدث عنه ، فقم بإفلات الرابط.

في النهاية ، أود أن أذكر مشروع Cosmic Frontier: إعادة إنتاج لسلسلة Escape Velocity الكلاسيكية (المزيد من Override ، ولكنه متوافق أيضًا مع Nova). هذه لعبة مذهلة ، ومن المحزن للغاية أن قلة من الناس يعرفونها. أطلق المبدعون الآن حملة على Kickstarter ، ولدى المطور الرئيسي مدونة مطورة مثيرة للاهتمام للغاية ، والتي تتحدث عن استخدام Hex Fiend لعكس تنسيقات بيانات الهندسة للعبة الأصلية. هذه قراءة عظيمة إذا كنت تعتقد أن مقالتي كانت مجنونة. ثم في إحدى المشاركات:

  • أطلقنا محاكي Mac الكلاسيكي لاستخدام واجهات برمجة التطبيقات القديمة التي عفا عليها الزمن لقراءة ملف بيانات مشفر.
  • عكس التشفير الهندسي من كود اللعبة
  • استخدموا اختراق نظام الملفات للوصول إلى نفس البيانات على جهاز Mac الحديث.

نعم ، هؤلاء أشخاص متحمسون حقًا ، وآمل أن يكتمل مشروعهم بنجاح ، لأن EV Nova هي لعبتي المفضلة.

All Articles