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*
16 진 덤프 :
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
)를 누를 때 0을 생성 할 수도 있습니다 .
and [ecx+32], ah
-ah = 0이라고 가정하면 바이트를 0으로 설정합니다. 출력 문자열의 길이가 32이므로 코드는 버퍼를 끝에서 끝까지 채 웁니다.
or [ecx+32], edx
-출력 바이트가 0으로 설정되어 있다고 가정하면 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);
}