ברוכים הבאים לאתר תחרויות קודגורו! › פורומים › אקסטרים › על CALL FAR וחולשתו
- This topic has 11 תגובות, 5 משתתפים, and was last updated לפני 17 שנים, 9 חודשים by HutsHuts.
-
מאתתגובות
-
25 בפברואר 2007 בשעה 09:28 #76956HutsHutsמשתתף
תחילה הסבר קצר על CALL FAR
עושה את שלושת הדברים הבאים CALL FAR כפי שנאמר כבר בפורום, הפקודה :
1. (SS) למחסנית האישית CS דוחפת את
2. (SS) למחסנית האישית IP דוחפת את3. בהתאם לפרמטרים שהיא מקבלת(קופצת לשם) CS,IP משנה את
גודלם 2 בתים CS,IP
כלומר נכתבים 4 בתים למחסנית האישית!!
לכן, אם נעדכן את הזירה להיות המחסנית האישית, השורד יכתוב את הבתים אל הזירה ובכך תתבצע תקיפה ממש מהירה.
מבצע, לא ישנה את מיקום השורד. CALL FAR כמו כן יש לדאוג שהקפיצה שהדוגמא לשורד פשוט המשתמש בפקודה זו והורג את עצמו לבסוף:
@start:
add ax,@call_far-@startmov ds,es
mov bx,50h
mov [bx+2],cs
mov [bx],axmov ss,cs
mov sp,ax
@call_far:
call far [bx]שורדים קצת יותר מתוחכמים משתמשים בטכניקה זו ומשלבים אותה עם טכניקות אחרות כמו לתקוף לא רציף, או לדאוג לכך שהשורד לא יהרוג את עצמו אלה יכתוב על עצמו פקודה חוקית אשר תגרום לו לכתוב את עצמו למקום אחר ולהמשיך לתקוף משם.
אולם, יש לזכור ששורדים המשתמשים בטכניקה זו מפזרים על המסך את המיקום שלהם!
השורד המנצח של השנה השתמש בעובדה הזו (נפרסמו בהמשך)
בהודעה הבאה נפרסם דוגמא לשורד פשוט שמחפש והורג Call far הפצצות של
25 בפברואר 2007 בשעה 09:52 #78375HutsHutsמשתתףיש לבדוק זאת CALL FAR כיוון שלא ניתן להניח שכל נקודה במסך הותקפה ע"י
תחילה הבהרה קצרה,
אם נכתוב באמצעות הפקודה STOSW
ES:DI יכתב לתוך AX
אך הכתובת האמיתית השמורה במחשב תהיה:
ES*10+DIהוא 1000 CS ערכו ההתחלתי של
(בהקסדצימלי)
לכן כדי שהכתובת שאנו קוראים תהיה הגיונית, הכתובת השמורה במחשב צריכה להיות בין 10000 לבין 20000 כלומר
כלומר ספרת העשרות אלפים צריכה להיות 1יש לשים לב שחייבת להתבצע בדיקה, אחרת השורד ינסה לתקוף מקום שלא בזירה, ויעוף
ולבסוף השורד:
mov bx,ax
inc cx
@loop:
add bx,9
les di,[bx]
;es,di gets the value in bx
sub di,2
mov dx,es
mov ax,010h
mul dx
;dx:ax equals to 10*es
add ax,di
;now if the carry flag is true if ax+di>10000
jnc @glisha
inc dx
@glisha:
;checks if 10000<es*10+di<20000
cmp dx,1
jne @loop
@sa:
mov ax,0CCCCh
stosw
jmp @loopשני הקבצים קומפלו באמצעות A86
זוהי הגרסה הראשונית ביותר לשורד הוצהוץ, השורד מכיל עוד כמה אסטרטגיות שיוסברו בהמשך
25 בפברואר 2007 בשעה 11:21 #78374HutsHutsמשתתףלאחר שעות רבות של עבודה וכתיבת הערות, צוות הוץהוץ גאה להציג את קוד המקור השורד HutsHuts בגרסאתו שלאחר העדכון (ניתן לקימפול בעזרת האסמבלר a86 שמופיע באתר).
כמה הערות לגבי השורד:
1. האנגלית שלנו סבירה, אבל לא מדהימה, מצטערים על שגיאות הכתיב והתחביר.
2. השורד במתכונתו המופיעה כאן אינו זהה לגמרי שורד שנשלח בתחרות. בתחרות היו אלה שני שורדים שהעתיקו כל אחד את מחצית הקוד לסגמנט המשותף כדי לבצע העתקה מהירה יותר. בנוסף לכך, גרסה זו כתובה בצורה ידידיותית יותר מאשר הגרסה המקורית (כדי להקל על הבנתה).
3. ניסינו ככל האפשר להסביר כל פעולה ושורה בקוד בעזרת תיעוד, אבל עדיין קשה מאוד להבין אותו, בהצלחה!
4. ד"א, יש גם שורדים שמשתמשים בcallfar ועדיין מנצחים את השורד הזה, תשברו ת'ראש לבד (לא רק bimp ו-cannon)להלן הקוד המתועד:
25 בפברואר 2007 בשעה 11:37 #78373HutsHutsמשתתףקוד המקור זמין להורדה בקישור:
http://www.sendspace.com/file/layuvv25 בפברואר 2007 בשעה 12:22 #78372AcePaceמשתתףThanks for the interesting look, well, good to know for next year.
25 בפברואר 2007 בשעה 13:36 #78371SpiritusמשתתףYou know, I think I just understood your team name. Hot Shots, is that it?
25 בפברואר 2007 בשעה 22:53 #78369DL!משתתףכל הכבוד, ממש עבודה יפה.
26 בפברואר 2007 בשעה 08:29 #78368HutsHutsמשתתףלא בדיוק, השם הוץהוץ נוצר למעשה במשחק ארץ עיר. אחד מחברי הקבוצה היה צריך לחשוב על חיה באות ה' ולא הצליח, אז הוא פשוט המציא כזו וקרא לה "הוץהוץ".
אבל גם הפרוש שלך מקורי…
28 בפברואר 2007 בשעה 07:49 #78366Spiritusמשתתף1. Your code didn't work, maybe it's just for me^^
2. Why didn't you use repe scasw? I think it's faster.
I wrote something like yours that uses repe scasw, and doesnt check byte by byte, but word by word, and then just writes to both possibilities(or actually 4, to eliminate those nasty DIMEs).
Here it is:%define Edge 128
%define Space 640;128
%define SSWrongUp 300
%define SSWrongDown 300
%define jumpOffset 17*0x100@code:
mov cx, (@DownEnd-@UpBeg)/2
mov si, ax
add si, @UpBeg-@code
rep movswadd si, @WrongUpBeg-@DownEnd
mov di, SSWrongUp
mov cx, (@WrongUpEnd-@WrongUpBeg+1)/2
rep movswxor si, si
mov cx, es
mov ds, cx
mov cx, cs
mov es, cx
mov ss, cxxor cx, cx
mov di, ax
add di, @UpBeg-@code
mov ax, 0x1212
movsw
jmp @UpBeg@UpBeg:
;Copy us
movsw
movsw
mov cl, (@MidEnd-@UpBeg-6)/2
rep movswmov sp, di
add sp, 2mov cl, Edge/2
sub di, @MidEnd-@UpBeg+Space
repe scasw
pushf
add di, @MidEnd-@UpBeg+Space-Edge
popf
jz @UpEnd;Problem found
mov dx, di ;Store position found problem
sub dx, (@MidEnd-@UpBeg+Space-Edge)
mov si, SSWrongUp ;Copy a different part from stack
add di, cx
add di, cx ;We add it twice, because scasw scans cx number of WORDS(So, number of bytes=cx*2).
mov bp, 0x10000-jumpOffset
nop@UpEnd:
@MidStart:
movsw
@MidEnd:@DownBeg:
movsw
movsw
mov cl, byte (@DownEnd-@DownBeg-6)/2
rep movsw
mov cl, Edge/2
add di, Space-Edge
repe scasw ;Scan upper edge, compare es:[di] with ax
pushf
sub di, Space+(@DownEnd-@UpBeg)
xor si, si
movsw
popf
jz @UpBeg;Problem found
mov dx, di ;Store position found problem
add di, @DownEnd-@UpBeg-2
add dx, Space+(@DownEnd-@UpBeg)-2
mov si, SSWrongDown ;Copy a different part from stack
add di, cx ;cx is what the repe scasw needed to perform before di would point to @UpBeg
add di, cx ;We add it twice, because scasw scans cx number of WORDS(So, number of bytes=cx*2).
mov bp, jumpOffset
movsw@DownEnd:
@WrongUpBeg:
movsw
movsw
mov cl, (@UpStop-@WrongUpBeg-6)/2
rep movsw
add di, bp
mov bx, di
movsw
jmp bx
nop@UpStop:
movsw
movsw
mov cl, (@WrongUpEnd-@UpStop-6)/2
rep movswmov bp, dx
sub bp, 2mov cl, 4
@mLoop:
mov sp, bp
pop bx
pop simov ax, 0x10
mul si
add ax, bxmov sp, ax
mov ax, 0xCCCC
push ax
inc bp
loop @mLoopmov ax, 0x1212
mov cl, Edge/2
rep stosw
add di, @DownEnd-@UpBeg+2*(Space-Edge)
mov cx, Edge/2
rep stoswsub di, @DownEnd-@UpBeg+Space
xor si, si
movsw
jmp @WrongUpEnd+Space@WrongUpEnd:
@end:
28 בפברואר 2007 בשעה 11:24 #78365HutsHutsמשתתף1. הקוד שלך גם לא התקמפל לי, איזה אסמבלר השתמשת?
2. בקשר ל REPE SCASW
זה אכן יהיה מהיר יותר, אבל בשורד שלנו החלטנו לשים את הדגש יותר על פגיעות הקוד, ופחות על מהירות השורד.
לשורד שלנו 2 שדות בגודל 2 בתים, וכל 100 תורות בערך השורד מבצע בהם בדיקה האם השתנו…
צריך לזכור שלהיות מהיר יותר זה לא בהכרח טוב יותר
בלופ הראשי, בו השורד בודק את השדות עד לשינוי אחד מהם, פגיעות השורד היא בערך 1.1 בתים
אולם לאחר הפגיעה באחד השדות, השורד עובר ללולאת ההריגה של ה CALL FAR
ושמה, פגיעות השורד היא כ-20 בתים ולכן אין מה למהר…
אם תריץ את השורד שלך נגד הרבה שורדים הכותבים
CALL FAR לא רציף
תגלה שהשורד לא יהיה חזק ואף יפסיד בהרבה
השורד שלנו איטי ולכן אם תריץ נגד שורדים המשתמשים ב CALL FAR
ומעתיקים את עצמם מהר לדוגמא כל 256 פקודות, השורד לא יספיק להרוג אותם לעולם
זה כמובן היה החשש שלנו וזו הסיבה שלא שלחנו את השורד המקורי כבר בהתחלה28 בפברואר 2007 בשעה 13:10 #78364Spiritusמשתתף1. lol!!! I used NASM, but it's funny, the survivors dont like each other apperantly:-)
btw, I see you used xchg between segments in your code, is it valid? I don't think the emulator supports it, but I can be mistaken. It just doesn't compile(actually, it doesn't assemble^^).
2. Yes, I see your point. I ran myn against Ninja, DIME 3someb & Zeus, and it scored jsut like ninja(both kicked the others guys asses^^).
You know, our survivor, ninja, copied itself every 256*8 opcodes, not 256… if we could only… bummer… no matter^^
And please answer me about the xchg, cause I want to run your survivor^^28 בפברואר 2007 בשעה 14:03 #78363ilum_shemמשתתףזה לא מטופל במנוע, אלא בשלב הקומפילציה.
הוראת xchg בין סגמנטים מתורגמת למעשה להחלפה בעזרת המחסנית.למשל הקוד: xchg ds,ss
יתורגם בפועל ל:
push ds
push ss
pop ds
pop ss -
מאתתגובות
- יש להתחבר למערכת על מנת להגיב.