كيفية قراءة وكتابة تسجيلات إشارات x86 مباشرة؟

StackOverflow https://stackoverflow.com/questions/1406783

  •  05-07-2019
  •  | 
  •  

سؤال

مما قرأته، يبدو أن هناك 9 أعلام مختلفة.هل من الممكن قراءتها/تغييرها مباشرة؟أعلم أنه يمكنني معرفة على سبيل المثال ما إذا تم تعيين علامة الصفر بعد تنفيذ تعليمات cmp/jmp، لكنني أسأل عما إذا كان من الممكن القيام بشيء مثل

mov eax, flags

أو شيء ما.

وأيضاً بالنسبة للكتابة هل من الممكن ضبطها باليد؟

هل كانت مفيدة؟

المحلول

يمكن تعيين بعض العلامات أو مسحها مباشرةً باستخدام تعليمات محددة:

لقراءة وكتابة علامة الصفر والحمل المساعد والتكافؤ وأعلام الحمل، يمكنك استخدامها لاهف لتحميل البتات الثمانية السفلية (هذه الأعلام الخمسة بالإضافة إلى 3 بتات غير محددة) في سجل AH، ويمكنك استخدام SAHF لتخزين تلك القيم من AH مرة أخرى في سجل العلامات.

يمكنك أيضًا استخدام دفع تعليمات لدفع الأعلام على المكدس، وقراءتها وتعديلها على المكدس، ثم استخدم بوبف1 تعليمات لتخزينها مرة أخرى في سجل الأعلام.

لاحظ أنه لا يمكنك تعيين إشارات VM وRF باستخدام POPF - فهي تحتفظ بقيمها السابقة.وبالمثل، يمكنك فقط تغيير مستوى امتياز الإدخال/الإخراج عند التنفيذ عند مستوى الامتياز 0، ولا يمكن تغيير علامة المقاطعة إلا عند التنفيذ على مستوى امتياز على الأقل بنفس امتياز مستوى امتياز الإدخال/الإخراج.


الحاشية السفلية 1:

لاحظ أن popf بطيء جدًا على وحدات المعالجة المركزية الحديثة؛يرى أغنر فوج دليل التحسين وجداول التعليمات.إنه مشفر بشكل صغير لأنه في وضع kernel قادر على تغيير مستوى امتياز IF وAC وIO.نحن نعاني من العقوبة بغض النظر عن الوضع الموجود على وحدات المعالجة المركزية الحالية لأن أجهزة فك التشفير ليست حساسة للوضع.

إذا أمكن، استخدم lahf/sahf بدلاً من Pushf/popf للأداء، أو احفظ علامة واحدة تهمك مثل setc al ثم في وقت لاحق add al, 255 لتعيين CF = (AL!=0).أو setnc al / sub al, 1 أو أيا كان.التسلسلات لتعيين أو مسح SF أو OF استنادًا إلى سجل 0 أو 1 هي أيضًا واضحة ومباشرة، مع/بدون قلب العلامة.

نصائح أخرى

يمكنك استخدام تعليمات Pushf وPopf التي ستدفع الأعلام إلى المكدس، ويمكنك تعديلها ثم إخراجها مرة أخرى.

إذا كنت تحتاج فقط البايت أقل من أعلام تسجيل (الذي يحتوي على SF، ZF، AF، PF، CF)، ثم هناك غريبة لكن مريحة LAHF التعليمات (ها ها ها)، الذي يحمل أسفل 8 بت ل مسجل الأعلام في ه، ونظيرتها SAHF لتخزين ه في الأعلام.

للعلم حمل على وجه التحديد، إلى x86 يقدم CLC، STC وCMC، لمسح، تعيين، وتكمل علم حمل، على التوالي.

وأبسط طريقة يستخدم <م> pushf / popf .

إذا كنت ترغب في نقل eflags إلى eax، استخدم رمز أدناه.

pushf                  # push eflags into stack
pop %eax               # pop it into %eax

SETcc

تعد عائلة التعليمات هذه طريقة أخرى لمراقبة بعض الأعلام/مجموعة الأعلام.

يقوم بتعيين قيمة البايت بناءً على العلامات الفردية.

على سبيل المثال، ل CF:

stc
setc al
; al == 1

clc
setc al
; al == 0

قابل للتشغيل على GitHub مع التأكيدات.

جي سي سي

تعد عائلة التعليمات هذه بالطبع إمكانية أخرى لبعض الأعلام، ويمكن استخدامها للتنفيذ SETcc:

jc set
mov al, 0
jmp end
set:
mov al, 1
end:

قابل للتشغيل على GitHub مع التأكيدات.

  • لهف:يقوم بتحميل إشارات الحالة إلى AH
  • نسخ البايت المنخفض لسجل EFLAGS بما في ذلك إشارات Sign وZero وCarry.
  • احفظ نسخة من الأعلام في متغير لحفظها

    .data
     saveflags BYTE ? 
    .code 
     lahf ; load flags into AH 
     mov saveflags,ah ; save them into a variable 
    
  • صحف:يخزن AH في أعلام الحالة

  • نسخ AH إلى البايت المنخفض لسجل EFLAGS
  • استرداد قيمة العلامات المخزنة سابقًا

    .code
     mov ah, saveflags ; load save flags into AH 
     sahf ; copy into flags register 
    
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top