작업은 간단합니다. 머신 코드에서 인쇄 가능한 보이는 ASCII 문자 0x21 ... 0x7e (공백 및 델타는 허용되지 않음) 만 사용하여 x86 (32 비트) 및 x86-64 (64 비트)로 다르게 분기되는 프로그램을 작성하십시오. .
- 조건부 어셈블리는 허용되지 않습니다.
- API 호출을 사용할 수 없습니다.
- 커널 모드 (링 0) 코드 사용은 허용되지 않습니다.
- Linux 또는 다른 보호 모드 OS에서는 IA-32 및 x86-64 모두에서 예외를 발생시키지 않고 코드를 실행해야합니다.
- 기능은 명령 행 매개 변수에 의존해서는 안됩니다.
- 모든 명령어는 0x21 ... 0x7e (십진수 33 ... 126) 범위의 ASCII 문자 만 사용하여 머신 코드로 인코딩해야합니다. 예를 들어.
cpuid
한계 (그것의 부족0f a2
), 당신은 자기 수정 코드를 사용하지 않는. - 동일한 이진 코드는 x86 및 x86-64에서 실행되어야하지만 파일 헤더 (ELF / ELF64 / etc.)가 다를 수 있으므로 다시 조립해야합니다. 그러나 이진 코드는 변경해서는 안됩니다.
- 솔루션은 i386 ... Core i7 사이의 모든 프로세서에서 작동해야하지만 더 제한적인 솔루션에도 관심이 있습니다.
- 코드는 32 비트 x86으로 분기되어야하지만 x86-64에서는 분기되지 않아야합니다. 분기 대상 주소는 짧은 점프 (
jmp rel8
)가 들어가는 최소 2 바이트의 공간이되도록 일부 코드를위한 공간이 있어야합니다 .
이기는 정답은 머신 코드에서 최소 바이트를 사용하는 것입니다. 파일 헤더의 바이트 (예 : ELF / ELF64)는 계산되지 않으며 분기 이후 (테스트 목적 등)의 모든 바이트는 계산되지 않습니다.
답을 ASCII, 16 진 바이트 및 주석이 달린 코드로 제시하십시오.
내 솔루션, 39 바이트 :
ASCII : fhotfhatfhitfhutfhotfhatfhitfhut_H3<$t!
16 진수 : 66 68 6F 74 66 68 61 74 66 68 69 74 66 68 75 74 66 68 6F 74 66 68 61 74 66 68 69 74 66 68 75 74 5F 48 33 3C 24 74 21
.
암호:
; can be compiled eg. with yasm.
; yasm & ld:
; yasm -f elf64 -m amd64 -g dwarf2 x86_x86_64_branch.asm -o x86_x86_64_branch.o; ld x86_x86_64_branch.o -o x86_x86_64_branch
; yasm & gcc:
; yasm -f elf64 -m amd64 -g dwarf2 x86_x86_64_branch.asm -o x86_x86_64_branch.o; gcc -o x86_x86_64_branch x86_x86_64_branch.o
section .text
global main
extern printf
main:
push word 0x746f ; 66 68 6f 74 (x86, x86-64)
push word 0x7461 ; 66 68 61 74 (x86, x86-64)
push word 0x7469 ; 66 68 69 74 (x86, x86-64)
push word 0x7475 ; 66 68 75 74 (x86, x86-64)
push word 0x746f ; 66 68 6f 74 (x86, x86-64)
push word 0x7461 ; 66 68 61 74 (x86, x86-64)
push word 0x7469 ; 66 68 69 74 (x86, x86-64)
push word 0x7475 ; 66 68 75 74 (x86, x86-64)
db 0x5f ; x86: pop edi
; x86-64: pop rdi
db 0x48, 0x33, 0x3c, 0x24
; x86:
; 48 dec eax
; 33 3c 24 xor edi,[esp]
; x86-64:
; 48 33 3c 24 xor rdi,[rsp]
jz @bits_64 ; 0x74 0x21
; branch only if running in 64-bit mode.
; the code golf part ends here, 39 bytes so far.
; the rest is for testing only, and does not affect the answer.
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
jmp @bits_32
@bits_64:
db 0x55 ; push rbp
db 0x48, 0x89, 0xe5 ; mov rbp,rsp
db 0x48, 0x8d, 0x3c, 0x25 ; lea rdi,
dd printf_msg ; [printf_msg]
xor eax,eax
mov esi,64
call printf
db 0x5d ; pop rbp
NR_exit equ 60
xor edi,edi
mov eax,NR_exit ; number of syscall (60)
syscall
@bits_32:
lea edi,[printf_msg]
mov esi,32
call printf
mov eax,NR_exit
int 0x80
section .data
printf_msg: db "running in %d-bit system", 0x0a, 0