รหัสเครื่อง x86 (32 บิต), 256 ไบต์
เมื่อฉันพิมพ์รหัสของฉันบนคอนโซลเพจรหัสของฉัน 437 ฉันเห็นสิ่งต่อไปนี้:
j XI a I a I a jbZ Q fiQ Gf a f Q I a I a I a I a h hisZ Q I a I a I a I a hBP Z Q iQ
y Q a I a I a I a h thaZ Q I a I a I a Ih ButZ Q a I a I a I a fhu fZf Q iQ g S Q a I a I a I a hsaidZ Q I a I a I a I a hshe Z Q I a I a I a I a hAnd Z Q TZBX b
สิ่งนี้มีอักขระช่องว่างบางส่วนดังนั้นนี่คือรหัสเดียวกันเมื่อฉันแทนที่อักขระแท็บทั้งหมดด้วย→
และอักขระช่องว่างที่ไม่แตก (ด้วยรหัส 255) โดย*
:
j XI a I a I a jbZ→Q fiQ Gf a f→Q I a I a I a I a h hisZ→Q I a I a I a I a hBP Z→Q iQ →→y →Q a I a I a I a h thaZ→Q I a I a I a Ih ButZ→Q a I a I a I a fhu fZf→Q iQ g→S →Q a I a I a I a hsaidZ→Q I a I a I a I a hshe Z→Q I a I a I a I a hAnd Z→Q TZBX*b*
hexdump:
6a 20 58 49 20 61 20 49 20 61 20 49 20 61 20 6a
62 5a 09 51 20 66 69 51 20 47 66 20 61 20 66 09
51 20 49 20 61 20 49 20 61 20 49 20 61 20 49 20
61 20 68 20 68 69 73 5a 09 51 20 49 20 61 20 49
20 61 20 49 20 61 20 49 20 61 20 68 42 50 20 20
5a 09 51 20 69 51 20 09 09 79 20 09 51 20 20 61
20 49 20 61 20 49 20 61 20 49 20 61 20 68 20 74
68 61 5a 09 51 20 49 20 61 20 49 20 61 20 49 20
61 20 49 68 20 42 75 74 5a 09 51 20 20 61 20 49
20 61 20 49 20 61 20 49 20 61 20 66 68 75 20 66
5a 66 09 51 20 69 51 20 67 09 53 20 09 51 20 20
61 20 49 20 61 20 49 20 61 20 49 20 61 20 68 73
61 69 64 5a 09 51 20 49 20 61 20 49 20 61 20 49
20 61 20 49 20 61 20 68 73 68 65 20 5a 09 51 20
49 20 61 20 49 20 61 20 49 20 61 20 49 20 61 20
68 41 6e 64 20 5a 09 51 20 54 5a 42 58 ff 62 ff
คำอธิบายบางอย่างเกี่ยวกับวิธีการทำงาน:
คำแนะนำที่เป็นประโยชน์คือ:
push imm8
, push imm16
และpush imm32
ตามมาด้วยการpop
สร้างค่าคงที่ สิ่งนี้สามารถสร้างศูนย์ (ในah
) เมื่อกดไบต์ ( imm8
)
and [ecx+32], ah
- สมมติว่าอา = 0 ชุดนี้ไบต์เป็นศูนย์ มันเพิ่งเกิดขึ้นที่ความยาวของสายอักขระออกเป็น 32 ดังนั้นโค้ดจะเติมบัฟเฟอร์ตั้งแต่ต้นจนจบ
or [ecx+32], edx
- สมมติว่าเอาต์พุตไบต์ถูกตั้งค่าเป็นศูนย์สำเนานี้edx
(4 ไบต์) เป็นเอาต์พุต ฉันใช้ตัวแปรกับdx
แทนedx
ใกล้ถึงจุดสิ้นสุดของบัฟเฟอร์เพราะไม่ควรเขียนเกินกว่าบัฟเฟอร์เอาต์พุต ข้อ จำกัด ของโค้ดทำให้ไม่สามารถเขียนไบต์เดียวด้วยวิธีนี้!
imul edx, [ecx+32], whatever
- นี่เป็นแนวคิดหลักในการต่อสู้ พอเอนโทรปีพอ[ecx+32]
และจำนวนอะไรก็สามารถสร้างผลลัพธ์ใด ๆ ฉันใช้มันเพื่อสร้างค่าที่ต้องการ 2 หรือ 3 ไบต์ ภาวะแทรกซ้อนบางอย่างคือเมื่อเขียนไปยังเอาต์พุตมันจะต้องทำตรรกะOR
ด้วยสิ่งที่มีอยู่แล้ว บางครั้งสิ่งนี้ทำให้มันจำเป็นต้องศูนย์ความจำอีกครั้ง
- ตัวแปรของ
jmp
คำสั่งถูกใช้เพื่อส่งคืน ฉันเลือกเพราะการเข้ารหัสของมันคือ0xff
ซึ่งสอดคล้องกับพื้นที่ไม่แตกหักในเพจรหัส 437 บิตของการยืดในกฎ แต่อย่างอื่นฉันคิดว่างานเป็นไปไม่ได้ ...
แอสเซมบลีซอร์สโค้ดพร้อมกับโปรแกรม C ที่รัน (ใช้ไวยากรณ์ Visual Studio):
#include <stdio.h>
__declspec(naked) void __fastcall doit(char* buf)
{
__asm {
push ' '
pop eax
dec ecx
and [ecx+32], ah // terminating 0 byte
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
push 98
pop edx
or [ecx+32], edx
imul dx, [ecx+32], 26183
and [ecx+32], ah
or [ecx+32], dx // two bytes: [.']
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
push 'sih '
pop edx
or [ecx+32], edx // 4 bytes: [ his]
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
push 538988610
pop edx
or [ecx+32], edx
imul edx, [ecx+32], 544803081
or [ecx+32], edx // 1 junk byte and 3 good bytes: (t's)
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
push 'aht '
pop edx
or [ecx+32], edx // 4 bytes: [ tha]
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
push 'tuB '
pop edx
or [ecx+32], edx // 1 junk byte and 3 good bytes: [But]
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
push word ptr 8309
pop dx
or [ecx+32], dx
imul edx, [ecx+32], 542312807
or [ecx+32], edx // 1 junk byte and 3 good bytes: [, ']
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
push 'dias'
pop edx
or [ecx+32], edx // 4 bytes: [said]
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
push ' ehs'
pop edx
or [ecx+32], edx // 4 bytes: [she ]
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
dec ecx
and [ecx+32], ah
push ' dnA'
pop edx
or [ecx+32], edx // 4 bytes: [And ]
push esp
pop edx
inc edx
pop eax
jmp dword ptr[edx-1]
}
}
int main()
{
char buf[100];
doit(buf);
puts(buf);
}