Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Ut pars testimonii 0x0A DC7831 DEF CON Nizhny Novogardiae Die XVI mensis Februarii relationem de fundamentis emulationis codicis binarii et nostrae progressionis - ferramentorum tribunalis aemulantis exhibemus. Copycat.

In hoc articulo describemus quomodo fabrica firmware in aemulo currere, commercium cum debugger demonstrare, et parvam analysim dynamicam firmware peragere.

erectus

Iam olim in via lactea longe

A duobus abhinc annis in laboratorio nostro firmware machinam investigare opus erat. Firmware compressus et inpeditus cum bootloader. Hoc perplexo modo faciebat, ut pluries memoria notitias variaret. Ipsum autem firmware tunc cum periphericis active interact. Et omnis id in mips core.

Ob rationes obiectivas emulatores prompti nobis non placuerunt, sed adhuc codicem currere voluimus. Tunc aemulatorem nostrum facere decrevimus, quod minimum faceret, et nos firmware principalem exsolvere permitteret. Hoc conati sumus et elaboratum est. Putavimus quid si peripherales addimus ad firmware principalem etiam faciendam. Non multum nocuit - et elaboravit. Nos identidem putavimus emulatorem fusilem facere.

Effectus computatralis systematis aemulator fuit Copycat.

Rhinoceros intra felem - firmware currunt in Kopycat aemulator
Cur Kopycat?

Est fabula de verbis.

  1. copycat (latin, nomen [ˈkΙ’pΙͺkΓ¦t]) - imitator, imitator
  2. feles (Latin, noun [ˈkæt]) - cat, cattus - animal ventus unius auctorum rei
  3. Littera "K" est e lingua programmandi Kotlin

Copycat

Cum aemulo creando, certae propositae propositae sunt;

  • facultas cito novos peripherales, modulos, nucleos processus creandi;
  • facultas virtualem machinam ex variis modulis convenire;
  • facultas onerandi data quaelibet binaria (firmware) in memoriam virtualis artificii;
  • facultas operandi cum snapshots (snapshots of the system state);
  • facultas penitus cum emulatore per constructo-peculatore;
  • nice quod lingua moderna ad progressionem.

Quam ob rem Kotlin electa est ad exsequendam architecturae bus (hoc est cum moduli per virtualem datarum rerum inter se communicant), JSON ut fabrica descriptionis forma, et GDB RSP ut protocollum ad commercium cum debugger.

Progressus progressus est paulo plus duobus annis et active continuatur. Hoc tempore, MIPS, x86, V850ES, ARM, PowerPC nuclei processus effecti sunt.

Exertum crescit et tempus est ad ampliorem publicum exhibere. Singulos descriptiones propositi postea faciemus, sed nunc Kopycat utendo intendemus.

Impatientissimis, promo versio aemulatoris ex Link.

Rhinoceros aemulator

Recordemur antea in colloquio SMARTRHINO-2018, experimentum fabrica "Rhinoceros" creatum esse ad docendas artes machinationis adversas. Processus static firmware analysis descriptus est hoc articulum.

Nunc studeamus "oratores" addere et in emulatore firmware currere.

Nos postulo:
1) Java 1.8
II) Python et modulus jep uti Python intus aemulator. Potes aedificare WHL modulus Jep pro Fenestra hic download.

Pro Fenestra:
1) com0com
2) multa lotura separassem

Pro Linux:
I) socat

Eclipse uti potes, IDA Pro vel radare2 ut client GDB.

Quid opus est?

Ut in aemulo firmware perficias, necesse est virtualem machinam "congregare", quae verae notae analogum est.

Vera fabrica ("rhino") in obstructionum schemate ostendi potest:

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Emulator structuram modularem habet et ultima virtualis fabrica in tabella JSON describi potest.

JSON 105 lines

{
  "top": true,

  // Plugin name should be the same as file name (or full path from library start)
  "plugin": "rhino",

  // Directory where plugin places
  "library": "user",

  // Plugin parameters (constructor parameters if jar-plugin version)
  "params": [
    { "name": "tty_dbg", "type": "String"},
    { "name": "tty_bt", "type": "String"},
    { "name": "firmware", "type": "String", "default": "NUL"}
  ],

  // Plugin outer ports
  "ports": [  ],

  // Plugin internal buses
  "buses": [
    { "name": "mem", "size": "BUS30" },
    { "name": "nand", "size": "4" },
    { "name": "gpio", "size": "BUS32" }
  ],

  // Plugin internal components
  "modules": [
    {
      "name": "u1_stm32",
      "plugin": "STM32F042",
      "library": "mcu",
      "params": {
        "firmware:String": "params.firmware"
      }
    },
    {
      "name": "usart_debug",
      "plugin": "UartSerialTerminal",
      "library": "terminals",
      "params": {
        "tty": "params.tty_dbg"
      }
    },
    {
      "name": "term_bt",
      "plugin": "UartSerialTerminal",
      "library": "terminals",
      "params": {
        "tty": "params.tty_bt"
      }
    },
    {
      "name": "bluetooth",
      "plugin": "BT",
      "library": "mcu"
    },

    { "name": "led_0",  "plugin": "LED", "library": "mcu" },
    { "name": "led_1",  "plugin": "LED", "library": "mcu" },
    { "name": "led_2",  "plugin": "LED", "library": "mcu" },
    { "name": "led_3",  "plugin": "LED", "library": "mcu" },
    { "name": "led_4",  "plugin": "LED", "library": "mcu" },
    { "name": "led_5",  "plugin": "LED", "library": "mcu" },
    { "name": "led_6",  "plugin": "LED", "library": "mcu" },
    { "name": "led_7",  "plugin": "LED", "library": "mcu" },
    { "name": "led_8",  "plugin": "LED", "library": "mcu" },
    { "name": "led_9",  "plugin": "LED", "library": "mcu" },
    { "name": "led_10", "plugin": "LED", "library": "mcu" },
    { "name": "led_11", "plugin": "LED", "library": "mcu" },
    { "name": "led_12", "plugin": "LED", "library": "mcu" },
    { "name": "led_13", "plugin": "LED", "library": "mcu" },
    { "name": "led_14", "plugin": "LED", "library": "mcu" },
    { "name": "led_15", "plugin": "LED", "library": "mcu" }
  ],

  // Plugin connection between components
  "connections": [
    [ "u1_stm32.ports.usart1_m", "usart_debug.ports.term_s"],
    [ "u1_stm32.ports.usart1_s", "usart_debug.ports.term_m"],

    [ "u1_stm32.ports.usart2_m", "bluetooth.ports.usart_m"],
    [ "u1_stm32.ports.usart2_s", "bluetooth.ports.usart_s"],

    [ "bluetooth.ports.bt_s", "term_bt.ports.term_m"],
    [ "bluetooth.ports.bt_m", "term_bt.ports.term_s"],

    [ "led_0.ports.pin",  "u1_stm32.buses.pin_output_a", "0x00"],
    [ "led_1.ports.pin",  "u1_stm32.buses.pin_output_a", "0x01"],
    [ "led_2.ports.pin",  "u1_stm32.buses.pin_output_a", "0x02"],
    [ "led_3.ports.pin",  "u1_stm32.buses.pin_output_a", "0x03"],
    [ "led_4.ports.pin",  "u1_stm32.buses.pin_output_a", "0x04"],
    [ "led_5.ports.pin",  "u1_stm32.buses.pin_output_a", "0x05"],
    [ "led_6.ports.pin",  "u1_stm32.buses.pin_output_a", "0x06"],
    [ "led_7.ports.pin",  "u1_stm32.buses.pin_output_a", "0x07"],
    [ "led_8.ports.pin",  "u1_stm32.buses.pin_output_a", "0x08"],
    [ "led_9.ports.pin",  "u1_stm32.buses.pin_output_a", "0x09"],
    [ "led_10.ports.pin", "u1_stm32.buses.pin_output_a", "0x0A"],
    [ "led_11.ports.pin", "u1_stm32.buses.pin_output_a", "0x0B"],
    [ "led_12.ports.pin", "u1_stm32.buses.pin_output_a", "0x0C"],
    [ "led_13.ports.pin", "u1_stm32.buses.pin_output_a", "0x0D"],
    [ "led_14.ports.pin", "u1_stm32.buses.pin_output_a", "0x0E"],
    [ "led_15.ports.pin", "u1_stm32.buses.pin_output_a", "0x0F"]
  ]
}

Attende ad modulum firmware sectioni params nomen est fasciculi qui prope machinam tamquam firmware onerari potest.

Virtualis fabrica eiusque commercium cum principali systemate operante repraesentari possunt ex hoc schemate:

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Instantia currentis aemulatoris involvit commercium cum COM portubus principalis OS (debug UART et UART pro moduli Bluetooth). Hi possunt esse portus reales quibus machinae sunt coniunctae vel virtuales COM portus (hoc enim tibi tantum opus est com0com/socat).

Nunc sunt duae rationes principales cum aemulo extrinseco inter se cohaerentes;

  • GDB RSP protocollum (ita instrumenta quae hoc protocollum sustinentia sunt Eclipse / ISS / radare2);
  • internus aemulator order versus (Argparse or Python).

Lorem ipsum COM port

Ut cum UART virtualis artificii in machina locali per terminalem secant, debes par virtualis COM portubus coniungendis creare. In casu nostro unus portus ab aemulo adhibetur et secundus a programmate terminali (PUTTY vel screen);

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

per com0com

Virtual COM portus configurantur utentes utilitatum setup ex ornamento com0com (consolatae versionis - C:Programma Tabulariorum (x86)com0comsetupс.exe, aut GUI version - C:Programma Lima (x86)com0comsetupg.exe):

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Reprehendo boxes enable quiddam implendo omnes enim portus virtuales creati, alioquin aemulus responsionem a COM portu exspectabit.

per socat

In systemata UNIX virtuali COM portuum ab aemulo utente utilitate socatorum automatice creata sunt, ad hoc facere, modo praepositionem in portu nominis incipientis emulatoris designare. socat:.

Internum imperium lineae interface (Argparse vel Python)

Cum Kopycat applicationis consolatorium est, aemulator duas rectas lineas interfacies praepositos praebet ut cum suis obiectis et differentiis mutuo occurrant: Argparse et Python.

Argparse est CLI in Kopycat aedificata et omnibus semper praesto est.

Jocus cli Python interpres eft. Eo utere, debes modulum Jep Pythonis instituere et aemulatorem ad operandum cum Pythone configurare (instruitur Python interpres in systemate principali utentis).

Python moduli Jep

Sub Linux Jep per pituitam institui potest:

pip install jep

Ut Jep in Fenestra installare, debes primum in Fenestra SDK instituere et Microsoft Visual Studio respondente. Pervenimus paulo facilius ad vos and WHL builds JEP pro currentibus Pythonis pro Fenestra versionibus, modulus e tabella institui potest:

pip install jep-3.8.2-cp27-cp27m-win_amd64.whl

Ad reprimendam institutionem Jep, currere debes in linea mandati:

python -c "import jep"

Mandatum sequens debet recipi in responsione:

ImportError: Jep is not supported in standalone Python, it must be embedded in Java.

In batch aemulator lima pro ratio tua (copycat.bat - Pro Fenestra; copycat - pro Linux) ad indicem parametri DEFAULT_JVM_OPTS addere addito parametri Djava.library.path - continere debet viam ad moduli Jep installed.

Effectus in Fenestra linea talis debet esse:

set DEFAULT_JVM_OPTS="-XX:MaxMetaspaceSize=256m" "-XX:+UseParallelGC" "-XX:SurvivorRatio=6" "-XX:-UseGCOverheadLimit" "-Djava.library.path=C:/Python27/Lib/site-packages/jep"

Deductis Kopycat

Aemulus est consolatorium JVM applicatione. Lorem exercetur per mandatum operativum mandatum linee script (sh/cmd).

Mandatum currere sub Windows:

binkopycat -g 23946 -n rhino -l user -y library -p firmware=firmwarerhino_pass.bin,tty_dbg=COM26,tty_bt=COM28

Mandatum currere sub Linux utendi socatorum utilitate;

./bin/kopycat -g 23946 -n rhino -l user -y library -p firmware=./firmware/rhino_pass.bin, tty_dbg=socat:./COM26,tty_bt=socat:./COM28

  • -g 23646 β€” TCP portus qui patebit aditum GDB servo;
  • -n rhino - nomen principalis ratio moduli (congregata fabrica);
  • -l user - nomen bibliothecae ad quaerendum moduli praecipui;
  • -y library - iter ad quaerendum modulos in fabrica comprehensos;
  • firmwarerhino_pass.bin - iter ad limam firmware;
  • COM26 et COM28 virtuales sunt COM portus.

Quam ob rem promptum ostendetur Python > (aut Argparse >):

18:07:59 INFO [eFactoryBuilder.create ]: Module top successfully created as top
18:07:59 INFO [ Module.initializeAndRes]: Setup core to top.u1_stm32.cortexm0.arm for top
18:07:59 INFO [ Module.initializeAndRes]: Setup debugger to top.u1_stm32.dbg for top
18:07:59 WARN [ Module.initializeAndRes]: Tracer wasn't found in top...
18:07:59 INFO [ Module.initializeAndRes]: Initializing ports and buses...
18:07:59 WARN [ Module.initializePortsA]: ATTENTION: Some ports has warning use printModulesPortsWarnings to see it...
18:07:59 FINE [ ARMv6CPU.reset ]: Set entry point address to 08006A75
18:07:59 INFO [ Module.initializeAndRes]: Module top is successfully initialized and reset as a top cell!
18:07:59 INFO [ Kopycat.open ]: Starting virtualization of board top[rhino] with arm[ARMv6Core]
18:07:59 INFO [ GDBServer.debuggerModule ]: Set new debugger module top.u1_stm32.dbg for GDB_SERVER(port=23946,alive=true)
Python >

Commercium cum ISS Pro

Ad simpliciorem probationem utimur Rhinoceros firmware tamquam fasciculus fons analysi in IDA in forma ELF file meta informationes ibi recondita sunt.

Praecipua firmware sine meta notitia uti potes.

Postquam Kopycat in IDA Pro deductis, in menu Debugger ito ad item "Switch debugger…" et eligere "Longinquus GDB debuggerΒ». Deinde constitue nexum: menu Debugger - Processus optiones…

Valores constitue:

  • Applicationem - aliquem valorem
  • Hostname: 127.0.0.1 (vel IP oratio machinae remotae ubi Kopycat currit)
  • Portus: 23946

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Nunc debugging button fit available (F9 key):

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Preme illud coniungere ad debugger modulum in emulatore. ISS modum debugging ingreditur, fenestrae additae in promptu factae sunt: ​​informationes de registris, de ACERVUS.

Nunc omnia signa debugger uti possumus:

  • GRADATUS executionem instructionum (Gradus in ΠΈ Gradus super β€” claves F7 et F8, respective);
  • incipiens et intermissa executione;
  • partum breakpoints pro utroque codice ac data (F2 key).

Debugger coniungens codicem firmware currere non significat. Praesens exsecutio positionis debet esse oratio 0x08006A74 - satus munus Reset_Handler. Si librum per enumerationem, munus vocationem videre potes summa. Potes ponere cursorem in hac linea (inscriptio 0x08006ABE) Et operandi Currere ad cursor (clavem F4).

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Deinde, munus inire F7 urgere potes summa.

Si currunt imperium processus continue (F9 key), tunc "Quaeso exspectes" fenestra apparebit una cum globulis suspendat:

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Te postvlante suspendat exsecutio codicis firmware suspenditur et continuari potest ex eadem inscriptione in codice ubi interpolata est.

Si codicem exequi pergas, in terminationibus virtuali COM portibus sequentes lineas videbis;

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Praesentia lineae "status bypass" indicat virtualem Bluetooth moduli modum recipiendi notitia ex portu COM usoris.

Nunc in termino Bluetooth (COM29 in pictura) mandata intrare potes secundum protocollum Rhinoceros. Exempli gratia, mandatum "MEOW filum "mur-mur" ad terminum Bluetooth reddet:

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Non omnino me aemulari

Cum aemulum aedificas, gradum singillatim/emulationis alicuius artificii eligere potes. Exempli gratia, modulus Bluetooth diversimode aemulari potest:

  • plenius certamini praeceptis certatim aemulatur;
  • AT Imitantur imperia, et elata rivus recipitur a portu in COM praecipuorum ratio;
  • virtualis fabrica notitia directio ad realem machinam integram praebet;
  • ut simplex stipulas quae semper redit "OK".

Praesens aemuli versio utitur secundo accessu - modulus virtualis Bluetooth configurationem facit, post quem permutat modum "procurandi" data a COM portu systematis principalis ad UART portum aemulatoris.

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Consideremus facultatem instrumenti simplicis codicis in casu aliqua pars peripheriae non impletur. Exempli gratia, si timer author notitiarum moderandorum translationis ad DMA creata non est (perscriptio in officio exercetur. ws2812b_waitsita in * 0x08006840) Firmware ergo semper exspecta vexillum ut reset occupatussita in * 0x200004C4quod ostendit negotium datae lineae DMA;

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Possumus circa hunc statum per manually resetting vexillum occupatus statim post eum insertis. In IDA Pro, munus Pythonis creare potes et illud in fractione appellas, ipsumque punctum in codice pone post valorem 1 ad vexillum scribens. occupatus.

Breakpoint tracto

Primum, munus Pythonis in ISS efficiamus. Menu Tabularium - Scriptum mandatum...

Novum PRAECISIO in indicem sinistram adde, ei nomen da (exempli gratia; CPM),
In textu campi dextrorsum, codicem functionis intrant;

def skip_dma():
    print "Skipping wait ws2812..."
    value = Byte(0x200004C4)
    if value == 1:
        PatchDbgByte(0x200004C4, 0)
return False

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Post hoc urgemus Curre et claude fenestram script.

Nunc eamus in codicem 0x0800688A, pone breakpoint (F2 key), edit (context menu Edit breakpoint...) , Pythonti genus scriptionis imponere noli;

Rhinoceros intra felem - firmware currunt in Kopycat aemulator
Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Si vexillum valorem current occupatus pares I, tum munus exsequi debetis skip_dma in linea script;

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Si firmware exsecutionem curris, excitatio codicis tractatoris praevaricationis videri potest in fenestra IDAE Output per lineam Skipping wait ws2812.... Nunc firmware non expectandum ut reset vexillum occupatus.

Commercium cum aemulo

Aemulationis causa emulationis inconveniens est causare delectationem et gaudium. Multo magis interest si aemulator adiuvat inquisitorem ad videndum data in memoria vel commercium staminum instituendi.

Ostendemus tibi quomodo dynamice instituas commercium inter RTOS munia. Primum supplicium desistere debes si currit. Si ad munus bluetooth_task_entry ad processui ramus "DUXERIT" imperium (inscriptio" 0x080057B8), tunc videre potes quid primum creatum sit et deinde ad systema queue missum ledControlQueueHandle aliquid afferre.

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Pone tibi breakpoint to access the variabilis ledControlQueueHandlesita in * 0x20000624 ac perseveret exsequendum codicem;

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Quam ob rem, sistenda in inscriptione primo occurrunt 0x080057CA priusquam munus vocantem osMailAllocErgo in inscriptione 0x08005806 priusquam munus vocantem osMailPut, deinde aliquantulum temporis ad inscriptione 0x08005BD4 (Prius vocant munus osMailGetquod pertinet ad officium leds_task_entry (Led-nego), id est, munerum switched, et nunc LED-CIGERE imperium accepit.

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Hoc simplici modo statuere potes quomodo RTOS munia inter se mutuo inter se cohaereant.

Re quidem vera, commercium operum magis perplexum esse potest, sed aemulo utens, hoc commercium sequi minus laboriosum fit.

hic Videre potes brevem curriculi video aemuli deducendi et mutuo occurrentis cum IDA Pro.

Duc cum Radare2

Tam universale instrumentum quam Radare2 ignorare non potes.

Ad emulatorem utens r2 coniungere, mandatum hoc spectare videtur;

radare2 -A -a arm -b 16 -d gdb://localhost:23946 rhino_fw42k6.elf

Nunc praesto launch (dc) et mora executionis (Ctrl+C).

Infeliciter, in momento, r2 difficultates habet cum operando cum ferramentis gdb servientis et memoriae layout, ob hoc, breakpoints et gradibus non operantur (mandatum ds). Speramus quod mox figetur.

Currens cum Eclipse

Una bene utendi aemulo est debug firmware machinae crescendo. Ad claritatem, firmware Rhinoceros quoque utimur. Potes de firmware fontes hic.

Eclipse utemur a statuto ut IDE Systema Workbench pro STM32.

Ut aemulator firmware onus in Eclipse directe compilatus, modulo addere debes. firmware=null ad aemulatorem launch mandatum;

binkopycat -g 23946 -n rhino -l user -y modules -p firmware=null,tty_dbg=COM26,tty_bt=COM28

Debug configuratione profecta sunt

In Eclipse, eligere menu Curre - Debug configurationes... In fenestra quod aperit, in sectione GDB Hardware Debugging debes novam configurationem addere, deinde in "Main" tab denotare propositum ac applicationem ad debugging:

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

In "Debugger" tab debes denotare imperium GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

Ac etiam parametros intrant ut cum servo GDB (hospes et portus iungantur);

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

De "Satu" tab, sequentes parametri notare debes:

  • enable checkbox Load image (ita ut imago firmware congregata in emulatorem oneratur);
  • enable checkbox Symbola onus;
  • Lorem adde mandatum: set $pc = *0x08000004 (Pc actis mandare posuit in memoria ad valorem ex oratio 0x08000004 - oratio reponitur ibi ResetHandler).

placere note, si limam firmware ex Eclipse emittere non vis, optiones Load image ΠΈ Curre mandata nihil opus est.

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Post clicking Debug, potes operari in debugger modum:

  • gradatim codice supplicium
    Rhinoceros intra felem - firmware currunt in Kopycat aemulator
  • correspondent breakpoints
    Rhinoceros intra felem - firmware currunt in Kopycat aemulator

illud. Eclipsis has, hmm... aliquas vafras.... et cum illis vivere debes. Exempli gratia, si cum incipiendo debugger nuntium "Nullus fons praesto est" 0x0β€³" apparet, tunc mandatum Gradum exequi (F5)

Rhinoceros intra felem - firmware currunt in Kopycat aemulator

Sed in finem

Patrium codicem aemulatus valde interesting res est. Fieri potest ut elit fabrica fabrica firmware debug sine reali fabrica. Pro indagatione, opportunitas est analysim dynamicam codicem ducere, quae ne cum artificio semper fieri potest.

Speciales volumus providere cum instrumento opportuno, mediocriter simplici et non multum laboris et temporis ad instituendum et currendum.

Scribe in commentaria de experientia tua utens hardware aemulos. Invitamus te ad disputandum et ad interrogata respondebis laeta eris.

Tantum usores descripserunt in aliquet participare possunt. InscribeTe gratissimum esse.

Quo aemulo usus es?

  • Ut develop (debug) firmware

  • Im 'investigationes firmware

  • Ludos deduco (Dendi, Sega, PSP)

  • quid aliud (scribe in comment)

7 utentes censuerunt. 2 utentes abstinuerunt.

Quod software uteris ad aemulandum patrium codicem?

  • QEMU

  • Unicornis engine

  • Proteus

  • quid aliud (scribe in comment)

6 utentes censuerunt. 2 utentes abstinuerunt.

Quid vis emendare in emulatore quo uteris?

  • Volo celeritate

  • Volo otium of setup / launch

  • Plus bene volo pro mutuo cum aemulante (API, hamis)

  • Im 'laetus in omnibus

  • quid aliud (scribe in comment)

8 utentes censuerunt. 1 Insere abstinuisse.

Source: www.habr.com