Map and projects (the most frequently updated page of this blog)

2009/12/24

when VMs have only one opcode...

VMs are common in advanced packers or virii, but they seem to follow the same architectures (x86 or stack machine).
I was curious, and implemented, around a small fibonacci example, the usual models of course, but as well the TTA and Subleq ones, two models of one instruction set architectures.

Opcode-less VMs are quite small in code, but the virtual code is quite obscure - which makes an easy but annoying challenge:
typically, you would expect that MOV is the most basic opcode, and arithmetic operations tend to be more complex. But in Subleq, a standard MOV is made of 4 lines of code, while SUB+JLE is only 1.
I was quite surprised myself (yet, it works, of course!), which proves I'm too familiar with standard models.

What about you ?

Binary Source (MASM32)

To give you an idea, here is the virtual code in the Subleq example (while on the other hand, the VM code itself is only 14 lines of asm):
000: reg1, reg1, 00C
00C: rom0, reg0, 018
018: reg0, reg1, 024
024: reg0, reg0, 030
030: reg2, reg2, 03C
03C: reg0, reg0, 048
048: reg0, reg2, 054
054: reg0, reg0, 060
060: reg3, reg3, 06C
06C: rom1, reg0, 078
078: reg0, reg3, 084
084: reg0, reg0, 090
090: reg4, reg4, 09C
09C: reg3, reg0, 0A8
0A8: reg0, reg4, 0B4
0B4: reg0, reg0, 0C0
0C0: reg2, reg0, 0CC
0CC: reg0, reg4, 0D8
0D8: reg0, reg0, 0E4
0E4: reg2, reg2, 0F0
0F0: reg3, reg0, 0FC
0FC: reg0, reg2, 108
108: reg0, reg0, 114
114: reg3, reg3, 120
120: reg4, reg0, 12C
12C: reg0, reg3, 138
138: reg0, reg0, 144
144: rom2, reg0, 150
150: reg0, reg1, 15C
15C: reg0, reg0, 168
168: reg1, reg0, 180*
174: reg0, reg0, 090*
180: reg0, reg0, 18C
18C: reg0, reg1, 1A4*
198: reg0, reg0, 090*
1A4: reg1, reg1, 1B0
1B0: reg3, reg0, 1BC
1BC: reg0, reg1, 1C8
1C8: reg0, reg0, 1D4

* conditional jumps

[...]
Quand les MVs n'ont qu'une seule instruction...

Les machines virtuelles sont courantes dans les packeurs avancés ou les virus, mais elles semblent toujours faites avec les mêmes architectures (x86 ou a pile). J'étais curieux, et j'ai écrit, autour d'un petit exemple de Fibonacci, les architectures classiques, bien sûr, mais aussi la TTA et la Subleq, qui sont toutes deux des modèles a une seule instruction.

Une machine virtuelle sans instruction a un code minuscule, mais le code virtuel est plutôt obscur, ce qui en fait un challenge facile laa implémenter mais plutôt casse-pied. D'habitude, on s'attend a ce que MOV soit l'instruction la plus simple, et que les opérations arithmétiques soient plus complexes. Mais dans une machine Subleq, un MOV standard nécessite 4 lignes de code, alors qu'un SUB+JLE, une seule.
J'étais très surpris moi-même (même si ça marche, bien sûr), ce qui prouve que je suis trop habitués aux modèles standards.

Et vous ?

Binaire Source

Pour vous donner une idée, voici le code virtuel de l'exemple en Subleq (alors que le code de la machine virtuelle ne fait que 14 lignes d'assembleur):
000: reg1, reg1, 00C
00C: rom0, reg0, 018
018: reg0, reg1, 024
024: reg0, reg0, 030
030: reg2, reg2, 03C
03C: reg0, reg0, 048
048: reg0, reg2, 054
054: reg0, reg0, 060
060: reg3, reg3, 06C
06C: rom1, reg0, 078
078: reg0, reg3, 084
084: reg0, reg0, 090
090: reg4, reg4, 09C
09C: reg3, reg0, 0A8
0A8: reg0, reg4, 0B4
0B4: reg0, reg0, 0C0
0C0: reg2, reg0, 0CC
0CC: reg0, reg4, 0D8
0D8: reg0, reg0, 0E4
0E4: reg2, reg2, 0F0
0F0: reg3, reg0, 0FC
0FC: reg0, reg2, 108
108: reg0, reg0, 114
114: reg3, reg3, 120
120: reg4, reg0, 12C
12C: reg0, reg3, 138
138: reg0, reg0, 144
144: rom2, reg0, 150
150: reg0, reg1, 15C
15C: reg0, reg0, 168
168: reg1, reg0, 180*
174: reg0, reg0, 090*
180: reg0, reg0, 18C
18C: reg0, reg1, 1A4*
198: reg0, reg0, 090*
1A4: reg1, reg1, 1B0
1B0: reg3, reg0, 1BC
1BC: reg0, reg1, 1C8
1C8: reg0, reg0, 1D4

* sauts conditionnels

2 comments:

  1. Simpa ce type de machine virtuelle ;)
    Je ne connaissais pas ...

    Comme tu dis ca peux être rigolo de faire un petit challenge basé dessus

    ReplyDelete
  2. N'est-ce pas ? en plus, pour Subleq, le stub est si petit que ça doit être possible de le dissimuler méchamment.
    Et vu qu'il y a un compilateur Subleq apparemment disponible :)

    ReplyDelete