Added the morphing problem

Along with all of its generation script stuff...
This commit is contained in:
John W 2017-03-11 20:30:25 -06:00
parent febcc473f1
commit 23125c60af
27 changed files with 1059 additions and 0 deletions

BIN
self-modifier/b0.bin Normal file

Binary file not shown.

BIN
self-modifier/b1.bin Normal file

Binary file not shown.

BIN
self-modifier/b2.bin Normal file

Binary file not shown.

BIN
self-modifier/b3.bin Normal file

Binary file not shown.

1
self-modifier/b4.bin Normal file
View file

@ -0,0 +1 @@
¼°wþ;$ân6ßi2*­Élu ež5ry ãi<19>åဠriZ?{ hpŽ0ä0$ùæ˜ flêgkß5.NÓâ)ˆW LL$ræ¶rü]<05> U)xˆŠrLOüM“\(¬l¯%wØ8trrq"˜j9úM8Þ®89:<3A><=>GGÊGÉiH¬qÿJKL…NOP%Y\â_ÜμZ[\ª¼Öæ„bcd¦®ghi±klmbû<rþX{<7B>}£yz{•}~ý<7F><C3BD><35>€ÏbBbŒ<62>Ž|<7C>˜™šœ<E280BA>žŸ µ£¤¥¦§¨©ª±ãÁßÕ<C39F>²Œ´µ¶å¸¹º»½¼¼¼ÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄÄüüüüÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄļ¼¼¼DDDDLLLLDDDD\\\\DDDDLLLLDDDD||||DDDDLLLLDDDD\\\\DDDDLLLLDDDD¼¼¼¼ÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄÄüüüüÄÄÄÄÌÌÌÌÄÄÄÄÜÜÜÜÄÄÄÄÌÌÌÌÄÄÄļ¼¼¼DDDDLLLLDDDD\\\\DDDDLLLLDDDD||||DDDDLLLLDDDD\\\\

View file

@ -0,0 +1,5 @@
format binary
use32
include 'std.inc'
resv_stuff 512-$

Binary file not shown.

90
self-modifier/build.py Normal file
View file

@ -0,0 +1,90 @@
import subprocess
# Build a self-modifying thinga-ma-jig
def run_command(cmd):
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stdin=subprocess.PIPE)
stdoutput = proc.stdout.read() + proc.stderr.read()
return stdoutput
def build_bin(name):
print(run_command('fasm %s.asm' % name))
def create_xor_block(last_shellcode_block, next_shellcode_block):
block = bytearray(b'')
for x in range(0, len(last_shellcode_block)): # each shellcode block should be 512 bytes
block.append((last_shellcode_block[x]) ^ (next_shellcode_block[x]))
return bytes(block)
def get_shellcode_block(name):
build_bin(name)
f = open('%s.bin' % name, 'rb')
out = f.read()
f.close()
return out
shellcode_files = ['first', 'second', 'third', 'fourth', 'last']
shellcode_blocks = [get_shellcode_block('base_block')]
morpher_file = 'morpher'
morpher_template = 'morpher.template.asm'
xor_blocks = []
xor_block_files = []
def build_shellcode_files():
for x in shellcode_files:
shellcode_blocks.append(get_shellcode_block(x))
def gen_xor_blocks():
for x in range(0, len(shellcode_files)):
xor_block = create_xor_block(shellcode_blocks[x], shellcode_blocks[x+1])
xor_blocks.append(xor_block)
f = open('b%d.bin' % x, 'wb')
f.write(xor_block)
f.close()
xor_block_files.append('b%d.bin' % x)
def create_morpher_file():
_mrph = 'file \'base_block.bin\'\n'
_data = ''
_block_list = ''
for x in xor_block_files:
_data += '%s: file \'%s\'\n' % (x, x)
_block_list += '%s, ' % x
_data += 'block_ptrs dd %s0' % _block_list
f = open(morpher_template, 'rb')
template = f.read().decode('utf-8')
f.close()
result = template % (_mrph, _data)
f = open('%s.asm' % morpher_file, 'wb')
f.write(result.encode('utf-8'))
f.close()
# The morpher has 3 sections, modifiable code, static code (morphing), data
# Modifiable code will be where each shellcode segment is done
# Static code has the morpher that sets up each shellcode segment
# Data has the XOR block pointers and indicies for the ones to use in order
# Begins by the morpher creating the first shellcode block, setting it up, then running it
# continues until the final block that will print the flag
# Kinda like a binary bomb but in one binary
# On entrance to each shellcode segment the ebx register will be a vtable of std funcs
# printf
# puts
# scanf
# esi contains the base address of the shellcode segment
# edi contains the address of the part of the flag that this segment fills
# edx contains the number of the block
build_shellcode_files()
gen_xor_blocks()
create_morpher_file()
build_bin(morpher_file)
#print(create_xor_block(b'123', b'321'))
#print(get_shellcode_block('shellcode'))

84
self-modifier/char.inc Normal file
View file

@ -0,0 +1,84 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Character defines
NULL equ 0x00
BELL equ 0x07
BSPC equ 0x08
TAB equ 0x09
ENDL equ 0x0A
CRET equ 0x0D
CHAR_0 equ 0x30
CHAR_1 equ 0x31
CHAR_2 equ 0x32
CHAR_3 equ 0x33
CHAR_4 equ 0x34
CHAR_5 equ 0x35
CHAR_6 equ 0x36
CHAR_7 equ 0x37
CHAR_8 equ 0x38
CHAR_9 equ 0x39
CHAR_A equ 0x41
CHAR_B equ 0x42
CHAR_C equ 0x43
CHAR_D equ 0x44
CHAR_E equ 0x45
CHAR_F equ 0x46
CHAR_G equ 0x47
CHAR_H equ 0x48
CHAR_I equ 0x49
CHAR_J equ 0x4a
CHAR_K equ 0x4b
CHAR_L equ 0x4c
CHAR_M equ 0x4d
CHAR_N equ 0x4e
CHAR_O equ 0x4f
CHAR_P equ 0x50
CHAR_Q equ 0x51
CHAR_R equ 0x52
CHAR_S equ 0x53
CHAR_T equ 0x54
CHAR_U equ 0x55
CHAR_V equ 0x56
CHAR_W equ 0x57
CHAR_X equ 0x58
CHAR_Y equ 0x59
CHAR_Z equ 0x5a
CHAR_a equ 0x61
CHAR_b equ 0x62
CHAR_c equ 0x63
CHAR_d equ 0x64
CHAR_e equ 0x65
CHAR_f equ 0x66
CHAR_g equ 0x67
CHAR_h equ 0x68
CHAR_i equ 0x69
CHAR_j equ 0x6a
CHAR_k equ 0x6b
CHAR_l equ 0x6c
CHAR_m equ 0x6d
CHAR_n equ 0x6e
CHAR_o equ 0x6f
CHAR_p equ 0x70
CHAR_q equ 0x71
CHAR_r equ 0x72
CHAR_s equ 0x73
CHAR_t equ 0x74
CHAR_u equ 0x75
CHAR_v equ 0x76
CHAR_w equ 0x77
CHAR_x equ 0x78
CHAR_y equ 0x79
CHAR_z equ 0x7a
;;;;;;;;;;;;;;;;;;;;;;;;;;;
macro resv c_size
{
db c_size dup (0)
}
macro resv_stuff c_size
{
repeat c_size
db % and 0xff
end repeat
}

View file

@ -0,0 +1,2 @@
Welcome to the RE training course, this problem has 4 phases. Solve all four to get the flag.
[Download](${morpher_exe})

140
self-modifier/first.asm Normal file
View file

@ -0,0 +1,140 @@
format binary
use32
include 'std.inc'
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
; printf
; puts
; scanf
; sin
; cos
; tan
; asin
; acos
; atan
; malloc
; free
; esi contains the base address of the shellcode segment
; edi contains the address of the part of the flag that this segment fills
; edx contains the number of the block
start:
push edx
push edi
push esi
mov eax, dword [ebx]
lea ecx, [esi + base_txt]
push ecx
call dword [eax]
add esp, 4
xor eax, eax
push eax
mov eax, esp
push eax
lea eax, [ebx + 8]
mov eax, dword [eax]
lea ecx, [esi+scanf_txt]
push ecx
call dword [eax]
add esp, 8
; inputt'd float is now on top of the stack
pop eax
mov dword [esi+temp_val], eax
sub esp, 8
cvtss2sd xmm0, dword [esi+temp_val]
movsd qword [esp], xmm0
; call cos
lea eax, [ebx + 0x10]
mov eax, dword [eax]
call dword [eax]
fstp qword [esp]
movsd xmm0, qword [esp]
add esp, 8
cvtss2sd xmm1, dword [esi+c_val]
mulsd xmm0, xmm1
push ebp
push ebp
movsd qword [esp], xmm0
; call atan
lea eax, [ebx + 0x20]
mov eax, dword [eax]
call dword [eax]
fstp qword [esp]
movsd xmm0, qword [esp]
pop eax
cvtss2sd xmm1, dword [esi+b_val]
pop ecx
mulsd xmm0, xmm1
push esp
push ebp
movsd qword [esp], xmm0
; call sin
lea eax, [ebx + 0xc]
mov eax, dword [eax]
call dword [eax]
fstp qword [esp]
cvtss2sd xmm1, dword [esi+a_val]
movsd xmm0, qword [esp]
mulsd xmm0, xmm1
movsd qword [esp], xmm0
cvtsd2ss xmm0, qword [esp]
pop eax
movss dword [esp], xmm0
pop eax
pop esi
push esi
cmp eax, dword [esi+final_val]
jnz trash
lea ecx, [esi+right_txt]
jmp past_trash
trash:
lea ecx, [esi+wrong_txt]
; Make this so it crashes badly
inc esp
past_trash:
push ecx
lea eax, [ebx + 0x4]
mov eax, dword [eax]
call dword [eax]
pop ebp
pop esi
pop edi
pop edx
mov eax, dword [esi+temp_val]
; 0x61375a7b = little endian of '{Z7a'
; 0x61375a7b ^ 0x3fab396d which is the value of the correct input 1.33769
; is equal to 0x5e9c6316
xor eax, 0x5e9c6316
mov dword [edi], eax
xor eax, eax
mov dword [esi+temp_val], eax
retn
b_val dd 0x4039999a
base_txt db 'Please enter the best number', ENDL, 0
a_val dd 0x40d00000
scanf_txt db '%f', 0
final_val dd 0xc092e6a0
right_txt db 'You got it!', 0
c_val dd 0xbf99999a
wrong_txt db 'You dumb.', 0
temp_val dd 0
resv_stuff 512-$

BIN
self-modifier/first.bin Normal file

Binary file not shown.

167
self-modifier/fourth.asm Normal file
View file

@ -0,0 +1,167 @@
format binary
use32
include 'std.inc'
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
; printf
; puts
; scanf
; sin
; cos
; tan
; asin
; acos
; atan
; malloc
; free
; esi contains the base address of the shellcode segment
; edi contains the address of the part of the flag that this segment fills
; edx contains the number of the block
; 2 - 3,5 - '-'
; 3 - 5,7 - '_'
; 5 - 7,11 - 'e'
; 7 - 11,13 - 'x'
; 11 - 13,17 - 't'
; 13 - 17,19 - '}'
; 17 - 19,23 - '}'
; 19 - 23,29 - '}'
; 3 * 7 * 11 * 17 = 3927
; answer "2 4 6 12"
; flag _xt}
start:
push edi
lea eax, [ebx + 0x4]
lea ecx, [esi+startup_txt]
mov eax, dword [eax]
push ecx
call dword [eax]
pop ebp
pop edi
lea ebp, [esi+one]
.lp:
call process
cmp byte [ebp+8], 125
jnz .lp
mov eax, dword [esi+super_val]
cmp eax, 3927
jnz .bad
jmp .finish
.bad:
lea eax, [ebx + 0x4]
lea ecx, [esi+wrong_txt]
mov eax, dword [eax]
push ecx
call dword [eax]
pop ebp
inc esp
.finish:
ret
two:
dd three,five
db '-',2
startup_txt db 'Numberz?', 0
three:
dd five,seven
db '_',3
fmt_txt db '%u',0
five:
dd seven,eleven
db 'e',5
; ebp = current node
process:
push ebp
push ebp
mov eax, esp
push eax
lea eax, [ebx + 8]
lea ecx, [esi+fmt_txt]
mov eax, dword [eax]
push ecx
call dword [eax]
pop ebp
pop eax
pop ecx
pop ebp
movzx eax, byte [ebp+9]
cmp eax, ecx
jle above_handler
jmp below_handler
seven:
dd eleven,thirteen
db 'x',7
above_handler:
mov ecx, dword [ebp+4]
lea ebp, [esi+ecx]
jmp add_next_char
eleven:
dd thirteen,seventeen
db 't',11
mul_handler:
movzx eax, byte [ebp+9]
mov edx, dword [esi+super_val]
mul edx
mov dword [esi+super_val], eax
ret
thirteen:
dd seventeen, nineteen
db '}',13
below_handler:
mov ecx, dword [ebp]
lea ebp, [esi+ecx]
jmp add_next_char
seventeen:
dd nineteen, twentythree
db '}',17
add_next_char:
movzx eax, byte [ebp+8]
mov byte [edi], al
inc edi
jmp mul_handler
nineteen:
dd twentythree, twentynine
db '}',19
super_val dd 1
twentythree:
dd 0, 0
db ':',23
twentynine:
dd 0, 0
db ')',29
wrong_txt db 'Nope!',0
one:
dd two, three
db 0,1
resv_stuff 512-$

BIN
self-modifier/fourth.bin Normal file

Binary file not shown.

13
self-modifier/grader.py Normal file
View file

@ -0,0 +1,13 @@
def grade(random, key):
if key.find("Z7a_ok_qfme_xt") != -1:
return True, "Correct!"
incorrect_txt = 'Wrong. '
if key.find("Z7a") == -1:
incorrect_txt += "Phase 1 failed. "
if key.find("_ok_") == -1:
incorrect_txt += "Phase 2 failed. "
if key.find("qfme") == -1:
incorrect_txt += "Phase 3 failed. "
if key.find("_xt") == -1:
incorrect_txt += "Phase 4 failed. "
return False, incorrect_txt

37
self-modifier/last.asm Normal file
View file

@ -0,0 +1,37 @@
format binary
use32
include 'std.inc'
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
; printf
; puts
; scanf
; sin
; cos
; tan
; asin
; acos
; atan
; malloc
; free
; esi contains the base address of the shellcode segment
; edi contains the address of the part of the flag that this segment fills
; edx contains the number of the block
jmp start
output_text db 'Assuming you got every challenge right here is the flag: %s', ENDL, 0
start:
shl edx, 2
sub edi, edx
push edi
mov eax, dword [ebx]
lea ecx, [esi + output_text]
push ecx
call dword [eax]
add esp, 8
ret
resv_stuff 512-$

BIN
self-modifier/last.bin Normal file

Binary file not shown.

109
self-modifier/morpher.asm Normal file
View file

@ -0,0 +1,109 @@
format PE console
entry start
include 'C:\\Projects/asm/INCLUDE/win32a.inc'
include 'C:\\Projects/asm/std.inc'
section '.mrph' code readable executable writeable
mrph:
file 'base_block.bin'
section '.stat' code readable executable
data import
library msvcrt, 'msvcrt.dll'
import msvcrt, \
printf , 'printf', \
puts , 'puts', \
scanf , 'scanf', \
sin , 'sin', \
cos , 'cos', \
tan , 'tan', \
asin , 'asin', \
acos , 'acos', \
atan , 'atan', \
malloc , 'malloc', \
free , 'free', \
getchar , 'getchar'
end data
do_morph:
push ebp
mov eax, 1
mov edx, dword [num_block]
lea ecx, [block_ptrs + 4*edx]
mov ecx, dword [ecx]
cmp ecx, 0 ; If the block ptr is null return
jz .finish
inc edx
mov dword [num_block], edx
lea edx, [ecx+512]
mov edi, mrph
.mod:
cmp ecx, edx
jz .finish
movzx eax, byte [ecx]
movzx ebp, byte [edi]
xor eax, ebp
mov byte [edi], al
inc edi
inc ecx
xor eax, eax
jmp .mod
.finish:
pop ebp
ret
; No args, flushes input.
flush_inp:
call [getchar]
cmp eax, -1
jz .finish
cmp eax, ENDL
jnz flush_inp
.finish:
ret
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
; esi contains the base address of the shellcode segment
; edi contains the address of the part of the flag that this segment fills
; edx contains the number of the block
run_morphed:
mov esi, mrph
mov edx, dword [num_block]
dec edx
lea edi, [flag + 4*edx]
mov ebx, func_vtable
call mrph
ret
start:
call do_morph
cmp eax, 0
jnz .finish
call run_morphed
call flush_inp
jmp start
.finish:
ret
section '.dat' data readable writeable
num_block dd 0
func_vtable dd printf, puts, scanf, sin, cos, tan, asin, acos, atan, malloc, free, 0
flag db 64 dup (0)
b0.bin: file 'b0.bin'
b1.bin: file 'b1.bin'
b2.bin: file 'b2.bin'
b3.bin: file 'b3.bin'
b4.bin: file 'b4.bin'
block_ptrs dd b0.bin, b1.bin, b2.bin, b3.bin, b4.bin, 0

BIN
self-modifier/morpher.exe Normal file

Binary file not shown.

View file

@ -0,0 +1,103 @@
format PE console
entry start
include 'C:\\Projects/asm/INCLUDE/win32a.inc'
include 'C:\\Projects/asm/std.inc'
section '.mrph' code readable executable writeable
mrph:
%s
section '.stat' code readable executable
data import
library msvcrt, 'msvcrt.dll'
import msvcrt, \
printf , 'printf', \
puts , 'puts', \
scanf , 'scanf', \
sin , 'sin', \
cos , 'cos', \
tan , 'tan', \
asin , 'asin', \
acos , 'acos', \
atan , 'atan', \
malloc , 'malloc', \
free , 'free', \
getchar , 'getchar'
end data
do_morph:
push ebp
mov eax, 1
mov edx, dword [num_block]
lea ecx, [block_ptrs + 4*edx]
mov ecx, dword [ecx]
cmp ecx, 0 ; If the block ptr is null return
jz .finish
inc edx
mov dword [num_block], edx
lea edx, [ecx+512]
mov edi, mrph
.mod:
cmp ecx, edx
jz .finish
movzx eax, byte [ecx]
movzx ebp, byte [edi]
xor eax, ebp
mov byte [edi], al
inc edi
inc ecx
xor eax, eax
jmp .mod
.finish:
pop ebp
ret
; No args, flushes input.
flush_inp:
call [getchar]
cmp eax, -1
jz .finish
cmp eax, ENDL
jnz flush_inp
.finish:
ret
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
; esi contains the base address of the shellcode segment
; edi contains the address of the part of the flag that this segment fills
; edx contains the number of the block
run_morphed:
mov esi, mrph
mov edx, dword [num_block]
dec edx
lea edi, [flag + 4*edx]
mov ebx, func_vtable
call mrph
ret
start:
call do_morph
cmp eax, 0
jnz .finish
call run_morphed
call flush_inp
jmp start
.finish:
ret
section '.dat' data readable writeable
num_block dd 0
func_vtable dd printf, puts, scanf, sin, cos, tan, asin, acos, atan, malloc, free, 0
flag db 64 dup (0)
%s

39
self-modifier/out.txt Normal file
View file

@ -0,0 +1,39 @@
1
1
3
5
9
17
31
57
105
193
355
653
1201
2209
4063
7473
13745
25281
46499
85525
157305
289329
532159
978793
1800281
3311233
6090307
11201821
20603361
37895489
69700671
128199521
235795681
433695873
797691075
1467182629
2698569577
668475985
539260895

View file

@ -0,0 +1,7 @@
title: Morphin
category: Reverse Engineering
value: 450
author: r3ndom
autogen: false
files:
- morpher.exe

120
self-modifier/second.asm Normal file
View file

@ -0,0 +1,120 @@
format binary
use32
include 'std.inc'
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
; printf
; puts
; scanf
; sin
; cos
; tan
; asin
; acos
; atan
; malloc
; free
; esi contains the base address of the shellcode segment
; edi contains the address of the part of the flag that this segment fills
; edx contains the number of the block
push edi
lea ecx, [esi+pattern_text]
push ecx
lea eax, [ebx + 0x4]
mov eax, dword [eax]
call dword [eax]
pop ebp
mov ecx, 0
printLoop:
push ecx
call adv_fib
push eax
lea ecx, [esi + format_text]
mov eax, dword [ebx]
push ecx
call dword [eax]
pop ecx
pop ebp
pop ecx
inc ecx
cmp ecx, 6
jnz printLoop
lea ecx, [esi+empty_text]
lea eax, [ebx + 0x4]
mov eax, dword [eax]
push ecx
call dword [eax]
pop ebp
lea ecx, [esi+inputVal]
push ecx
lea eax, [ebx + 8]
mov eax, dword [eax]
lea ecx, [esi+unsignFmt]
push ecx
call dword [eax]
add esp, 8
mov ecx, dword [esi+inputVal]
pop edi
; 433695873 is the answer
; (struct.unpack('<I', b'_ok_')[0] ^ 0x19d9ac81)
; This part of the flag is _ok_ ^ the 35th value in the pattern.
xor ecx, 0x46b2c3de
mov dword [edi], ecx
push edi
lea ecx, [esi+pray_text]
mov eax, dword [ebx]
push ecx
call dword [eax]
pop ecx
pop edi
mov dword [esi+inputVal], 0
ret
pattern_text db 'What is the 35th number (index 34) in the following sequence?', 0
format_text db '%d ', 0
; ecx = arg
adv_fib:
cmp ecx, 2
jg do_more
mov eax, 1
ret
unsignFmt db '%u', 0
inputVal dd 0
do_more:
push edx
dec ecx
push ecx
call adv_fib
pop ecx
push eax
dec ecx
push ecx
call adv_fib
pop ecx
push eax
dec ecx
call adv_fib
pop edx
add eax, edx
pop edx
add eax, edx
pop edx
ret
empty_text db 0
pray_text db 'Hope you got it right! Result: [%s]', ENDL, 0
resv_stuff 512-$

BIN
self-modifier/second.bin Normal file

Binary file not shown.

32
self-modifier/std.inc Normal file
View file

@ -0,0 +1,32 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Standard Includes of my
; code
include 'char.inc'
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; File descriptor macros
STDIN equ 0
STDOUT equ 1
STDERR equ 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Standard prologue of a function
macro prologue
{
push ebp
mov ebp, esp
}
; Standard epilogue of a function
macro epilogue
{
mov esp, ebp
pop ebp
}
; Allocates space on the stack for something
macro local_alloc size
{
sub esp,size
}

110
self-modifier/third.asm Normal file
View file

@ -0,0 +1,110 @@
format binary
use32
include 'std.inc'
; On entrance to each shellcode segment the ebx register will be a vtable of std funcs
; printf
; puts
; scanf
; sin
; cos
; tan
; asin
; acos
; atan
; malloc
; free
; esi contains the base address of the shellcode segment
; edi contains the address of the part of the flag that this segment fills
; edx contains the number of the block
jmp start
startup_text db 'What did you say?',0
start:
push edi
lea ecx, [esi+startup_text]
push ecx
lea eax, [ebx + 0x4]
mov eax, dword [eax]
call dword [eax]
pop ebp
xor eax, eax
push eax
push eax
mov eax, esp
push eax
lea eax, [ebx + 8]
mov eax, dword [eax]
lea ecx, [esi+scanf_text]
push ecx
call dword [eax]
add esp, 8
pop ecx
pop eax
pop edi
mov dword [edi], ecx
lea edx, [esi+to_match]
.check:
movzx ecx, byte [edi]
call check_char
cmp eax, 0
jz idiot
inc edi
inc edx
cmp byte [edx], 0
jnz .check
ret
scanf_text db '%4[^',ENDL,']'
; ecx = input'd char
; edx = ptr to char to match
check_char:
cmp ecx, CHAR_a ; 97
jl fail
cmp ecx, 126
jge fail
sub ecx, CHAR_a ; 97
add ecx, esi
lea ecx, [ecx + alphabet]
movzx eax, byte [ecx]
cmp byte [edx], al
jnz fail
mov eax, 1
ret
idiot_text db 'Wrong...', 0
fail:
mov eax, 0
ret
to_match db 'ezpr', 0
idiot:
lea ecx, [esi+idiot_text]
push ecx
lea eax, [ebx + 0x4]
mov eax, dword [eax]
call dword [eax]
pop ebp
dec esp
ret
alphabet db '{m}krzyjfwngpshteoialduqxvcb|', 0
; abcdefghijklmnopqrstuvwxyz{|}
; flag is "qfme"
resv_stuff 512-$

BIN
self-modifier/third.bin Normal file

Binary file not shown.