┐───────────────────────┌
                                                      │       ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄
                                                      │       █   █ █ █ █   █ │
                                                      │       ▀▀▀▀█ █ █ █   █ │
                                                      │     ▄     █ █   █   █ │
                                                      │ ▄▄▄▄▄                 │
                                                      │ █   █                 │
                                                      │ █   █                 │
                                                      │ █▄▄▄█                 │
                                                      │ ▄   ▄                 │
                                                      │ █   █                 │
                                                      │ █   █                 │
                                                      │ █▄▄▄█                 │
                                                      │ ▄▄▄▄▄                 │
                                                      │   █                   │
דיסאסמבלי-שגוי פולימורפית                             │   █                   │
~ S01den                                              ┘───█───────────────────└

נכתב באהבה ע"י S01den, מהצוות של tmp.out !
mail: S01den@protonmail.com

[ תורגם ע"י Lit3r4lly ]	

--- הקדמה ---

כשכתבתי את [0]Lin32.Bakunin, תהיתי לעצמי איך לעשות את זה יותר מעניין 
מסתם וירוס שכתוב ב-MIPS ומדפיס קצת שטויות. אני פשוט רציתי לעצבן רברסרים.
ואז נזכרתי בטכניקת ה-False-Disassembly שמימשתי בחלק מה-crackme's שלי.

בגלל שפולימורפיזם זה מגניב, רציתי להבין אם זה אפשרי ליצור משהו מעניין בעזרת ערבוב של זה יחד עם
טכניקת ה-False-Disassembly.

התשובה היא כן, וקראתי לשיטה הזו (אני לא יודע אם זו טכניקה מקורית שלי או לא), שיטת
ה-"דיסאסמבלי-שגוי פולימורפית" או בפשטות "פולימורפיזם מזוייף".

--- איך False-Disassembly עובד? ---

הטכניקה הזו היא די פשוטה להבנה ולמימוש, ואני גיליתי עליה במסמך המפורסם של [1]Silvio Cesare על
טכניקות anti-debugging ורברסינג בלינוקס.
פשוט צריך לשים כמה בייטים רנדומליים שבד"כ מייצגים התחלה של הוראה מסויימת (Opcode) לפני קטע הקוד,
כמו בדוגמה הבאה:

-------------------- נחתך-כאן --------------------
hey:                      hey:
   xor %rbx, %rbx             .ascii "\x48\x31"
   jmp yo            ====>     xor %rbx, %rbx
                               jmp yo
---------------------------------------------------
עכשיו, אם נסתכל על שני קטעי הקוד שעברו disassemble, אנחנו נקבל משהו כזה (radare2 מה לעזעזאל?):
-------------------- נחתך-כאן --------------------
;-- hey:
0x00401002      4831db         xor rbx, rbx
0x00401005      eb02           jmp 0x401009

                     ||
                     \/
;-- hey:
0x00401002      48314831       xor qword [rax + 0x31], rcx
0x00401006      dbeb           fucomi st(3)
0x00401008      026631         add ah, byte [rsi + 0x31]

---------------------------------------------------
מדוע הדיסאסמבלר מתנהג בצורה הזו?

ובכן, \x48\x31 הם בד"כ ייצוג של ההתחלה של הוראת [2]xor, והבייטים שבאים לאחר מכן מייצגים לרוב את
האוגרים שאיתם האופרציה עובדת.

אז למעשה הבייטים ה"מאתחלים" הללו שהוספנו נדבקים לבייטים העוקבים, שהם למעשה בעצמם בייטים "מאתחלים", וכך
הדיסאסמבלר מפרש את אותם בייטים מאתחלים באמת, כבייטים המייצגים את הרגיסטרים ובגלל זה מופיע לנו זבל במקום ההוראות הרצויות.

לכן, כדי שנוכל להריץ קוד שבנוי בצורה שכזו, אנחנו חייבים לקפוץ מעל הבייטים שהוספנו.
זה אמור להיות משהו כזה:
-------------------- נחתך-כאן --------------------
_start:
jmp hey+2

hey:
   .ascii "\x48\x31"
   xor %rbx, %rbx
   jmp yo
---------------------------------------------------
--- הקוד המלא ---

עכשיו, דמיינו שאתם יכולים רנדומלית לשנות את כל הבייטים הללו שמייצרים את ה-false-disassembly בכל
אופרציה, וכך גם הקוד שעבר disassembly ישתנה גם ולכן הרברסר
שיחקור את הקוד, יחשוב שהוא פולימורפי בזמן שרק מספר בייטים בודדים שונו.

וכעת, ללא דיחוי נוסף, הקוד המלא.
----------- נחתך כאן -----------
# build cmd: as Linux.FakePolymorphism.asm -o fakePoly.o ; ld fakePoly.o -o fakePoly

# this code is a fake polymorphic example, feel free to try/use/whatever it!
# It grabs itself its code, modify the fake-disassembly bytes and put the result
# on the stack.

.text
  .global _start

_start:
jmp true_start+2 # jump over the fake-disassembly bytes

true_start:
.ascii "\x48\x31"  # fake-disassembly bytes
xor %rbx, %rbx
jmp get_code+2 # jump over the fake-disassembly bytes

get_code:
  .ascii "\x66\x31"  # fake-disassembly bytes
  call get_rip
  sub $0x10 ,%rax # 0x10 is the number of bytes between _start abd this instruction
  movb (%rax,%rbx), %al
  movb %al, (%rsp,%rbx)
  inc %rbx
  cmp $0x54, %rbx  # 0x54 is the total size of this code
  jne get_code+2

  # Pseudo RNG thanks to the time stamp counter
  rdtsc
  xor $0xdead, %rax
  mov %ax, 2(%rsp)
  xor $0xbeef, %rdx
  mov %ax, 9(%rsp)

  mov $60, %rax
  mov $0, %rdi
  syscall # sys_exit

get_rip:
  mov (%rsp), %rax
  ret
----------------------------
--- סיכום ---

אני מקווה שנהנתם מהמאמר הזה ושתנסו לממש את הטכניקה הזו בוירוסים והcrackme's שלכם!

ביחד עם sblip, כתבנו וירוס פולימורפי  (Lin64.Eng3ls, תעיפו מבט על המאמר והקוד !) שמשתמש בטכניקה
הזו בשביל לערפל את הקוד של המפענח של עצמו.

הקוד של המפענח:
------- נחתך-כאן -------
  pop rcx
  jmp jmp_over+2
  jmp_over:
    db `\x48\x31` ; false disassembly
    mov al,0x00
    xor rdx, rdx

  decoder:
    jmp jmp_over2+2

    jmp_over2:
      db `\xb8\xd9` ; false disassembly
      mov dl, byte [r12+rdi]
      cmp rdi, STUB_SIZE-1
      jna no_decrypt

      jmp jmp_over3+2
      jmp_over3:
        db `\x48\x81` ; false disassembly
        xor dl, al

  no_decrypt:
    mov byte [rbx+rdi], dl
    inc rdi
  loop decoder
-------------------------
והנה מספר מפענחים שהבאתי מבינארים זדוניים שונים שעברו [3]disassemble, בוא נראה את הטריק בפעולה:
1. 
  0x0c003f46      59             pop rcx                 
  0x0c003f47      eb02           jmp 0xc003f4b           
  0x0c003f49      00d6           add dh, dl              
  0x0c003f4b      b06d           mov al, 0x6d            
  0x0c003f4d      4831d2         xor rdx, rdx            
  0x0c003f50      eb02           jmp 0xc003f54           
  0x0c003f52      1aca           sbb cl, dl              
  0x0c003f54      418a143c       mov dl, byte [r12 + rdi]
  0x0c003f58      4881ff870000.  cmp rdi, 0x87           
  0x0c003f5f      7606           jbe 0xc003f67           
  0x0c003f61      eb02           jmp 0xc003f65           
  0x0c003f63      c0d630         rcl dh, 0x30            
  0x0c003f66      c28814         ret 0x1488              
  0x0c003f69      3b48ff         cmp ecx, dword [rax - 1]
  0x0c003f6c      c7             invalid                 
  0x0c003f6d      e2e1           loop 0xc003f50          

2.
  0x0c003fe6      59             pop rcx
  0x0c003fe7      eb02           jmp 0xc003feb
  0x0c003fe9      ce             invalid
  0x0c003fea      0ab0a34831d2   or dh, byte [rax - 0x2dceb75d]
  0x0c003ff0      eb02           jmp 0xc003ff4
  0x0c003ff2      39cb           cmp ebx, ecx
  0x0c003ff4      418a143c       mov dl, byte [r12 + rdi]
  0x0c003ff8      4881ff870000.  cmp rdi, 0x87
  0x0c003fff      7606           jbe 0xc004007
  0x0c004003      0e             invalid
  0x0c004004      0a30           or dh, byte [rax]
  0x0c004006      c28814         ret 0x1488
  0x0c004009      3b48ff         cmp ecx, dword [rax - 1]
  0x0c00400c      c7             invalid
  0x0c00400d      e2e1           loop 0xc003ff0
התוצאות שונות מאוד מהקוד המקורי.

--- הערות ורפרנסים ---
[0] https://vx-underground.org/papers/VXUG
      /Exclusive/Bakounin/Writing_virus_in_MIPS_assembly_for_fun.txt
[1] http://www.ouah.org/linux-anti-debugging.txt // Silvio המסמך של
[2] https://www.felixcloutier.com/x86/xor
[3] radare2 עם