hello there
This commit is contained in:
commit
7107be2bd0
7 changed files with 574 additions and 0 deletions
307
README.md
Normal file
307
README.md
Normal file
|
|
@ -0,0 +1,307 @@
|
||||||
|
# Lost Legacy
|
||||||
|
|
||||||
|
This is a CTF from [ph0wn](https://ctf.ph0wn.org/) 2021.
|
||||||
|
|
||||||
|
Thank to the team at ph0wn for the great CTF!
|
||||||
|
|
||||||
|
## Subject:
|
||||||
|
|
||||||
|
```
|
||||||
|
Pico the Croco has dug an old floppy disk of one of his first hacks, when he managed to infiltrate an authentification system. The small authenticator program (its size is 3 records only...) is still there along with the Id database (only 5 records), but unfortunately the system disk has faded up.
|
||||||
|
|
||||||
|
Hopefully there are emulators and archives on the net that will allow him to run the program again, but now the program asks him for an id and a password, and Pico doesn't fully remember his own id (and don't ask him for his password, that's more than 35 years old after all).
|
||||||
|
|
||||||
|
Yet, Pico remembers Niklaus Wirth was recognized by the authentication system, and that Pr. Wirth never hid his password ("Oberon is as simple as possible"). Of course the authenticator has all the ids, passwords and greetings in the greetings file, but they are all encrypted. That's too bad because there's a first flag for you in his greeting, and even a second flag in Pico's password (really? wow, that sounds like an anomaly in space-time continuum...).
|
||||||
|
|
||||||
|
Pico would gladly accept help from Martin Odersky or Peter Sollich, but these guys are way too busy now, so will you help him and catch these flags ? It's time to reverse that M-Code, in every sense...
|
||||||
|
|
||||||
|
Flags: There are 2 flags to find for this challenge, 1 for "Lost Legacy 1" and 1 for "Lost Legacy 2". You should normally find the first flag (for "Lost Legacy 1") before the second, but it is not totally impossible you find them in a different order. If this is the case and you find a valid flag but it is "not valid", try it on "Lost Legacy 2" (or reciprocally).
|
||||||
|
```
|
||||||
|
|
||||||
|
This challenge provide us with a `.sym`, a `.cmd` and a `database.bin`.
|
||||||
|
|
||||||
|
Obviously, `file` does not recognize the format:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ file greet.mcd
|
||||||
|
greet.mcd: DOS 2.0 backup id file, sequence 1
|
||||||
|
$ file greet.sym
|
||||||
|
greet.sym: data
|
||||||
|
$ file database.bin
|
||||||
|
database.bin: data
|
||||||
|
```
|
||||||
|
|
||||||
|
The instructions gives us a few names an mention Oberon (I'm still not sure if it is a language, an OS, or both).
|
||||||
|
|
||||||
|
After some research arround the subject (and a big hint on the discord :eyes:), I arrived to the conclusion that the `.sym` is bytecode from Modula 2.
|
||||||
|
|
||||||
|
More research on Modula brought me to this github user: Oric4ever (https://github.com/Oric4ever).
|
||||||
|
|
||||||
|
## Run the program:
|
||||||
|
|
||||||
|
First, he have a emulator to run this program on linux:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/Oric4ever/Turbo-Modula-2-Reloaded.git
|
||||||
|
cd Turbo-Modula-2-Reloaded/vm_linux
|
||||||
|
make
|
||||||
|
cp ../m2.dsk image.dsk
|
||||||
|
sudo mount -o loop ./image.dsk /mnt
|
||||||
|
sudo mkdir /mnt/EXAMPLES.DIR/PHOWN.DIR
|
||||||
|
sudo cp ../../greet.* /mnt/EXAMPLES.DIR/PHOWN.DIR/
|
||||||
|
sudo cp ../../database.bin /mnt/EXAMPLES.DIR/PHOWN.DIR/
|
||||||
|
./m2 # start the emulator
|
||||||
|
cd examples
|
||||||
|
cd phown
|
||||||
|
greet # start the program
|
||||||
|
```
|
||||||
|
|
||||||
|
First test to see if it works: try the given credentials:
|
||||||
|
|
||||||
|
```
|
||||||
|
Id : Niklaus Wirth
|
||||||
|
Pwd: Oberon is as simple as possible
|
||||||
|
Access granted...
|
||||||
|
Much respect, Professor, dear author of Pascal, Modula(-2), Oberon...
|
||||||
|
```
|
||||||
|
|
||||||
|
It works!
|
||||||
|
|
||||||
|
## Reverse
|
||||||
|
|
||||||
|
Now, we need a way to analyse the code. Once again, Oric4ever saves us by providing a dissassembler:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/Oric4ever/Reversing-Turbo-Modula2.git
|
||||||
|
cd Reversing-Turbo-Modula2
|
||||||
|
gcc unassemble.c -o unassemble
|
||||||
|
./unassemble ../greet.mcd
|
||||||
|
```
|
||||||
|
|
||||||
|
It takes a minute to get used to the syntax. The main point is the use of the stack for everything. Some functions/instructions are not really clear on what they take on argmument, but on the whole, it is readable.
|
||||||
|
|
||||||
|
There are 3 main procedures: `proc2` is the main function, `proc1` takes an array as argument end cipher it in place, `proc3` takes a byte in input and return a byte. `proc2` maps its input with `proc3`. For more details on `proc1` and `proc3`, see the equivalent code in `cipher.py`
|
||||||
|
|
||||||
|
### Patching
|
||||||
|
|
||||||
|
In `proc2`, we can see that the program decipher the greeting message from the database when the access is granted. Let's try to trick it to display a message without having the password.
|
||||||
|
|
||||||
|
Here is the line (`00d0`) checking if the access is granted:
|
||||||
|
|
||||||
|
```
|
||||||
|
00cf 27 load local word-7 # <-- word-7 = access granted
|
||||||
|
00d0 e3 20 jpfalse 00f2
|
||||||
|
00d2 8c 0a .. load immediate string "granted..."
|
||||||
|
```
|
||||||
|
|
||||||
|
Reminder: the jump destination is given by an offset in the binary instruction: `0x00f2=0x00d2+0x20`.
|
||||||
|
|
||||||
|
If we replace the `20` by `0` in the binary, the jump does nothing. Let's try that:
|
||||||
|
|
||||||
|
To patch the file, we can open `greet.mcd` with vim and use the command `:%!xxd` to get a hexa representation of the file. We just have to find the byte to modify and change it, but carefull not to touch anything else (`xxd` is touchy, even replacing a space by another space can have strange results on the binary). When it's done, `:%!xxd -r` to get back the binary format, save the file, put it on the emulator, and:
|
||||||
|
`:%!xxd -e`: `-e` because little endian
|
||||||
|
|
||||||
|
```
|
||||||
|
# greet2
|
||||||
|
Id : plop
|
||||||
|
Pwd: plop
|
||||||
|
Access granted...
|
||||||
|
(Intergalactic) Digital Research, Inc. Welcome, CEO, greetings to Dorothy...
|
||||||
|
```
|
||||||
|
|
||||||
|
Patching works! But can onlu get the greetings for the last user of the database.
|
||||||
|
|
||||||
|
Well, no probleme, let's patch a little more. Adding code in the middle of a binary is tricky, it might broke the program in a lot of way, so it is better to replace existing code by new code. Good think the tests that checks if the user and the password match take some place. We override those (after all, who need authentication?). We want to read the greating message from the file, apply `proc1` to it, then print the result. Here is the code:
|
||||||
|
|
||||||
|
```
|
||||||
|
23 load local word-3
|
||||||
|
82 18 load stack address 24
|
||||||
|
8d 4f load immediate 79
|
||||||
|
f1 call proc1
|
||||||
|
23 load local word-3
|
||||||
|
82 18 load stack address 24
|
||||||
|
8d 4f load immediate 79
|
||||||
|
f0 07 call TERMINAL.WriteString
|
||||||
|
f0 06 call TERMINAL.WriteLn
|
||||||
|
|
||||||
|
27 load local word-7 # to override the test after this code
|
||||||
|
27 load local word-7
|
||||||
|
27 load local word-7
|
||||||
|
27 load local word-7
|
||||||
|
```
|
||||||
|
|
||||||
|
We add `27` at the end to finish overiding the previous code. `nop` instructions would do the job, but I'm too lazzy to look for the right op-code. Loading `word-7` to the stack is harmless and do the job.
|
||||||
|
|
||||||
|
Here is the diff in the binary:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
000000b0: de02 27b6 e31d 2223 8d3f f01b 2423 8d10 ..'..."#.?..$#..
|
||||||
|
000000c0: 8d10 c4a0 de0a 2523 8208 8d20 8d20 c4a0 ......%#... . ..
|
||||||
|
000000d0: 37e4 278c 0741 6363 6573 7320 96f0 0727 7.'..Access ...'
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
000000b0: de02 27b6 e31d 2223 8d3f f01b 2382 188d ..'..."#.?..#...
|
||||||
|
000000c0: 4ff1 2382 188d 4ff0 07f0 0627 2727 2727 O.#...O..'''''''
|
||||||
|
000000d0: 37e4 278c 0741 6363 6573 7320 96f0 0727 7.'..Access ...'
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# greet
|
||||||
|
Id : histausse
|
||||||
|
Pwd: lik3sPl4typ0des
|
||||||
|
Much respect, Professor, dear author of Pascal, Modula(-2), Oberon...
|
||||||
|
Greetings to a Turbo Modula-2 author! We will miss Borland...
|
||||||
|
Welcome to a Turbo Modula-2 author! and congrats for Scala!
|
||||||
|
YES!!! Ph0wn{Pico hack3d this place!} Greetings to Axelle & Ludo...
|
||||||
|
(Intergalactic) Digital Research, Inc. Welcome, CEO, greetings to Dorothy...
|
||||||
|
Access denied.
|
||||||
|
```
|
||||||
|
|
||||||
|
We could try the same approche to print passwords, but sadly, the program compare the ciphered version of the IDs/Pwds in input with the already cipher version of the database.
|
||||||
|
|
||||||
|
We could continue to do crazy stuff by patching the programe: for instance, `proc1` is likely to be a bijection, so applying `proc1` to the cipher text enought times will endup deciphering the text. But its not worth it.
|
||||||
|
|
||||||
|
### Reversing and breaking the encryption procedure
|
||||||
|
|
||||||
|
`proc1` can be translate by:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def proc1(leng:int, s:str):
|
||||||
|
for w2 in range(leng):
|
||||||
|
w3 = s[w2]
|
||||||
|
s[w2] = proc3(w2+s[w2])
|
||||||
|
```
|
||||||
|
|
||||||
|
And `proc3` by:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def proc3(a):
|
||||||
|
w3 = 1
|
||||||
|
w2 = 1
|
||||||
|
w4 = a & 255
|
||||||
|
while (w2 <= w4):
|
||||||
|
w3 *= 3
|
||||||
|
while (w3 > 256):
|
||||||
|
w3 -= 257
|
||||||
|
w2 += 1
|
||||||
|
return w3 & 255
|
||||||
|
```
|
||||||
|
|
||||||
|
There is a usable version of those function in `cipher.py`. Let's test it:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python cipher.py "Niklaus Wirth"
|
||||||
|
0x9d
|
||||||
|
0xd
|
||||||
|
0x5e
|
||||||
|
0x4b
|
||||||
|
0xc9
|
||||||
|
0x99
|
||||||
|
0x33
|
||||||
|
0xa0
|
||||||
|
0x57
|
||||||
|
0xe2
|
||||||
|
0x5c
|
||||||
|
0xab
|
||||||
|
0xeb
|
||||||
|
$ xxd database.bin | head -n 1
|
||||||
|
00000000: 9d0d 5e4b c999 33a0 57e2 5cab eb98 0000 ..^K..3.W.\.....
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see, we get back the ciphered version of `"Niklaus Wirth"` found in the database.
|
||||||
|
|
||||||
|
Now, let's break it.
|
||||||
|
|
||||||
|
We have a small problem, because we have to find the number of time we execute a loop. We will have to do the hypothesis that `w2 > (a & 255)` is equivalent to `(w3 & 255) == proc3(a)`. From this hypothesis, it is not too hard to write a `decipher` function:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def decipher(l:list[int])->str:
|
||||||
|
values = []
|
||||||
|
for i, c in enumerate(l):
|
||||||
|
w3 = 1
|
||||||
|
w2 = 0 # There is a small off by one :)
|
||||||
|
while (w3 & 255) != c:
|
||||||
|
w3 *= 3
|
||||||
|
while (w3 > 256):
|
||||||
|
w3 -= 257
|
||||||
|
w2 += 1
|
||||||
|
values.append(chr(w2-i))
|
||||||
|
return "".join(values)
|
||||||
|
```
|
||||||
|
|
||||||
|
My problem now is that I'm not to sure about how the database is parsed. It looks alligned enought, so I doubt I will decipher every chunks of `32` bytes alligned with `16` bytes:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def read_database():
|
||||||
|
with open("database.bin", "br") as db:
|
||||||
|
for i in range(40):
|
||||||
|
db.seek(i*16)
|
||||||
|
chunk = db.read(32)
|
||||||
|
try:
|
||||||
|
print(decipher(chunk))
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
```
|
||||||
|
|
||||||
|
Not very elegent, but good enough:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ python decipher.py
|
||||||
|
Niklaus Wirthrq?RUb_^YcQccY]
|
||||||
|
Oberon is as simple as possible
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
FF!#Õ^~&6n¹k)ÒBÏ1L½
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
Turbo Modula-2qponmlkjihgfedcba
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
|MübW[ð®4]Å¿:
|
||||||
|
66]hKæZ¬Êß N
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
Scala4everutsrqponmlkjihgfedcba
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
!ÇÝæ¼Ç"ÌWçFwaxgÍâ>®\
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
Pico le crocorq@X g^kD="XQS[c
|
||||||
|
Ph0wn{TM2 hacks NW's work!}dcba
|
||||||
|
^g70{1tsrq¤XÄ
|
||||||
|
á Õt3l
|
||||||
|
©´hÔñ°£åC|ÉÜ(R°t{ã+߯ɹ
|
||||||
|
Ù'ì8bÀó;£ï¿ÙÉ*ë!¼#t!¿®½
|
||||||
|
er9BU ¤/¤¾ÍÃnÒ'ß#
|
||||||
|
Ó~â(7ï3uIRe0´?Q³UwaxgÍâ>®\
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
Gates is nuts!qponmlkjihgfedcba
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
Î9Ï ·=Ä)aîAy§ËG0·d¦
|
||||||
|
xÈ
|
||||||
|
U} VeÎtu±\K&
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
chr() arg not in range(0x110000)
|
||||||
|
```
|
||||||
|
|
||||||
|
We can see that `Pico le croco` uses the password `Ph0wn{TM2 hacks NW's work!}` :)
|
||||||
|
|
||||||
|
Just for fun:
|
||||||
|
|
||||||
|
```
|
||||||
|
# greet
|
||||||
|
Id : Pico le croco
|
||||||
|
Pwd: Ph0wn{TM2 hacks NW's work!}
|
||||||
|
Access granted...
|
||||||
|
YES!!! Ph0wn{Pico hack3d this place!} Greetings to Axelle & Ludo...
|
||||||
|
```
|
||||||
27
cipher.py
Normal file
27
cipher.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def proc1(s:str)->list[int]:
|
||||||
|
ret_list = []
|
||||||
|
for i, c in enumerate(s):
|
||||||
|
ret_list.append(proc3(ord(c)+i))
|
||||||
|
return ret_list
|
||||||
|
|
||||||
|
def proc3(a:int):
|
||||||
|
w3 = 1
|
||||||
|
w2 = 1
|
||||||
|
w4 = a & 255
|
||||||
|
while (w2 <= w4):
|
||||||
|
w3 *= 3
|
||||||
|
while (w3 > 256):
|
||||||
|
w3 -= 257
|
||||||
|
w2 += 1
|
||||||
|
return w3 & 255
|
||||||
|
|
||||||
|
def test(s):
|
||||||
|
for c in proc1(s):
|
||||||
|
print(hex(c))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test(sys.argv[1])
|
||||||
BIN
database.bin
Normal file
BIN
database.bin
Normal file
Binary file not shown.
37
decipher.py
Normal file
37
decipher.py
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from cipher import proc1
|
||||||
|
TEST_ID = "Niklaus Wirth"
|
||||||
|
TEST_PWD = "Oberon is as simple as possible"
|
||||||
|
|
||||||
|
def decipher(l:list[int])->str:
|
||||||
|
values = []
|
||||||
|
for i, c in enumerate(l):
|
||||||
|
w3 = 1
|
||||||
|
w2 = 0 # There is a small off by one :)
|
||||||
|
while (w3 & 255) != c:
|
||||||
|
w3 *= 3
|
||||||
|
while (w3 > 256):
|
||||||
|
w3 -= 257
|
||||||
|
w2 += 1
|
||||||
|
values.append(chr(w2-i))
|
||||||
|
return "".join(values)
|
||||||
|
|
||||||
|
def read_database():
|
||||||
|
with open("database.bin", "br") as db:
|
||||||
|
for i in range(40):
|
||||||
|
db.seek(i*16)
|
||||||
|
chunk = db.read(32)
|
||||||
|
try:
|
||||||
|
print(decipher(chunk))
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
print(decipher(proc1(TEST_ID)))
|
||||||
|
print(decipher(proc1(TEST_PWD)))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
read_database()
|
||||||
BIN
greet.mcd
Normal file
BIN
greet.mcd
Normal file
Binary file not shown.
BIN
greet.sym
Normal file
BIN
greet.sym
Normal file
Binary file not shown.
203
greet.txt
Normal file
203
greet.txt
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
module start at 0140
|
||||||
|
0140 : Module GREET
|
||||||
|
depends on TERMINAL
|
||||||
|
depends on FILES
|
||||||
|
depends on TEXTS
|
||||||
|
|
||||||
|
GREET.proc0: 011c
|
||||||
|
GREET.proc1: 0032
|
||||||
|
GREET.proc2: 005b
|
||||||
|
GREET.proc3: 0001
|
||||||
|
GREET.proc4: 004e
|
||||||
|
|
||||||
|
# GREET.proc3: # CF the python code for this one
|
||||||
|
0001 d4 f9 enter -7
|
||||||
|
0003 91 load immediate 1
|
||||||
|
0004 33 store local word-3
|
||||||
|
0005 91 load immediate 1
|
||||||
|
0006 32 store local word-2
|
||||||
|
0007 03 load param1
|
||||||
|
0008 8d ff load immediate 255
|
||||||
|
000a e8 bitwise_and
|
||||||
|
000b 34 store local word-4
|
||||||
|
000c 22 load local word-2
|
||||||
|
000d 24 load local word-4
|
||||||
|
000e a4 uless_or_equal
|
||||||
|
000f e3 1a jpfalse 002b
|
||||||
|
0011 23 load local word-3
|
||||||
|
0012 23 load local word-3
|
||||||
|
0013 a6 add
|
||||||
|
0014 23 load local word-3
|
||||||
|
0015 a6 add
|
||||||
|
0016 33 store local word-3
|
||||||
|
0017 23 load local word-3
|
||||||
|
0018 8e 00 01 load immediate 256
|
||||||
|
001b a3 ugreater_than
|
||||||
|
001c e3 08 jpfalse 0026
|
||||||
|
001e 23 load local word-3
|
||||||
|
001f 8e ff fe load immediate -257
|
||||||
|
0022 a6 add
|
||||||
|
0023 33 store local word-3
|
||||||
|
0024 e4 0f jp 0017
|
||||||
|
0026 22 load local word-2
|
||||||
|
0027 ac inc
|
||||||
|
0028 32 store local word-2
|
||||||
|
0029 e4 1f jp 000c
|
||||||
|
002b 23 load local word-3
|
||||||
|
002c 8d ff load immediate 255
|
||||||
|
002e e8 bitwise_and
|
||||||
|
002f 85 81 fct_leave 129
|
||||||
|
0031 ff
|
||||||
|
|
||||||
|
# GREET.proc1: # Encrypt / HASH ? ciffer(string, len)
|
||||||
|
0032 d4 fb enter -5
|
||||||
|
0034 90 load immediate 0
|
||||||
|
0035 32 store local word-2 # w2 = 0
|
||||||
|
0036 04 load param2 # start of loop
|
||||||
|
0037 22 load local word-2
|
||||||
|
0038 0d load indexed byte
|
||||||
|
0039 33 store local word-3 # w3 = str[w2] ?
|
||||||
|
003a 04 load param2
|
||||||
|
003b 22 load local word-2
|
||||||
|
003c 23 load local word-3
|
||||||
|
003d 22 load local word-2
|
||||||
|
003e a6 add # load w2 + str[w2] ?
|
||||||
|
003f f3 call proc3
|
||||||
|
0040 1d store indexed byte # str[w2] = proc3(w2+str[w2])
|
||||||
|
0041 22 load local word-2 # w2 ++
|
||||||
|
0042 ac inc
|
||||||
|
0043 32 store local word-2
|
||||||
|
0044 22 load local word-2
|
||||||
|
0045 03 load param1
|
||||||
|
0046 a3 ugreater_than # w2 > len
|
||||||
|
0047 df 02 orjp 004b
|
||||||
|
0049 23 load local word-3
|
||||||
|
004a ab eq0
|
||||||
|
004b e5 17 jpfalse 0036
|
||||||
|
004d 8a leave4
|
||||||
|
|
||||||
|
GREET.proc4:
|
||||||
|
004e 64 load stack word4
|
||||||
|
004f 61 load stack word1
|
||||||
|
0050 74 store stack word4
|
||||||
|
0051 61 load stack word1
|
||||||
|
0052 62 load stack word2
|
||||||
|
0053 61 load stack word1
|
||||||
|
0054 73 store stack word3
|
||||||
|
0055 65 load stack word5
|
||||||
|
0056 2e 62 load stack word 98
|
||||||
|
0058 69 load stack word9
|
||||||
|
0059 6e load stack word14
|
||||||
|
005a ff
|
||||||
|
|
||||||
|
# GREET.proc2:
|
||||||
|
005b d4 f3 enter -13
|
||||||
|
005d 8d 80 load immediate 128
|
||||||
|
005f d2 reserve
|
||||||
|
0060 33 store local word-3
|
||||||
|
0061 8d 10 load immediate 16
|
||||||
|
0063 d2 reserve
|
||||||
|
0064 34 store local word-4
|
||||||
|
0065 8d 20 load immediate 32
|
||||||
|
0067 d2 reserve
|
||||||
|
0068 35 store local word-5
|
||||||
|
0069 8c 05 .. load immediate string "Id : "
|
||||||
|
0070 94 load immediate 4
|
||||||
|
0071 f0 07 call TERMINAL.WriteString
|
||||||
|
0073 24 load local word-4
|
||||||
|
0074 9f load immediate 15
|
||||||
|
0075 f0 04 call TERMINAL.ReadLine
|
||||||
|
0077 24 load local word-4 # word-4 = ID
|
||||||
|
0078 9f load immediate 15
|
||||||
|
0079 f1 call proc1
|
||||||
|
007a 8c 05 .. load immediate string "Pwd: "
|
||||||
|
0081 94 load immediate 4
|
||||||
|
0082 f0 07 call TERMINAL.WriteString
|
||||||
|
0084 25 load local word-5
|
||||||
|
0085 8d 1f load immediate 31
|
||||||
|
0087 f0 04 call TERMINAL.ReadLine
|
||||||
|
0089 25 load local word-5 # word-5 = Pwd
|
||||||
|
008a 8d 1f load immediate 31
|
||||||
|
008c f1 call proc1
|
||||||
|
008d 80 fe load local address -2
|
||||||
|
008f 02 04 load proc_addr proc4
|
||||||
|
0091 9b load immediate 11
|
||||||
|
0092 f0 11 call FILES.Open
|
||||||
|
0094 e3 6a jpfalse 0100 # if open fails
|
||||||
|
0096 22 load local word-2
|
||||||
|
0097 ef 01 14 call FILES.NoTrailer
|
||||||
|
009a 90 load immediate 0
|
||||||
|
009b 37 store local word-7 # let's call word-7 "user_found"
|
||||||
|
009c 22 load local word-2 # while (not end of file and not user_found) ----
|
||||||
|
009d f0 18 call FILES.EOF # // word-2 is the file descriptor
|
||||||
|
009f b6 not
|
||||||
|
00a0 de 02 andjp 00a4
|
||||||
|
00a2 27 load local word-7
|
||||||
|
00a3 b6 not
|
||||||
|
00a4 e3 1d jpfalse 00c3
|
||||||
|
00a6 22 load local word-2
|
||||||
|
00a7 23 load local word-3
|
||||||
|
00a8 8d 3f load immediate 63
|
||||||
|
00aa f0 1b call FILES.ReadRec # read(database, world-3)
|
||||||
|
00ac 24 load local word-4 # // read 64 bytes? and put it in world-3
|
||||||
|
00ad 23 load local word-3
|
||||||
|
00ae 8d 10 load immediate 16
|
||||||
|
00b0 8d 10 load immediate 16
|
||||||
|
00b2 c4 string_comp # user_found = (word-3 == cipher(ID))
|
||||||
|
00b3 a0 equal
|
||||||
|
00b4 de 0a andjp 00c0
|
||||||
|
00b6 25 load local word-5
|
||||||
|
00b7 23 load local word-3
|
||||||
|
00b8 82 08 load stack address 8 # <- not sure what is does? add an offset?
|
||||||
|
00ba 8d 20 load immediate 32
|
||||||
|
00bc 8d 20 load immediate 32
|
||||||
|
00be c4 string_comp # user_found &= (word-3bis == cipher(PWD))
|
||||||
|
00bf a0 equal
|
||||||
|
00c0 37 store local word-7
|
||||||
|
00c1 e4 27 jp 009c # end while ----------------------------------------
|
||||||
|
00c3 8c 07 .. load immediate string "Access "
|
||||||
|
00cc 96 load immediate 6
|
||||||
|
00cd f0 07 call TERMINAL.WriteString
|
||||||
|
00cf 27 load local word-7
|
||||||
|
00d0 e3 20 jpfalse 00f2
|
||||||
|
00d2 8c 0a .. load immediate string "granted..."
|
||||||
|
00de 99 load immediate 9
|
||||||
|
00df f0 07 call TERMINAL.WriteString
|
||||||
|
00e1 f0 06 call TERMINAL.WriteLn
|
||||||
|
00e3 23 load local word-3
|
||||||
|
00e4 82 18 load stack address 24
|
||||||
|
00e6 8d 4f load immediate 79
|
||||||
|
00e8 f1 call proc1 # This is intersting.
|
||||||
|
00e9 23 load local word-3 # Eigher the cipher is an involution (doubious)
|
||||||
|
00ea 82 18 load stack address 24 # or the greeting is encoded with the invers of
|
||||||
|
00ec 8d 4f load immediate 79 # cipher
|
||||||
|
00ee f0 07 call TERMINAL.WriteString
|
||||||
|
00f0 e2 0c jp 00fe
|
||||||
|
00f2 8c 07 .. load immediate string "denied."
|
||||||
|
00fb 96 load immediate 6
|
||||||
|
00fc f0 07 call TERMINAL.WriteString
|
||||||
|
00fe e2 14 jp 0114
|
||||||
|
0100 02 04 load proc_addr proc4 # *proc4 = database.bin
|
||||||
|
0102 9b load immediate 11
|
||||||
|
0103 f0 07 call TERMINAL.WriteString
|
||||||
|
0105 8c 0a .. load immediate string " not found"
|
||||||
|
0111 99 load immediate 9
|
||||||
|
0112 f0 07 call TERMINAL.WriteString
|
||||||
|
0114 f0 06 call TERMINAL.WriteLn
|
||||||
|
0116 80 fe load local address -2
|
||||||
|
0118 f0 13 call FILES.Close
|
||||||
|
011a 88 leave0
|
||||||
|
011b ff
|
||||||
|
|
||||||
|
# GREET.proc0:
|
||||||
|
011c d4 ff enter -1
|
||||||
|
011e f2 call proc2
|
||||||
|
011f 50 end_program
|
||||||
|
0120 2d ff load global word 255
|
||||||
|
0122 de fe andjp 0222
|
||||||
|
0124 36 store local word-6
|
||||||
|
0125 ff call proc15
|
||||||
|
0126 0b ff f3 load .dword243
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue